Reverse a Card Present Payment
This guide explains how to reverse an authorized payment in a card-present environment using the Getnet Global API. A reversal undoes the authorization before it is captured. No money moves, so the funds never leave the cardholder’s account.
Choose Between Reversal and Cancellation
Reversal and cancellation are separate operations with separate endpoints. Choose one based on whether the transaction is captured.
| Reversal | Cancellation | |
|---|---|---|
| When to use | The transaction is authorized but not captured yet. | The transaction is captured. |
| Money movement | No money has moved. The reversal undoes the authorization. | The money has moved. The funds return to the customer. |
| Amount | Full amount only. Partial reversals are not supported. | Full, or partial from D+1. |
| Endpoint | POST /dpm/payments-gwproxy/v2/payments/reversal | POST /dpm/payments-gwproxy/v2/payments/cancel |
To check whether a transaction is captured, query its status with the Get Transaction Status guide. An AUTHORIZED status means you can reverse it. A CAPTURED status means you must cancel it instead.
To cancel a captured transaction, see Cancel a Card Present Payment.
Understand Manual and Automatic Reversal
Getnet already reverses some transactions automatically. The platform triggers an automatic reversal after a communication failure, a processing interruption, or a timeout. This keeps transactions consistent and prevents unintended authorizations.
The Reversal endpoint covers a different case: the reversals you decide to request. It does not replace the automatic process.
If your terminal timed out waiting for an authorization response, check the transaction status before you call the Reversal endpoint. Getnet may have already reversed it.
Requirements
Before following the steps, you need to:
- API Credentials: Get your
client_idandclient_secretfrom the Integration Support team. - Authentication: Generate a Bearer token with the Authentication endpoint.
- Seller ID: Your seller identifier, sent in the
x-seller-idheader. Get it from the Integration Support team with your API credentials. The reversal uses it to find the original transaction. - Payment ID: The
payment_idreturned by the original authorization. - Card Data (optional): The card number (PAN) or the Track 2 data of the original transaction. You do not need to keep card data to reverse a payment. Without it, send an empty
cardobject. - Terminal Identifiers (Brazil): The
terminal_code,logical_code, andserial_numberof the terminal that processed the transaction.
Step 1: Reverse the Payment
To reverse a card-present payment, call the Reversal endpoint with the original transaction’s payment_id. Always include the additional_data.card object, even when it is empty. The endpoint is available in all countries integrated with SEP Card Present.
Headers
Send these headers on every reversal request.
| Header | Description | Required |
|---|---|---|
Authorization | Bearer followed by your access token. | Yes |
Content-Type | application/json | Yes |
x-seller-id | Your seller identifier. | Yes |
country | Country identifier. Defaults to BR. Send your country if you operate outside Brazil. | No |
tenant | Tenant identifier. Defaults to santander. | No |
Request Attributes
The request body identifies the original transaction and the terminal that processed it.
| Attribute | Description | Required |
|---|---|---|
idempotency_key | Unique key for this request (1-64 characters). If you repeat a key, the API returns the same data. | Yes |
payment_id | The payment_id of the original authorization. | Yes |
payment_method | The payment method of the original transaction. We recommend that you omit it: Getnet uses the payment method of the original transaction. If you send it, it must match the original authorization. | No |
amount | Amount in cents. Omit it: a reversal always covers the full amount. | No |
custom_key | Your own key to identify the reversal (3-32 characters). | No |
additional_data.terminal | Identifiers of the terminal that processed the original transaction. | Yes |
additional_data.terminal.terminal_code | Terminal code. | Yes (Brazil) |
additional_data.terminal.logical_code | Logical code of the terminal. | Yes (Brazil) |
additional_data.terminal.serial_number | Serial number of the terminal. | Yes (Brazil) |
additional_data.card | Card data of the original transaction. Send the object even without card data: "card": {}. | Yes |
additional_data.card.number | Card number (PAN), up to 32 characters. | No |
additional_data.card.track_2 | Track 2 data, up to 150 characters. Accepted with or without number. | No |
additional_data.card.expiration_month | Two-digit expiration month, as a string (for example, "12"). | No |
additional_data.card.expiration_year | Two-digit expiration year, as a string (for example, "26"). | No |
additional_data.currency | ISO 4217 currency code of the original transaction (for example, BRL). | No |
Example 1: Reversal with Card Number
Used when you have the card number (PAN) of the original transaction.
curl --request POST \
--url https://api.pre.globalgetnet.com/dpm/payments-gwproxy/v2/payments/reversal \
--header 'Authorization: Bearer <YOUR_TOKEN>' \
--header 'Content-Type: application/json' \
--header 'x-seller-id: 19ffd677-3691-4c4d-88c9-79cc91b95c0d' \
--data '{
"idempotency_key": "b10be7a7-d76e-4cd6-8ebe-4f68b9271d9c",
"payment_id": "b0b7851a-e558-4d94-b34e-86d69138de77",
"custom_key": "2bc94fa13c8d4df28e52a996912bbab5",
"additional_data": {
"terminal": {
"terminal_code": "TF123456",
"logical_code": "654321",
"serial_number": "ABC123"
},
"card": {
"number": "4111111111111111",
"expiration_month": "12",
"expiration_year": "26"
},
"currency": "BRL"
}
}'Example 2: Reversal with Track 2
Used when you send the Track 2 data instead of the number field. Track 2 already contains the card number.
curl --request POST \
--url https://api.pre.globalgetnet.com/dpm/payments-gwproxy/v2/payments/reversal \
--header 'Authorization: Bearer <YOUR_TOKEN>' \
--header 'Content-Type: application/json' \
--header 'x-seller-id: 19ffd677-3691-4c4d-88c9-79cc91b95c0d' \
--data '{
"idempotency_key": "3f6c2d8e-91a4-4b7e-8c05-d2e7a19b4f60",
"payment_id": "b0b7851a-e558-4d94-b34e-86d69138de77",
"additional_data": {
"terminal": {
"terminal_code": "TF123456",
"logical_code": "654321",
"serial_number": "ABC123"
},
"card": {
"track_2": "4111111111111111=26122010000000000000"
},
"currency": "BRL"
}
}'Example 3: Reversal without Card Data
Used when you do not have the card data of the original transaction. Send the card object empty.
curl --request POST \
--url https://api.pre.globalgetnet.com/dpm/payments-gwproxy/v2/payments/reversal \
--header 'Authorization: Bearer <YOUR_TOKEN>' \
--header 'Content-Type: application/json' \
--header 'x-seller-id: 19ffd677-3691-4c4d-88c9-79cc91b95c0d' \
--data '{
"idempotency_key": "7a2e9c41-5b3d-4f8a-9e16-c0d4b8f2a735",
"payment_id": "b0b7851a-e558-4d94-b34e-86d69138de77",
"additional_data": {
"terminal": {
"terminal_code": "TF123456",
"logical_code": "654321",
"serial_number": "ABC123"
},
"card": {},
"currency": "BRL"
}
}'Step 2: Verify the Response
On success, the API returns HTTP 200 with status set to REVERSED and reason_code set to 00.
{
"idempotency_key": "b10be7a7-d76e-4cd6-8ebe-4f68b9271d9c",
"seller_id": "19ffd677-3691-4c4d-88c9-79cc91b95c0d",
"request_id": "51d212f6-ad05-499c-90a1-e05c3b6ea0db",
"payment_id": "b0b7851a-e558-4d94-b34e-86d69138de77",
"order_id": "471994a7-ba22-453e-8afc-f0137d1710c2",
"amount": 4000,
"status": "REVERSED",
"reason_code": "00",
"reason_message": "Payment successful reversal.",
"authorization_code": "601878",
"trace_number": 0,
"canceled_at": "2026-09-04T18:14:54.057Z",
"custom_key": "2bc94fa13c8d4df28e52a996912bbab5"
}The amount field always contains the full amount of the original authorization. The canceled_at field records the date and time of the reversal.
Handle Errors
If the request fails, the response body carries the error in details[]. Each entry has these fields:
status: The result of the request, such asDENIED.error_code: The error code.description: The HTTP status text, such asBad Request.description_detail: The explanation of the error.
For example:
{
"message": "Bad Request",
"name": "RequestCancelApi",
"status_code": 400,
"details": [
{
"status": "DENIED",
"error_code": "CANCEL-400",
"description": "Bad Request",
"description_detail": "Denied. Payment already reversed"
}
]
}Use the HTTP status to decide your next action:
| HTTP status | What to do |
|---|---|
400 | Fix the request before you send it again. CANCEL-400 with Denied. Payment already reversed means the payment is already reversed. Do not retry. |
401 | Check your credentials and your Bearer token. Do not retry with the same token. |
429, 5xx, or a timeout | Retry with the same idempotency_key. If the first request went through, the API returns the same result instead of processing a second reversal. |
A 200 response can also carry status set to DENIED or ERROR. In that case the reversal was not processed. Check reason_code and reason_message for the cause.
For the full list of error codes, see Errors.
Step 3: Receive the Reversal Webhook (Optional)
Subscribe to the REVERSED_TRANSACTIONS event to get notified when a reversal is processed. To subscribe, call the Subscribe to a webhook event endpoint (POST /dpm/webhooks/v1/subscriptions) with event set to REVERSED_TRANSACTIONS.
The payload includes complete_cancel, which is always true for this event. For the full payload, see the Webhooks Reference.
Next Steps
Now that you know how to reverse payments, explore these related card-present features:
- Cancel a Card Present Payment: Return the funds of a captured transaction.
- Pre-authorized Payments: Manage two-step flows for reservations and delayed captures.
- Single-Step Payments: Process standard chip and magnetic stripe sales.