> ## Documentation Index
> Fetch the complete documentation index at: https://primer.io/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Cancel payments

export const ApiEndpoint = ({method, path}) => {
  const getMethodColor = method => {
    switch (method?.toUpperCase()) {
      case "GET":
        return "#0285c7";
      case "POST":
        return "#008d71";
      case "PUT":
        return "#16a34a";
      case "PATCH":
        return "#808080";
      case "DELETE":
        return "#dc2626";
      default:
        return "#6b7280";
    }
  };
  const getEndpointUrl = (method, path) => {
    const endpoints = {
      "POST /client-session": "/api-reference/v2.4/api-reference/client-session-api/create-a-client-session",
      "PATCH /client-session": "/api-reference/v2.4/api-reference/client-session-api/update-client-session",
      "POST /payments": "/api-reference/v2.4/api-reference/payments-api/create-a-payment",
      "POST /payments/<YOUR-PAYMENT-ID>/resume": "/api-reference/v2.4/api-reference/payments-api/resume-payment",
      "POST /payments/<YOUR-PAYMENT-ID>/adjust-authorization": "/api-reference/v2.4/api-reference/payments-api/adjust-authorized-amount",
      "POST /payments/<PAYMENT_ID>/cancel": "/api-reference/v2.4/api-reference/payments-api/cancel-payment",
      "POST /payments/<PAYMENT_ID>/refund": "/api-reference/v2.4/api-reference/payments-api/refund-payment",
      "GET /payments/<PAYMENT_ID>": "/api-reference/v2.4/api-reference/payments-api/get-a-payment",
      "GET /payment-instruments": "/api-reference/v2.4/api-reference/payment-methods-api/list-saved-payment-methods",
      "DELETE /payment-instruments/<PAYMENT_METHOD_TOKEN>": "/api-reference/v2.4/api-reference/payment-methods-api/delete-payment-method-payment-methods-token-delete"
    };
    const key = `${method?.toUpperCase()} ${path}`;
    return endpoints[key] || "#";
  };
  const getPrettyPath = (method, path) => {
    const pathMapping = {
      "POST /payments/<YOUR-PAYMENT-ID>/resume": "/payments/{paymentId}/resume",
      "POST /payments/<YOUR-PAYMENT-ID>/adjust-authorization": "/payments/{paymentId}/adjust-authorization",
      "POST /payments/<PAYMENT_ID>/cancel": "/payments/{paymentId}/cancel",
      "POST /payments/<PAYMENT_ID>/refund": "/payments/{paymentId}/refund",
      "GET /payments/<PAYMENT_ID>": "/payments/{paymentId}",
      "DELETE /payment-instruments/<PAYMENT_METHOD_TOKEN>": "/payment-instruments/{paymentMethodToken}"
    };
    const key = `${method?.toUpperCase()} ${path}`;
    return pathMapping[key] || path;
  };
  const methodColor = getMethodColor(method);
  const url = getEndpointUrl(method, path);
  const displayPath = getPrettyPath(method, path);
  return <div style={{
    display: "inline-flex",
    alignItems: "center",
    cursor: "pointer",
    margin: "2px 0",
    padding: "4px",
    paddingRight: "6px",
    background: "rgb(245, 245, 245)",
    borderRadius: "6px",
    whiteSpace: "nowrap",
    textDecoration: "none"
  }}>
      <a href={url} target="_blank" rel="noopener noreferrer" style={{
    textDecoration: "none",
    border: "none"
  }}>
        <span style={{
    display: "inline-block",
    whiteSpace: "nowrap",
    padding: "0 8px",
    fontSize: "13px",
    lineHeight: "23px",
    borderRadius: "6px",
    fontWeight: 400,
    backgroundColor: methodColor,
    color: "white",
    border: "none"
  }}>
          {method.toUpperCase()}
        </span>
        <code style={{
    padding: "0",
    marginLeft: "4px",
    fontFamily: "monospace",
    color: methodColor,
    border: "none",
    textDecorationColor: methodColor
  }}>
          {displayPath}
        </code>
      </a>
    </div>;
};

export const TxnTag = ({status}) => {
  const getStyles = status => {
    const baseStyle = {
      display: 'inline-block',
      padding: '4px 8px',
      borderRadius: '4px',
      fontSize: '13px',
      fontWeight: '400'
    };
    switch (status) {
      case "PENDING":
        return {
          ...baseStyle,
          backgroundColor: '#ececec',
          color: '#9f9f9f'
        };
      case "AUTHORIZED":
        return {
          ...baseStyle,
          backgroundColor: '#ecfdf5',
          color: '#047857'
        };
      case "SETTLED":
      case "PARTIALLY_SETTLED":
        return {
          ...baseStyle,
          backgroundColor: '#ecfdf5',
          color: '#047857'
        };
      case "DECLINED":
      case "FAILED":
        return {
          ...baseStyle,
          backgroundColor: '#fef2f2',
          color: '#dc2626'
        };
      case "CANCELLED":
        return {
          ...baseStyle,
          backgroundColor: '#fefce8',
          color: '#d78203'
        };
      case "SETTLING":
        return {
          ...baseStyle,
          backgroundColor: '#e0f2fe',
          color: '#0c4a6e'
        };
      default:
        return {
          ...baseStyle,
          backgroundColor: '#f3f4f6',
          color: '#374151'
        };
    }
  };
  return <span style={getStyles(status)}>{status}</span>;
};

## How to cancel a payment

Primer enables you to cancel a payment across all your processors in a unified way. By cancelling a payment, the authorization is voided and the hold on customer funds is released.

In order to cancel a payment, the payment must not have reached <TxnTag status="SETTLED" /> status. Once the payment is cancelled, the payment can no longer be captured.

All cancel requests are sent to the processor used in the authorization request.

To check the status of the payment, you can use:

* the [payments timeline](https://dashboard.primer.io/payments) in the Primer Dashboard
* payment webhooks to [receive status updates](/api-reference/endpoints/v2.4/payment-webhooks/payment-status-update)
* the <ApiEndpoint method="GET" path="/payments/<PAYMENT_ID>" /> API call

Cancel a payment with Primer in three ways:

<CardGroup cols={3}>
  <Card title="Payments timeline" icon="hourglass" href="#cancel-a-payment-via-the-payments-timeline">
    Manually cancel a payment from an easy-to-use dashboard.
  </Card>

  <Card title="Workflows" icon="desktop" href="#cancel-a-payment-via-workflows">
    Automate sophisticated payment flows to cancel your payments.
  </Card>

  <Card title="Payments API" icon="user" href="#cancel-a-payment-via-payments-api">
    Programmatically cancel your payments via API based on your business logic.
  </Card>
</CardGroup>

### Cancel a payment via the Payments Timeline

<Note>
  This is useful to enable your team to cancel payments directly from within the dashboard.
</Note>

Manually cancel a specific payment from the Payments Timeline in the Primer Dashboard.

Select the payment from the list view and navigate to the specific payment details page. If the payment has <TxnTag status="AUTHORIZED" /> or <TxnTag status="PENDING" /> status, the **Cancel** button in the top right corner will be enabled.

<Frame caption="Cancel button enabled">![Cancel button enabled](https://goat-assets.production.core.primer.io/marketing/payment-operations/external-docs/cancel/can-cancel.png)</Frame>

Once you select the **Cancel** button, the cancel request will be sent to the processor. After it's been processed, the payment will be cancelled and the payment details page will reflect this.

<Frame caption="Cancelled payment details">
  ![Cancelled payment details](https://goat-assets.production.core.primer.io/marketing/payment-operations/external-docs/cancel/canceled-payment.png)
</Frame>

### Cancel a payment via Workflows

Use Workflows to set up business logic on when and how to cancel a payment - without writing a single line of code. Simply add the ["Cancel payment" action](/workflows/apps/native-apps/primer-payments-app/cancel-payment-action) from the Primer Payments app to a workflow.

You can configure any additional business flows in between your ["Authorize payment"](/workflows/apps/native-apps/primer-payments-app/authorize-payment-action) and "Cancel payment" actions, creating powerful payment flows that suit your needs.

For example, you may want to validate that the processor CVV and AVS checks `MATCHED` and, if not, cancel the payment - this becomes very easy with Primer.

<Frame caption="Cancelled action example">
  ![Cancelled action
  example](https://goat-assets.production.core.primer.io/marketing/payment-operations/external-docs/cancel/cancel-payment-action-example.png)
</Frame>

Learn more [here](/workflows/apps/native-apps/primer-payments-app/cancel-payment-action) about the Payments app and the "Cancel payment" action.

### Cancel a payment via Payments API

Cancel a payment using the Payments API - see the [API reference](/api-reference/v2.4/api-reference/payments-api/cancel-a-payment) for the details.

```bash BASH theme={"dark"}
curl --request POST \
     --url https://api.sandbox.primer.io/payments/<YOUR_PAYMENT_ID>/cancel \
     --header 'X-API-KEY: <YOUR_API_KEY>' \
     --header 'X-API-VERSION: 2.2' \
     --header 'X-Idempotency-Key: <YOUR_IDEMPOTENCY_KEY>'
```

Include the Primer payment ID in the request, which you will have received as part of the payment creation and authorization.

It is optional to pass the cancellation `reason` in the payload for your own records.
