Skip to main content

Cancel Payments

There may be scenarios in which you need to cancel a payment, such as a customer placing a payment by mistake or an authorized payment that needs to be voided before settlement.

Both Payment Intents and the direct Payments API support cancellation. A succeeded payment cannot be canceled — use the refund flow instead.

Getting Started

To get started, you will need a Credova Account.

Get your Secret Key

Next you will need your Secret Key. Go to your Developers section and click Reveal for your Secret Key and copy the value.

Save the Secret Key as it will be used in the next steps of this guide.

Payment Intents

A Payment Intent can be canceled from any non-terminal status: requires_payment_method, requires_confirmation, or requires_capture. It cannot be canceled once it has succeeded.

Cancel the Payment Intent

Call the Cancel Payment Intent endpoint with the intent ID:

Cancel a Payment Intent
curl 'https://api.publicsquare.com/payment_intents/pmt_int_2xNjK7abcdefghij/cancel' \
-X 'POST' \
-H 'X-API-KEY: <SECRET_API_KEY>' \
-H 'Content-Type: application/json'

You should see a response with status: canceled:

Canceled Payment Intent
{
"id": "pmt_int_2xNjK7abcdefghij",
"account_id": "acc_B518niGwGYKzig6vtrRVZGGGV",
"environment": "test",
"status": "canceled",
"amount": 1000,
"currency": "USD",
"cancellation_reason": "requested",
"canceled_date": "2026-04-15T15:10:00Z",
"payment_id": null,
"created_date": "2026-04-15T14:22:10Z",
"modified_date": "2026-04-15T15:10:00Z"
}

Handling Cancellation Errors

If you attempt to cancel an intent that is already canceled, you will receive a 409 Conflict:

Already Canceled
{
"error": {
"code": "payment_intent_already_canceled",
"message": "This PaymentIntent has already been canceled."
}
}

If a confirm is currently in progress, cancellation will be rejected until the confirm completes. Retry the cancel once the intent transitions out of processing:

Confirm In Progress
{
"error": {
"code": "payment_intent_confirm_in_progress",
"message": "A confirm is currently in progress. Please try again shortly."
}
}
If the intent has already succeeded, cancel is not available. Follow the Issue a Refund guide instead.

Legacy

The direct Payments API offers the ability to cancel a payment before it is settled or captured.

In order to cancel a payment, we will need the ID of an authorized or recently captured payment. Assuming you have a payment similar to:

Authorized Payment
{
"id": "pmt_2YKewBonG4tgk12MheY3PiHDy",
"account_id": "acc_B518niGwGYKzig6vtrRVZGGGV",
"environment": "test",
"status": "requires_capture",
...
}

We need to make a call to Cancel Payment endpoint:

Cancel a Payment
curl 'https://api.publicsquare.com/payments/cancel' \
-X 'POST' \
-H 'X-API-KEY: <SECRET_API_KEY>' \
-H 'Content-Type: application/json' \
-d '{
"payment_id": "pmt_2YKewBonG4tgk12MheY3PiHDy"
}'

Payment Response

Given the above example, you should see a cancelled payment result similar to:

Canceled Payment
{
"id": "pmt_2YKewBonG4tgk12MheY3PiHDy",
"account_id": "acc_B518niGwGYKzig6vtrRVZGGGV",
"environment": "test",
"status": "cancelled",
"transaction_id": "trx_95rvMJvAVeG68W4NtLdfkN3LG",
"amount": 1000,
"amount_capturable": 0,
"amount_charged": 1000,
"amount_refunded": 0,
"refunded": false,
...
"transaction": {
"id": "trx_95rvMJvAVeG68W4NtLdfkN3LG",
"account_id": "acc_B518niGwGYKzig6vtrRVZGGGV",
"environment": "test",
"status": "cancelled",
"amount": 1000,
"fee_amount": 0,
"net_amount": 1000,
...
},
...
}

Handling Cancellation Failures

If a payment cannot be cancelled because the payment has already been settled, an error response will be returned:

Cancellation Failed
{
"title": "Error",
"status": 400,
"detail": "payment cancellation failed."
}

If payment cancellation fails, you can follow the refund payment guide.

Cancelling a Specific Capture

If a payment has multiple partial captures, pass payment_capture_id to cancel one capture instead of the whole payment.

Voiding a pending capture. A capture that has not settled yet can be voided on its own. The capture moves to cancelled, amount_charged decreases, and the payment stays partially_captured if other captures remain — or reverts to requires_capture if it does not.

Void a Pending Capture
curl 'https://api.publicsquare.com/payments/cancel' \
-X 'POST' \
-H 'X-API-KEY: <SECRET_API_KEY>' \
-H 'Content-Type: application/json' \
-d '{
"payment_id": "pmt_2YKewBonG4tgk12MheY3PiHDy",
"payment_capture_id": "cpt_3fRkT8bcdefghijklmnop"
}'

Releasing the remaining authorization. Omit payment_capture_id on a partially_captured payment to release the remaining authorized amount without cancelling any settled captures. The payment moves to succeeded if at least one capture settled, or cancelled if none did.

Release the Remaining Authorization
curl 'https://api.publicsquare.com/payments/cancel' \
-X 'POST' \
-H 'X-API-KEY: <SECRET_API_KEY>' \
-H 'Content-Type: application/json' \
-d '{
"payment_id": "pmt_2YKewBonG4tgk12MheY3PiHDy"
}'
A release is rejected with a 422 while any capture is still pending: payment has a capture still processing; wait for it to settle before releasing the remainder.

Voiding a capture that has already settled is rejected. Use a refund instead:

Capture Already Settled
{
"title": "Error",
"status": 400,
"detail": "this payment capture has already settled; use a refund to reverse it instead."
}

A payment_capture_id that does not exist on the payment returns a 404.

Conclusion

This guide showed you how to cancel a payment. You can also follow our refund payment guide which will attempt to cancel the payment and fallback to issuing a refund.

Follow these guides to learn more: