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

# POS Payment Status Webhook Payload

> Reference for the Atoa 'pos Payment Status Webhook Response' webhook payload, the fields Atoa sends and an example JSON body to handle.

Delivers notifications for all POS terminal (Pax machine) activity:

* **Payments** — Pay by Bank and card payments at the terminal.
* **Refunds (voids)** — refunds from the POS terminal. Not delivered under `REFUND_STATUS`.

API or Dashboard refunds are delivered under `REFUND_STATUS`, not here.

## Payment statuses

| Status        | Description                                                                                 |
| ------------- | ------------------------------------------------------------------------------------------- |
| **COMPLETED** | Payment processed successfully. Funds have been transferred to the merchant's account.      |
| **FAILED**    | Payment was unsuccessful, including reversed transactions. The customer will need to retry. |
| **EXPIRED**   | Payment request expired before the customer completed the payment.                          |

## Refund statuses

| Status        | Description                                                                        |
| ------------- | ---------------------------------------------------------------------------------- |
| **COMPLETED** | Refund processed successfully. Funds have been credited to the customer's account. |
| **FAILED**    | Refund could not be processed. The refund may need to be retried.                  |

<Note>
  Distinguish payment from refund deliveries by checking for `refundId`. Refund payloads use `refundId` and `refundAmount` instead of payment fields like `tipAmount` and `storeDetails`.
</Note>

<Info>
  **V2 signing required:** Subscribing to `POS_PAYMENT_STATUS` requires a [V2 signing secret](/api-reference/Webhook/v2-signing). All POS webhooks are delivered with V2 signing — the `X-Atoa-Signature` header contains the HMAC-SHA256 signature and the body includes an `eventType` field.
</Info>

***

## Payloads

<ResponseExample>
  ```json Payment - Completed theme={null}
  {
    "merchantId": "41a77f74-8b67-4f04-be50-c8dd5ad8836f",
    "customerId": "Abcam",
    "consumerId": "60513141-4d0f-4d3d-9c8a-cc1bd61f40fd",
    "merchantName": "My Shop",
    "paymentIdempotencyId": "ATOA1695808662681",
    "status": "COMPLETED",
    "statusDetails": null,
    "paidAmount": 25.50,
    "tipAmount": 0,
    "currency": "GBP",
    "createdAt": "2026-03-20T14:30:00.000Z",
    "updatedAt": "2026-03-20T14:31:00.000Z",
    "taxAmount": 0,
    "serviceAmount": 0,
    "transactionType": "CARD",
    "storeDetails": {
      "id": "d77e02d5-4e93-46cf-a8be-50da650df562",
      "address": "London",
      "locationName": "London Store"
    },
    "orderId": "POS-ORDER-001",
    "paymentRequestId": "9baa68d8-362a-4127-994d-2ea622ef35ee",
    "errorDescription": null,
    "redirectUrlParams": "{}",
    "splitBill": false,
    "notes": "POS terminal payment",
    "metadata": {
      "bookingId": "BK-42427",
      "orderReference": "ORD-1"
    },
    "customFields": [
      {
        "fieldName": "Invoice Number",
        "value": "INV-2026-0042",
        "filledBy": "BUSINESS"
      }
    ],
    "eventType": "POS_PAYMENT_STATUS"
  }
  ```

  ```json Payment - Failed theme={null}
  {
    "merchantId": "41a77f74-8b67-4f04-be50-c8dd5ad8836f",
    "customerId": "Abcam",
    "consumerId": "60513141-4d0f-4d3d-9c8a-cc1bd61f40fd",
    "merchantName": "My Shop",
    "paymentIdempotencyId": "ATOA1695808662681",
    "status": "FAILED",
    "statusDetails": null,
    "paidAmount": 25.50,
    "tipAmount": 0,
    "currency": "GBP",
    "createdAt": "2026-03-20T14:30:00.000Z",
    "updatedAt": "2026-03-20T14:30:05.000Z",
    "taxAmount": 0,
    "serviceAmount": 0,
    "transactionType": "CARD",
    "storeDetails": {
      "id": "d77e02d5-4e93-46cf-a8be-50da650df562",
      "address": "London",
      "locationName": "London Store"
    },
    "orderId": "POS-ORDER-002",
    "paymentRequestId": "9baa68d8-362a-4127-994d-2ea622ef35ee",
    "errorDescription": "Card processing error. Please try a different card.",
    "redirectUrlParams": "{}",
    "splitBill": false,
    "notes": "POS terminal payment",
    "metadata": {
      "bookingId": "BK-42427",
      "orderReference": "ORD-1"
    },
    "customFields": [
      {
        "fieldName": "Invoice Number",
        "value": "INV-2026-0042",
        "filledBy": "BUSINESS"
      }
    ],
    "eventType": "POS_PAYMENT_STATUS"
  }
  ```

  ```json Payment - Expired theme={null}
  {
    "merchantId": "41a77f74-8b67-4f04-be50-c8dd5ad8836f",
    "customerId": "Abcam",
    "status": "EXPIRED",
    "paidAmount": 25.50,
    "currency": "GBP",
    "storeDetails": {
      "id": "d77e02d5-4e93-46cf-a8be-50da650df562",
      "address": "London",
      "locationName": "London Store"
    },
    "orderId": "POS-ORDER-003",
    "paymentRequestId": "9baa68d8-362a-4127-994d-2ea622ef35ee",
    "redirectUrl": "https://paywithatoa.co.uk",
    "redirectUrlParams": {},
    "metadata": {
      "bookingId": "BK-42427",
      "orderReference": "ORD-1"
    },
    "customFields": [
      {
        "fieldName": "Invoice Number",
        "value": "INV-2026-0042",
        "filledBy": "BUSINESS"
      }
    ],
    "eventType": "POS_PAYMENT_STATUS"
  }
  ```

  ```json Refund - Completed theme={null}
  {
    "refundId": "c4e92a73-5f12-47c9-8b31-6e54f2d8a91c",
    "paymentRequestId": "8f2471db-3456-9cd8-eff2-1a3b5c7d9e0f",
    "paymentIdempotencyId": "ATOA1893245678912",
    "status": "COMPLETED",
    "paidAmount": 25.50,
    "refundAmount": 10.00,
    "currency": "GBP",
    "refundNotes": "Customer requested partial refund",
    "orderId": "POS-ORDER-001",
    "createdAt": "2026-03-20T15:00:00.000Z",
    "updatedAt": "2026-03-20T15:01:30.000Z",
    "metadata": {
      "refundReason": "damaged-item",
      "ticketId": "SUP-9981"
    },
    "customFields": [
      {
        "fieldName": "Invoice Number",
        "value": "INV-2026-0042",
        "filledBy": "BUSINESS"
      }
    ],
    "eventType": "POS_PAYMENT_STATUS"
  }
  ```

  ```json Refund - Failed theme={null}
  {
    "refundId": "c4e92a73-5f12-47c9-8b31-6e54f2d8a91c",
    "paymentRequestId": "8f2471db-3456-9cd8-eff2-1a3b5c7d9e0f",
    "paymentIdempotencyId": "ATOA1893245678912",
    "status": "FAILED",
    "paidAmount": 25.50,
    "refundAmount": 10.00,
    "currency": "GBP",
    "refundNotes": "Customer requested partial refund",
    "orderId": "POS-ORDER-001",
    "createdAt": "2026-03-20T15:00:00.000Z",
    "updatedAt": "2026-03-20T15:01:30.000Z",
    "errorMessage": "The customer's bank rejected the refund. Please try again.",
    "metadata": {
      "refundReason": "damaged-item",
      "ticketId": "SUP-9981"
    },
    "customFields": [
      {
        "fieldName": "Invoice Number",
        "value": "INV-2026-0042",
        "filledBy": "BUSINESS"
      }
    ],
    "eventType": "POS_PAYMENT_STATUS"
  }
  ```
</ResponseExample>

***

<a id="pos-card-refund" />

## Custom fields

Custom fields collected during the terminal payment appear as a `customFields` array. For refunds, custom fields from the original payment are carried over.

| Field       | Type   | Description                                          |
| ----------- | ------ | ---------------------------------------------------- |
| `fieldName` | string | The name of the custom field (e.g. "Invoice Number") |
| `value`     | string | The value entered for the field                      |
| `filledBy`  | string | Who provided the value — `BUSINESS` or `PAYEE`       |

<Note>
  Only present when custom fields were entered at the terminal. Not included in `PAYMENTS_STATUS` or `EXPIRED_STATUS` webhooks.
</Note>

***

## Metadata

Merchant-supplied metadata set when creating the payment appears as a `metadata` object — a flat map of string keys to string values. Unlike custom fields (entered at the terminal), metadata is supplied programmatically and is frozen at payment creation.

<Note>
  Only present when metadata was supplied on the payment. See [Process Payment](/api-reference/Payment/process-payment) for the field limits.
</Note>

***

## Signature verification

All `POS_PAYMENT_STATUS` webhooks use V2 signing. To verify the signature, use the `X-Atoa-Signature` header as described in the [V2 Webhook Signing guide](/api-reference/Webhook/v2-signing).
