Bag is live โ€” accept USDC & card payments globally. Get started โ†’
BagBag Docs
API Reference

Webhook Events

Complete reference for all webhook event types, payloads, and delivery behavior.

Webhook Events

Bag sends webhook events to your registered endpoint when payment and subscription lifecycle events occur. All events are signed with HMAC-SHA256 for verification.


Event List

EventCategoryDescription
payment.completedPaymentPayment confirmed on-chain
payment.failedPaymentTransaction reverted or timed out
subscription.createdSubscriptionNew subscription created
subscription.updatedSubscriptionSubscription plan or status changed
subscription.renewedSubscriptionRecurring payment succeeded
subscription.renewal_dueSubscriptionUpcoming renewal requires customer action
subscription.past_dueSubscriptionPayment failed, grace period active
subscription.canceledSubscriptionSubscription permanently canceled

Common Envelope

Every webhook delivery follows this structure:

{
  "event": "event.name",
  "data": { ... },
  "webhookDeliveryId": "d4e5f6a1-b2c3-7890-abcd-ef1234567890",
  "timestamp": "2026-04-01T12:00:00.000Z"
}
FieldTypeDescription
eventstringEvent type identifier
dataobjectEvent-specific payload (see below)
webhookDeliveryIdstringUnique delivery ID for idempotency
timestampstringISO 8601 timestamp of the event

Sandbox events also include "livemode": false in the data object.


Payment Events

payment.completed

Fired when a payment is confirmed on-chain.

{
  "event": "payment.completed",
  "data": {
    "sessionId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
    "paymentLinkId": "3b9f8f22-7f1f-4c3a-8f5a-2d7a0d3e9b1c",
    "txHash": "0xabc123def456...",
    "merchantWalletAddress": "0xYourWalletAddress",
    "amount": 29.99,
    "network": "base_sepolia"
  },
  "webhookDeliveryId": "d4e5f6a1-b2c3-7890-abcd-ef1234567890",
  "timestamp": "2026-04-01T12:05:00.000Z"
}
FieldTypeDescription
sessionIdstringCheckout session ID
paymentLinkIdstringPayment link that initiated the checkout
txHashstringOn-chain transaction hash
merchantWalletAddressstringMerchant's receiving wallet
amountnumberPayment amount in USD
networkstringBlockchain network (e.g., base, ethereum, polygon, solana)

Recommended action: Fulfill the order, grant access, send a receipt.


payment.failed

Fired when a transaction reverts or the checkout session times out.

{
  "event": "payment.failed",
  "data": {
    "sessionId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
    "paymentLinkId": "3b9f8f22-7f1f-4c3a-8f5a-2d7a0d3e9b1c",
    "reason": "Transaction reverted"
  },
  "webhookDeliveryId": "d4e5f6a1-b2c3-7890-abcd-ef1234567890",
  "timestamp": "2026-04-01T12:05:00.000Z"
}
FieldTypeDescription
sessionIdstringCheckout session ID
paymentLinkIdstringPayment link that initiated the checkout
reasonstringHuman-readable failure reason

Recommended action: Notify the customer, allow retry.


Subscription Events

subscription.created

Fired when a new subscription is created (after initial payment or trial start).

{
  "event": "subscription.created",
  "data": {
    "subscriptionId": "sub_abc123",
    "paymentLinkId": "3b9f8f22-7f1f-4c3a-8f5a-2d7a0d3e9b1c",
    "customerEmail": "customer@example.com",
    "status": "active",
    "currentPeriodEnd": "2026-05-01T12:00:00.000Z",
    "livemode": true
  },
  "webhookDeliveryId": "d4e5f6a1-b2c3-7890-abcd-ef1234567890",
  "timestamp": "2026-04-01T12:00:00.000Z"
}
FieldTypeDescription
subscriptionIdstringSubscription ID
paymentLinkIdstringPayment link used to create the subscription
customerEmailstringCustomer's email address
statusstringInitial status (active or trialing)
currentPeriodEndstringEnd of the current billing period (ISO 8601)
livemodebooleantrue for production, false for sandbox

Recommended action: Store the subscription ID, grant access.


subscription.updated

Fired when a subscription's status or details change (pause, resume, plan change, cancelAtPeriodEnd set).

{
  "event": "subscription.updated",
  "data": {
    "subscriptionId": "sub_abc123",
    "status": "paused",
    "previousStatus": "active",
    "livemode": true
  },
  "webhookDeliveryId": "d4e5f6a1-b2c3-7890-abcd-ef1234567890",
  "timestamp": "2026-04-15T10:00:00.000Z"
}
FieldTypeDescription
subscriptionIdstringSubscription ID
statusstringNew status
previousStatusstringStatus before the change
cancelAtPeriodEndbooleanPresent when cancellation is scheduled for period end
currentPeriodEndstringPresent when the period changes (e.g., on resume)
livemodebooleantrue for production, false for sandbox

Recommended action: Update stored subscription state.


subscription.renewed

Fired when a recurring payment succeeds.

{
  "event": "subscription.renewed",
  "data": {
    "subscriptionId": "sub_abc123",
    "currentPeriodStart": "2026-05-01T12:00:00.000Z",
    "currentPeriodEnd": "2026-06-01T12:00:00.000Z",
    "amount": 29.99,
    "txHash": "0xdef789...",
    "livemode": true
  },
  "webhookDeliveryId": "d4e5f6a1-b2c3-7890-abcd-ef1234567890",
  "timestamp": "2026-05-01T12:00:30.000Z"
}
FieldTypeDescription
subscriptionIdstringSubscription ID
currentPeriodStartstringStart of the new billing period
currentPeriodEndstringEnd of the new billing period
amountnumberRenewal payment amount
txHashstringOn-chain transaction hash (stablecoin) or charge ID (card)
livemodebooleantrue for production, false for sandbox

Recommended action: Extend access period.


subscription.renewal_due

Fired when an upcoming renewal requires customer action (e.g., stablecoin re-approval).

{
  "event": "subscription.renewal_due",
  "data": {
    "subscriptionId": "sub_abc123",
    "currentPeriodEnd": "2026-10-01T12:00:00.000Z",
    "reason": "permit2_approval_expiring",
    "livemode": true
  },
  "webhookDeliveryId": "d4e5f6a1-b2c3-7890-abcd-ef1234567890",
  "timestamp": "2026-09-25T12:00:00.000Z"
}
FieldTypeDescription
subscriptionIdstringSubscription ID
currentPeriodEndstringWhen the current period ends
reasonstringWhy action is needed (e.g., permit2_approval_expiring)
livemodebooleantrue for production, false for sandbox

Recommended action: Notify the customer to re-approve their wallet or update payment method.


subscription.past_due

Fired when a renewal payment fails and the subscription enters the dunning grace period.

{
  "event": "subscription.past_due",
  "data": {
    "subscriptionId": "sub_abc123",
    "failedAt": "2026-05-01T12:00:00.000Z",
    "retryCount": 1,
    "nextRetryAt": "2026-05-02T12:00:00.000Z",
    "livemode": true
  },
  "webhookDeliveryId": "d4e5f6a1-b2c3-7890-abcd-ef1234567890",
  "timestamp": "2026-05-01T12:01:00.000Z"
}
FieldTypeDescription
subscriptionIdstringSubscription ID
failedAtstringWhen the payment failed
retryCountnumberNumber of retry attempts so far
nextRetryAtstringWhen the next retry is scheduled
livemodebooleantrue for production, false for sandbox

Recommended action: Warn the customer, suggest updating payment method.


subscription.canceled

Fired when a subscription is permanently canceled (immediately or at period end).

{
  "event": "subscription.canceled",
  "data": {
    "subscriptionId": "sub_abc123",
    "cancelAtPeriodEnd": false,
    "livemode": true
  },
  "webhookDeliveryId": "d4e5f6a1-b2c3-7890-abcd-ef1234567890",
  "timestamp": "2026-04-20T15:30:00.000Z"
}
FieldTypeDescription
subscriptionIdstringSubscription ID
cancelAtPeriodEndbooleantrue if canceled at period end, false if immediate
livemodebooleantrue for production, false for sandbox

Recommended action: Revoke access (immediately or at period end based on cancelAtPeriodEnd).


Delivery and Retries

Bag retries failed deliveries up to 5 times with exponential backoff:

AttemptDelayMethod
1ImmediateInline
2+5 secondsInline
3+10 secondsInline
4+40 secondsBackground
5+80 secondsBackground

After 5 failed attempts, the delivery is marked as failed. You can retry manually from the dashboard under Webhooks > Delivery Log.


What's next

On this page