Event catalog
This catalog is the published mirror of Paylera’s single source of truth for
event types — contracts/vocabulary.yaml (which also generates the SDK
constants). Every event Paylera emits is listed here; anything not on this page
is not emitted.
Subscribe to the exact event types you care about, or leave the endpoint’s
event list empty to receive all of them. There is no prefix or wildcard
matching — subscription.* is not a valid subscription; list each type. In
production prefer an explicit list over “all” so a new event type doesn’t
silently start hitting your handler.
Events are grouped by aggregate. The second segment is a past-tense action.
Subscriptions
| Event | When |
|---|---|
subscription.created | Subscription created (in any starting state — trialing, active, or pending_activation). |
subscription.updated | A subscription field changed (quantity, metadata, payment method, etc.). Carries previous_attributes; usually re-fetch. |
subscription.plan_changed | The plan actually changed — immediately for upgrades and longer-cycle switches, or at the period roll when a scheduled change applies. plan_id now points at the new plan. See the payload below. |
subscription.plan_change_scheduled | A downgrade or shorter-cycle switch was queued; it applies at the period roll (effective_at). See the payload below. |
subscription.plan_change_unscheduled | A queued plan change was reverted before the roll; the subscription stays on its current plan. |
subscription.cancel_scheduled | cancel_at_period_end was set — cancellation is scheduled for the current period end. |
subscription.canceled | Transitioned to canceled. |
subscription.expired | Subscription reached the end of its life and transitioned to ended. |
subscription.paused | Transitioned to paused. |
subscription.resumed | Returned to active from paused. |
subscription.trial_ended | Trial ended; transitioned to active or past_due. |
subscription.entitlements_changed | A per-subscription entitlement override was upserted or cleared; affects exactly this subscription. |
subscription.commitment_emitted | A commitment shortfall landed as a top-up line on the period’s invoice; carries the shortfall amount. |
subscription.commitment_satisfied | The period met the commitment floor without a top-up (evidence event, no charge). |
subscription.plan_changed payload
A compact transition payload — the from/to plan ids and timestamp, not the full subscription object:
{ "subscription_id": "…", "from_plan_id": "…", "to_plan_id": "…", "status": "active", "plan_changed_at": "2026-07-15T04:58:56Z"}subscription.plan_change_scheduled payload
{ "subscription_id": "…", "current_plan_id": "…", "scheduled_plan_id": "…", "status": "active", "scheduled_at": "2026-07-16T09:12:00Z", "effective_at": "2026-08-01T00:00:00Z"}effective_at is the current period end — the moment the swap applies (a
subscription.plan_changed event fires then). If the change is reverted first,
subscription.plan_change_unscheduled fires instead, carrying
unscheduled_plan_id and unscheduled_at.
Invoices
| Event | When |
|---|---|
invoice.finalized | Draft transitioned to open. |
invoice.issued | Invoice issued to the customer. |
invoice.paid | Transitioned to paid. |
invoice.partially_paid | A payment covered part of the balance; invoice is partially_paid. |
invoice.overdue | An open/partially_paid invoice aged past its due_at. |
invoice.voided | Transitioned to void. |
invoice.uncollectible | Transitioned to uncollectible. |
invoice.credit_note_issued | A credit note was issued against this invoice. |
invoice.credit_note_voided | A credit note on this invoice was voided. |
Payments
| Event | When |
|---|---|
payment.requires_action | 3DS / SCA needed; see data.next_action. |
payment.succeeded | Capture succeeded. |
payment.failed | Capture failed; reason in data.last_error. |
payment.refunded | The payment was refunded (fully or partially). |
payment.charged_back | The customer initiated a chargeback. |
payment_state_conflict | Ops signal: the reconciler rejected a provider transition that was illegal for the payment’s current state. |
Dunning
| Event | When |
|---|---|
dunning.opened | A dunning cycle opened after a failed payment. |
dunning.retry_scheduled | A dunning retry was scheduled. |
dunning.awaiting_customer_action | The cycle is waiting on the customer (e.g. SCA / a new card). |
dunning.resolved | Dunning succeeded; the subscription is back to active. |
dunning.exhausted | The dunning policy ran out of attempts. |
Hosted checkout
Note the underscore — these are checkout_session.* events (not the dotted
checkout.session.* names Stripe uses).
| Event | When |
|---|---|
checkout_session.created | A hosted-checkout session URL was created. |
checkout_session.completed | The customer finished checkout. |
checkout_session.expired | The session TTL elapsed without completion. |
checkout_session.canceled | The merchant canceled the session before completion. |
Catalog & entitlements
| Event | When |
|---|---|
plan.entitlements_changed | A plan’s entitlement grant was upserted or cleared; affects every subscription on that plan. |
product.deleted / plan.deleted / feature.deleted / billable_metric.deleted | The catalog row was soft-deleted (archived) via the idempotent DELETE …/{code} surface. |
Coupons
| Event | When |
|---|---|
coupon.created / coupon.archived / coupon.restored | Coupon management lifecycle. |
coupon.redeemed | A customer attached the coupon (POST …/redeem). |
coupon.detached | The coupon was removed from a customer. |
Subscription credits
| Event | When |
|---|---|
subscription_credit.granted | A new-cycle credit grant was posted. |
subscription_credit.consumed | A usage track call debited an active grant. |
subscription_credit.rolled_over | Prior-cycle leftover survived the rollover policy into the new cycle. |
subscription_credit.expired | The remaining balance was written off at cycle end or rolled-credit TTL. |
Customers
| Event | When |
|---|---|
customer.created | Customer object created. |
customer.updated | Any customer field changed. |
customer.external_ref_discovered | The RevenueAttribution worker back-linked a previously-orphaned revenue.* row to this customer via an email-fingerprint match. Payload: customer_id, tenant_id, provider, external_id, revenue_event_id, discovered_at, discovery_method (v1: email_fingerprint). |
Affiliates & payouts
| Event | When |
|---|---|
affiliate.commission_payable | A commission’s hold period elapsed and it became payable. |
affiliate.commission_paid | A commission was paid out. |
affiliate.commission_reversed | The originating payment was refunded/charged back; the commission was reversed. |
affiliate.commission_clawed_back | An already-paid commission was clawed back. |
payout_batch.submitted | A payout batch was submitted to the provider. |
payout_batch.completed | Every transfer in the batch succeeded. |
payout_batch.failed | A transfer in the batch failed. |
referral.earnings_accrued | A referred tenant paid a Paylera platform invoice, accruing referral earnings. |
Referrals (customer-to-customer)
Rewards for a merchant’s own customers referring each other. Paylera records the
attribution and the reward ledger and tells you when to act; it never moves money
for these — mint or claw back the credit in your own system, keyed on reward_id.
| Event | When |
|---|---|
referral.attributed | A customer signed up with another customer’s referral code (POST /v1/referral_attributions). One per referred customer, ever. |
referral_reward.issued | The referred customer’s first paid invoice settled; one event per beneficiary (referrer / referee) with amount_minor + currency to credit. Also sent when an operator issues a manual reward. |
referral_reward.reversed | The qualifying payment was fully refunded or charged back (reason = refund / chargeback), or an operator reversed a reward (manual). Claw back what is still unspent. |
Revenue (observability)
Normalised, multi-source revenue signals emitted when an external ingestor (Stripe, Toss, Apple ASSN V2, Google Play RTDN) lands a revenue row. They feed the revenue dashboards and do not supplant revenue recognition.
Money-bearing events (revenue.captured, revenue.refunded,
revenue.subscription_started, revenue.subscription_renewed,
revenue.subscription_recovered, revenue.one_time_purchase) carry
amount_minor + currency (normalised to your reporting currency),
source_amount_minor + source_currency (as observed at the provider), and
fx_rate_used (string-encoded decimal). revenue.refunded carries a
positive amount_minor; the event type conveys that it’s a refund.
| Event | When |
|---|---|
revenue.captured | Money captured (a charge succeeded). |
revenue.refunded | A refund was issued. |
revenue.subscription_started | Initial subscription purchase. |
revenue.subscription_renewed | A recurring renewal succeeded. |
revenue.subscription_recovered | Grace-period recovery: the subscription resumed paid status. |
revenue.one_time_purchase | A one-time / IAP purchase. |
revenue.subscription_canceled | Subscription canceled (lifecycle; no money fields). |
revenue.subscription_grace_period_entered | Payment failed; billing entered grace (lifecycle; no money fields). |
revenue.subscription_expired | Subscription ended (lifecycle; no money fields). |
revenue.unknown_currency_seen | Ops alert: an unrecognised ISO currency code was observed. |
Operational & platform
Primarily ops/observability signals. tenant.* are platform-side (Paylera
billing your tenant), not events about your own customers.
| Event | When |
|---|---|
provider.webhook_received | An inbound provider webhook was accepted. |
provider.webhook_unresolved | An inbound provider webhook could not be matched to a payment. |
rounding_adjustment_emitted | A rounding adjustment line was emitted. |
usage.late_event_received | A usage event arrived after its period had closed. |
webhook_delivery.dead_lettered | An endpoint’s delivery gave up after max_attempts. webhook_delivery.* events are never themselves fanned out to endpoints (no amplification loop). |
tenant.entered_grace | The platform subscription went past_due; the 14-day grace window opened. |
tenant.suspended | The grace window elapsed; the tenant was suspended (end-customer subs paused). |
tenant.frozen | 30 days of suspension passed; the platform subscription is terminal. |
tenant.access_restored | Payment succeeded; the tenant walked back to active (paused subs auto-resume). |
tenant.export_window_closed | A frozen tenant’s export deadline elapsed. |
Payload schema
Every event carries a canonical data object. For most aggregates it is the
full canonical representation of the aggregate at the moment of the change — for
example, invoice.paid carries the entire invoice including line items, totals,
and payments, so you can trust the snapshot. A few transition events
(subscription.plan_changed, subscription.commitment_emitted, …) carry a
compact, change-specific payload instead of the full object, as shown above.
previous_attributes is included only on *.updated events and lists the
fields that changed with their pre-change values. Because
subscription.updated events for the same subscription can interleave, re-fetch
the subscription when you handle one rather than trusting field order.
For the full canonical payload shape per event, see
docs/billing_specs/billing_event_catalog/payload_schemas.yaml in the monorepo.
Schema versioning
Every event carries schema_version. Within a major version, fields are added
freely; never removed or renamed. A new major version (schema_version: 2)
ships behind a separate event type (e.g. invoice.paid.v2) with an overlap
window, deprecation header, and sunset date — the same policy as the API. See
Versioning.