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

# Authorize Card

Save a customer's card for future charges **without taking a payment**. Atoa returns a secure hosted page link — the customer enters their card details and completes 3DS verification, and the card is stored against their customer profile, ready to charge later.

<Note>
  No amount is involved and no money moves. The customer sees a 3DS verification, not a payment. Money moves only when you call [Charge Saved Card](./charge-saved-card).
</Note>

<Info>
  Card details are captured exclusively on Atoa's PCI-compliant hosted page — they never touch your systems. Each call generates a fresh single-purpose link; request a new one rather than reusing old links.
</Info>

### Authorization

Bearer `<accessSecret>`

**Path Parameters**

<ParamField path="customerId" type="string" required>
  The Atoa customer UUID returned by the [Create Customer API](/api-reference/Customers/create-customer). This is **not** your own merchant reference for the customer.
</ParamField>

**Request Body Schema**

All fields are optional — an empty body `{}` is valid.

<ParamField body="sendLinkToCustomer" type="boolean" default="false">
  When `true`, Atoa delivers the link to the customer by email; if the customer has no email, by SMS. The link is also returned in the response either way. Fails with `400` if the customer has neither an email address nor a phone number.
</ParamField>

<ParamField body="successRedirectUrl" type="string">
  Where the hosted page redirects the customer after the card is saved successfully.
</ParamField>

<ParamField body="failureRedirectUrl" type="string">
  Where the hosted page redirects the customer if saving the card fails.
</ParamField>

**Response**

<ResponseField name="hostedPageUrl" type="string">
  Secure hosted page URL. Open it in a browser, embed it in a WebView, or share it with the customer. Once they complete card entry and 3DS, the card is saved — there is no separate confirmation call to make.
</ResponseField>

After the customer completes the hosted page flow, retrieve the saved card with [List Payment Methods](/api-reference/PaymentMethods/list-payment-methods) and use its `id` as `paymentMethodId` when charging.

<RequestExample>
  ```bash curl 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"
  }'
  ```

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

  url = "https://api.atoa.me/api/customers/{customerId}/cards/authorize"

  payload = {
      "sendLinkToCustomer": False,
      "successRedirectUrl": "https://yoursite.com/cards/success",
      "failureRedirectUrl": "https://yoursite.com/cards/failure"
  }
  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/customers/{customerId}/cards/authorize",
    {
      method: "POST",
      headers: {
        Authorization: "Bearer <token>",
        "Content-Type": "application/json",
      },
      body: JSON.stringify({
        sendLinkToCustomer: false,
        successRedirectUrl: "https://yoursite.com/cards/success",
        failureRedirectUrl: "https://yoursite.com/cards/failure",
      }),
    }
  );

  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/customers/{customerId}/cards/authorize",
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_CUSTOMREQUEST => "POST",
    CURLOPT_POSTFIELDS => json_encode([
      "sendLinkToCustomer" => false,
      "successRedirectUrl" => "https://yoursite.com/cards/success",
      "failureRedirectUrl" => "https://yoursite.com/cards/failure"
    ]),
    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/customers/{customerId}/cards/authorize"
    payload := strings.NewReader(`{
      "sendLinkToCustomer": false,
      "successRedirectUrl": "https://yoursite.com/cards/success",
      "failureRedirectUrl": "https://yoursite.com/cards/failure"
    }`)

    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/customers/{customerId}/cards/authorize")
    .header("Authorization", "Bearer <token>")
    .header("Content-Type", "application/json")
    .body("{\"sendLinkToCustomer\":false,\"successRedirectUrl\":\"https://yoursite.com/cards/success\",\"failureRedirectUrl\":\"https://yoursite.com/cards/failure\"}")
    .asString();
  ```
</RequestExample>

<ResponseExample>
  ```json 200 theme={null}
  {
    "hostedPageUrl": "https://atoa.me/add-card?..."
  }
  ```

  ```json 400 theme={null}
  {
    "name": "BAD_REQUEST",
    "message": "customerId must be a valid UUID.",
    "status": 400,
    "errors": []
  }
  ```

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