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

# Manual Cancel Payment

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

Cancel a previously authorized card payment. This releases the hold on the customer's card.

Only applicable for `MANUAL_CAPTURE` and `CAPTURE_BEFORE_EXPIRY` payments that have **not yet been captured**. Cannot cancel `AUTO_CAPTURE` or already captured payments.

### Authorization

Bearer `<accessSecret>`

**Path Parameters**

<ParamField path="paymentRequestId" type="string" required>
  The payment request ID from the [Charge Saved Card](./charge-saved-card) response.
</ParamField>

**Request Body Schema**

<ParamField body="cancelledReasonCode" type="string">
  Reason for cancellation.

  <Accordion title="Possible values">
    * `Duplicate` — Duplicate payment
    * `Abandoned` — Payment was abandoned
    * `Requested by customer` — Customer requested cancellation
    * `Other` — Other reason (requires `cancelledReasonDescription`)
  </Accordion>
</ParamField>

<ParamField body="cancelledReasonDescription" type="string">
  Additional cancellation notes. Max 60 characters. **Required** when `cancelledReasonCode` is `Other`.
</ParamField>

**Response**

<ResponseField name="success" type="boolean">
  `true` if the payment was cancelled successfully.
</ResponseField>

<ResponseField name="message" type="string">
  Confirmation message.
</ResponseField>

<RequestExample>
  ```bash curl theme={null}
  curl --request POST \
    --url https://api.atoa.me/api/payments/card/payment-request/{paymentRequestId}/cancel \
    --header 'Authorization: Bearer <token>' \
    --header 'Content-Type: application/json' \
    --data '{
    "cancelledReasonCode": "Requested by customer",
    "cancelledReasonDescription": "Customer no longer needs the item"
  }'
  ```

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

  url = "https://api.atoa.me/api/payments/card/payment-request/{paymentRequestId}/cancel"
  payload = {
      "cancelledReasonCode": "Requested by customer",
      "cancelledReasonDescription": "Customer no longer needs the item"
  }
  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/payment-request/{paymentRequestId}/cancel",
    {
      method: "POST",
      headers: {
        Authorization: "Bearer <token>",
        "Content-Type": "application/json",
      },
      body: JSON.stringify({
        cancelledReasonCode: "Requested by customer",
        cancelledReasonDescription: "Customer no longer needs the item",
      }),
    }
  );

  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/payment-request/{paymentRequestId}/cancel",
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_CUSTOMREQUEST => "POST",
    CURLOPT_POSTFIELDS => json_encode([
      "cancelledReasonCode" => "Requested by customer",
      "cancelledReasonDescription" => "Customer no longer needs the item"
    ]),
    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/payment-request/{paymentRequestId}/cancel"
    payload := strings.NewReader(`{
      "cancelledReasonCode": "Requested by customer",
      "cancelledReasonDescription": "Customer no longer needs the item"
    }`)

    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/payment-request/{paymentRequestId}/cancel")
    .header("Authorization", "Bearer <token>")
    .header("Content-Type", "application/json")
    .body("{\"cancelledReasonCode\":\"Requested by customer\",\"cancelledReasonDescription\":\"Customer no longer needs the item\"}")
    .asString();
  ```
</RequestExample>

<ResponseExample>
  ```json 200 theme={null}
  {
    "success": true,
    "message": "Payment cancelled successfully"
  }
  ```

  ```json 400 theme={null}
  {
    "name": "BAD_REQUEST",
    "message": "Cannot cancel an AUTO_CAPTURE or already captured payment",
    "status": 400,
    "errors": []
  }
  ```

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