> ## Documentation Index
> Fetch the complete documentation index at: https://docs.zafapay.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Card Payments

> How to integrate card payments with hosted checkout

## Overview

Card payments use **hosted checkout**. Simply redirect the user to the `payment_url` from the API response, and card input through 3D Secure authentication is handled automatically.

## Payment Flow

<Steps>
  <Step title="Create Payment">
    Call `POST /v1/payments` to create a payment and obtain `payment_url`
  </Step>

  <Step title="Redirect">
    Redirect user to `payment_url`
  </Step>

  <Step title="Payment Complete">
    After payment, user is automatically redirected to your configured `success_redirect_url` or `failure_redirect_url` — or to the `success_url` / `failure_url` you passed on this payment
  </Step>
</Steps>

## Implementation Example

```javascript theme={null}
// 1. Create payment via API
const response = await fetch('https://api.sandbox.zafapay.com/v1/payments', {
  method: 'POST',
  headers: {
    'Authorization': 'Bearer YOUR_ACCESS_TOKEN',
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({
    amount: 100,
    currency: 'usd'
  })
});

const payment = await response.json();

// 2. Redirect user to hosted checkout
window.location.href = payment.payment_url;

// 3. User completes payment on hosted page
// 4. User is redirected to success_redirect_url or failure_redirect_url
```

## Redirect URLs

By default the customer returns to the URLs configured for your account in the merchant dashboard. To send a specific payment somewhere else — for example when you run two separate forms on one account — pass the URLs when creating the payment:

```json theme={null}
{
  "amount": 1000,
  "currency": "jpy",
  "external_id": "order_12345",
  "success_url": "https://your-site.com/orders/12345/thanks",
  "failure_url": "https://your-site.com/orders/12345/failed",
  "cancel_url": "https://your-site.com/orders/12345/cancelled"
}
```

| Field         | Used when            |
| ------------- | -------------------- |
| `success_url` | The payment succeeds |
| `failure_url` | The payment fails    |
| `cancel_url`  | The customer cancels |

Each field is optional and falls back to your dashboard default when omitted. ZAFA PAY appends `request_id`, `transaction_id`, and `status` to the URL as query parameters:

```
https://your-site.com/orders/12345/thanks?request_id=req_xxx&transaction_id=txn_xxx&status=succeeded
```

<Note>
  URLs must use `http` or `https`. These work for every checkout type, including crypto payments.
</Note>

<Warning>
  A redirect confirms only that the customer returned to your site. Always treat the [webhook](/en/api-reference/webhooks) or a Get Payment API call as the source of truth before fulfilling an order.
</Warning>

## Authorization & Capture

For two-step payments (authorize first, capture later):

```javascript theme={null}
// Step 1: Authorize
const payment = await createPayment({
  amount: 100,
  currency: 'usd',
  capture_method: 'manual'  // Authorization only
});

// Step 2: Capture (when ready to charge)
await fetch(`https://api.sandbox.zafapay.com/v1/payments/${payment.transaction_id}/capture`, {
  method: 'POST',
  headers: {
    'Authorization': 'Bearer YOUR_ACCESS_TOKEN'
  }
});
```

## Test Cards

| Card Number      | Description        |
| ---------------- | ------------------ |
| 4242424242424242 | Successful payment |
| 4000002500003155 | Requires 3D Secure |
| 4000000000000002 | Declined           |
| 4000000000000259 | Chargeback         |
| 4000000000009995 | Insufficient funds |
| 4000000000009987 | Lost card          |
| 4000000000009979 | Stolen card        |
| 4000000000000069 | Expired card       |
| 4000000000000127 | Incorrect CVC      |
| 4000000000000119 | Processing error   |

<Info>
  For complete API parameters and response details, see the [Create Payment](/api-reference/payments/create-payment) API reference.
</Info>
