Refund a POS sale
- Sandbox:
PUT https://sandbox.payme.io/api/sales/{sale_guid}
- Production:
PUT https://live.payme.io/api/sales/{sale_guid}
Credentials
- Request body field
seller_payme_id (required): The seller's MPL. The sale must belong to this seller.
- Request body field
payme_client_key (optional): Partners only: your partner key. You can send it in the PayMe-Partner-Key header instead.
Overview
Refunds a sale paid on a POS device. PayMe sends the refund to the device in payment.pos_id and returns the result in the same response.
Example: PUT https://sandbox.payme.io/api/sales/SALE1700-000000AA-EXAMPLE1-SALE0001.
- Send
payment.action refund. Without it, this endpoint pays the sale instead of refunding it (see POS module overview).
- Leave out
payment.amount to refund everything that can still be refunded, or send a smaller amount for a partial refund.
payment.verify_only true runs the checks and returns without refunding.
refunded_from_creditcard is true when the seller's balance didn't cover the refund and PayMe charged the seller's card on file for the difference.
Authentication
Send seller_payme_id (the seller's MPL) in the JSON body. The sale must belong to this seller. Partners also send payme_client_key, in the body or the PayMe-Partner-Key header.
Errors
| HTTP |
Code |
When |
| 500 |
1 |
A required field is missing: seller_payme_id, payment or payment.method. |
| 500 |
350 |
No sale has this ID. |
| 500 |
4 |
payment.method isn't the sale's payment method (pos). |
| 400 |
720 |
The POS service isn't active for this seller. |
| 400 |
26014 |
payment.pos_id is missing, or the seller has no device with this ID. |
| 400 |
26017 |
The device has no POS record. |
| 400 |
26018 |
The device isn't active. |
| 500 |
Decline code |
The device or the card company declined the refund. |
Parameters
| Name |
In |
Type |
Required |
Description |
sale_guid |
path |
string |
yes |
The sale's payme_sale_id. |
Request body
Content type: application/json
| Field |
Type |
Required |
Description |
seller_payme_id |
string |
yes |
The seller's MPL. The sale must belong to this seller. |
payme_client_key |
string |
no |
Partners only: your partner key. You can send it in the PayMe-Partner-Key header instead. |
payment |
object |
yes |
The refund to send to the device. |
payment.method |
string |
yes |
pos. It must match the sale's payment method. |
payment.action |
string |
yes |
refund. Without it, the call pays the sale instead of refunding it. |
payment.pos_id |
string |
yes |
The device that processes the refund. |
payment.amount |
integer |
no |
Amount to refund, in minor units. Default: everything that can still be refunded. |
payment.verify_only |
boolean |
no |
true runs the checks without refunding. |
language |
string |
no |
Language of messages: he (default), en, es, ru or ar. |
Request example
{
"seller_payme_id": "MPLDEMO-MPLDEMO-MPLDEMO-1234567",
"payment": {
"method": "pos",
"action": "refund",
"pos_id": "001"
},
"language": "en"
}
Code samples
curl
curl -X PUT 'https://sandbox.payme.io/api/sales/<sale_guid>' \
-H 'Content-Type: application/json' \
--data-raw '{
"seller_payme_id": "MPLDEMO-MPLDEMO-MPLDEMO-1234567",
"payment": {
"method": "pos",
"action": "refund",
"pos_id": "001"
},
"language": "en"
}'
Node.js
const response = await fetch("https://sandbox.payme.io/api/sales/<sale_guid>", {
method: "PUT",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({
"seller_payme_id": "MPLDEMO-MPLDEMO-MPLDEMO-1234567",
"payment": {
"method": "pos",
"action": "refund",
"pos_id": "001"
},
"language": "en"
}),
});
console.log(await response.text());
Python
import requests
response = requests.put(
"https://sandbox.payme.io/api/sales/<sale_guid>",
json={
"seller_payme_id": "MPLDEMO-MPLDEMO-MPLDEMO-1234567",
"payment": {
"method": "pos",
"action": "refund",
"pos_id": "001",
},
"language": "en",
},
)
print(response.text)
PHP
<?php
$body = <<<'BODY'
{
"seller_payme_id": "MPLDEMO-MPLDEMO-MPLDEMO-1234567",
"payment": {
"method": "pos",
"action": "refund",
"pos_id": "001"
},
"language": "en"
}
BODY;
$ch = curl_init('https://sandbox.payme.io/api/sales/<sale_guid>');
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'PUT',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
'Content-Type: application/json',
],
CURLOPT_POSTFIELDS => $body,
]);
$response = curl_exec($ch);
curl_close($ch);
echo $response;
Responses
200 — The refund was processed. (success)
| Field |
Type |
Description |
status_code |
integer |
0 on success. |
payme_status |
string |
success. |
payme_sale_id |
string |
PayMe's sale ID. |
payme_sale_code |
integer |
PayMe's numeric sale ID. |
payme_sale_status |
string |
refunded, or partial-refund after a partial refund. |
sale_status |
string |
Same as payme_sale_status. |
currency |
string |
ISO 4217 currency code. |
price |
integer |
The original sale amount, in minor units. |
transaction_id |
string |
Your reference for the sale. |
sale_refund_buffer |
integer |
Amount that can still be refunded, in minor units. |
payme_transaction_id |
string |
ID of the refund transaction. |
payme_transaction_total |
integer |
Amount refunded, in minor units. |
payme_transaction_card_brand |
string |
Card brand. |
payme_transaction_auth_number |
string |
Authorization number of the refund. |
payme_signature |
string |
Signature of the refund. See Callbacks. |
refunded_from_creditcard |
boolean |
true if PayMe charged the seller's card on file because the balance didn't cover the refund. |
sale_invoice_number |
string |
Number of the credit document, if the invoicing service issued one. Otherwise null. |
sale_invoice_url |
string |
Link to the credit document, if one was issued. Otherwise null. |
{
"status_code": 0,
"payme_status": "success",
"payme_sale_id": "SALE1700-000000AA-EXAMPLE1-SALE0001",
"payme_sale_code": 12346578,
"payme_sale_status": "refunded",
"sale_status": "refunded",
"currency": "ILS",
"price": 10000,
"transaction_id": "order-1001",
"sale_refund_buffer": 0,
"payme_transaction_id": "TRAN1700-000000AA-EXAMPLE1-TRAN0002",
"payme_transaction_total": 10000,
"payme_transaction_card_brand": "Mastercard",
"payme_transaction_auth_number": "0123456",
"payme_signature": "db1c276**********c5b39",
"refunded_from_creditcard": false,
"sale_invoice_number": null,
"sale_invoice_url": null
}
400 — The device or the POS service can't take the refund. See the error table. (error)
| Field |
Type |
Description |
status_code |
integer |
1 on failure. |
status_error_details |
string |
What went wrong, in the language you asked for (Hebrew by default). |
status_additional_info |
string |
The field or value concerned. Can be null. |
status_error_code |
integer |
PayMe error code. See the error table above and Errors. |
session |
string |
PayMe session ID. Quote it when you contact support. |
{
"status_code": 1,
"status_error_details": "Desired device is inactive",
"status_additional_info": null,
"status_error_code": 26018,
"session": "FhT3aXe7"
}
500 — The request was refused or the refund was declined. See the error table. (error)
| Field |
Type |
Description |
status_code |
integer |
1 on failure. |
status_error_details |
string |
What went wrong, in the language you asked for (Hebrew by default). |
status_additional_info |
string |
The field or value concerned. Can be null. |
status_error_code |
integer |
PayMe error code. See the error table above and Errors. |
session |
string |
PayMe session ID. Quote it when you contact support. |
{
"status_code": 1,
"status_error_details": "Sale was not found",
"status_additional_info": "SALE1700-000000AA-EXAMPLE1-SALE0001",
"status_error_code": 350,
"session": "FhT3aXe7"
}