> ## Documentation Index
> Fetch the complete documentation index at: https://devdocs.paywithatoa.co.uk/llms.txt
> Use this file to discover all available pages before exploring further.

# Introduction | Card on File API

> Atoa Card on File: securely save a customer's card during checkout and charge it later for repeat or subscription payments.

Card on File lets you securely save customer card details and charge them later — for recurring, on-demand, or subscription payments — without the customer re-entering their card.

<Note>
  Card on File requires card payments to be activated on your merchant account. Contact support if not enabled.
</Note>

## Save During Checkout

For most merchants, saving cards during the checkout flow is the simplest and most effective approach.

<Steps>
  <Step title="Create a Customer (Optional but Recommended)">
    Use the [Create Customer API](/api-reference/Customers/create-customer) to create a customer before checkout. This enables better tracking and customer management.

    ```bash theme={null}
    curl --request POST \
      --url https://api.atoa.me/api/customers \
      --header 'Authorization: Bearer <token>' \
      --header 'Content-Type: application/json' \
      --data '{
        "fullName": "John Doe",
        "email": "john@example.com",
        "phoneNumber": "7598570522",
        "phoneCountryCode": "44"
      }'
    ```

    Response includes `id` (customer UUID) to use as `atoaCustomerId` in the next step.
  </Step>

  <Step title="Process Payment with savePaymentMethod">
    Call [Process Payment](/api-reference/Payment/process-payment) with `savePaymentMethod=true` and `atoaCustomerId` from step 1:

    ```bash theme={null}
    curl --request POST \
      --url https://api.atoa.me/api/payments/process-payment \
      --header 'Authorization: Bearer <token>' \
      --header 'Content-Type: application/json' \
      --data '{
        "customerId": "merchant-ref-123",
        "orderId": "order-456",
        "amount": 1000,
        "storeId": "store-uuid",
        "paymentMethod": ["CARD"],
        "atoaCustomerId": "<atoaCustomerId>", // UUID returned from Create Customer API
        "savePaymentMethod": true,
        "redirectUrl": "https://yoursite.com/payment-callback"
      }'
    ```

    <Note>
      `atoaCustomerId` is the Atoa customer UUID returned from step 1 (Create Customer API). This is different from `customerId`, which is your own merchant reference for the customer.
    </Note>

    The card is automatically saved after successful 3DS authentication.
  </Step>

  <Step title="Retrieve Saved Cards">
    Use [List Payment Methods](/api-reference/PaymentMethods/list-payment-methods) to see all cards saved for a customer:

    ```bash theme={null}
    curl --request GET \
      --url https://api.atoa.me/api/customers/{customerId}/cards \
      --header 'Authorization: Bearer <token>'
    ```
  </Step>

  <Step title="Process Future Payments">
    **Option A: Faster Checkout (One-Click)**

    Pass `atoaCustomerId` in process-payment to automatically show saved cards at checkout:

    ```bash theme={null}
    curl --request POST \
      --url https://api.atoa.me/api/payments/process-payment \
      --header 'Authorization: Bearer <token>' \
      --header 'Content-Type: application/json' \
      --data '{
        "customerId": "merchant-ref-123",
        "orderId": "order-789",
        "amount": 2000,
        "storeId": "store-uuid",
        "paymentMethod": ["CARD"],
        "atoaCustomerId": "customer-uuid",
        "redirectUrl": "https://yoursite.com/payment-callback"
      }'
    ```

    Customer sees their saved cards and can complete payment with one click.

    **Option B: Charge Saved Card**

    Use [Charge Saved Card](/api-reference/CardOnFile/charge-saved-card) to charge a saved card without customer interaction:

    ```bash theme={null}
    curl --request POST \
      --url https://api.atoa.me/api/payments/card/process-payment \
      --header 'Authorization: Bearer <token>' \
      --header 'Content-Type: application/json' \
      --data '{
        "customerId": "merchant-ref-123",
        "amount": 2000,
        "paymentMethodId": "<paymentMethodId>", // ID from List Payment Methods API
        "capture": "AUTO_CAPTURE"
      }'
    ```
  </Step>
</Steps>

## Authentication

All Card on File endpoints use Bearer token authentication. Generate your `accessSecret` from the **Atoa Business App** or **Web Dashboard** (Profile icon > Settings > API Access).

```
Authorization: Bearer <accessSecret>
```

## Capture Types

When processing a card payment, you choose a capture type that determines how and when funds are collected:

| Capture Type            | Behaviour                                                                                                                                                                              |
| ----------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `AUTO_CAPTURE`          | Payment is captured immediately. No further action needed. Status goes to `COMPLETED`.                                                                                                 |
| `MANUAL_CAPTURE`        | Payment is authorized but not captured. You must call [Manual Capture Payment](/api-reference/CardOnFile/capture-payment) to collect the funds. Status is `AUTHORIZED` until captured. |
| `CAPTURE_BEFORE_EXPIRY` | Payment is authorized and will be automatically captured before the authorization expires, unless you manually capture or cancel it first.                                             |

## Payment Status Lifecycle

```mermaid theme={null}
---
config:
  flowchart:
    curve: linear
---
flowchart LR
    PP["Process Payment"] --> AC["AUTO_CAPTURE"]
    PP --> MC["MANUAL_CAPTURE"]
    PP --> CBE["CAPTURE_BEFORE_EXPIRY"]

    AC -->|"Immediate"| COMP1["✅ COMPLETED"]

    MC --> AUTH1["AUTHORIZED"]
    AUTH1 -->|"Capture"| COMP2["✅ COMPLETED"]
    AUTH1 -->|"Cancel"| CANC1["❌ CANCELLED"]

    CBE --> AUTH2["AUTHORIZED"]
    AUTH2 -->|"Capture"| COMP3["✅ COMPLETED"]
    AUTH2 -->|"Cancel"| CANC2["❌ CANCELLED"]
    AUTH2 -->|"Auto-capture before expiry"| COMP4["✅ COMPLETED"]
```

## Webhooks

Card on File payments trigger the same `PAYMENTS_STATUS` webhook event as Pay by Bank payments. Subscribe to webhooks to receive real-time notifications when payment status changes.

For card payments, the webhook payload includes additional statuses:

| Status       | Description                                                                                   |
| ------------ | --------------------------------------------------------------------------------------------- |
| `COMPLETED`  | Payment has been captured successfully. Funds will be settled to the merchant.                |
| `PENDING`    | Payment is being processed.                                                                   |
| `AUTHORIZED` | Payment has been authorized but not yet captured (MANUAL\_CAPTURE / CAPTURE\_BEFORE\_EXPIRY). |
| `FAILED`     | Payment failed. The `errorDescription` field contains details.                                |
| `CANCELLED`  | An authorized payment was cancelled before capture.                                           |

See [Payment Status Webhook Payload](/api-reference/Webhook/processPaymentWebhookResponse) for the full payload structure.

## Checking Payment Status

Use the existing [Get Payment Status](/api-reference/Payment/getPaymentStatus) API (`GET /api/payments/v1/payment-status/{paymentRequestId}`) to check the status of card payments. For card transactions, the response includes a `cardPaymentDetails` object in each transaction detail with card-specific information such as card type, capture type, and masked card number.

## Error Handling

All endpoints return errors in this format:

```json theme={null}
{
  "name": "BAD_REQUEST",
  "message": "Invalid atoaCustomerId. Customer not found or does not belong to this business.",
  "status": 400,
  "errors": []
}
```

| Status Code | Description                                              |
| ----------- | -------------------------------------------------------- |
| `400`       | Validation error — check the `message` field for details |
| `401`       | Invalid or missing authentication token                  |
| `404`       | Resource not found (customer, card, or payment)          |
| `409`       | Conflict (e.g., duplicate customer email)                |
| `500`       | Internal server error                                    |
