Refund a sale

Credentials

Overview

Refunds a paid sale, in full or in part. The money goes back to the payment method the buyer paid with. On an authorized sale the same call voids the hold instead; see Void an authorization.

Credentials

Name the seller: send seller_payme_id, or seller_id with your partner key (payme_client_key). A seller needs no partner key. A partner key on its own fails with error 1. The sale must belong to the seller you name; otherwise the call returns HTTP 403, error 303.

Rules

Callback

When the refund succeeds, PayMe sends a refund callback (notify_type: refund) to the sale's sale_callback_url and to your partner's sale callback URL. A void sends the same callback. See Callbacks.

With the invoicing service active on the account, a refund issues a credit document; the original document is not cancelled.

Language of errors

Errors about the refund itself (wrong status, amount, nothing left to refund) come back in the language the sale was created with, whatever you send in language.

Parameters

This endpoint takes no path, query or header parameters.

Request body

Content type: application/json

Field Type Required Description
payme_client_key string no Partners: your partner key. You can send it in the PayMe-Partner-Key header instead. A seller leaves it out.
seller_payme_id string no The seller's MPL. Required unless you send seller_id with payme_client_key. You can send it in the PayMe-Merchant-Key header instead.
seller_id string no Partners: your own ID for the seller (the seller_id you set when you created it). Send it with payme_client_key instead of seller_payme_id.
payme_sale_id string yes The sale to refund: PayMe's sale ID, or your own transaction_id for that sale.
sale_refund_amount integer no Amount to refund, in minor units (1000 = 10.00). Leave it out to refund everything that is left. Never send 0. A partial amount must be at least the account's minimum sale value (500 by default).
verify_only boolean no true to check the call without making it: PayMe validates the request and returns the amounts, but changes nothing and sends no callback. Default false.
language string no Language of error messages: en, or he (the default). es, ru and ar are accepted, but messages then come back mostly in English. Any other value returns error 51.

Request example

{
  "seller_payme_id": "MPLDEMO-MPLDEMO-MPLDEMO-1234567",
  "payme_sale_id": "SALEDEMO-XXXXXXXX-XXXXXXXX-XXXXXXXX",
  "sale_refund_amount": 1000,
  "language": "en"
}

Code samples

curl

curl -X POST 'https://sandbox.payme.io/api/refund-sale' \
  -H 'Content-Type: application/json' \
  --data-raw '{
  "seller_payme_id": "MPLDEMO-MPLDEMO-MPLDEMO-1234567",
  "payme_sale_id": "SALEDEMO-XXXXXXXX-XXXXXXXX-XXXXXXXX",
  "sale_refund_amount": 1000,
  "language": "en"
}'

Node.js

const response = await fetch("https://sandbox.payme.io/api/refund-sale", {
  method: "POST",
  headers: {
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    "seller_payme_id": "MPLDEMO-MPLDEMO-MPLDEMO-1234567",
    "payme_sale_id": "SALEDEMO-XXXXXXXX-XXXXXXXX-XXXXXXXX",
    "sale_refund_amount": 1000,
    "language": "en"
  }),
});

console.log(await response.text());

Python

import requests

response = requests.post(
    "https://sandbox.payme.io/api/refund-sale",
    json={
        "seller_payme_id": "MPLDEMO-MPLDEMO-MPLDEMO-1234567",
        "payme_sale_id": "SALEDEMO-XXXXXXXX-XXXXXXXX-XXXXXXXX",
        "sale_refund_amount": 1000,
        "language": "en",
    },
)

print(response.text)

PHP

<?php

$body = <<<'BODY'
{
  "seller_payme_id": "MPLDEMO-MPLDEMO-MPLDEMO-1234567",
  "payme_sale_id": "SALEDEMO-XXXXXXXX-XXXXXXXX-XXXXXXXX",
  "sale_refund_amount": 1000,
  "language": "en"
}
BODY;

$ch = curl_init('https://sandbox.payme.io/api/refund-sale');
curl_setopt_array($ch, [
    CURLOPT_CUSTOMREQUEST => 'POST',
    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 made (or, with verify_only, would be accepted). (success)

Field Type Description
status_code integer 0: success.
status_error_code integer 0 on success.
payme_status string success.
refunded_from_creditcard boolean true when the seller's balance didn't cover the refund and PayMe took the shortfall from the seller's card on file.
sale_invoice_number string Number of the credit document, when the invoicing service is active on the account; otherwise null.
sale_invoice_url string Link to the credit document, when the invoicing service is active on the account; otherwise null.
sale_refund_buffer integer Amount still left to refund, in minor units.
sale_status string The sale's status after the refund: refunded, or partial-refund after a partial refund.
payme_transaction_total integer Amount refunded to the buyer, in minor units.
payme_transaction_total_aft_deduction integer Amount taken from the seller for this refund, after fees, in minor units.
payme_transaction_id string PayMe's ID of the refund transaction. null when verify_only is true.
payme_transaction_card_brand string Card brand. null when verify_only is true.
payme_transaction_auth_number string Authorization number from the card issuer. null when verify_only is true.
payme_transaction_voucher string Voucher number. null when verify_only is true.
payme_signature string PayMe's signature for the transaction. null when verify_only is true.
payme_transaction_acquirer string The acquirer, or null.
payme_transaction_arn string Acquirer reference (EMV UID) when the acquirer returns one; usually null. Not returned when verify_only is true.
session string PayMe's ID for this request. Quote it when you contact PayMe.
{
  "status_code": 0,
  "status_error_code": 0,
  "payme_status": "success",
  "refunded_from_creditcard": false,
  "sale_invoice_number": null,
  "sale_invoice_url": null,
  "sale_refund_buffer": 9000,
  "sale_status": "partial-refund",
  "payme_transaction_total": 1000,
  "payme_transaction_total_aft_deduction": 1000,
  "payme_transaction_id": "TRANDEMO-XXXXXXXX-XXXXXXXX-XXXXXXXX",
  "payme_transaction_card_brand": "Mastercard",
  "payme_transaction_auth_number": "72****4",
  "payme_transaction_voucher": "24****9",
  "payme_signature": "b71e**************ca5a",
  "payme_transaction_acquirer": null,
  "payme_transaction_arn": null,
  "session": "Ab12Cd34"
}

400 — Error 1: no seller named (a partner key on its own). Error 352: sale_refund_amount isn't a positive number. Error 357: this sale type can't be refunded, for example a customer deposit. Error 20: the seller doesn't belong to the partner key sent. (error)

Field Type Description
status_code integer 1: the request failed.
status_error_code integer PayMe's error code. See Errors.
status_error_details string The error message, in the language you asked for.
status_additional_info string Extra detail: usually the field at fault, the sale's current status, or the masked card number.
session string PayMe's ID for this request. Quote it when you contact PayMe.
{
  "status_code": 1,
  "status_error_details": "Required parameter is missing",
  "status_additional_info": "seller_payme_id",
  "status_error_code": 1,
  "session": "Ab12Cd34"
}

403 — Error 303: the sale belongs to another partner or another seller. (error)

Field Type Description
status_code integer 1: the request failed.
status_error_code integer PayMe's error code. See Errors.
status_error_details string The error message, in the language you asked for.
status_additional_info string Extra detail: usually the field at fault, the sale's current status, or the masked card number.
session string PayMe's ID for this request. Quote it when you contact PayMe.
{
  "status_code": 1,
  "status_error_details": "Could not access sale",
  "status_additional_info": "",
  "status_error_code": 303,
  "session": "Ab12Cd34"
}

429 — Error 998: another call for this sale is still running. Wait, then check the sale before retrying. (error)

Field Type Description
status_code integer 1: the request failed.
status_error_code integer PayMe's error code. See Errors.
status_error_details string The error message, in the language you asked for.
status_additional_info string Extra detail: usually the field at fault, the sale's current status, or the masked card number.
session string PayMe's ID for this request. Quote it when you contact PayMe.
{
  "status_code": 1,
  "status_error_details": "Operation is not permitted",
  "status_additional_info": "Duplicated action detected, please retry later",
  "status_error_code": 998,
  "session": "Ab12Cd34"
}

500 — Request errors. 1: a required field is missing. 200: unknown partner key. 251: unknown seller. 350: no sale has this ID. 305: the sale isn't completed or partial-refund (its status is in status_additional_info). 309: already fully refunded. 352: the amount is outside the account's limits. 503: more than what is left to refund. 517: more than the sale price. 4: POS, eCheck or Verifone prepaid sale. (error)

Field Type Description
status_code integer 1: the request failed.
status_error_code integer PayMe's error code. See Errors.
status_error_details string The error message, in the language you asked for.
status_additional_info string Extra detail: usually the field at fault, the sale's current status, or the masked card number.
session string PayMe's ID for this request. Quote it when you contact PayMe.
{
  "status_code": 1,
  "status_error_details": "Cannot perform action due to an incorrect status",
  "status_additional_info": "chargeback",
  "status_error_code": 305,
  "session": "Ab12Cd34"
}