API Specification: POST /charges
- Endpoint:
POST /v1/charges - Description: Initiates a new payment charge.
- Headers:
* Content-Type: application/json * Idempotency-Key: <UUIDv4> (Required) - A client-generated unique identifier for the request.
``json { "amount": { "value": "100.00", "currency": "USD" }, "source": { "type": "card", "token": "tok_visa" }, "description": "Order #12345 payment", "metadata": { "customer_id": "cust_abc" } } ``
- Response (201 Created - Success):
``json { "id": "ch_xyz789", "amount": { "value": "100.00", "currency": "USD" }, "status": "succeeded", "created_at": "2023-10-27T10:00:00Z" } ``
- Response (200 OK - Idempotent Replay): Returns the original successful response, without re-processing.
``json { "id": "ch_xyz789", "amount": { "value": "100.00", "currency": "USD" }, "status": "succeeded", "created_at": "2023-10-27T10:00:00Z" } ``
- Response (400 Bad Request - Idempotency Key Mismatch): If the
Idempotency-Key exists but the request body differs.
``json { "code": "idempotency_key_mismatch", "message": "Idempotency key '...' used with a different request payload." } ``
- Response (4xx/5xx - Original Failure Replay): Returns the original error response if the initial attempt failed.
``json { "code": "card_declined", "message": "The payment card was declined." } ``
Idempotency Key Strategy
The Idempotency-Key must be a client-generated UUIDv4, included in the HTTP header. The server stores this key alongside the full request payload and the final response. Upon receiving a request with an Idempotency-Key, the server first checks if the key exists. If it does, it validates if the incoming request body exactly matches the stored payload. A mismatch results in a 400 Bad Request. Keys remain valid for replay for 24 hours to accommodate client retry logic and network transient errors. After 24 hours, the key may expire, and a new request with the same key could be processed as a distinct operation.
Replay Semantics
When a duplicate request with an active Idempotency-Key is received:
- Original Succeeded: The server retrieves and returns the stored
201 Created response with a 200 OK status. This confirms the operation's prior completion. - Original Failed: The server returns the *original error response* (e.g.,
400 Bad Request, 500 Internal Server Error) and its corresponding status code, preventing re-execution of a known-to-fail operation. - Original Pending: For long-running operations, the server might return a
202 Accepted or 409 Conflict while the original request is still processing, prompting the client to poll for the final status.
Resource Model
- Charge: Represents a financial debit. Key fields include
id, amount, currency, status (succeeded, failed, pending), source (payment method details), and created_at.