Charge a Hosted Fields token
- Sandbox:
POST https://sandbox.payme.io/api/generate-sale - Production:
POST https://live.payme.io/api/generate-sale
Credentials
- Request body field
seller_payme_id(required): The seller's MPL. Send it in the JSON body:generate-saledoesn't read thePayMe-Merchant-Keyheader, so a request without a body MPL returns error1. Partners may sendseller_idwithpayme_client_keyinstead. - Request body field
payme_client_key(optional): Partners only: your partner key (or send thePayMe-Partner-Keyheader). Withseller_payme_id, the seller must belong to you, otherwise error20.
Overview
Charges the token that instance.tokenize() returned, from your server, in one call: send it as buyer_key. There is no payment page and no sale_url. Read the result from status_code: a declined charge also returns HTTP 200.
POST https://sandbox.payme.io/api/generate-sale (production: https://live.payme.io/api/generate-sale), with a JSON body (Content-Type: application/json).
This is the server step of the Hosted Fields guide. The same call charges any saved token; see Save a card and charge it later.
| To | Send |
|---|---|
| Charge now (J4) | sale_type: sale (default) |
| Authorize now, capture later (J5, up to 168 hours) | sale_type: authorize; then capture-sale |
Credentials
Send seller_payme_id (the MPL) in the JSON body: this endpoint doesn't read the PayMe-Merchant-Key header, so a request without a body MPL returns error 1. Partners add payme_client_key (or the PayMe-Partner-Key header) and may name the seller by seller_id instead. See Authentication.
What to expect
- Success:
status_code: 0and the sale and transaction fields, the same as the callback. - Decline: HTTP 200 with
status_code: 1,status_error_code(for example20004) andstatus_error_details. - Every call creates a new sale, even when the charge is refused. Check the sale before you retry; see Idempotency and Retries.
- The token's own payment method is used.
- Errors:
buyer_keywithcapture_buyerreturns601, withsale_typetoken/seller-token602, withtemplate606, and withmulti-capture357. A token of another seller returns605; an inactive or already-used single-use token returns604; a charge over the seller's processing limit returns130. - Never put card numbers in any field (error
20), and don't send the legacypricefield (major units; it overridessale_price).
Callbacks
When the sale is paid, PayMe sends a POST with an application/x-www-form-urlencoded body to sale_callback_url. The notification types and fields are on Callbacks.
Issuing an invoice to a business
With the invoicing service active on the account, send buyer_business_name and buyer_business_code to issue the invoice to a business. Send both, or neither.
Parameters
This endpoint takes no path, query or header parameters.
Request body
Content type: application/json
| Field | Type | Required | Description |
|---|---|---|---|
seller_payme_id |
string | yes | The seller's MPL. Send it in the JSON body: generate-sale doesn't read the PayMe-Merchant-Key header, so a request without a body MPL returns error 1. Partners may send seller_id with payme_client_key instead. |
payme_client_key |
string | no | Partners only: your partner key (or send the PayMe-Partner-Key header). With seller_payme_id, the seller must belong to you, otherwise error 20. |
seller_id |
string | no | Partners only: your own ID for the seller, set in create-seller, sent instead of seller_payme_id. Requires payme_client_key. |
buyer_key |
string | yes | The token from instance.tokenize(), or a saved buyer_key. The sale is charged at once. |
sale_price |
integer | yes | Sale amount in minor units: 50.75 is sent as 5075. The default allowed range is 500–4000000, the same in every currency; PayMe can set a different range for a partner. A missing, non-numeric or out-of-range value returns error 352. Decimals are rounded. |
currency |
string | yes | Sale currency, a 3-letter ISO 4217 code such as ILS, enabled on the account (otherwise error 252). Required for sale and authorize; a token or template sale without it uses the account's default currency. |
product_name |
string | yes | Short description of the product or service, up to 500 characters. Shown to the buyer, and on the invoice when the invoicing service is active. Missing returns error 353. |
transaction_id |
string | no | Your own order reference, up to 50 characters. PayMe returns it in responses and callbacks but doesn't check it for uniqueness. |
installments |
string | no | Number of payments: 1 (default) to 12. More than one installment is ILS only (312) and needs a card token. Fixed values above 12 fail unless PayMe has enabled more installments on your account. A non-numeric value returns 10, an ILS price lower than the number of installments 358. |
sale_type |
string | no | sale (default) – charge now (J4). authorize – reserve the amount for up to 168 hours, then capture it with capture-sale (J5). token, seller-token and template can't be combined with buyer_key (602, 606). |
market_fee |
number | no | The partner's (marketplace's) fee: a percentage of the sale price, VAT included, from 0 to 60. It is added on top of PayMe's fees and transferred to the marketplace once a month. Default: the seller's market fee set at create-seller. A non-numeric value returns 10, a negative one 304, and more than 60 308. Ignored for sellers paid directly. |
sale_callback_url |
string | no | Where PayMe sends server-to-server callbacks for this sale, as a form-encoded POST; see Callbacks. If omitted, PayMe uses your partner's default callback URL, if one is set; a seller has no dashboard setting for it, so send it on every call. Must be a public address: localhost, private or loopback IP addresses and IPv6 addresses are refused with error 21, which fails the whole call. |
language |
string | no | Language of the payment page and the error messages. Default he. he and en are fully supported; es, ru and ar are accepted, but messages and the payment page are then mostly in English. Case-insensitive; any other value, or an empty string, returns error 51. |
buyer_business_name |
string | no | With the invoicing service: the business name the invoice is issued to. Send it together with buyer_business_code, or neither. |
buyer_business_code |
integer | no | With the invoicing service: the business code (VAT identifier) the invoice is issued to. Send it together with buyer_business_name, or neither. |
items |
array | no | Line items of the sale, as an array of objects. If you send items, every item needs name, quantity, unit_price and total; an invalid item returns error 20 (HTTP 422) with the failing rules in status_additional_info. Item keys are case-insensitive. |
items[].name |
string | yes | Item name, 1–50 characters. |
items[].quantity |
integer | yes | Quantity, 0–999999. |
items[].unit_price |
integer | yes | Price of one unit, in minor units. |
items[].total |
integer | yes | Line total after discount, in minor units, 0–9000000000. |
items[].unit_measurement |
string | no | Unit of measurement, for example kg. |
items[].discount_total |
number | no | Discount on this line, in minor units, sent as a negative number. |
items[].description |
string | no | Item description, up to 150 characters. |
items[].product_code |
string | no | Your catalog code for the item, up to 100 characters. |
items[].commodity_code |
number | no | Numeric commodity code of the item. |
items[].custom1 |
string | no | Free text for your own use, up to 100 characters. |
items[].custom2 |
string | no | Free text for your own use, up to 100 characters. |
Request example
{
"seller_payme_id": "MPLDEMO-MPLDEMO-MPLDEMO-1234567",
"buyer_key": "BUYERDEMO-BUYERDEMO-BUYERDEMO-1234567",
"sale_price": 1000,
"currency": "ILS",
"product_name": "Smartphone",
"transaction_id": "order-1001",
"installments": "1",
"sale_callback_url": "https://your-server.example.com/payme/callback",
"language": "en"
}
Code samples
curl
curl -X POST 'https://sandbox.payme.io/api/generate-sale' \
-H 'Content-Type: application/json' \
--data-raw '{
"seller_payme_id": "MPLDEMO-MPLDEMO-MPLDEMO-1234567",
"buyer_key": "BUYERDEMO-BUYERDEMO-BUYERDEMO-1234567",
"sale_price": 1000,
"currency": "ILS",
"product_name": "Smartphone",
"transaction_id": "order-1001",
"installments": "1",
"sale_callback_url": "https://your-server.example.com/payme/callback",
"language": "en"
}'
Node.js
const response = await fetch("https://sandbox.payme.io/api/generate-sale", {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({
"seller_payme_id": "MPLDEMO-MPLDEMO-MPLDEMO-1234567",
"buyer_key": "BUYERDEMO-BUYERDEMO-BUYERDEMO-1234567",
"sale_price": 1000,
"currency": "ILS",
"product_name": "Smartphone",
"transaction_id": "order-1001",
"installments": "1",
"sale_callback_url": "https://your-server.example.com/payme/callback",
"language": "en"
}),
});
console.log(await response.text());
Python
import requests
response = requests.post(
"https://sandbox.payme.io/api/generate-sale",
json={
"seller_payme_id": "MPLDEMO-MPLDEMO-MPLDEMO-1234567",
"buyer_key": "BUYERDEMO-BUYERDEMO-BUYERDEMO-1234567",
"sale_price": 1000,
"currency": "ILS",
"product_name": "Smartphone",
"transaction_id": "order-1001",
"installments": "1",
"sale_callback_url": "https://your-server.example.com/payme/callback",
"language": "en",
},
)
print(response.text)
PHP
<?php
$body = <<<'BODY'
{
"seller_payme_id": "MPLDEMO-MPLDEMO-MPLDEMO-1234567",
"buyer_key": "BUYERDEMO-BUYERDEMO-BUYERDEMO-1234567",
"sale_price": 1000,
"currency": "ILS",
"product_name": "Smartphone",
"transaction_id": "order-1001",
"installments": "1",
"sale_callback_url": "https://your-server.example.com/payme/callback",
"language": "en"
}
BODY;
$ch = curl_init('https://sandbox.payme.io/api/generate-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 — Token charged. The response holds the sale and transaction fields, the same as the callback, and has no sale_url. (success)
| Field | Type | Description |
|---|---|---|
status_code |
integer | 0 the token was charged; 1 the charge failed (a decline also comes with HTTP 200). |
payme_status |
string | success or error. |
status_error_code |
integer | 0 on success; otherwise the error or decline code, see Errors. |
payme_sale_id |
string | PayMe's sale ID. Every call creates a new sale, even when the charge is refused. |
payme_sale_code |
integer | Short numeric sale code, for display only. |
sale_status |
string | See Sale Statuses: completed for a charge, authorized for sale_type: authorize. |
sale_type |
string | Sale type name, for example Sale; see Sale Types. |
sale_payment_method |
string | The token's payment method; it replaces any sale_payment_method you sent. |
price |
integer | Sale amount in minor units. |
currency |
string | Sale currency (ISO 4217). |
transaction_id |
string | Your order reference, as sent. |
is_token_sale |
boolean | false: this charge isn't a token-saving sale. |
payme_signature |
string | Signature, computed as described on Callbacks. |
payme_transaction_id |
string | PayMe's ID for this charge. |
payme_transaction_total |
integer | Amount of this transaction, in minor units. |
payme_transaction_auth_number |
string | Authorization number from the card company. |
buyer_card_mask |
string | First 6 and last 4 digits of the card. |
installments |
integer | Number of installments. |
sale_paid_date |
string | When the payment happened. |
sale_3ds |
boolean | Whether 3D Secure was used. |
{
"status_code": 0,
"payme_status": "success",
"status_error_code": 0,
"payme_sale_id": "SALE1700-000000AA-EXAMPLE1-SALE0001",
"payme_sale_code": 12345678,
"sale_status": "completed",
"sale_type": "Sale",
"sale_payment_method": "credit-card",
"price": 1000,
"currency": "ILS",
"transaction_id": "order-1001",
"is_token_sale": false,
"payme_signature": "f8ffc5bb45fe6c3ad326c439f1a21c28",
"payme_transaction_id": "TRAN1700-000000AA-EXAMPLE1-TXN00001",
"payme_transaction_total": 1000,
"payme_transaction_auth_number": "0123456",
"buyer_card_mask": "455743******3431",
"installments": 1,
"sale_paid_date": "2026-11-09 10:15:02",
"sale_3ds": false
}
200 — Declined. A declined token charge returns HTTP 200; check status_code. (error)
| Field | Type | Description |
|---|---|---|
status_code |
integer | 1: the charge failed. |
status_error_code |
integer | Decline or error code, for example 20004; see Errors. |
status_error_details |
string | The message, in the requested language. |
payme_sale_id |
string | The sale this call created. |
{
"status_code": 1,
"status_error_code": 20004,
"status_error_details": "Refusal by credit company. Please try a different card",
"payme_sale_id": "SALE1700-000000AA-EXAMPLE1-SALE0001",
"sale_url": "https://sandbox.payme.io/sale/generate/SALE1700-000000AA-EXAMPLE1-SALE0001"
}
500 — Request refused. Most request errors return HTTP 500 with status_code: 1; some return 400, 403, 422 or 429. See Errors. (error)
| Field | Type | Description |
|---|---|---|
status_code |
integer | 1 for an error. |
status_error_code |
integer | PayMe's error code, for example 251 (seller not found) or 352 (invalid price). |
status_error_details |
string | The error message, in the requested language (Hebrew by default). |
status_additional_info |
string | Extra detail, usually the name of the field at fault. |
session |
string | Request ID. Quote it when you contact PayMe. |
{
"status_code": 1,
"status_error_details": "Seller was not found",
"status_additional_info": "seller_payme_id",
"status_error_code": 251,
"session": "AtsJ0as5"
}