Skip to content

Event catalog

Events are grouped by aggregate type. Subscribe to specific types or to a prefix (subscription.*) — never * in production.

Subscriptions

EventWhen
subscription.createdObject created (any state).
subscription.activatedTransitioned to active.
subscription.trial_startedEntered trialing.
subscription.trial_will_endT-3 days before trial end.
subscription.trial_endedTrial ended; transitioned to active or past_due.
subscription.trial_extendedTrial end pushed out by extend-trial.
subscription.updatedPlan, quantity, metadata, or other fields changed.
subscription.pausedEntered paused.
subscription.resumedReturned to active from paused.
subscription.past_dueA payment failed; entered past_due.
subscription.dunning_attemptA dunning retry was issued.
subscription.dunning_recoveredDunning succeeded; back to active.
subscription.dunning_exhaustedDunning policy ran out.
subscription.canceledEntered canceled.
subscription.reactivatedCancellation was reversed before period end.
subscription.commitment_startedCommitment block began.
subscription.commitment_renewedCommitment auto-renewed.
subscription.commitment_endingT-30 days before commitment end.
subscription.commitment_endedCommitment block expired.
subscription.usage_threshold_crossedComponent-configured threshold crossed mid-period.
subscription.refund_processedRecognition adjusted after a refund on a subscription invoice.

Invoices

EventWhen
invoice.createdDraft invoice created.
invoice.updatedDraft invoice edited.
invoice.finalizedTransitioned to open.
invoice.paidTransitioned to paid.
invoice.payment_failedA payment attempt against this invoice failed.
invoice.voidedTransitioned to void.
invoice.marked_uncollectibleTransitioned to uncollectible.
invoice.fx_rate_lockedFX rate stamped at finalisation.

Payments

EventWhen
payment.createdA new attempt started.
payment.requires_action3DS / SCA needed; see data.next_action.
payment.action_completedCustomer completed the action; capture in progress.
payment.processingProvider is settling.
payment.succeededCapture succeeded.
payment.failedCapture failed; reason in data.last_error.
payment.canceledPayment cancelled before capture.
payment.settledFunds settled at provider; carries final settlement amount and FX rate.
payment.charged_backCustomer initiated a chargeback.
payment.dispute_wonDispute resolved in your favour.
payment.dispute_lostDispute resolved against you; funds removed.

Refunds & credit notes

EventWhen
refund.createdRefund object created.
refund.succeededProvider returned the funds.
refund.failedProvider rejected the refund.
credit_note.createdA credit note was issued.
credit_note.refund_succeededCash returned (when outcome: refund).
credit_note.refund_failedRefund leg of credit note failed.

Customers & payment methods

EventWhen
customer.createdCustomer object created.
customer.updatedAny customer field changed.
customer.deletedCustomer marked deleted (soft delete).
customer.payment_method_attachedMethod added.
customer.payment_method_detachedMethod removed.
customer.tax_id_invalidatedAsync tax-ID validation failed.
customer.external_ref_discoveredRevenueAttribution worker back-linked a previously-orphaned revenue.* event to this customer via email-fingerprint match. Payload: customer_id, tenant_id, provider, external_id, revenue_event_id, discovered_at, discovery_method (v1 value: email_fingerprint; future: manual, oauth_link).
payment_method.verifiedVerify call completed.
payment_method.expiredCard expired (we detect it).

Wallets

EventWhen
wallet.creditedBalance increased.
wallet.debitedBalance decreased.
wallet.auto_topup_succeededAuto-top-up captured a payment.
wallet.auto_topup_failedAuto-top-up payment failed.
wallet.below_drift_floorBalance hit drift_floor and settlement could not complete.

Catalog

EventWhen
product.created / product.updated / product.archivedProduct CRUD.
plan.created / plan.updated / plan.archivedPlan CRUD.

Discounts

EventWhen
coupon.created / coupon.updated / coupon.deletedCoupon CRUD.
discount.appliedCoupon attached to a customer / subscription / invoice.
discount.removedDetached.
discount.expiredA repeating discount used its last cycle.
promotion_code.redeemedA customer used a public promo code.

Affiliates

EventWhen
affiliate.created / affiliate.updatedAffiliate CRUD.
commission.accruedQualifying payment produced a commission.
commission.eligibleHold period elapsed.
commission.reversedOriginating payment refunded / charged back.
payout_batch.createdBatch assembled.
payout_batch.settledAll transfers in the batch succeeded.
payout_batch.failedA transfer failed.

Hosted surfaces

EventWhen
checkout.session.createdSession URL was created.
checkout.session.completedCustomer finished checkout.
checkout.session.expiredTTL elapsed without completion.
portal.session.completedCustomer closed the portal; carries summary.

Multi-source revenue capture

Observability projections from Stripe, Toss, Apple App Store Server Notifications V2, and Google Play RTDN. These events report what the upstream provider told us happened — they do not supplant Revenue recognition (a separate workstream that owns GAAP/IFRS schedules against Paylera-issued invoices).

Money-bearing events (revenue.captured, revenue.refunded, revenue.subscription_started, revenue.subscription_renewed, revenue.one_time_purchase) carry:

  • amount_minor, currency — normalised to your tenant’s reporting currency.
  • source_amount_minor, source_currency — as observed at the provider.
  • fx_rate_used — string-encoded decimal (precision-preserving).

Lifecycle events (subscription_canceled, subscription_grace_period_entered, subscription_expired) carry no money fields. revenue.subscription_recovered carries money (the renewal that broke the grace period).

revenue.refunded carries a positive amount_minor; the refund nature is conveyed by the event type, not by a negative amount.

For the full canonical payload shape per event, see docs/billing_specs/billing_event_catalog/payload_schemas.yaml in the monorepo.

EventWhen
revenue.capturedMoney captured (charge succeeded).
revenue.refundedRefund issued. amount_minor is positive; the event type conveys “this is a refund”.
revenue.subscription_startedInitial subscription purchase.
revenue.subscription_renewedRecurring renewal succeeded.
revenue.subscription_canceledSubscription canceled (lifecycle, no money fields).
revenue.subscription_grace_period_enteredPayment failed; billing in grace period (lifecycle, no money fields).
revenue.subscription_recoveredGrace-period recovery: subscription resumed paid status.
revenue.subscription_expiredSubscription ended (lifecycle completion, no money fields).
revenue.one_time_purchaseOne-time IAP / one-shot purchase.
revenue.unknown_currency_seenOps-only alert: an unknown ISO currency code was observed (forward-compat; producer wires when FX coverage table lands).

Revenue recognition

EventWhen
revrec.schedule_createdSchedule attached to a paid invoice.
revrec.schedule_adjustedRefund / credit note changed a schedule.
revrec.period_closedA close transaction committed.
revrec.period_close_failedA close was attempted and failed.

Meta

EventWhen
webhook_endpoint.delivery_failedA delivery exhausted retries.
webhook_endpoint.disabledAn endpoint was disabled (manual or after sustained 4xx).

Payload schema

Every event’s data 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 — not just the changed fields. This means your handler can decide whether to re-fetch (for subscription.updated, you usually should — events for the same subscription may interleave with subscription.updated events you care about) or trust the payload (for invoice.paid, the snapshot is authoritative).

previous_attributes is included only on *.updated events and lists the fields that changed with their pre-change values.

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 (subscription.activated.v2) with overlap, deprecation header, and sunset date — the same versioning policy as the API. See Versioning.