Payment flow simulator
Docking Sequence
Follow one card payment through a 3-D Secure challenge and back, then break the handoffs that lose real money.
Fictional merchant · illustrative model · no real payments
Pre-flight
Changing the fault or a defence restarts the sequence. The address bar keeps your setup, so you can share it.
Docking track
Kestrel Supply (fictional) · ORD-2048 · ₺18,400.00- Buyer’s browser
- Merchant API · replica A
- Payment provider
- Issuer ACS
- 01OrderThe buyer commits to a fictional B2B order.not reached yet
- 02Payment intentThe merchant opens a payment and remembers what it started.not reached yet
- 03Issuer challengeThe issuer’s ACS asks the buyer to prove the card is theirs.not reached yet
- 04CallbackThe buyer’s browser brings the result back to the merchant.not reached yet
- 05CaptureThe merchant turns the hold into a charge.not reached yet
- 06ConfirmedOne payment, one confirmed order, one fulfilment.not reached yet
Standing by. Pick a fault and your defences, then press Next step.
Ledger
- On hold
- 0
- Captured
- 0
- Refunded
- 0
- Orders confirmed
- 0
- Fulfilments
- 0
- Merchant’s order
- Not created
- Buyer sees
- Checkout page
Flight log
No messages yet. Press Next step to send the first one.
Debrief
Run the sequence to the end to see what the merchant and the buyer are left with.
Model boundaries
Kestrel Supply, the order, the payment provider and every incident here are fictional. Nothing contacts a bank or payment service, and there is no card form. The flow is simplified to one provider, one card and one challenge, and each fault has a fixed, authored outcome. In this model the merchant keeps the token → order mapping only in replica A’s memory. Real providers let you attach your own reference to the payment (iyzico returns your conversationId to the callback) or look the payment up by its ID (Stripe adds it to the return URL), which also prevents the “Callback on another replica” fault. Providers also differ in other ways: some complete the payment only when the merchant calls them after the callback, others notify by webhook, and authorisation windows vary by card network. No outcome here describes a real merchant’s incident.
Why this room
Umut’s B2B marketplace work in the projects section includes 3-D Secure and bank-transfer payment flows. Payments are where a lost handoff costs real money, so this room is about designing for the handoffs. The merchant, order and incidents here are fictional.
Sources
- EMVCo: EMV 3-D Secure overview (opens in a new tab)
Lower-risk payments can pass without extra steps; for higher-risk ones the issuer may ask for a challenge such as a one-time passcode.
- EMVCo: 3DS messages (AReq, ARes, RReq) (opens in a new tab)
The 3DS Server sends the Authentication Request (AReq); the Directory Server passes its data on to the issuer’s ACS, which can ask for a challenge and reports the outcome in a Results Request (RReq).
- Stripe: Authenticate with 3D Secure (opens in a new tab)
After authentication the customer is sent back to your return URL with the payment’s ID in the query string; with separate capture the payment then waits in requires_capture.
- Stripe: Place a hold on a payment method (opens in a new tab)
An authorisation holds the funds until you capture them; online card authorisations are usually valid for 7 days, then the funds are released.
- Stripe: Idempotent requests (opens in a new tab)
A retry with the same idempotency key returns the saved result of the first request, so the operation is not performed twice.
- Stripe: Webhooks, duplicates and ordering (opens in a new tab)
An endpoint can receive the same event more than once and out of order; log the event IDs you have processed and skip the ones already logged.
- Stripe: Fulfil orders (opens in a new tab)
Customers are not guaranteed to reach your landing page, so fulfilment needs webhooks and must be safe to run more than once, even concurrently.
- iyzico: 3DS implementation (opens in a new tab)
After the bank step, iyzico posts the result with paymentId and conversationId to your callbackUrl; a separate Auth request then completes the payment.
- Redis: SET with NX and EX (opens in a new tab)
SET … NX writes a key only if it does not exist, and EX gives it an expiry: building blocks for shared payment context and idempotency records.