checkout.completed webhook.
A common example is an order reference:
Before you start
You need:- a server API key from Settings → API Keys;
- a plan identifier and supported charge period;
- a backend endpoint that creates checkout sessions.
checkout.completed if you want to receive the metadata when checkout finishes.
Keep the server API key in your backend. Never expose it in browser or mobile code.
Add metadata when creating the session
Passmetadata at the top level of the Checkout API request body. Kelviq preserves the keys exactly as supplied, so order_ref and orderRef are different keys.
checkoutUrl. The create response does not echo the metadata, so save checkoutSessionId alongside your internal record if you also need to look up the Kelviq session later.
This guide uses the sandbox host and a sandbox server API key. Switch both to production together when you are ready to accept live payments.
Read metadata after checkout
When payment succeeds, thecheckout.completed event includes the metadata at data.object.metadata:
id, not a metadata value, as your idempotency key. Kelviq can deliver the same event more than once during automatic retries or a manual resend.
Learn how to register an endpoint and verify signatures →
Choose useful metadata
Keep the object small and focused on correlation. A stable naming convention makes webhook handlers easier to maintain.
Metadata is helpful context, but it is not proof of payment or authorization. Confirm
event.type, verify the signature, and use Kelviq’s resource IDs when calling Kelviq APIs.
Checkout metadata and customer metadata are different
Checkout metadata describes one checkout session. Customer metadata describes the customer record and can be managed through the Customers API. Adding metadata to a checkout session does not replace or update customer metadata.Test the complete flow
- Create a session with a sandbox server API key and recognizable test metadata.
- Open the returned
checkoutUrland complete a sandbox payment. - Open Settings → Webhooks, then inspect the
checkout.completeddelivery. - Confirm that
data.object.metadatacontains the same keys and values. - Resend the delivery and confirm that your idempotency check prevents duplicate work.