Payment events
For engineers handling payment webhooks sent by Stripe, Paddle, or Solidgate after a funnel checkout.
You'll have a clear per-scenario matrix plus an idempotent handler skeleton.
You need a webhook endpoint registered in your payment provider's dashboard.
Scenarios#
Scenario What fires Source of app_user_id One-time purchase checkout.session.completed (Stripe) / transaction.completed (Paddle) / order.approved (Solidgate)metadata.app_user_id on the session / transaction / orderSubscription, first payment checkout.session.completed + invoice.paid (Stripe) / subscription.created + transaction.completed (Paddle)metadata.app_user_id on the subscription or customerSubscription renewal invoice.paid (Stripe) / transaction.completed (Paddle) / subscription.renewed (Solidgate)metadata.app_user_id on the subscriptionSubscription schedule phase change invoice.paid + subscription_schedule.updated (Stripe)Subscription metadata Stripe upsell checkout.session.completed with mode=payment after the original subscriptionSession metadata Cancellation / refund customer.subscription.deleted / charge.refunded (Stripe) / subscription.canceled (Paddle) / subscription.canceled (Solidgate)Subscription metadata
Stripe event matrix#
Event Fires on When to handle checkout.session.completedAny completed Checkout Session Always. Primary signal for first payment. invoice.paidEach subscription invoice For subscription renewals. Also the first payment if using subscription schedules. customer.subscription.updatedSubscription state change Plan change, trial end, quantity change. customer.subscription.deletedSubscription canceled Revoke access. charge.refundedRefund issued Revoke access if the refund is a full cancellation.
Paddle event matrix#
Event Fires on When to handle transaction.completedCompleted transaction (one-time or subscription payment) Always. Primary payment signal. subscription.createdNew subscription Start entitlement. subscription.updatedSubscription state change Plan, pause, resume. subscription.canceledSubscription canceled Revoke at period end.
Solidgate event matrix#
Event Fires on When to handle order.approvedOrder completed Start or renew entitlement. subscription.renewedRenewal billed Extend entitlement. subscription.canceledSubscription canceled Revoke at period end.
Idempotency#
Every event has an id. Every payment object Zellify creates carries app_user_id . Use one or both as your idempotency key:
Dedupe on event.id to ignore repeat deliveries of the same event.
Key entitlement writes by app_user_id so repeated events converge on the same user record.
Reading app_user_id from events#
Missing app_user_id: If app_user_id is missing from metadata on an event, the event likely refers to an object not created by Zellify (manual refund in the dashboard, direct API call, test object). Handle defensively; do not assume a user mapping.
Checkout metadata
What Zellify attaches on which objects per provider. app_user_id
Your idempotency key across every event. Mobile app with custom backend
End-to-end recipe consuming these events. Using existing webhooks
Adapt an existing handler.