Skip to main content

Overview

Two-step (authorize and capture) payment flows let you reserve funds on a customer’s card without immediately charging them. This is useful for scenarios like hotel reservations, pre-orders, or marketplace payments where the final amount may change.

Flow Diagram

Step 1: Authorize

Create a payment with capture: false to authorize without capturing:
const authorization = await fetch('https://api-sandbox.y.uno/v1/payments', {
  method: 'POST',
  headers: {
    'public-api-key': process.env.YUNO_PUBLIC_KEY,
    'private-secret-key': process.env.YUNO_PRIVATE_KEY,
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    checkout_session: 'session-id',
    payment_method: { type: 'CARD', token: 'one-time-token' },
    amount: { currency: 'USD', value: 150.00 },
    country: 'US',
    capture: false,  // Authorization only
    customer: {
      email: 'customer@example.com',
    },
  }),
});
const authResult = await authorization.json();
// authResult.status === 'AUTHORIZED'
Authorizations typically expire after 7 days (varies by provider and card issuer). Capture the payment before the authorization expires, or the funds will be released automatically.

Step 2a: Capture

Capture the authorized payment to transfer the funds. Use the transaction_id from the authorize response:
const capture = await fetch(
  `https://api-sandbox.y.uno/v1/payments/${paymentId}/transactions/${transactionId}/capture`,
  {
    method: 'POST',
    headers: {
      'public-api-key': process.env.YUNO_PUBLIC_KEY,
      'private-secret-key': process.env.YUNO_PRIVATE_KEY,
      'Content-Type': 'application/json',
    },
    body: JSON.stringify({}),
  }
);
// Payment status changes to SUCCEEDED
Not all providers support partial capture. Verify provider capabilities in the Coverage Matrix before implementing partial capture flows.

Step 2b: Cancel (Void)

Cancel an authorized payment to release the held funds:
const cancel = await fetch(
  `https://api-sandbox.y.uno/v1/payments/${paymentId}/cancel`,
  {
    method: 'POST',
    headers: {
      'public-api-key': process.env.YUNO_PUBLIC_KEY,
      'private-secret-key': process.env.YUNO_PRIVATE_KEY,
      'Content-Type': 'application/json',
    },
    body: JSON.stringify({
      reason: 'Customer cancelled order',
    }),
  }
);
// Payment status changes to CANCELLED

Status Transitions

FromActionToNotes
AUTHORIZEDCaptureSUCCEEDEDFull or partial amount
AUTHORIZEDCancelCANCELLEDFunds released
AUTHORIZEDExpiryEXPIREDAutomatic after ~7 days
SUCCEEDEDRefundREFUNDEDSee Refunds

Best Practices

  • Set internal reminders to capture or cancel authorizations before they expire
  • Use cancel (void) instead of refund for un-captured authorizations to avoid processing fees
  • Log the authorization ID for reconciliation purposes
  • Implement idempotency keys to prevent duplicate captures