Create a payment contract
- Sandbox:
POST https://sandbox.payme.io/api/payment-contracts
- Production:
POST https://live.payme.io/api/payment-contracts
Credentials
- Header
PayMe-Merchant-Key (API key)
Creates a contract that sends a payment to another seller (payment.type 1) or requests a payment from one (payment.type 2). PayMe asks the recipient to approve it by SMS or email; once it is approved, the payment runs on payment.due_date. See B2B payment contracts for the setup, the statuses and the callbacks.
- Authentication: send the initiator's
seller_payme_id (MPL) in the PayMe-Merchant-Key header, or as seller_payme_id in the body.
- Amounts are in minor units (
1000 = 10.00).
- Payment method: for
credit-card and il-direct-debit, send the payment method's buyer_key at the top level of the body, not inside payment. Without it, on a contract that sends a payment, PayMe charges the payer's attached card that is valid on the due date and expires last (or the last Active direct-debit authorization).
- Retries are safe: a request that repeats the initiator, recipient,
amount, currency, payment.due_date and payment.type of a contract created in the last 5 minutes (and not failed) returns that contract instead of creating a new one.
Errors
| HTTP status |
Error code |
Message |
When |
422 |
20 |
(a validation message) |
A required field is missing or a value is invalid. status_additional_info joins all the validation messages. |
400 |
252 |
Currency is not allowed for this seller |
currency isn't enabled for the initiator or the recipient. |
400 |
320 |
Currency is not supported |
il-direct-debit with a currency other than ILS. |
400 |
25 |
Please verify phone number |
recipient.phone isn't a valid mobile or international number. |
400 |
251 |
Seller was not found |
recipient.payme_id matches no seller. |
400 |
381 |
Not enough details for unique recipient identification |
Only recipient.business_code was sent and it matches no PayMe seller. Add email or phone. |
400 |
383 |
Initiator and recipient are the same |
The recipient is the initiator's own account. |
400 |
384 |
Recipient account settings problem - please contact Customer Support |
The recipient's seller account is inactive. |
400 |
389 |
The payment method isn't attached to the payer's account, please attach it or use a different one |
credit-card or il-direct-debit, and the payer has no such payment method attached. |
400 |
390 |
The credit card expiration date is lower than the payment's due date, please add another payment method |
No attached card is valid on payment.due_date. |
400 |
391 |
We didn't find any bank debits we can use for that account, please create a new one or select a different payment method |
No direct-debit authorization is Active. |
400 |
392 |
The selected payment method isn't matching the provided token |
buyer_key isn't one of the payer's attached payment methods of this payment.method. |
400 |
393 |
The contract amount is over the maximum amount for the selected payment method |
A credit-card or il-direct-debit contract over 5000000. |
400 |
394 |
The selected payment method does not match the provided token |
buyer_key sent with funds-transfer. |
500 |
1 |
Required parameter is missing |
No seller key: neither the PayMe-Merchant-Key header nor seller_payme_id in the body. status_additional_info is payme_client_key. |
500 |
251 |
Seller was not found |
The seller key is unknown. |
500 |
163 |
Account settings problem - please contact Customer Support |
The initiator's seller account is inactive. |
500 |
900 |
Please provide all required information in JSON format. Make sure to include 'Content-Type: application/json' header |
The request isn't JSON. |
Parameters
| Name |
In |
Type |
Required |
Description |
PayMe-Merchant-Key |
header |
string |
yes |
The initiator's seller_payme_id (MPL). You can send seller_payme_id in the JSON body instead. |
Request body
Content type: application/json
| Field |
Type |
Required |
Description |
description |
string |
yes |
What the payment is for, for example an invoice number. The recipient sees it. |
amount |
integer |
yes |
Amount in minor units (1000 = 10.00). At least 1. credit-card and il-direct-debit contracts: at most 5000000 (error 393). |
currency |
string |
yes |
The currency, as a 3-letter ISO 4217 code: ILS, USD, EUR, GBP, TRY, CHF, SEK, NOK, CAD, ZAR, JPY, AUD, AED, ARS, BHD, BRL, CNY, INR, KRW, KWD, KZT, MXN, NGN, PLN, RON, RUB, SAR, UAH, PHP, VND or HKD. It must be enabled for both sellers on the contract, otherwise the call returns error 252. il-direct-debit supports only ILS. |
buyer_key |
string |
no |
The payment method to charge: a buyer_key from seller_credit_cards or seller_bank_authorizations of get-sellers for the payer. Send it at the top level, not inside payment. Only for credit-card and il-direct-debit; with funds-transfer it returns error 394. If you omit it on a contract that sends a payment, PayMe charges the attached card that is valid on payment.due_date and expires last, or the last Active direct-debit authorization. |
remote_id |
string |
no |
Your own reference for the contract: letters, digits, - and _. PayMe doesn't check that it is unique. |
callback_url |
string |
no |
A valid URL that receives a callback on every status change. See Callbacks. |
recipient |
object |
yes |
Who receives the payment (payment.type 1) or is asked to pay (payment.type 2). Send at least one of payme_id, business_code, email or phone; PayMe uses them to find the recipient's PayMe seller account. If no seller matches, PayMe still sends the approval request to the email or phone, and the recipient opens a PayMe account when approving. To target one specific seller, send payme_id alone. |
recipient.payme_id |
string |
no |
The recipient's seller_payme_id (MPL), or the seller_payme_id_checksum from List previous recipients. When you send it, send no other recipient field (validation error otherwise). |
recipient.business_code |
integer |
no |
The recipient's business number. If it is the only identifier you send, it must match a PayMe seller (error 381 otherwise). |
recipient.email |
string |
no |
The recipient's email address. PayMe sends the approval request here and uses it to find the recipient's seller account. |
recipient.phone |
string |
no |
The recipient's mobile number: an Israeli mobile number (e.g. 0500000001) or an international number with its country code. PayMe sends the approval request here by SMS and uses it to find the recipient's seller account. An invalid number returns error 25. |
recipient.name |
string |
no |
The recipient's name. Returned by List previous recipients. |
recipient.language |
string |
no |
The language of the notifications sent to the recipient: he or en. Default: he. If the recipient already has a PayMe seller account, that account's language is used instead. |
payment |
object |
yes |
The payment details. |
payment.type |
integer |
yes |
1 – the initiator sends a payment to the recipient; 2 – the initiator requests a payment from the recipient. |
payment.method |
string |
yes |
funds-transfer – from the payer's PayMe balance; credit-card – an attached card; il-direct-debit – an attached Israeli direct-debit authorization (ILS only). |
payment.due_date |
string |
yes |
When the payment runs, YYYY-MM-DD HH:MM:SS. Must be in the future. |
payment.recurring |
object |
no |
Send it to repeat the payment. The contract is recurring only when both fields are sent. |
payment.recurring.frequency_type |
integer |
no |
How often the payment repeats: 1 day, 2 week, 3 month, 4 year, 5 quarter. |
payment.recurring.iterations |
integer |
no |
Number of payments, 1 to 54. Required when you send frequency_type. |
Request example
{
"description": "December payment",
"amount": 500000,
"currency": "ILS",
"buyer_key": "BUYERDEMO-BUYERDEMO-BUYERDEMO-1234567",
"remote_id": "INV-2026-12",
"callback_url": "https://www.example.com/callback",
"recipient": {
"business_code": 515555555,
"email": "supplier@example.com",
"phone": "0500000001",
"name": "Example Supplies Ltd",
"language": "en"
},
"payment": {
"type": 1,
"method": "credit-card",
"due_date": "2026-12-22 10:00:00"
}
}
Code samples
curl
curl -X POST 'https://sandbox.payme.io/api/payment-contracts' \
-H 'Content-Type: application/json' \
-H 'PayMe-Merchant-Key: <PayMe-Merchant-Key>' \
--data-raw '{
"description": "December payment",
"amount": 500000,
"currency": "ILS",
"buyer_key": "BUYERDEMO-BUYERDEMO-BUYERDEMO-1234567",
"remote_id": "INV-2026-12",
"callback_url": "https://www.example.com/callback",
"recipient": {
"business_code": 515555555,
"email": "supplier@example.com",
"phone": "0500000001",
"name": "Example Supplies Ltd",
"language": "en"
},
"payment": {
"type": 1,
"method": "credit-card",
"due_date": "2026-12-22 10:00:00"
}
}'
Node.js
const response = await fetch("https://sandbox.payme.io/api/payment-contracts", {
method: "POST",
headers: {
"Content-Type": "application/json",
"PayMe-Merchant-Key": "<PayMe-Merchant-Key>",
},
body: JSON.stringify({
"description": "December payment",
"amount": 500000,
"currency": "ILS",
"buyer_key": "BUYERDEMO-BUYERDEMO-BUYERDEMO-1234567",
"remote_id": "INV-2026-12",
"callback_url": "https://www.example.com/callback",
"recipient": {
"business_code": 515555555,
"email": "supplier@example.com",
"phone": "0500000001",
"name": "Example Supplies Ltd",
"language": "en"
},
"payment": {
"type": 1,
"method": "credit-card",
"due_date": "2026-12-22 10:00:00"
}
}),
});
console.log(await response.text());
Python
import requests
response = requests.post(
"https://sandbox.payme.io/api/payment-contracts",
headers={
"PayMe-Merchant-Key": "<PayMe-Merchant-Key>",
},
json={
"description": "December payment",
"amount": 500000,
"currency": "ILS",
"buyer_key": "BUYERDEMO-BUYERDEMO-BUYERDEMO-1234567",
"remote_id": "INV-2026-12",
"callback_url": "https://www.example.com/callback",
"recipient": {
"business_code": 515555555,
"email": "supplier@example.com",
"phone": "0500000001",
"name": "Example Supplies Ltd",
"language": "en",
},
"payment": {
"type": 1,
"method": "credit-card",
"due_date": "2026-12-22 10:00:00",
},
},
)
print(response.text)
PHP
<?php
$body = <<<'BODY'
{
"description": "December payment",
"amount": 500000,
"currency": "ILS",
"buyer_key": "BUYERDEMO-BUYERDEMO-BUYERDEMO-1234567",
"remote_id": "INV-2026-12",
"callback_url": "https://www.example.com/callback",
"recipient": {
"business_code": 515555555,
"email": "supplier@example.com",
"phone": "0500000001",
"name": "Example Supplies Ltd",
"language": "en"
},
"payment": {
"type": 1,
"method": "credit-card",
"due_date": "2026-12-22 10:00:00"
}
}
BODY;
$ch = curl_init('https://sandbox.payme.io/api/payment-contracts');
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'POST',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
'Content-Type: application/json',
'PayMe-Merchant-Key: <PayMe-Merchant-Key>',
],
CURLOPT_POSTFIELDS => $body,
]);
$response = curl_exec($ch);
curl_close($ch);
echo $response;
Responses
201 — The contract was created (or, on a retry within 5 minutes, the existing contract is returned). The contract fields appear at the top level and again under data. (success)
| Field |
Type |
Description |
status_code |
integer |
0 on success. |
session |
string |
PayMe session ID. Quote it when you contact PayMe support. |
id |
integer |
PayMe's numeric ID of the contract. |
guid |
string |
The contract ID (CONT…). Use it in the contract URLs, e.g. /payment-contracts/{guid}/invoices. |
description |
string |
What the payment is for, as sent. |
seller_payme_id |
string |
The initiator's seller_payme_id (MPL). |
remote_id |
string |
Your reference, as sent. null if you didn't send one. |
created_date |
string |
When the contract was created, YYYY-MM-DD HH:MM:SS. |
confirmed_by_recipient_date |
string |
When the recipient approved, YYYY-MM-DD HH:MM:SS. null until then. |
confirmed_by_initiator_date |
string |
When the initiator side was confirmed, YYYY-MM-DD HH:MM:SS. null until then. |
resolution_date |
string |
Reserved. Currently always null. |
status |
integer |
Contract status: 1 initial, waiting for the recipient; 2 recipient confirmed (moves to 3 at once); 3 approved, waiting for the due date; 4 completed; 5 failed or cancelled (see error_code). |
amount |
integer |
Amount in minor units (1000 = 10.00). |
currency |
string |
ISO 4217 currency code, e.g. ILS. |
payme_signature |
string |
Lowercase hex MD5 of the partner's client key, the partner's client password and the contract guid, joined with no separator. See Callbacks. |
fast_reconciliation |
boolean |
PayMe-internal processing flag. false for contracts created as described in these pages. |
error_code |
integer |
Why the contract failed: 11000–11004, listed on B2B payment contracts. null while the contract hasn't failed. |
error_note |
string |
Free text about the failure, such as the cancellation note or the payment error message. null otherwise. |
error_text |
string |
The name of error_code, e.g. Recipient Rejected. null otherwise. |
recipient |
object |
The recipient details exactly as you sent them (only the keys you sent appear), plus local_name and intl_name. |
recipient.payme_id |
string |
As sent. |
recipient.business_code |
integer |
As sent: a number, or a string if you sent a string. |
recipient.email |
string |
As sent. |
recipient.phone |
string |
As sent. |
recipient.name |
string |
As sent. |
recipient.language |
string |
As sent. |
recipient.local_name |
string |
The recipient seller's registered business name. "" while the recipient has no PayMe seller account. |
recipient.intl_name |
string |
The recipient seller's registered business name in English. "" while the recipient has no PayMe seller account. |
payment |
object |
The payment details. |
payment.type |
integer |
1 – the initiator sends a payment; 2 – the initiator requests a payment. |
payment.method |
string |
funds-transfer, credit-card or il-direct-debit. |
payment.guarantee_type |
integer |
Used by PayMe's financing services. Ignore it. |
payment.due_date |
string |
When the payment runs, YYYY-MM-DD HH:MM:SS. |
payment.recurring |
object |
Repetition of the payment. Both fields are null on a one-time contract. |
payment.recurring.frequency_type |
integer |
1 day, 2 week, 3 month, 4 year, 5 quarter. |
payment.recurring.iterations |
integer |
Number of payments. |
data |
object |
The same contract fields as the top level, repeated. |
{
"status_code": 0,
"session": "FhT3aXe7",
"id": 63,
"guid": "CONT1700-000000AA-EXAMPLE1-CONT0001",
"description": "December payment",
"seller_payme_id": "MPLDEMO-MPLDEMO-MPLDEMO-1234567",
"remote_id": "INV-2026-12",
"created_date": "2026-11-09 12:00:13",
"confirmed_by_recipient_date": null,
"confirmed_by_initiator_date": null,
"resolution_date": null,
"status": 1,
"amount": 500000,
"currency": "ILS",
"payme_signature": "5dbf1885ce1d4e082757a2cd6086edd1",
"fast_reconciliation": false,
"error_code": null,
"error_note": null,
"error_text": null,
"recipient": {
"business_code": 515555555,
"email": "supplier@example.com",
"phone": "0500000001",
"name": "Example Supplies Ltd",
"language": "en",
"local_name": "",
"intl_name": ""
},
"payment": {
"type": 1,
"method": "credit-card",
"guarantee_type": null,
"due_date": "2026-12-22 10:00:00",
"recurring": {
"frequency_type": null,
"iterations": null
}
},
"data": {
"id": 63,
"guid": "CONT1700-000000AA-EXAMPLE1-CONT0001",
"description": "December payment",
"seller_payme_id": "MPLDEMO-MPLDEMO-MPLDEMO-1234567",
"remote_id": "INV-2026-12",
"created_date": "2026-11-09 12:00:13",
"confirmed_by_recipient_date": null,
"confirmed_by_initiator_date": null,
"resolution_date": null,
"status": 1,
"amount": 500000,
"currency": "ILS",
"payme_signature": "5dbf1885ce1d4e082757a2cd6086edd1",
"fast_reconciliation": false,
"error_code": null,
"error_note": null,
"error_text": null,
"recipient": {
"business_code": 515555555,
"email": "supplier@example.com",
"phone": "0500000001",
"name": "Example Supplies Ltd",
"language": "en",
"local_name": "",
"intl_name": ""
},
"payment": {
"type": 1,
"method": "credit-card",
"guarantee_type": null,
"due_date": "2026-12-22 10:00:00",
"recurring": {
"frequency_type": null,
"iterations": null
}
}
}
}
422 — Validation error: a required field is missing or a value is invalid. (error)
| Field |
Type |
Description |
status_code |
integer |
1 on failure. |
status_error_details |
string |
The error message. |
status_additional_info |
string |
More detail, such as the field or value that failed. On 422, every validation message, joined with spaces. |
status_error_code |
integer |
PayMe error code. See the error table above. |
session |
string |
PayMe session ID. Quote it when you contact PayMe support. |
{
"status_code": 1,
"status_error_details": "The payment.method field is required.",
"status_additional_info": "The payment.method field is required.",
"status_error_code": 20,
"session": "FhT3aXe7"
}
400 — The request is valid but can't be carried out. See the error table above. (error)
| Field |
Type |
Description |
status_code |
integer |
1 on failure. |
status_error_details |
string |
The error message. |
status_additional_info |
string |
More detail, such as the field or value that failed. On 422, every validation message, joined with spaces. |
status_error_code |
integer |
PayMe error code. See the error table above. |
session |
string |
PayMe session ID. Quote it when you contact PayMe support. |
{
"status_code": 1,
"status_error_details": "The contract amount is over the maximum amount for the selected payment method",
"status_additional_info": "Max amount 5000000",
"status_error_code": 393,
"session": "FhT3aXe7"
}
500 — No seller key, an unknown or inactive seller, or a body that isn't JSON. (error)
| Field |
Type |
Description |
status_code |
integer |
1 on failure. |
status_error_details |
string |
The error message. |
status_additional_info |
string |
More detail, such as the field or value that failed. On 422, every validation message, joined with spaces. |
status_error_code |
integer |
PayMe error code. See the error table above. |
session |
string |
PayMe session ID. Quote it when you contact PayMe support. |
{
"status_code": 1,
"status_error_details": "Required parameter is missing",
"status_additional_info": "payme_client_key",
"status_error_code": 1,
"session": "FhT3aXe7"
}