> ## 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.

# Charge Saved Card | Card on File API

> Charge saved card via the Atoa Card on File API, request parameters, response schema and code samples in cURL, Python, JavaScript, PHP, Go and Java.

Charge a customer's saved card without them being present (off-session). The customer must have a previously saved payment method (see [List Payment Methods](/api-reference/PaymentMethods/list-payment-methods)).

<Note>
  The response always returns `status: "PENDING"` to confirm that the payment processing has started. The final status (`COMPLETED`, `AUTHORIZED`, `FAILED`) is updated asynchronously once the card network confirms the transaction. Use [Webhooks](/api-reference/Webhook/processPaymentWebhookResponse) to receive real-time status updates, or poll the [Get Payment Status](/api-reference/Payment/getPaymentStatus) API.
</Note>

<Info>
  For `MANUAL_CAPTURE` or `CAPTURE_BEFORE_EXPIRY`, the payment will move to `AUTHORIZED` once confirmed — you must then call [Manual Capture Payment](./capture-payment) to collect the funds. For `AUTO_CAPTURE`, the payment moves directly to `COMPLETED`.
</Info>

### Authorization

Bearer `<accessSecret>`

**Request Body Schema**

<ParamField body="customerId" type="string" required>
  The customer UUID to charge. Must be a valid UUID.
</ParamField>

<ParamField body="paymentMethodId" type="string" required>
  The saved card ID from [List Payment Methods](/api-reference/PaymentMethods/list-payment-methods) response (`id` field). 1-64 characters.
</ParamField>

<ParamField body="captureType" type="string" required>
  How to capture the payment.

  <Accordion title="Possible values">
    * `AUTO_CAPTURE` — Capture immediately once confirmed. Final status: `COMPLETED`.
    * `MANUAL_CAPTURE` — Authorize only. Final status: `AUTHORIZED`. Call [Manual Capture Payment](./capture-payment) later to collect funds.
    * `CAPTURE_BEFORE_EXPIRY` — Authorize and auto-capture before expiry if not manually captured or cancelled. Final status: `AUTHORIZED` until captured.
  </Accordion>
</ParamField>

<ParamField body="amount" type="number" required>
  Payment amount in pounds. Example: `10.50` for ten pounds fifty pence. Minimum: £1.
</ParamField>

<ParamField body="orderId" type="string" required>
  Your merchant order reference for tracking. 1-50 characters, must not be blank.
</ParamField>

<ParamField body="notes" type="string">
  Short payment description or notes. Max 30 characters.
</ParamField>

<ParamField body="storeId" type="string">
  Store UUID. If not provided, the merchant's primary store is used. Refer [Get Stores API](../Payment/getstores).
</ParamField>

**Response**

<ResponseField name="paymentRequestId" type="string">
  Unique payment identifier (UUID). Use this for [Capture](./capture-payment), [Cancel](./cancel-payment), and status queries.
</ResponseField>

<ResponseField name="status" type="string">
  Always `PENDING` in the initial response. Indicates that payment processing has been initiated. The final status is updated asynchronously via [webhook](/api-reference/Webhook/processPaymentWebhookResponse).
</ResponseField>

<ResponseField name="amount" type="number">
  Payment amount in pounds.
</ResponseField>

<ResponseField name="currency" type="string">
  Currency code (e.g., `GBP`).
</ResponseField>

<ResponseField name="orderId" type="string">
  Your merchant order reference.
</ResponseField>

<ResponseField name="customerId" type="string">
  The charged customer's UUID.
</ResponseField>

<ResponseField name="paymentMethodId" type="string">
  The card used for payment.
</ResponseField>

<ResponseField name="captureType" type="string">
  The capture type used.
</ResponseField>

<ResponseField name="createdAt" type="string">
  ISO 8601 timestamp.
</ResponseField>

<ResponseField name="expiresAt" type="string">
  When the authorization expires (only for MANUAL\_CAPTURE / CAPTURE\_BEFORE\_EXPIRY).
</ResponseField>

<RequestExample>
  ```bash curl 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": "550e8400-e29b-41d4-a716-446655440000",
    "paymentMethodId": "card_abc123def456",
    "captureType": "AUTO_CAPTURE",
    "amount": 10.50,
    "orderId": "ORDER-001",
    "notes": "Payment for order #001"
  }'
  ```

  ```python Python theme={null}
  import requests

  url = "https://api.atoa.me/api/payments/card/process-payment"

  payload = {
      "customerId": "550e8400-e29b-41d4-a716-446655440000",
      "paymentMethodId": "card_abc123def456",
      "captureType": "AUTO_CAPTURE",
      "amount": 10.50,
      "orderId": "ORDER-001",
      "notes": "Payment for order #001"
  }
  headers = {
      "Authorization": "Bearer <token>",
      "Content-Type": "application/json"
  }

  response = requests.post(url, json=payload, headers=headers)
  print(response.json())
  ```

  ```javascript JavaScript theme={null}
  const response = await fetch(
    "https://api.atoa.me/api/payments/card/process-payment",
    {
      method: "POST",
      headers: {
        Authorization: "Bearer <token>",
        "Content-Type": "application/json",
      },
      body: JSON.stringify({
        customerId: "550e8400-e29b-41d4-a716-446655440000",
        paymentMethodId: "card_abc123def456",
        captureType: "AUTO_CAPTURE",
        amount: 10.50,
        orderId: "ORDER-001",
        notes: "Payment for order #001",
      }),
    }
  );

  const data = await response.json();
  console.log(data);
  ```

  ```php PHP theme={null}
  <?php

  $curl = curl_init();

  curl_setopt_array($curl, [
    CURLOPT_URL => "https://api.atoa.me/api/payments/card/process-payment",
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_CUSTOMREQUEST => "POST",
    CURLOPT_POSTFIELDS => json_encode([
      "customerId" => "550e8400-e29b-41d4-a716-446655440000",
      "paymentMethodId" => "card_abc123def456",
      "captureType" => "AUTO_CAPTURE",
      "amount" => 10.50,
      "orderId" => "ORDER-001",
      "notes" => "Payment for order #001"
    ]),
    CURLOPT_HTTPHEADER => [
      "Authorization: Bearer <token>",
      "Content-Type: application/json"
    ],
  ]);

  $response = curl_exec($curl);
  curl_close($curl);
  echo $response;
  ```

  ```go Go theme={null}
  package main

  import (
    "fmt"
    "strings"
    "net/http"
    "io/ioutil"
  )

  func main() {
    url := "https://api.atoa.me/api/payments/card/process-payment"
    payload := strings.NewReader(`{
      "customerId": "550e8400-e29b-41d4-a716-446655440000",
      "paymentMethodId": "card_abc123def456",
      "captureType": "AUTO_CAPTURE",
      "amount": 10.50,
      "orderId": "ORDER-001",
      "notes": "Payment for order #001"
    }`)

    req, _ := http.NewRequest("POST", url, payload)
    req.Header.Add("Authorization", "Bearer <token>")
    req.Header.Add("Content-Type", "application/json")

    res, _ := http.DefaultClient.Do(req)
    defer res.Body.Close()
    body, _ := ioutil.ReadAll(res.Body)
    fmt.Println(string(body))
  }
  ```

  ```java Java theme={null}
  HttpResponse<String> response = Unirest.post("https://api.atoa.me/api/payments/card/process-payment")
    .header("Authorization", "Bearer <token>")
    .header("Content-Type", "application/json")
    .body("{\"customerId\":\"550e8400-e29b-41d4-a716-446655440000\",\"paymentMethodId\":\"card_abc123def456\",\"captureType\":\"AUTO_CAPTURE\",\"amount\":10.50,\"orderId\":\"ORDER-001\",\"notes\":\"Payment for order #001\"}")
    .asString();
  ```
</RequestExample>

<ResponseExample>
  ```json 201 (AUTO_CAPTURE) theme={null}
  {
    "paymentRequestId": "9baa68d8-362a-4127-994d-2ea622ef35ee",
    "status": "PENDING",
    "amount": 10.50,
    "currency": "GBP",
    "orderId": "ORDER-001",
    "customerId": "550e8400-e29b-41d4-a716-446655440000",
    "paymentMethodId": "card_abc123def456",
    "captureType": "AUTO_CAPTURE",
    "createdAt": "2025-06-15T10:30:00.000Z"
  }
  ```

  ```json 201 (MANUAL_CAPTURE) theme={null}
  {
    "paymentRequestId": "9baa68d8-362a-4127-994d-2ea622ef35ee",
    "status": "PENDING",
    "amount": 10.50,
    "currency": "GBP",
    "orderId": "ORDER-001",
    "customerId": "550e8400-e29b-41d4-a716-446655440000",
    "paymentMethodId": "card_abc123def456",
    "captureType": "MANUAL_CAPTURE",
    "createdAt": "2025-06-15T10:30:00.000Z",
    "expiresAt": "2025-06-22T10:30:00.000Z"
  }
  ```

  ```json 400 theme={null}
  {
    "name": "BAD_REQUEST",
    "message": "Amount should not be less than £1.",
    "status": 400,
    "errors": []
  }
  ```

  ```json 404 theme={null}
  {
    "name": "NOT_FOUND",
    "message": "Customer or card not found",
    "status": 404,
    "errors": []
  }
  ```
</ResponseExample>
