Single Payment Flow
Overview
A single-allocation payment charges one payment method for the full transaction amount. This is the most common payment flow. The paymentAllocations array contains exactly 1 entry.
Key characteristics:
- One allocation — no rollback logic needed
- Idempotent via
merchantTransactionId(up to 5 attempts) - Supports
CARDandBANK_ACCOUNTpayment methods - Supports both
SALE(immediate charge) andPRE-AUTH(hold then capture) for cards
Sequence Diagram
API Request
info
For complete field definitions and constraints, see the Create Payment API Spec.
Pay with Wallet (Stored Payment Method)
Uses paymentMethodId to reference a card already stored in the customer's wallet.
Sample Request
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": "order-20260404-001",
"amount": 15000,
"currencyCode": "USD",
"authorizeCard": false,
"partialAuthorization": false,
"description": "Payment for order #12345",
"statementDescriptorSuffix": "ORDER123",
"customer": {
"hsid": "b313c1d1-b5b6-4ec7-8b5a-3a9cf7755060",
"firstName": "John",
"lastName": "Doe",
"email": "john.doe@example.com"
},
"paymentAllocations": [
{
"amount": 15000,
"paymentMethodId": "b0b3c48d-4cf6-404a-a554-e14640a51c5b"
}
],
"metadata": {
"orderId": "12345",
"channel": "web"
}
}'
One-Time Pay (Inline Payment Method)
Provides payment method details inline — the method is not saved to the wallet.
Sample Request
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": "order-20260404-002",
"amount": 5000,
"currencyCode": "USD",
"authorizeCard": false,
"partialAuthorization": false,
"customer": {
"enterpriseIdentifier": "123456789"
},
"paymentAllocations": [
{
"amount": 5000,
"paymentMethod": {
"type": "CARD",
"card": {
"number": "4242424242424242",
"expMonth": 12,
"expYear": 2028,
"cvc": "123"
}
}
}
]
}'
API Response
202 Accepted (Immediate Response)
The service returns 202 immediately with the payment in INITIATED or PENDING state.
{
"url": "https://api-stg.uhg.com/api/financial/commerce/nonprodcheckout/v2/payments/550e8400-e29b-41d4-a716-446655440000",
"data": {
"id": "550e8400-e29b-41d4-a716-446655440000",
"merchantTransactionId": "order-20260404-001",
"amount": 15000,
"currencyCode": "USD",
"status": "INITIATED",
"authorizeCard": false,
"authRequired": false,
"partialAuthorization": false,
"statementDescriptorSuffix": "ORDER123",
"description": "Payment for order #12345",
"customer": {
"firstName": "John",
"lastName": "Doe",
"email": "john.doe@example.com",
"hsid": "b313c1d1-b5b6-4ec7-8b5a-3a9cf7755060"
},
"paymentAllocations": null,
"paymentDateUtc": "2026-04-04T10:30:00Z",
"metadata": {
"orderId": "12345",
"channel": "web"
}
}
}
200 OK — Completed Payment (GET)
After processing completes, a GET /v2/payments/{paymentId} returns the full result:
{
"url": "https://api-stg.uhg.com/api/financial/commerce/nonprodcheckout/v2/payments/550e8400-e29b-41d4-a716-446655440000",
"data": {
"id": "550e8400-e29b-41d4-a716-446655440000",
"merchantTransactionId": "order-20260404-001",
"amount": 15000,
"authorizedAmount": 15000,
"capturedAmount": 15000,
"currencyCode": "USD",
"status": "COMPLETED",
"authorizeCard": false,
"authRequired": false,
"partialAuthorization": false,
"statementDescriptorSuffix": "ORDER123",
"description": "Payment for order #12345",
"customer": {
"firstName": "John",
"lastName": "Doe",
"email": "john.doe@example.com",
"hsid": "b313c1d1-b5b6-4ec7-8b5a-3a9cf7755060"
},
"paymentAllocations": [
{
"id": "a1b2c3d4-e5f6-7890-1234-567890abcdef",
"amount": 15000,
"authorizedAmount": 15000,
"capturedAmount": 15000,
"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_3NabcXYZ123456789"
}
}
],
"paymentDateUtc": "2026-04-04T10:30:00Z",
"metadata": {
"orderId": "12345",
"channel": "web"
},
"merchant": {
"id": "b955db5e-aef2-47de-bbb9-c80b9cc16e8f",
"name": "Example Merchant"
}
}
}
Validation Rules
| Rule | HTTP Status | Error |
|---|---|---|
paymentAllocations array must have exactly 1 item (single payment) | 400 | INVALID_REQUEST |
paymentAllocations[0].amount must equal top-level amount | 400 | INVALID_REQUEST |
amount must be ≥ 1 and ≤ 100,000,000 | 400 | INVALID_REQUEST |
merchantTransactionId must be 1-50 characters | 400 | INVALID_REQUEST |
Each allocation must have either paymentMethodId OR paymentMethod, not both | 400 | INVALID_REQUEST |
authorizeCard: true requires partialAuthorization: true | 400 | INVALID_REQUEST |
Customer must have at least one identifier (hsid, enterpriseIdentifier, or metadata) | 400 | INVALID_REQUEST |
Error Scenarios
400 — Bad Request (Schema Validation)
{
"title": "INVALID_REQUEST",
"status": 400,
"detail": "Invalid request format. Please check JSON structure and field types"
}
403 — Forbidden (Merchant Not Linked)
{
"title": "FORBIDDEN",
"status": 403,
"detail": "403 FORBIDDEN. RequestId: abc123-def456"
}
422 — Unprocessable Entity (Payment Failed)
{
"title": "PAYMENT_ERROR",
"status": 422,
"detail": "Payment processing failed for all records. Check individual records for error details",
"data": {
"id": "550e8400-e29b-41d4-a716-446655440000",
"merchantTransactionId": "order-20260404-001",
"amount": 15000,
"status": "FAILED",
"paymentAllocations": [
{
"id": "a1b2c3d4-e5f6-7890-1234-567890abcdef",
"amount": 15000,
"status": "FAILED",
"error": {
"code": "card_declined",
"message": "Your card was declined."
}
}
]
}
}
Webhook Payload — PAYMENT_SUCCEEDED
{
"name": "PAYMENT_SUCCEEDED",
"source": "merchant-portal",
"payload": {
"id": "550e8400-e29b-41d4-a716-446655440000",
"merchantTransactionId": "order-20260404-001",
"amount": 15000,
"currencyCode": "USD",
"status": "COMPLETED",
"customer": {
"firstName": "John",
"lastName": "Doe",
"email": "john.doe@example.com"
},
"paymentAllocations": [
{
"id": "a1b2c3d4-e5f6-7890-1234-567890abcdef",
"amount": 15000,
"status": "COMPLETED",
"paymentMethod": {
"type": "CARD",
"card": {
"lastFour": "4242",
"brand": "visa"
}
}
}
],
"paymentDateUtc": "2026-04-04T10:30:00Z"
}
}
Edge Cases
| Scenario | Behavior | Notes |
|---|---|---|
Duplicate merchantTransactionId (retry ≤ 5) | Returns existing payment with current status | No new processing; idempotent response |
Duplicate merchantTransactionId (retry > 5) | 422 UNPROCESSABLE_ENTITY | Merchant must generate a new ID |
| Stripe timeout | Allocation marked FAILED, payment marked FAILED | Circuit breaker may open if repeated |
| Customer not found | Payment transitions to PENDING_FOR_CUSTOMER_CREATION then FAILED | Error logged with resolution details |
Invalid paymentMethodId | 422 UNPROCESSABLE_ENTITY | PM must exist in customer's wallet |
| Expired card | 422 PAYMENT_ERROR with vendor error | Allocation error contains decline reason |