Book Seller · Cross-submission synthesis
One Purchase, End to End
This sequence combines the strongest recurring elements: durable intake, bounded seller selection, an expiring hold, payment authorization, seller confirmation, capture, and explicit compensation.
Actors
BuyerOrder APIWorkflowSellerStripe
1 · Durable intake
01
Buyer → StripeTokenize card details and complete any required customer authentication.
02
Buyer → Order APIPOST ISBN, maximum price, payment token, and client idempotency key.
03
Order API → Order DBInsert PENDING order and durable dispatch record in one transaction.Duplicate client key returns the original order.
04
Order API → BuyerReturn order ID and PENDING status.
2 · Candidate selection
05
Queue → WorkflowStart one workflow identity for the order.
06
Workflow → Offer indexRead candidate sellers with price at or below the maximum.
07
Workflow → Order DBConditionally claim the transition SEARCHING → COMMITTING for one seller.Competing workers update zero rows and stop.
3 · Hold, authorize, confirm, capture
08
Workflow → SellerCreate an idempotent hold. Persist hold ID, held price, and expiry.
09
Workflow → StripeCreate or confirm a manual-capture PaymentIntent for the held price.
10
Workflow → SellerConfirm the purchase with the hold and order identifiers.
11
Workflow → StripeCapture the authorized amount with a stable capture key.
12
Workflow → Order DBPersist COMPLETED and emit the final order event.
4 · Recovery branches
| State | Action |
|---|---|
| Hold rejected | Release the winner claim and try the next candidate. |
| Authorization failed | Release hold and fail or try another seller. |
| Seller confirm timed out | Retry with the same key; void authorization before hold expiry when retries end. |
| Capture ambiguous | Read provider state or await webhook; reuse the same key. |
| Captured without fulfillment | Refund, mark REFUND_PENDING, and alert operations. |
| Worker crash | Resume from the persisted workflow state after redelivery. |