Checkout metadata

For engineers reading payment webhooks and matching them back to funnel sessions. You'll have the canonical field list and the per-provider object names that carry it. You need access to your payment provider's dashboard or API to inspect the objects.

Zellify attaches a single, well-defined metadata object to every payment object it creates. The same set of fields goes on the Customer, the Subscription, the Checkout Session, the Transaction, the Order — whatever the provider supports. There is no per-object subset: if you read the metadata field on any Zellify-created payment object, you will see the same shape.

Canonical fields#

Every Zellify-created payment object carries these fields. Some are conditional — the field is omitted when the value is not available, rather than set to null.

FieldTypeWhen set
app_user_idstring (UUID)Always. The funnel session identifier — the same value sent as context.appUserId in the Registration webhook. See app_user_id.
organization_idstring (UUID)Always. The Zellify organization that owns the funnel.
funnel_idstringAlways. The funnel where the checkout happened.
campaign_idstringAlways. The campaign link the visitor used to reach the funnel.
experiment_idstringOnly when the campaign targets an A/B experiment.
fbpstringOnly when the visitor has a Meta _fbp browser cookie.
fbcstringOnly when the visitor came from a Meta ad click and has an _fbc value.

That is the entire payload. Zellify does not vary the field list by object type, by payment mode, or by provider.

Where it lives per provider#

The fields above are identical across providers. What differs is the property name on the object (metadata vs custom_data) and which objects carry it.

Stripe#

Property name on the object: metadata

Attached to every Stripe object Zellify creates during a checkout:

  • Customer.metadata
  • Checkout Session.metadata
  • Subscription.metadata (for subscription mode)
  • Subscription Schedule phases — each phase carries the same metadata (used for multi-phase pricing)
  • Invoice.metadata (for upsells, which are charged via invoice)

Read it from the primary object in the webhook event: the session for checkout.session.completed, the subscription or invoice for invoice.paid, etc. See Payment events for the full event matrix.

The Stripe Customer's email is on the Customer object's top-level email field, not in metadata.

Paddle#

Property name on the object: custom_data

Attached to:

  • Customer.custom_data
  • Transaction.custom_data

Paddle subscriptions are created from the originating transaction, so the transaction's custom_data is what reaches your subscription webhook events.

Solidgate#

Property name on the object: metadata (called order_metadata when Zellify sends it).

Attached to:

  • Order.metadata
  • Subscription.metadata (carried over from the order on subscription products)

The Solidgate payment intent also carries two top-level customer-identity fields, separate from metadata:

  • customer_email — the user's email
  • customer_account_id — set to the same value as app_user_id, used to link the Solidgate customer record to the Zellify funnel session

Reading metadata in webhooks#

The metadata lives on the primary object inside the event, not at the event root. If the field is missing, the event likely refers to an object Zellify did not create (manual dashboard action, direct API call, refund created in Stripe UI). Handle that case defensively rather than assuming app_user_id is always present.

read-metadata.ts
1function readAppUserId(obj: { metadata?: Record<string, string> }): string | null {2  return obj.metadata?.app_user_id ?? null3}

For Paddle, replace metadata with custom_data.

Zellify-created objects only: Zellify only attaches these fields to objects it creates through the funnel checkout flow. Objects you create manually in your payment provider's dashboard or API will not carry them.
app_user_id
The single most important field in this contract.
Payment events
Which webhook events you'll see the metadata on.
Stripe integration
Connect, configure, verify.
Paddle integration
Merchant-of-record setup and custom_data.
Solidgate integration
API key and webhook key pair setup.