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.

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

Save During Checkout

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

1

Create a Customer (Optional but Recommended)

Use the Create Customer API to create a customer before checkout. This enables better tracking and customer management.

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.

2

Process Payment with savePaymentMethod

Call Process Payment with savePaymentMethod=true and atoaCustomerId from step 1:

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"
  }'

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.

The card is automatically saved after successful 3DS authentication.

3

Retrieve Saved Cards

Use List Payment Methods to see all cards saved for a customer:

curl --request GET \
  --url https://api.atoa.me/api/customers/{customerId}/cards \
  --header 'Authorization: Bearer <token>'
4

Process Future Payments

Option A: Faster Checkout (One-Click)

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

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 to charge a saved card without customer interaction:

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"
  }'

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 TypeBehaviour
AUTO_CAPTUREPayment is captured immediately. No further action needed. Status goes to COMPLETED.
MANUAL_CAPTUREPayment is authorized but not captured. You must call Manual Capture Payment to collect the funds. Status is AUTHORIZED until captured.
CAPTURE_BEFORE_EXPIRYPayment is authorized and will be automatically captured before the authorization expires, unless you manually capture or cancel it first.

Payment Status Lifecycle

---
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:

StatusDescription
COMPLETEDPayment has been captured successfully. Funds will be settled to the merchant.
PENDINGPayment is being processed.
AUTHORIZEDPayment has been authorized but not yet captured (MANUAL_CAPTURE / CAPTURE_BEFORE_EXPIRY).
FAILEDPayment failed. The errorDescription field contains details.
CANCELLEDAn authorized payment was cancelled before capture.

See Payment Status Webhook Payload for the full payload structure.

Checking Payment Status

Use the existing 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:

{
  "name": "BAD_REQUEST",
  "message": "Invalid atoaCustomerId. Customer not found or does not belong to this business.",
  "status": 400,
  "errors": []
}
Status CodeDescription
400Validation error — check the message field for details
401Invalid or missing authentication token
404Resource not found (customer, card, or payment)
409Conflict (e.g., duplicate customer email)
500Internal server error