payment checkout¶
Checkout, told twice. The first scenario is the path everyone draws; the second is the one that actually costs money, and it is the reason status exists as a first-class attribute rather than a colour convention.
The source — 02-storytelling/01-payment-checkout.dgm
%% Checkout, told twice. The first scenario is the path everyone draws; the
%% second is the one that actually costs money, and it is the reason `status`
%% exists as a first-class attribute rather than a colour convention.
flowchart LR
browser[Shopper's Browser]
checkout[Checkout Service]
subgraph psp[Payment Providers]
gw[Primary Gateway]
backup[Backup Gateway]
end
ledger[(Order Ledger)]
browser --> checkout
checkout --> gw
checkout --> backup
checkout --> ledger
scenario "happy path" { speed: 1.0 }
step submit "Shopper submits the order" {
flow browser -> checkout { label: "POST /checkout", dur: 600ms }
highlight checkout { style: active }
}
step authorize "The primary gateway authorises the card" {
flow checkout -> gw { label: "authorize $84.10", dur: 700ms, ease: out }
highlight gw
}
step record "The order is written to the ledger" {
flow gw -> checkout -> ledger { label: "order 8812", dur: 900ms }
}
step confirm "Confirmation travels back to the shopper" {
flow checkout -> browser { label: "201 Created", dur: 600ms, style: response }
}
%% The outage is not a second story, it is the same story until the gateway
%% stops answering. `variant` says so: this scenario replays "happy path"
%% through the `submit` step — `until` is inclusive — and then diverges. The
%% shared opening is written once, so a change to how an order is submitted
%% cannot end up describing one path and not the other.
scenario "gateway outage" { variant: "happy path", until: submit, outcome: fail }
step attempt "The primary gateway never answers" {
flow checkout -> gw {
label: "authorize $84.10",
dur: 1100ms,
status: fail
}
note gw "no response in 8s\nconnect timeout"
}
step retry "Checkout fails over to the backup provider" {
flow checkout -> backup { label: "retry: authorize", dur: 700ms, ease: in-out }
dim gw
highlight backup
}
step settle "The backup gateway approves it" {
flow backup -> checkout -> ledger { label: "approved · order 8812", dur: 1000ms }
dim gw
}
step outage-confirm "The shopper sees the same 201 either way" {
flow checkout -> browser { label: "201 Created", dur: 600ms, style: response }
dim gw
}