Abuja Digital Studio · Est. 2018
Start a Project
DocsOCartOne-click post-purchase upsells
Reference

One-click post-purchase upsells

OCartorravo.com/docs/ocart/upsells

One-click post-purchase upsells

After the buyer pays, OCart can present an upsell offer that charges the same card with no re-entry. The flow is implemented as an 8-step sequence in OCart_Upsell_Handler::accept().

How the charge works

  1. Browser POSTs to /wp-json/ocart/v1/upsells/<offer-id>/accept with an X-Idempotency-Key header.
  2. Handler validates: offer eligible, cart owns the parent order, parent order paid, signed token valid and within the 30-minute window, single-use jti not yet burned.
  3. Resolves the gateway adapter for the parent order via OCart_Gateway_Registry::for_order().
  4. Fetches the saved off-session payment method (gateway-side check).
  5. Initiates an off-session charge with the idempotency key.
  6. Outcome dispatch: succeeded, requires_action, declined, or error.
  7. On success, OCart creates a child order or merges into the parent (configurable strategy).
  8. Fires the ocart/upsell/accepted action with parent and child order references.

Token security

Upsell tokens are HMAC-signed and short-lived. Default TTL is 30 minutes (upsells.one_click_token_ttl_min in ocart_settings). Each token carries a unique jti that is burned on first use, so replays are blocked at the validation step.

SCA / 3DS handling

If the gateway returns requires_action, the frontend redirects the buyer to the gateway's confirmation step, then resumes the funnel. SCA modal handling is controlled by upsells.sca_modal_enabled (default true).

Card storage

No card data touches your database. Only the gateway-side payment-method ID (for example pm_abc123 from Stripe, or a Paystack authorization code) is stored in WC order meta.

Order strategy

Two options, set with upsells.order_strategy_default:

  • Strategy A (default) - child order. New WC order created for the upsell.
  • Strategy B - merge into the parent line items, if within merge_cutoff_min (default 5 minutes). Falls back to Strategy A after that.
One-click post-purchase upsells · OCart Docs | Orravo