Skip to main content
Version: v2

Request Lifecycle

Overview

This document traces a POST /v2/payments request end-to-end — from the API gateway through the service layers, to the payment vendor, and finally to the webhook dispatch. Understanding this flow is essential before implementing or modifying any payment logic.


End-to-End Sequence — Create Payment


Key Checkpoints

StepWhat HappensFailure Behavior
1 — Gateway authOAuth2 token validated, scope checked (merchant, user, merchant-pci)401 Unauthorized or 403 Forbidden
2 — Request validationJSON schema, field constraints, allocation sum check400 Bad Request with field-level errors
3 — Idempotency checkmerchantTransactionId + merchantId uniquenessReturns existing payment if ≤ 5 attempts; 422 if exceeded
4 — Insert transactionTransaction record persisted with status=INITIATED before 202 is returnedDatabase error → 500
5 — Customer check (async)Customer lookup/creation runs post-processing (after 202 returned). Failures transition transaction to FAILED and publish eventsVisible via GET /v2/payments polling — never surfaces as synchronous HTTP error
6 — Vendor processingStripe PaymentIntent created per allocationAllocation marked FAILED; triggers rollback for split-tender
7 — State persistenceTerminal state written atomicallyDatabase transaction ensures consistency
8 — Webhook dispatchAsync delivery with at-least-once guaranteeRetries with exponential backoff; does not block response

Synchronous vs Asynchronous Boundaries

Important

POST /v2/payments always returns 202 Accepted with status INITIATED. Customer check runs post-processing — any customer-service failure (e.g. invalid metadata key, unknown customer) is surfaced asynchronously via GET /v2/payments polling or the PAYMENT_UPDATED webhook, never as a synchronous HTTP error.

See Customer Creation During Payment and Error Strategy — Async Error Surfacing for full details.


GET Payment Lifecycle


Cancel / Capture Flow Summary

OperationMethodPreconditionAsync?
CancelPATCH /v2/payments/{paymentId}/cancelPayment in AUTHORIZED, ACCEPTED, or PENDING stateYes — returns 202
CapturePATCH /v2/payments/{paymentId}/capturePayment in AUTHORIZED stateYes — returns 202