Cancel Payment Flow
π InternalInternal information β not visible in the public (merchant) site.
Overviewβ
The cancel endpoint (PATCH /v2/payments/{paymentId}/cancel) allows merchants to void or cancel an in-progress or authorized payment. Cancellation triggers a Stripe void or reversal depending on the current payment state.
Cancellation Eligibilityβ
| Payment State | Cancel Allowed? | Stripe Action |
|---|---|---|
AUTHORIZED | β | Void the PaymentIntent |
ACCEPTED | β | Reverse the ACH transaction |
PENDING | β | Cancel before processing |
INITIATED | β | Cancel before processing |
PROCESSING | β | Wait for terminal state |
COMPLETED | β | Use refund (POST /v2/refunds) instead |
FAILED | β | Already terminal |
CANCELLED | β | Already terminal |
Cancellation Reasonsβ
| Value | When to Use |
|---|---|
DUPLICATE | Merchant identified this as a duplicate payment |
FRAUDULENT | Suspected fraudulent activity |
REQUESTED_BY_CUSTOMER | Customer asked to cancel |
ABANDONED | Customer did not complete (e.g., 3DS timeout) |
API Requestβ
curl -X PATCH "https://api-stg.uhg.com/api/financial/commerce/nonprodcheckout/v2/payments/770e8400-e29b-41d4-a716-446655440000/cancel" \
-H "Authorization: Bearer <token>" \
-H "X-Merchant-Id: b955db5e-aef2-47de-bbb9-c80b9cc16e8f" \
-H "X-Upstream-Env: dev" \
-H "Content-Type: application/json" \
-d '{
"paymentCancellationReason": "REQUESTED_BY_CUSTOMER",
"paymentCancellationMessage": "Customer changed their mind before shipment"
}'
Request Bodyβ
| Field | Type | Required | Description |
|---|---|---|---|
paymentCancellationReason | string (enum) | Yes | One of: DUPLICATE, FRAUDULENT, REQUESTED_BY_CUSTOMER, ABANDONED |
paymentCancellationMessage | string | No | Free-text context (for audit trail) |
API Response β 202 Acceptedβ
{
"url": "https://api-stg.uhg.com/.../v2/payments/770e8400-e29b-41d4-a716-446655440000",
"data": {
"id": "770e8400-e29b-41d4-a716-446655440000",
"merchantTransactionId": "preauth-20260404-001",
"amount": 25000,
"status": "CANCEL_INITIALIZED",
"paymentAllocations": [
{
"id": "cccc1111-2222-3333-4444-555566667777",
"amount": 25000,
"status": "CANCEL_INITIALIZED"
}
]
}
}
GET β After Cancellation (200 OK)β
{
"data": {
"id": "770e8400-e29b-41d4-a716-446655440000",
"amount": 25000,
"status": "CANCELLED",
"paymentAllocations": [
{
"id": "cccc1111-2222-3333-4444-555566667777",
"amount": 25000,
"status": "CANCELED"
}
]
}
}
Webhook β PAYMENT_CANCELLEDβ
{
"name": "PAYMENT_CANCELLED",
"source": "merchant-portal",
"payload": {
"id": "770e8400-e29b-41d4-a716-446655440000",
"merchantTransactionId": "preauth-20260404-001",
"amount": 25000,
"status": "CANCELLED",
"paymentAllocations": [
{
"id": "cccc1111-2222-3333-4444-555566667777",
"amount": 25000,
"status": "CANCELED"
}
]
}
}
Error Scenariosβ
| Scenario | HTTP Status | Error Title | Detail |
|---|---|---|---|
Payment in COMPLETED state | 422 | UNPROCESSABLE_ENTITY | Payment cannot be cancelled in COMPLETED state |
Payment in FAILED state | 422 | UNPROCESSABLE_ENTITY | Payment already failed |
| Payment not found | 404 | NOT_FOUND | paymentId not found |
Missing paymentCancellationReason | 400 | INVALID_REQUEST | paymentCancellationReason is required |
| Invalid cancellation reason value | 400 | INVALID_REQUEST | Invalid enum value |
| Stripe void failed | 422 | PAYMENT_ERROR | Cancellation processing failed |