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

# Trigger test webhook event

> Send a test webhook event via the Atoa Webhooks API, request parameters, response schema and code samples in cURL, Python, JavaScript, PHP, Go and Java.

Sends a test webhook to your sandbox URL. Body and signature match a production event — verify your endpoint without creating a real payment.

<Note>
  **Sandbox-only** — production keys are rejected. Delivers to all sandbox endpoints subscribed to the specified `eventType`.
</Note>

### Authorization

Bearer `<sandbox-token>`

**Request Body Schema**

<ParamField body="eventType" type="string" required>
  The webhook event to simulate.

  <Accordion title="Possible values">
    * `PAYMENTS_STATUS` — payment-status webhook (pay-by-bank or card)
    * `EXPIRED_STATUS` — payment expired (customer didn't pay in time)
    * `REFUND_STATUS` — refund-status webhook
    * `POS_PAYMENT_STATUS` — POS event — choose which event to simulate via `type`
  </Accordion>
</ParamField>

<ParamField body="orderId" type="string">
  Override the `orderId`. Defaults to a generated test value.
</ParamField>

<ParamField body="amount" type="number">
  Override the `paidAmount` in pounds (e.g. `10.05` for £10.05). Defaults to a test value.
</ParamField>

<ParamField body="paymentMethod" type="string">
  Override the `paymentMethod`.

  <Accordion title="Possible values">
    * `CARD`
    * `PAY_BY_BANK`
  </Accordion>
</ParamField>

<ParamField body="status" type="string">
  Override the `status`. Valid values depend on `eventType`:

  <Accordion title="Allowed values per event">
    * `PAYMENTS_STATUS` → `COMPLETED` | `AUTHORIZED` (CARD only) | `FAILED`
    * `REFUND_STATUS` → `COMPLETED` | `CANCELLED` | `FAILED`
    * `EXPIRED_STATUS` → ignored (always emits `EXPIRED`)
    * `POS_PAYMENT_STATUS` → depends on `type` (see below)
  </Accordion>
</ParamField>

<ParamField body="type" type="string">
  **`POS_PAYMENT_STATUS` only** — selects which POS event to simulate.

  <Accordion title="Possible values">
    * `PAYMENTS_STATUS` — a completed POS payment (default)
    * `REFUND_STATUS` — a POS refund
    * `EXPIRED_STATUS` — an expired POS payment
  </Accordion>

  Rejected for non-POS events.
</ParamField>

<ParamField body="customFields" type="array">
  **`POS_PAYMENT_STATUS` only** — custom field entries for the payload. Defaults to a test fixture. Rejected for non-POS events.

  <Expandable>
    <ParamField body="value" type="string">
      The custom field value (e.g. a customer ID).
    </ParamField>

    <ParamField body="fieldName" type="string">
      The label for the field (e.g. "Customer ID").
    </ParamField>
  </Expandable>
</ParamField>

**Response**

<ResponseField name="message" type="string">
  Confirmation that the test webhook was dispatched. Payload arrives at your registered URL asynchronously.
</ResponseField>

<RequestExample>
  ```bash cURL theme={null}
  curl --request POST \
    --url https://api.atoa.me/api/webhook/test \
    --header 'Authorization: Bearer <sandbox-token>' \
    --header 'Content-Type: application/json' \
    --data '{
    "eventType": "PAYMENTS_STATUS"
  }'
  ```

  ```bash cURL (override fields) theme={null}
  curl --request POST \
    --url https://api.atoa.me/api/webhook/test \
    --header 'Authorization: Bearer <sandbox-token>' \
    --header 'Content-Type: application/json' \
    --data '{
    "eventType": "PAYMENTS_STATUS",
    "orderId": "test-order-001",
    "amount": 10.05,
    "paymentMethod": "CARD",
    "status": "AUTHORIZED"
  }'
  ```

  ```bash cURL (POS event) theme={null}
  curl --request POST \
    --url https://api.atoa.me/api/webhook/test \
    --header 'Authorization: Bearer <sandbox-token>' \
    --header 'Content-Type: application/json' \
    --data '{
    "eventType": "POS_PAYMENT_STATUS",
    "type": "PAYMENTS_STATUS",
    "status": "COMPLETED",
    "customFields": [{ "value": "CUST_001", "fieldName": "Customer ID" }]
  }'
  ```

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

  url = "https://api.atoa.me/api/webhook/test"
  payload = {
      "eventType": "PAYMENTS_STATUS",
      "orderId": "test-order-001",
      "amount": 10.05,
      "paymentMethod": "CARD",
      "status": "AUTHORIZED"
  }
  headers = {
      "Authorization": "Bearer <sandbox-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/webhook/test", {
    method: "POST",
    headers: {
      Authorization: "Bearer <sandbox-token>",
      "Content-Type": "application/json",
    },
    body: JSON.stringify({
      eventType: "PAYMENTS_STATUS",
      orderId: "test-order-001",
      amount: 10.05,
      paymentMethod: "CARD",
      status: "AUTHORIZED",
    }),
  });

  const data = await response.json();
  console.log(data);
  ```
</RequestExample>

<ResponseExample>
  ```json 200 theme={null}
  {
    "message": "Test webhook triggered successfully."
  }
  ```

  ```json 400 (production token) theme={null}
  {
    "name": "BAD_REQUEST",
    "message": "Webhook test triggers are only supported for sandbox tokens.",
    "status": 400
  }
  ```

  ```json 400 (invalid status for event) theme={null}
  {
    "name": "BAD_REQUEST",
    "message": "status=\"AUTHORIZED\" is not valid for REFUND_STATUS. Valid: COMPLETED, CANCELLED, FAILED.",
    "status": 400,
    "errors": []
  }
  ```

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

  ```json 404 (no subscription found) theme={null}
  {
    "name": "NOT_FOUND",
    "message": "No webhook subscription is configured for this merchant and event.",
    "status": 404
  }
  ```
</ResponseExample>
