Submit a payment receipt
Attach receipt evidence to a pending payment that accepts receipt submission.
Some bank-transfer payments require receipt evidence after the payer completes the transfer. The
Merchant API accepts either a previously uploaded private payment_receipt asset or a direct
multipart image upload.
Direct uploads must be JPEG or PNG and no larger than 5 MiB. The platform verifies the object size and file signature before it is sent to the Provider. An asset can be attached to one payment intent only.
Endpoint
POST /payment_intents/:id/receiptRequired headers:
Authorization: Basic <base64(publicKey:secretKey)>.- JSON requests use
Content-Type: application/jsonand preserve the{ "asset_id": "..." }contract. - Multipart requests use
Content-Type: multipart/form-dataand require a validIdempotency-Key.
Request
For an existing private receipt asset:
curl -s -X POST "$API_BASE/payment_intents/dord_01HZYABCDXYZ/receipt" \
-u "$API_PUBLIC_KEY:$API_SECRET_KEY" \
-H "Content-Type: application/json" \
-d '{"asset_id":"asst_01HZYRECEIPT"}'For a direct upload, send the image in the file field. The idempotency fingerprint uses the image
digest, so retries with a new multipart boundary remain safe:
curl -s -X POST "$API_BASE/payment_intents/dord_01HZYABCDXYZ/receipt" \
-u "$API_PUBLIC_KEY:$API_SECRET_KEY" \
-H "Idempotency-Key: receipt-dord-01HZYABCDXYZ-v1" \
-F "file=@receipt.jpg;type=image/jpeg"The intent must still be pending and configured to accept receipt submission. Repeating the request with the same asset is safe. A rejected receipt may be replaced with a new receipt; a different receipt while one is processing or submitted is rejected.
Outcome and reconciliation
The response is the payment intent and includes a nested receipt projection:
{ "status": "required" }— the payment requires a receipt and none is attached.{ "status": "processing" }— the receipt is attached and verification is in progress.{ "status": "submitted" }— the Provider accepted the receipt.{ "status": "rejected", "failure_code": "receipt_rejected", "failure_message": "Receipt was rejected" }— the Provider rejected it; the payment remains pending and can receive a replacement.
Continue to poll the payment intent or consume the merchant webhook.
The multipart response is idempotent for 24 hours. Reusing a key with a different image digest
returns idempotency_conflict. Provider upload outcomes are reconciled durably; a Provider
rejection does not change the Payment status.