Checking access…

Skip to main content
Version: v2

Confirming a Payment Allocation (3DS)

When a payment allocation requires 3D Secure (3DS) authentication, it enters either the AUTH_REQUIRED or CONFIRMATION_REQUIRED status. The customer must complete the 3DS challenge in their browser or app before the allocation can proceed. Once the challenge is complete, the merchant calls the Confirm Allocation endpoint to continue the payment flow for that specific allocation.

Business Context

For business rules and lifecycle details, see Split Tender Payments β€” Business Guide.


Integration Details
  • Prerequisites: Merchant account must be configured for split-tender payments. The allocation must be in AUTH_REQUIRED or CONFIRMATION_REQUIRED status.
  • API Endpoint: PATCH /v2/payments/{paymentId}/allocations/{allocationId}/confirm
  • API Spec: Confirm Payment Allocation
  • Scope: merchant
  • API Version: v2
  • Required Headers: X-Merchant-Id (UUID), X-Checkout-Id (UUID)
  • Request Body: None
  • Response: 202 Accepted β€” updated transaction with the confirmed allocation in CONFIRMATION_INITIALIZED
  • Error Handling: See Payment Error Codes for applicable error codes.

When to Call This Endpoint​

Call this endpoint when polled or webhook-notified that an allocation has transitioned to:

StatusMeaning
AUTH_REQUIRED3DS authentication is required before authorization can proceed
CONFIRMATION_REQUIREDAuthorization is complete but explicit confirmation is needed before capture

Do not call this endpoint for allocations in any other status. The service will reject the request if the allocation is not in a confirmable state.

Sibling Failure Check

If another allocation in the same transaction is already in FAILED, PAYMENT_METHOD_FAILED, CANCELED, CANCEL_INITIALIZED, or CANCEL_FAILED, the confirm call will be rejected with 422. The transaction is already heading toward cancellation β€” completing a 3DS challenge would only result in an immediate rollback of the confirmed leg.


API Request​

Path Parameters​

ParameterTypeDescription
paymentIdUUIDThe V2 transaction ID (id from the create payment response)
allocationIdUUIDThe specific allocation ID (paymentAllocations[n].id) to confirm

Required Headers​

HeaderTypeDescription
AuthorizationstringBearer token
X-Merchant-IdUUIDMerchant identifier β€” must match the merchant that owns the transaction
X-Checkout-IdUUIDCheckout session ID β€” must match the checkout session under which the payment was created

Request Body​

None β€” this is a PATCH with no body.

Sample Request
curl -X PATCH "https://api-stg.uhg.com/api/financial/commerce/nonprodcheckout/v2/payments/{paymentId}/allocations/{allocationId}/confirm" \
-H "Authorization: Bearer <token>" \
-H "X-Merchant-Id: b955db5e-aef2-47de-bbb9-c80b9cc16e8f" \
-H "X-Checkout-Id: f3a1c2d4-e5f6-7890-ab12-cd34ef567890" \
-H "X-Upstream-Env: dev" \
-H "Accept: application/json"

Validation​

The endpoint performs the following checks in order. The first failure short-circuits and returns an error.

OrderCheckFailure
1Transaction exists404 Not Found
2X-Merchant-Id matches the transaction's merchant403 Forbidden
3Payment legs exist for the transaction404 Not Found
4All payment legs belong to X-Merchant-Id403 Forbidden
5No sibling allocation is in an abort state (FAILED, PAYMENT_METHOD_FAILED, CANCELED, CANCEL_INITIALIZED, CANCEL_FAILED)422 Unprocessable Entity
6The target allocation ID exists within this transaction422 Unprocessable Entity
7X-Checkout-Id matches the checkout ID stored in the allocation's metadata422 Unprocessable Entity
8The allocation status is AUTH_REQUIRED or CONFIRMATION_REQUIRED422 Unprocessable Entity
9Checkout session is active (not expired or in a terminal state)422 Unprocessable Entity

API Response​

Success β€” 202 Accepted​

Returns the full updated transaction. The confirmed allocation transitions to CONFIRMATION_INITIALIZED. The transaction-level status reflects the combined state of all allocations.

Response Structure

The complex object is trimmed for brevity. Refer to the API Spec for the full response structure.

Sample Response β€” Allocation CONFIRMATION_INITIALIZED
{
"url": "https://api-stg.uhg.com/v2/payments/3222ac8a-c8fa-4426-bd99-e96a909569b0",
"data": {
"id": "3222ac8a-c8fa-4426-bd99-e96a909569b0",
"merchantTransactionId": "c407ecc7-25f0-4fd9-844b-e9baca53707a",
"amount": 100,
"status": "AUTH_REQUIRED",
"paymentAllocations": [
{
"id": "8cd647c5-f9ff-42a0-b7d9-084c7f5d7d47",
"amount": 60,
"status": "CONFIRMATION_INITIALIZED",
"paymentMethod": {
"// ... see API Spec for full paymentMethod object ...": "..."
}
},
{
"id": "777373ac-dccf-499f-8c77-1d5e198508ad",
"amount": 40,
"status": "AUTH_REQUIRED",
"paymentMethod": {
"// ... see API Spec for full paymentMethod object ...": "..."
}
}
]
}
}
Sample Response β€” Validation Failure (422)
{
"title": "UNPROCESSABLE_ENTITY",
"detail": "Payment cannot be confirmed",
"status": 422
}

Status Handling​

After confirming an allocation, track the overall transaction status by polling GET /v2/payments/{paymentId} or listening to webhooks. The parent transaction status is derived from the combined statuses of all allocations.

Recommended Strategy

Use webhooks as the primary mechanism for status updates (PAYMENT_SUCCEEDED, PAYMENT_FAILED). Fall back to polling only if webhooks are unavailable.

Post-Confirm Status Progression​

Allocation Status After ConfirmMeaning
CONFIRMATION_INITIALIZEDConfirm accepted; processing with Stripe underway
AUTHORIZEDStripe confirms the PaymentIntent; awaiting capture
COMPLETEDAllocation fully captured and complete
FAILEDConfirmation processing failed at the processor

Status Mapping Table​

The parent transaction's status reflects the lowest-ranked allocation status across all legs (i.e., the allocation that is furthest behind drives the parent). If one allocation has been confirmed but another still requires 3DS, the parent remains in AUTH_REQUIRED.

Allocation 1Allocation 2Parent StatusDescription
⏳ CONFIRMATION_INITIALIZED⏳ AUTH_REQUIRED⏳ AUTH_REQUIREDOne confirmed, one still pending 3DS
⏳ CONFIRMATION_INITIALIZED⏳ CONFIRMATION_INITIALIZED⏳ CONFIRMATION_INITIALIZEDBoth confirmed, awaiting Stripe processing
βœ… COMPLETEDβœ… COMPLETEDβœ… COMPLETEDBoth complete β€” final state
❌ FAILED⏳ CONFIRMATION_INITIALIZED❌ FAILEDOne failed β€” parent immediately reflects failure
❌ PAYMENT_METHOD_FAILED⏳ AUTH_REQUIRED❌ PAYMENT_METHOD_FAILEDPayment method failure β€” cancel proceeds; no need to wait for 3DS
πŸ”„ ROLLED_BACK❌ FAILED❌ FAILEDRollback complete β€” final state
Capture Gating

When any allocation is in AUTH_REQUIRED, the orchestrator pauses the capture pipeline for the entire transaction. No allocation will be captured until all pending 3DS challenges are resolved. This prevents partial captures across a split-tender transaction.


Error Handling​

Error Code References

For the complete list of error codes and remediation steps, see Payment Error Codes.

Confirm-Specific Error Scenarios​

ScenarioHTTP StatusDescription
Missing X-Checkout-Id header400Required header not present in the request
Merchant mismatch403X-Merchant-Id does not own the transaction
Transaction not found404paymentId does not exist
Allocation not found422allocationId is not part of this transaction
Checkout ID mismatch422X-Checkout-Id does not match the checkout session in the allocation's metadata
Sibling allocation in abort state422A sibling is in FAILED, PAYMENT_METHOD_FAILED, CANCELED, CANCEL_INITIALIZED, or CANCEL_FAILED β€” completing 3DS would trigger an immediate rollback
Ineligible allocation status422Allocation is not in AUTH_REQUIRED or CONFIRMATION_REQUIRED
Checkout session invalid422Checkout session has expired, completed, or is agent-initiated
3DS in Agent Sessions

If a split-tender allocation requires 3DS authentication during an agent-assisted session, the entire payment fails. Agents cannot complete 3DS challenges. The confirm endpoint will reject requests from agent checkout sessions.


FAQ​

Q: Can I call this endpoint for both allocations at the same time?
A: Yes, but each allocation requires a separate PATCH call. The service applies an advisory lock per allocation to prevent duplicate concurrent confirms.

Q: What if the customer doesn't complete the 3DS challenge?
A: The allocation stays in AUTH_REQUIRED or CONFIRMATION_REQUIRED. No automatic timeout is applied β€” the allocation remains in that status until confirmed or the checkout session expires.

Q: What happens if the checkout session expires before I call confirm?
A: The endpoint will return a 422 at validation step 8 (checkout session active check). Initiate a new checkout session and payment.

Q: Will the other allocation be affected if one confirm fails?
A: If one allocation's confirm fails after the other has already progressed, CCG automatically rolls back the successful allocation (cancellation). The parent transaction moves to FAILED.

Q: Does the confirm endpoint publish a new event to the stripe adapter?
A: The event is published with dataVersion: "0.1". The existing stripe adapter PaymentConsumer handles it β€” no new consumer or routing is required.


Integration Checklist​

Before going live with the confirm allocation flow, verify:

  • Your integration polls or subscribes to webhooks to detect AUTH_REQUIRED / CONFIRMATION_REQUIRED status on individual allocations
  • You store the allocationId from the create payment response for each payment leg
  • You store the X-Checkout-Id used during the original payment creation β€” the same value must be passed to the confirm call
  • Your 3DS challenge flow returns control to your application before calling confirm
  • You handle 422 responses gracefully β€” log the detail field for diagnostic context
  • You do not call confirm from an agent-assisted session (agent flows will always result in a 422)
  • You test against staging using the Payment Error Codes test card scenarios for 3DS flows