> ## Documentation Index
> Fetch the complete documentation index at: https://docs.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/payment-methods/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/card-on-file/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>

## Save a Card Without a Payment

If you want to store a card **before** any money moves — for example when onboarding a customer, setting up a subscription, or collecting card details over a link — use the standalone [Authorize Card](/api-reference/card-on-file/authorize-card) API instead of `process-payment`.

<Steps>
  <Step title="Create a Customer">
    Use the [Create Customer API](/api-reference/customers/create-customer) and keep the returned `id` — this is the `customerId` used in the next step.
  </Step>

  <Step title="Request a Card Authorization Link">
    Call [Authorize Card](/api-reference/card-on-file/authorize-card). Atoa returns a secure hosted page URL. No amount is involved and no money moves.

    ```bash theme={null}
    curl --request POST \
      --url https://api.atoa.me/api/customers/{customerId}/cards/authorize \
      --header 'Authorization: Bearer <token>' \
      --header 'Content-Type: application/json' \
      --data '{
        "sendLinkToCustomer": false,
        "successRedirectUrl": "https://yoursite.com/cards/success",
        "failureRedirectUrl": "https://yoursite.com/cards/failure"
      }'
    ```

    Response includes a `hostedPageUrl`. Present it in your app or WebView, or set `sendLinkToCustomer=true` to have Atoa deliver it by email (or SMS if the customer has no email).
  </Step>

  <Step title="Customer Saves Their Card">
    The customer enters their card details on Atoa's PCI-compliant hosted page and completes 3DS authentication. Card details never touch your systems, and there is no separate confirmation call to make.
  </Step>

  <Step title="Charge the Saved Card Later">
    Retrieve the card with [List Payment Methods](/api-reference/payment-methods/list-payment-methods), then charge it at any time with [Charge Saved Card](/api-reference/card-on-file/charge-saved-card) using the returned `paymentMethodId`.
  </Step>
</Steps>

## Which Flow Should I Use?

Both flows end with a card on file — the difference is whether a payment happens at the same time.

|                         | `savePaymentMethod` in Process Payment                                                                                           | Standalone Authorize Card                                                                                                               |
| ----------------------- | -------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------- |
| **When to use**         | Customer is already paying at checkout and you want to save their card for next time                                             | You want to save a card upfront, with no payment — e.g. subscription setup, onboarding                                                  |
| **Endpoint**            | [Process Payment](/api-reference/payment/process-payment) with `savePaymentMethod=true`                                          | [Authorize Card](/api-reference/card-on-file/authorize-card)                                                                            |
| **Money moves?**        | Yes — the payment amount is charged                                                                                              | No — authorization only, £0                                                                                                             |
| **Customer experience** | Pays as normal at checkout; card is saved automatically after successful 3DS                                                     | Opens a hosted page link, enters card details, completes 3DS — no payment shown                                                         |
| **Link delivery**       | Not applicable — happens inside checkout                                                                                         | Return the `hostedPageUrl` yourself, or set `sendLinkToCustomer=true` for email/SMS delivery                                            |
| **What you get back**   | A normal payment response; the saved card appears in [List Payment Methods](/api-reference/payment-methods/list-payment-methods) | A `hostedPageUrl`; the saved card appears in [List Payment Methods](/api-reference/payment-methods/list-payment-methods) once completed |

Either way, charge the saved card later with [Charge Saved Card](/api-reference/card-on-file/charge-saved-card).

## 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/card-on-file/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/process-payment-webhook-response) for the full payload structure.

## Checking Payment Status

Use the existing [Get Payment Status](/api-reference/payment/get-payment-status) 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                                    |
