High-level sequence
1. Initialize order
- Endpoint:
POST /v2/orders - Input:
cartId(UUID)
Order
record in PENDING status, and locks the cart to prevent further changes.
Returns: orderId
2. Create payment intent
- Endpoint:
POST /v2/orders/:orderId/payment-intent - Input:
orderId,paymentMethod(e.g.STRIPE,PAYPAL,CRYPTO,BONUM,TELR)
orderId) is attached to the provider’s intent so reconciliation can happen later.
Returns: clientSecret (Stripe) or checkoutUrl (PayPal, hosted PSPs).
3. Calculate distribution (internal)
Runs synchronously inside step 2. Computes:- Droplinked commission — platform fee
- Provider fees — pass-through PSP charges
- Merchant share — what settles to the merchant
- Affiliate / referral splits — when an attribution session is active
For PSPs that settle off-platform (e.g. Bonum), the saga records the split plan without
executing a live transfer — settlement happens out-of-band and is reconciled later.
4. Confirmation (webhook-driven)
- Trigger: a signed webhook from the payment provider — for Stripe,
payment_intent.succeeded. - Ingress: the provider’s own mount (for example
POST /stripe/acp/webhook), or the normalisedPOST /payment/webhook/genericfor events relayed by Integration Services. The full list is on Webhooks.
POST /v2/orders/:orderId/capture-paypal on
return to capture and confirm. That route is recovery-safe — an already-captured order
confirms cleanly, and an already-confirmed order is a no-op.
The handler verifies the signature, then executes the confirmation saga:
1
Validate
Checks order status; rejects if already terminal.
2
3
Distribute revenue
Executes the splits calculated in step 3 (or records them for off-platform settlement).
4
Finalize
Updates order status to
CONFIRMED.Retry and replay safety
Two mechanisms, and it is worth knowing which one is load-bearing:- Forward-only order state — the durable guarantee. A stale
AUTHORIZEDevent arriving afterCAPTUREDis dropped rather than rewinding the order, and re-applying a terminal transition is a no-op. - Event-id dedupe — a per-provider cache keyed on the provider’s event id with a 24-hour window. It absorbs a retry that lands on the same application instance. It is in-process: it does not span instances and does not survive a restart, so treat it as an optimisation rather than a guarantee.
POST /v2/orders is not — that
creates a second order. See Idempotency and retries
for the per-endpoint table, and note that Droplinked does not read an Idempotency-Key
request header.
For the full webhook + replay matrix, see Checkout stability.
Related
- Webhooks — every inbound route and its signature scheme
- Idempotency and retries
- Payment method coverage
- Checkout stability playbook