Skip to main content
Version: v2

Split-Tender Payment Flow

Overview

A split-tender payment distributes a single transaction across exactly 2 payment allocations (currently CARD + CARD only). The system treats the two allocations as an atomic unit — if one fails, the successful allocation is automatically rolled back.

Key characteristics:

  • Exactly 2 entries in paymentAllocations
  • Only CARD + CARD combinations supported
  • Only SALE transactions (not pre-auth)
  • Automatic rollback (cancel/reverse) if any allocation fails
  • ROLLED_BACK status and remediation object on reversed allocations

Sequence Diagram


API Request

Sample Request — Split-Tender (2 Cards)
curl -X POST "https://api-stg.uhg.com/api/financial/commerce/nonprodcheckout/v2/payments" \
-H "Authorization: Bearer <token>" \
-H "X-Merchant-Id: b955db5e-aef2-47de-bbb9-c80b9cc16e8f" \
-H "X-Upstream-Env: dev" \
-H "Content-Type: application/json" \
-d '{
"merchantTransactionId": "split-20260404-001",
"amount": 20000,
"currencyCode": "USD",
"authorizeCard": false,
"partialAuthorization": false,
"customer": {
"hsid": "b313c1d1-b5b6-4ec7-8b5a-3a9cf7755060"
},
"paymentAllocations": [
{
"amount": 12000,
"paymentMethodId": "b0b3c48d-4cf6-404a-a554-e14640a51c5b"
},
{
"amount": 8000,
"paymentMethodId": "c1d4e5f6-7890-1234-5678-90abcdef1234"
}
],
"metadata": {
"orderId": "split-order-789"
}
}'

Validation Rules (Split-Tender Specific)

RuleHTTP StatusError
paymentAllocations must have exactly 2 items400INVALID_REQUEST
alloc[0].amount + alloc[1].amount must equal top-level amount400INVALID_REQUEST
Both allocations must use CARD payment methods400INVALID_REQUEST
authorizeCard must be false (pre-auth not supported for split-tender)400INVALID_REQUEST
Each allocation amount must be ≥ 1400INVALID_REQUEST

API Response — Both Succeed (GET 200)

{
"url": "https://api-stg.uhg.com/.../v2/payments/660e8400-e29b-41d4-a716-446655440000",
"data": {
"id": "660e8400-e29b-41d4-a716-446655440000",
"merchantTransactionId": "split-20260404-001",
"amount": 20000,
"authorizedAmount": 20000,
"capturedAmount": 20000,
"currencyCode": "USD",
"status": "COMPLETED",
"paymentAllocations": [
{
"id": "aaaa1111-2222-3333-4444-555566667777",
"amount": 12000,
"authorizedAmount": 12000,
"capturedAmount": 12000,
"status": "COMPLETED",
"paymentMethod": {
"id": "b0b3c48d-4cf6-404a-a554-e14640a51c5b",
"type": "CARD",
"card": { "lastFour": "4242", "brand": "visa", "expMonth": 12, "expYear": 2028 }
},
"vendor": { "name": "STRIPE", "transactionId": "pi_alloc1_abc" }
},
{
"id": "bbbb1111-2222-3333-4444-555566667777",
"amount": 8000,
"authorizedAmount": 8000,
"capturedAmount": 8000,
"status": "COMPLETED",
"paymentMethod": {
"id": "c1d4e5f6-7890-1234-5678-90abcdef1234",
"type": "CARD",
"card": { "lastFour": "1234", "brand": "mastercard", "expMonth": 6, "expYear": 2027 }
},
"vendor": { "name": "STRIPE", "transactionId": "pi_alloc2_def" }
}
]
}
}

API Response — One Fails + Rollback (422)

When allocation[1] fails, allocation[0] is automatically rolled back:

{
"title": "PAYMENT_ERROR",
"status": 422,
"detail": "Payment processing failed for all records. Check individual records for error details",
"data": {
"id": "660e8400-e29b-41d4-a716-446655440000",
"merchantTransactionId": "split-20260404-001",
"amount": 20000,
"status": "FAILED",
"paymentAllocations": [
{
"id": "aaaa1111-2222-3333-4444-555566667777",
"amount": 12000,
"status": "ROLLED_BACK",
"remediation": {
"action": "CANCEL",
"reason": "CCG_AUTOMATED_CANCEL",
"vendorTransactionId": "pi_cancel_abc"
},
"paymentMethod": {
"type": "CARD",
"card": { "lastFour": "4242", "brand": "visa" }
}
},
{
"id": "bbbb1111-2222-3333-4444-555566667777",
"amount": 8000,
"status": "FAILED",
"error": {
"code": "card_declined",
"message": "Your card was declined."
},
"paymentMethod": {
"type": "CARD",
"card": { "lastFour": "1234", "brand": "mastercard" }
}
}
]
}
}

Rollback Logic

Operational Risk

If rollback (cancel of allocation[0]) fails, the allocation enters CANCEL_FAILED state. This requires manual intervention — see Incident Playbooks (coming soon).


Webhook — Split-Tender PAYMENT_FAILED (with rollback)

{
"name": "PAYMENT_FAILED",
"source": "merchant-portal",
"payload": {
"id": "660e8400-e29b-41d4-a716-446655440000",
"merchantTransactionId": "split-20260404-001",
"amount": 20000,
"status": "FAILED",
"paymentAllocations": [
{
"id": "aaaa1111-2222-3333-4444-555566667777",
"amount": 12000,
"status": "ROLLED_BACK"
},
{
"id": "bbbb1111-2222-3333-4444-555566667777",
"amount": 8000,
"status": "FAILED"
}
]
}
}

Comparison: Single vs Split-Tender

AspectSingle AllocationSplit-Tender
Cards12
paymentAllocations1 entryExactly 2 entries
RollbackN/AAutomatic (cancel successful if sibling fails)
ROLLED_BACK statusNeverYes, on the cancelled allocation
remediation objectNever presentPresent on rolled-back allocation
Retry scopeRetry the single cardAll-or-nothing — both retried together
Pre-auth supportYesNo (authorizeCard must be false)