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

# Process Payment: Create a Payment Request

> Create an Atoa payment request and get back a payment link, QR code and paymentRequestId to collect a Pay by Bank or card payment.

To initiate a new payment request that can be completed by the customer, you will need to obtain your API key from the Atoa Business App. This endpoint should be called on the server-side to prevent exposing your API key.

### Authorization

Bearer `<token>`

**Request Body Schema**

<ParamField body="customerId" type="string" required>
  Unique Customer Id.
</ParamField>

<ParamField body="orderId" type="string" required>
  An Identifier you can use for transaction reference and signature verification.
</ParamField>

<ParamField body="amount" type="number" required>
  The total cart amount for the payment.
</ParamField>

<ParamField body="storeId" type="string">
  If you want to create a payment under a particular store, else the transaction
  would be created in the default store. Refer [Get-Stores API](./getstores).
</ParamField>

<ParamField body="paymentMethod" type="string[]">
  Controls the set of payment methods shown to the consumer during checkout. If not specified, the checkout defaults to offering all payment methods enabled on the merchant account.

  <Accordion title="Possible enum values">
    * `PAY_BY_BANK` – When provided, only Pay by Bank will be shown to the customer.

    * `CARD` – When provided, only card payment will be shown to the customer. If card is not enabled in your account please contact support.

    * If both `PAY_BY_BANK` and `CARD` are passed, both options are displayed, allowing the customer to choose their preferred payment method during checkout.
  </Accordion>
</ParamField>

<ParamField body="savePaymentMethod" type="boolean" default="false">
  Save the customer's card during checkout for future payments. When enabled:

  * Card is saved after successful 3DS authentication
  * **Requires `atoaCustomerId`** (from [Create Customer](/api-reference/Customers/create-customer))
  * Only supported for card payments (`paymentMethod` must include `CARD`)
  * Cannot be used with `splitBill`
  * Card payments must be enabled on your account

  <Info>See [Card on File guide](/api-reference/CardOnFile/introduction) for the full integration flow.</Info>
</ParamField>

<ParamField body="atoaCustomerId" type="string">
  Customer ID from [Create Customer](/api-reference/Customers/create-customer). Links this payment to a customer.

  **Benefits:**

  * **Save Cards**: Required when `savePaymentMethod=true`
  * **Faster Checkout**: Returning customers see their saved cards automatically
  * **Tracking**: Links all payments to the customer for reporting
</ParamField>

<ParamField body="autoRedirect" type="boolean">
  Auto-redirection is disabled by default (false). Enabling it (true) automatically redirects users to Atoa's payment webpage for transaction completion.
</ParamField>

<ParamField body="consumerDetails" type="object">
  <Expandable>
    <ParamField body="phoneCountryCode" type="string" initialValue="44">
      Consumer phone country code
    </ParamField>

    <ParamField body="phoneNumber" type="string">
      Consumer phone number
    </ParamField>

    <ParamField body="email" type="string">
      Consumer email
    </ParamField>

    <ParamField body="firstName" type="string">
      Consumer first name
    </ParamField>

    <ParamField body="lastName" type="string">
      Consumer last name
    </ParamField>
  </Expandable>
</ParamField>

<a id="payment-expiration" />

<ParamField body="callbackParams" type="object">
  The completion of the payment process, the specified data is appended to the redirected URL. For example, if your redirected URL is `https://paywithatoa.co.uk/` and your callback data is `{couponCode:245561,refId:2342},` the final redirected URL would be `https://paywithatoa.co.uk/?couponCode=245561&refId=2342`.
</ParamField>

<ParamField body="expiresIn" type="number" default="180000">
  **Expressed in milliseconds:** This specifies the time after which an individual payment request will expire. If no expiresIn time is provided when creating a payment request, it will default to expire exactly 3 minutes later.

  <Info>Note:- All URLs received in the API response will never expire. It's the individual payment request that will expire if the user does not complete the payment within the specified time. Refer to the webhook guide for more details about the [expiry payload](../../introduction#payment-expiration-payload).</Info>
</ParamField>

<ParamField body="notes" type="string">
  Adds a custom note to the payment for tracking and reconciliation. The note is always visible in the Atoa dashboard and can be used for internal reference.
  <Info>Note:-  The note must be 30 characters or less.</Info>
</ParamField>

<ParamField body="metadata" type="object">
  Set of key-value pairs that you can attach to an object. This can be useful for storing additional information about the object in a structured format.

  * Up to **50** key-value pairs.
  * Each key must be **1–40** characters and must not contain `[` or `]`.
  * Each value must be a **string** of at most **500** characters.

  Once set, metadata is returned in the [Get Transactions](/api-reference/Payment/get-transactions), [Get Payout Transactions](/api-reference/Payouts/getPayoutTransactions), and [Get Payment Status](/api-reference/Payment/getPaymentStatus) responses, and is included in the [Payment Status Webhook](/api-reference/Webhook/processPaymentWebhookResponse).

  <Info>Metadata is frozen when the payment is created and cannot be changed afterwards. An empty object (`{}`) is treated as no metadata.</Info>
</ParamField>

<ParamField body="enableTips" type="boolean" default="true">
  Deciding whether to include tip collection on payments. The option to enter tips will only be displayed if tips are enabled in the Atoa Business app as well. In the event that tips are enabled in the app but 'enableTips' is passed as false, it will override and prevent the tips input from being shown to the user.
</ParamField>

<ParamField body="allowRetry" type="boolean" default="true">
  To enable consumers to retry their payment if the transaction fails or stalls, set this parameter to true. If not, set it to false. The default value is true.
</ParamField>

<ParamField body="redirectUrl" type="string">
  You have the option to include a redirect URL. Once the payment is successfully completed, the customer will be automatically redirected to the specified URL.
</ParamField>

<ParamField body="splitBill" type="boolean" default="false">
  By default, split bill is set to false. The 'splitBill' parameter empowers your customers with the ability to seamlessly divide the total bill among their friends during the payment process. This feature proves particularly valuable in scenarios like dining at restaurants, facilitating a hassle-free equal distribution of expenses within a group of friends.
</ParamField>

<ParamField body="template" type="enum">
  To elevate your customer's payment experience through ATOA QR codes on both the Till display and customer receipts, utilize the following parameter.

  Displaying QR Codes on Kiosk or Till:

  Generate an ATOA QR template image for external displays by including the 'template' parameter with values 'EXTERNAL\_DISPLAY' (SVG format) or 'EXTERNAL\_DISPLAY\_PNG' (PNG format). This feature enables customers to easily scan the QR code from the kiosk or till, ensuring a swift and seamless payment process.

  Printing QR Codes on Customer Receipts:

  Effortlessly integrate an ATOA QR image into your customer receipts by using the 'template' parameter with values 'RECEIPT' (SVG format) or 'RECEIPT\_PNG' (PNG format). Print this on the customer receipt from the terminal printer, allowing customers to scan the QR code and complete the payment process.
</ParamField>

<Note>
  If a redirection URL is initially set during access token creation but a
  different URL is provided in the process-payment API, the URL from the
  process-payment API will be prioritized.
</Note>

**Response**

<ResponseField name="qrCodeUrl" type="string">
  URL to retrieve the QR code for payment initiation. Suitable for scanning with
  any camera app.
</ResponseField>

<ResponseField name="qrCodeUrlPng" type="string">
  URL for the QR code in PNG format, offering a background-free image for
  versatile use.
</ResponseField>

<ResponseField name="templateUrl" type="string">
  URL to fetch display or receipt images based on the specified template. Ideal
  for QR displays on kiosks or printing on receipts.
</ResponseField>

<ResponseField name="paymentUrl" type="string">
  Direct link for payment, encoded in the QR code. It bridges the QR scan to the
  payment gateway.
</ResponseField>

<ResponseField name="paymentRequestId" type="string">
  A unique identifier for the payment request, crucial for tracking the payment
  from start to finish.
</ResponseField>

<RequestExample>
  ```bash cURL 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": "549000a4-eee4-4b7d-bc88-c529a92544cd",
    "orderId": "6eb7e0f8-972a-4bf6-99d2-864bdccd5a34",
    "amount": 123,
    "storeId": "43c7b991-0803-4177-9589-d165d9a779f6",
    "redirectUrl": "https://paywithatoa.co.uk"
  }'
  ```

  ```bash Save Card During Checkout (cURL) theme={null}
  # Requires atoaCustomerId from Create Customer API
  curl --request POST \
    --url https://api.atoa.me/api/payments/process-payment \
    --header 'Authorization: Bearer <token>' \
    --header 'Content-Type: application/json' \
    --data '{
    "customerId": "549000a4-eee4-4b7d-bc88-c529a92544cd",
    "orderId": "6eb7e0f8-972a-4bf6-99d2-864bdccd5a34",
    "amount": 123,
    "storeId": "43c7b991-0803-4177-9589-d165d9a779f6",
    "paymentMethod": ["CARD"],
    "atoaCustomerId": "a1b2c3d4-5678-90ab-cdef-1234567890ab",
    "savePaymentMethod": true,
    "redirectUrl": "https://paywithatoa.co.uk"
  }'
  ```

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

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

  payload = {
      "customerId": "549000a4-eee4-4b7d-bc88-c529a92544cd",
      "orderId": "6eb7e0f8-972a-4bf6-99d2-864bdccd5a34",
      "amount": 123,
      "storeId": "43c7b991-0803-4177-9589-d165d9a779f6",
      "redirectUrl": "https://paywithatoa.co.uk"
  }
  headers = {
      "Authorization": "Bearer <token>",
      "Content-Type": "application/json"
  }

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

  ```python Save Card During Checkout (Python) theme={null}
  # Requires atoaCustomerId from Create Customer API
  import requests

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

  payload = {
      "customerId": "549000a4-eee4-4b7d-bc88-c529a92544cd",
      "orderId": "6eb7e0f8-972a-4bf6-99d2-864bdccd5a34",
      "amount": 123,
      "storeId": "43c7b991-0803-4177-9589-d165d9a779f6",
      "paymentMethod": ["CARD"],
      "atoaCustomerId": "a1b2c3d4-5678-90ab-cdef-1234567890ab",
      "savePaymentMethod": True,
      "redirectUrl": "https://paywithatoa.co.uk"
  }
  headers = {
      "Authorization": "Bearer <token>",
      "Content-Type": "application/json"
  }

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

  ```javascript JavaScript theme={null}
  const options = {
    method: "POST",
    headers: {
      Authorization: "Bearer <token>",
      "Content-Type": "application/json",
    },
    body: JSON.stringify({
      customerId: "549000a4-eee4-4b7d-bc88-c529a92544cd",
      orderId: "6eb7e0f8-972a-4bf6-99d2-864bdccd5a34",
      amount: 123,
      storeId: "43c7b991-0803-4177-9589-d165d9a779f6",
      redirectUrl: "https://paywithatoa.co.uk"
    })
  };

  fetch("https://api.atoa.me/api/payments/process-payment", options)
    .then((response) => response.json())
    .then((response) => console.log(response))
    .catch((err) => console.error(err));
  ```

  ```javascript Save Card During Checkout (JavaScript) theme={null}
  // Requires atoaCustomerId from Create Customer API
  const options = {
    method: "POST",
    headers: {
      Authorization: "Bearer <token>",
      "Content-Type": "application/json",
    },
    body: JSON.stringify({
      customerId: "549000a4-eee4-4b7d-bc88-c529a92544cd",
      orderId: "6eb7e0f8-972a-4bf6-99d2-864bdccd5a34",
      amount: 123,
      storeId: "43c7b991-0803-4177-9589-d165d9a779f6",
      paymentMethod: ["CARD"],
      atoaCustomerId: "a1b2c3d4-5678-90ab-cdef-1234567890ab",
      savePaymentMethod: true,
      redirectUrl: "https://paywithatoa.co.uk"
    })
  };

  fetch("https://api.atoa.me/api/payments/process-payment", options)
    .then((response) => response.json())
    .then((response) => console.log(response))
    .catch((err) => console.error(err));
  ```

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

  $curl = curl_init();

  curl_setopt_array($curl, [
    CURLOPT_URL => "https://api.atoa.me/api/payments/process-payment",
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_ENCODING => "",
    CURLOPT_MAXREDIRS => 10,
    CURLOPT_TIMEOUT => 30,
    CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
    CURLOPT_CUSTOMREQUEST => "POST",
    CURLOPT_POSTFIELDS => json_encode([
      "customerId" => "549000a4-eee4-4b7d-bc88-c529a92544cd",
      "orderId" => "6eb7e0f8-972a-4bf6-99d2-864bdccd5a34",
      "amount" => 123,
      "storeId" => "43c7b991-0803-4177-9589-d165d9a779f6",
      "redirectUrl" => "https://paywithatoa.co.uk"
    ]),
    CURLOPT_HTTPHEADER => [
      "Authorization: Bearer <token>",
      "Content-Type: application/json"
    ],
  ]);

  $response = curl_exec($curl);
  $err = curl_error($curl);
  curl_close($curl);

  if ($err) {
    echo "cURL Error #:" . $err;
  } else {
    echo $response;
  }
  ```

  ```php Save Card During Checkout (PHP) theme={null}
  <?php
  // Requires atoaCustomerId from Create Customer API

  $curl = curl_init();

  curl_setopt_array($curl, [
    CURLOPT_URL => "https://api.atoa.me/api/payments/process-payment",
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_ENCODING => "",
    CURLOPT_MAXREDIRS => 10,
    CURLOPT_TIMEOUT => 30,
    CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
    CURLOPT_CUSTOMREQUEST => "POST",
    CURLOPT_POSTFIELDS => json_encode([
      "customerId" => "549000a4-eee4-4b7d-bc88-c529a92544cd",
      "orderId" => "6eb7e0f8-972a-4bf6-99d2-864bdccd5a34",
      "amount" => 123,
      "storeId" => "43c7b991-0803-4177-9589-d165d9a779f6",
      "paymentMethod" => ["CARD"],
      "atoaCustomerId" => "a1b2c3d4-5678-90ab-cdef-1234567890ab",
      "savePaymentMethod" => true,
      "redirectUrl" => "https://paywithatoa.co.uk"
    ]),
    CURLOPT_HTTPHEADER => [
      "Authorization: Bearer <token>",
      "Content-Type: application/json"
    ],
  ]);

  $response = curl_exec($curl);
  $err = curl_error($curl);
  curl_close($curl);

  if ($err) {
    echo "cURL Error #:" . $err;
  } else {
    echo $response;
  }
  ```

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

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

  func main() {
  	url := "https://api.atoa.me/api/payments/process-payment"

  	payload := strings.NewReader(`{
  		"customerId": "549000a4-eee4-4b7d-bc88-c529a92544cd",
  		"orderId": "6eb7e0f8-972a-4bf6-99d2-864bdccd5a34",
  		"amount": 123,
  		"storeId": "43c7b991-0803-4177-9589-d165d9a779f6",
  		"redirectUrl": "https://paywithatoa.co.uk"
  	}`)

  	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))
  }
  ```

  ```go Save Card During Checkout (Go) theme={null}
  // Requires atoaCustomerId from Create Customer API
  package main

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

  func main() {
  	url := "https://api.atoa.me/api/payments/process-payment"

  	payload := strings.NewReader(`{
  		"customerId": "549000a4-eee4-4b7d-bc88-c529a92544cd",
  		"orderId": "6eb7e0f8-972a-4bf6-99d2-864bdccd5a34",
  		"amount": 123,
  		"storeId": "43c7b991-0803-4177-9589-d165d9a779f6",
  		"paymentMethod": ["CARD"],
  		"atoaCustomerId": "a1b2c3d4-5678-90ab-cdef-1234567890ab",
  		"savePaymentMethod": true,
  		"redirectUrl": "https://paywithatoa.co.uk"
  	}`)

  	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/process-payment")
    .header("Authorization", "Bearer <token>")
    .header("Content-Type", "application/json")
    .body("{\n  \"customerId\": \"549000a4-eee4-4b7d-bc88-c529a92544cd\",\n  \"orderId\": \"6eb7e0f8-972a-4bf6-99d2-864bdccd5a34\",\n  \"amount\": 123,\n  \"storeId\": \"43c7b991-0803-4177-9589-d165d9a779f6\",\n  \"redirectUrl\": \"https://paywithatoa.co.uk\"\n}")
    .asString();
  ```

  ```java Save Card During Checkout (Java) theme={null}
  // Requires atoaCustomerId from Create Customer API
  HttpResponse<String> response = Unirest.post("https://api.atoa.me/api/payments/process-payment")
    .header("Authorization", "Bearer <token>")
    .header("Content-Type", "application/json")
    .body("{\n  \"customerId\": \"549000a4-eee4-4b7d-bc88-c529a92544cd\",\n  \"orderId\": \"6eb7e0f8-972a-4bf6-99d2-864bdccd5a34\",\n  \"amount\": 123,\n  \"storeId\": \"43c7b991-0803-4177-9589-d165d9a779f6\",\n  \"paymentMethod\": [\"CARD\"],\n  \"atoaCustomerId\": \"a1b2c3d4-5678-90ab-cdef-1234567890ab\",\n  \"savePaymentMethod\": true,\n  \"redirectUrl\": \"https://paywithatoa.co.uk\"\n}")
    .asString();
  ```
</RequestExample>

<ResponseExample>
  ```json 200 theme={null}
  {
    "qrCodeUrl": "https://atoa-merchant-dev.s3.eu-west-2.amazonaws.com/payment-qr-codes/eed6202f-4dfd-42fc-9bc6-48323556b59d/1692703721570.svg?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=AKIASV2VH7U5MIC62E5K%2F20230822%2Feu-west-2%2Fs3%2Faws4_request&X-Amz-Date=20230822T112842Z&X-Amz-Expires=3600&X-Amz-Signature=a17f22e0291ba9f3706fd686b41a8eda0aa5335e1f5bcac90aa05aa2425a4a7f&X-Amz-SignedHeaders=host",
    "qrCodeUrlPng": "https://atoa-merchant-dev.s3.eu-west-2.amazonaws.com/payment-qr-codes/eed6202f-4dfd-42fc-9bc6-48323556b59d/1692703721570.png?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=AKIASV2VH7U5MIC62E5K%2F20230822%2Feu-west-2%2Fs3%2Faws4_request&X-Amz-Date=20230822T112842Z&X-Amz-Expires=3600&X-Amz-Signature=a17f22e0291ba9f3706fd686b41a8eda0aa5335e1f5bcac90aa05aa2425a4a7f&X-Amz-SignedHeaders=host",
    "templateUrl": "https://atoa-merchant-dev.s3.eu-west-2.amazonaws.com/payment-qr-codes/eed6202f-4dfd-42fc-9bc6-48323556b59d/1692703721570.svg?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=AKIASV2VH7U5MIC62E5K%2F20230822%2Feu-west-2%2Fs3%2Faws4_request&X-Amz-Date=20230822T112842Z&X-Amz-Expires=3600&X-Amz-Signature=a17f22e0291ba9f3706fd686b41a8eda0aa5335e1f5bcac90aa05aa2425a4a7f&X-Amz-SignedHeaders=host",
    "paymentUrl": "https://atoa.me/pay/?paymentRequestId=9baa68d8-362a-4127-994d-2ea622ef35ee&callbackParams=e30=&source=EXTERNAL_MERCHANT",
    "paymentRequestId": "9baa68d8-362a-4127-994d-2ea622ef35ee"
  }
  ```

  ```json 400 - Missing Required Field theme={null}
  {
    "name": "BAD_REQUEST",
    "message": "customerId should not be undefined",
    "status": 400,
    "errors": "[]"
  }
  ```

  ```json 400 - savePaymentMethod Without atoaCustomerId theme={null}
  {
    "name": "BAD_REQUEST",
    "message": "Saving payment method requires atoaCustomerId.",
    "status": 400,
    "errors": "[]"
  }
  ```

  ```json 400 - savePaymentMethod for Pay by Bank Only theme={null}
  {
    "name": "BAD_REQUEST",
    "message": "Saving payment method is only supported for card payments",
    "status": 400,
    "errors": "[]"
  }
  ```

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

  ```json 401 theme={null}
  {
    "name": "UNAUTHORIZED",
    "message": "Unauthorized"
    "status": 400,
    "errors": "[]"
  }
  ```

  ```json 500 theme={null}
  {
    "name": "INTERNAL_SERVER_ERROR",
    "message": "Cannot read property 'phoneCountryCode' of undefined",
    "status": 500,
    "errors": "[]"
  }
  ```
</ResponseExample>
