curl --request POST \
--url https://api.sandbox.cheqpay.mx/pos/v2/payment-orders/{id}/refund \
--header 'Content-Type: application/json' \
--header 'x-api-key: <api-key>' \
--header 'x-merchant-id: <api-key>' \
--data '
{
"amount": 1000,
"reason": "customer requested",
"paymentId": "a0b0c9d4-6ce9-40e4-873a-e234c1d93639"
}
'import requests
url = "https://api.sandbox.cheqpay.mx/pos/v2/payment-orders/{id}/refund"
payload = {
"amount": 1000,
"reason": "customer requested",
"paymentId": "a0b0c9d4-6ce9-40e4-873a-e234c1d93639"
}
headers = {
"x-api-key": "<api-key>",
"x-merchant-id": "<api-key>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {
'x-api-key': '<api-key>',
'x-merchant-id': '<api-key>',
'Content-Type': 'application/json'
},
body: JSON.stringify({
amount: 1000,
reason: 'customer requested',
paymentId: 'a0b0c9d4-6ce9-40e4-873a-e234c1d93639'
})
};
fetch('https://api.sandbox.cheqpay.mx/pos/v2/payment-orders/{id}/refund', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.sandbox.cheqpay.mx/pos/v2/payment-orders/{id}/refund",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'amount' => 1000,
'reason' => 'customer requested',
'paymentId' => 'a0b0c9d4-6ce9-40e4-873a-e234c1d93639'
]),
CURLOPT_HTTPHEADER => [
"Content-Type: application/json",
"x-api-key: <api-key>",
"x-merchant-id: <api-key>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api.sandbox.cheqpay.mx/pos/v2/payment-orders/{id}/refund"
payload := strings.NewReader("{\n \"amount\": 1000,\n \"reason\": \"customer requested\",\n \"paymentId\": \"a0b0c9d4-6ce9-40e4-873a-e234c1d93639\"\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("x-api-key", "<api-key>")
req.Header.Add("x-merchant-id", "<api-key>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://api.sandbox.cheqpay.mx/pos/v2/payment-orders/{id}/refund")
.header("x-api-key", "<api-key>")
.header("x-merchant-id", "<api-key>")
.header("Content-Type", "application/json")
.body("{\n \"amount\": 1000,\n \"reason\": \"customer requested\",\n \"paymentId\": \"a0b0c9d4-6ce9-40e4-873a-e234c1d93639\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.sandbox.cheqpay.mx/pos/v2/payment-orders/{id}/refund")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["x-api-key"] = '<api-key>'
request["x-merchant-id"] = '<api-key>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"amount\": 1000,\n \"reason\": \"customer requested\",\n \"paymentId\": \"a0b0c9d4-6ce9-40e4-873a-e234c1d93639\"\n}"
response = http.request(request)
puts response.read_body{
"id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"status": "COMPLETED",
"amount": "100000",
"refundedAmount": "100000",
"paymentMethodType": "CARD",
"createdAt": "2023-11-07T05:31:56Z",
"updatedAt": "2023-11-07T05:31:56Z"
}Refund a Payment of a payment order (v2)
Refunds one of the Payments under a payment order. For legacy single-Payment orders (allowPartials=false), paymentId is optional and the sole Payment is refunded. For split-tender orders (allowPartials=true), paymentId is required — the caller must say which Payment to refund. The action does NOT update the order’s status directly: the orchestrator consumer recomputes the aggregate status from the resulting PaymentEvent. After a full refund of every Payment, the order transitions to REFUNDED (terminal). After a partial refund, it transitions back to PARTIALLY_PAID and accepts new Payments via the addPayment endpoint. This is an internal endpoint.
curl --request POST \
--url https://api.sandbox.cheqpay.mx/pos/v2/payment-orders/{id}/refund \
--header 'Content-Type: application/json' \
--header 'x-api-key: <api-key>' \
--header 'x-merchant-id: <api-key>' \
--data '
{
"amount": 1000,
"reason": "customer requested",
"paymentId": "a0b0c9d4-6ce9-40e4-873a-e234c1d93639"
}
'import requests
url = "https://api.sandbox.cheqpay.mx/pos/v2/payment-orders/{id}/refund"
payload = {
"amount": 1000,
"reason": "customer requested",
"paymentId": "a0b0c9d4-6ce9-40e4-873a-e234c1d93639"
}
headers = {
"x-api-key": "<api-key>",
"x-merchant-id": "<api-key>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {
'x-api-key': '<api-key>',
'x-merchant-id': '<api-key>',
'Content-Type': 'application/json'
},
body: JSON.stringify({
amount: 1000,
reason: 'customer requested',
paymentId: 'a0b0c9d4-6ce9-40e4-873a-e234c1d93639'
})
};
fetch('https://api.sandbox.cheqpay.mx/pos/v2/payment-orders/{id}/refund', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.sandbox.cheqpay.mx/pos/v2/payment-orders/{id}/refund",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'amount' => 1000,
'reason' => 'customer requested',
'paymentId' => 'a0b0c9d4-6ce9-40e4-873a-e234c1d93639'
]),
CURLOPT_HTTPHEADER => [
"Content-Type: application/json",
"x-api-key: <api-key>",
"x-merchant-id: <api-key>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api.sandbox.cheqpay.mx/pos/v2/payment-orders/{id}/refund"
payload := strings.NewReader("{\n \"amount\": 1000,\n \"reason\": \"customer requested\",\n \"paymentId\": \"a0b0c9d4-6ce9-40e4-873a-e234c1d93639\"\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("x-api-key", "<api-key>")
req.Header.Add("x-merchant-id", "<api-key>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://api.sandbox.cheqpay.mx/pos/v2/payment-orders/{id}/refund")
.header("x-api-key", "<api-key>")
.header("x-merchant-id", "<api-key>")
.header("Content-Type", "application/json")
.body("{\n \"amount\": 1000,\n \"reason\": \"customer requested\",\n \"paymentId\": \"a0b0c9d4-6ce9-40e4-873a-e234c1d93639\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.sandbox.cheqpay.mx/pos/v2/payment-orders/{id}/refund")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["x-api-key"] = '<api-key>'
request["x-merchant-id"] = '<api-key>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"amount\": 1000,\n \"reason\": \"customer requested\",\n \"paymentId\": \"a0b0c9d4-6ce9-40e4-873a-e234c1d93639\"\n}"
response = http.request(request)
puts response.read_body{
"id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"status": "COMPLETED",
"amount": "100000",
"refundedAmount": "100000",
"paymentMethodType": "CARD",
"createdAt": "2023-11-07T05:31:56Z",
"updatedAt": "2023-11-07T05:31:56Z"
}Authorizations
API key for authentication (required)
Merchant ID for identifying the merchant (required)
Path Parameters
Payment order ID
Body
Refund amount in minor currency units (centavos): 5000 = $50.00 MXN. Must be a positive integer. Bounded per Payment by module-payment (cannot exceed that Payment's remaining capturable amount). Note: unlike the legacy v1 refund endpoint, which takes major units, v2 takes minor units.
x > 01000
Optional free-text reason. Persisted on the order's refundReason field for auditing.
"customer requested"
Which Payment of the order to refund. Required when the order has allowPartials=true. For non-partial orders this can be omitted and the lone Payment is used.
"a0b0c9d4-6ce9-40e4-873a-e234c1d93639"
Response
Refund accepted by module-payment. The response is a snapshot of the resulting Payment-level refund — the order's aggregate status is materialized asynchronously by the consumer.
Refund event id
"COMPLETED"
Amount of THIS refund (smallest currency unit)
"100000"
Cumulative refunded amount of the targeted Payment after this call
"100000"
"CARD"