Skip to main content
All Modulus-defined fields use snake_case. Merchant-owned keys inside metadata preserve their original spelling and casing. These examples show the complete canonical envelope delivered to your endpoint.

Nullable fields

For a declined event, decline_details is populated and failure_details is null. For a failed event, the inverse is true. Processor-specific error text is not forwarded; error_code and error_message use the documented merchant-safe values.

Decline error codes

These appear in decline_details.error_code on payment.declined events. Branch on error_code, not error_message.

Failure error codes

These appear in failure_details.error_code on payment.failed events. Metadata is the snapshot belonging to the originating Payment Link or Payment Intent. The two sources are never merged, and merchant-owned metadata keys are not converted to snake_case.

Resource identifiers

  • Payment Link events contain data.payment_link_id and omit data.payment_intent_id.
  • Payment Intent events contain data.payment_intent_id and omit data.payment_link_id.
  • The two identifiers are never merged or used as aliases.

Timestamps

  • Envelope created_at: when the webhook event was created.
  • data.created_at: when the underlying transaction was created.
  • data.updated_at: when that transaction was last updated.
For payment.expired, no transaction or payment attempt exists. The transaction fields data.id, data.payment_attempt_id, data.created_at, and data.updated_at are therefore null. Use the envelope created_at for the time the expiry was observed and the event was created; expiry detection is lazy, so this can be later than the resource’s configured expires_at. All non-null timestamps are UTC RFC 3339 values. Delivery order is not guaranteed; use data.updated_at when comparing transaction state and deduplicate on the envelope id.

Event inspection

Use GET /v1/webhook_events and GET /v1/webhook_events/{id} to inspect the persisted canonical event. Use the reporting API as the authoritative payment state when reconciling a delayed or missing webhook. The event-management response uses these fields: List operations return data and pagination. Pass pagination.next_cursor as the next request’s cursor; next_cursor is null when has_more is false.