Quickstart
Prerequisites
- Sandbox seller_payme_id (MPL)
- A public HTTPS URL that can receive POST requests (not localhost or a private IP)
Related
Your first sale in the sandbox: you will create a sale, pay it as a buyer, receive PayMe's callback, and refund it. Every field below comes from the endpoint pages linked in each step.
You need:
- a sandbox
seller_payme_id(MPL) — see Authentication. Keep it on your server: on its own it authenticates seller-level calls; - a public URL that accepts
POSTrequests, for the callback. It may not belocalhostor a private IP address; use HTTPS.
Getting sandbox credentials. If you already have a PayMe account, open the test account from the dashboard: click your name at the top → Switch to test account → Create test account. A developer with no account registers at https://paid.co.il → "הרשמה" (Register), then opens the test account from the dashboard as above. The "התנסות" (Try it out) button opens a shared demo, not your own sandbox: it has no keys of your own. The sandbox is free and asks for no signatures. Your keys, your MPL (seller_payme_id, with a test/production toggle), both base URLs and the Hosted Fields JSAPI credentials are on one dashboard page: Admin → API & Integration (API ואינטגרציה). If that page is missing, install the API service from the dashboard app store (חנות אפליקציות) first; depending on your account it may carry a charge. Partners receive payme_client_key from PayMe Partners (partners@payme.io); it is never issued to individual sellers. Integration questions: partners@payme.io.
Step 1 — Create the sale
Endpoint: POST /generate-sale. No payment happens yet.
curl -X POST https://sandbox.payme.io/api/generate-sale \
-H 'Content-Type: application/json' \
-d '{
"seller_payme_id": "MPLDEMO-MPLDEMO-MPLDEMO-1234567",
"sale_price": 1000,
"currency": "ILS",
"product_name": "Test order",
"transaction_id": "order-1001",
"installments": "1",
"sale_callback_url": "https://your-server.example.com/payme/callback",
"sale_return_url": "https://your-site.example.com/payment/success",
"language": "en"
}'
| Field | Meaning |
|---|---|
seller_payme_id |
Your MPL. Required. |
sale_price |
Price in minor units: 1000 = 10.00. Default allowed range 500–4000000, in every currency (so 500 is 5.00 ILS but 500 JPY). Required. |
currency |
3-letter ISO 4217 code, enabled on your account. Required. |
product_name |
Short product description, up to 500 characters. Required. |
transaction_id |
Your own order ID, for correlation with PayMe. Optional. |
installments |
1–12 fixed, or 1NN (102–112) to let the buyer choose up to NN, for example 106 for up to 6. Optional, default 1. More than 12 can be enabled for your account on request. |
sale_callback_url |
Where PayMe sends the server-to-server callback. 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. |
sale_return_url |
Where the buyer is redirected after paying. If omitted, your partner's default return URL is used, if one is set. |
language |
Payment page and error-message language. If omitted, messages are in Hebrew — always send "en" while integrating. |
sale_price and installments accept a number or a numeric string (1000 or "1000", 1 or "1"). A non-numeric sale_price returns error 352; a non-numeric installments returns error 10. A decimal sale_price is rounded to whole minor units.
Successful response (for the request above):
{
"status_code": 0,
"sale_url": "https://sandbox.payme.io/sale/generate/XXXXXXXX-XXXXXXXX-XXXXXXXX-XXXXXXXX",
"payme_sale_id": "XXXXXXXX-XXXXXXXX-XXXXXXXX-XXXXXXXX",
"payme_sale_code": 12345678,
"price": 1000,
"transaction_id": "order-1001",
"currency": "ILS",
"sale_payment_method": "credit-card"
}
status_code0means success,1means error.- Save
payme_sale_id(PayMe's sale ID) next to yourtransaction_id. You need it to refund. - Responses also carry a
sessionvalue; quote it when you contact PayMe. - If
status_codeis1, readstatus_error_codeandstatus_error_details— see Errors. Errors usually come back with HTTP 500, so checkstatus_code, not the HTTP status. - PayMe does not de-duplicate
transaction_id: sending this request twice creates two sales.
Step 2 — Pay as the buyer
Open sale_url in a browser (or an IFRAME). Pay with a sandbox test card, for example:
| Card number | Expiry | CVV | Social ID |
|---|---|---|---|
5326105300985846 |
12/30 |
658 |
008336174 |
This is a local Israeli card that accepts ILS only. Other cards, including cards that force a decline, are on Test Cards and Payment Methods.
You can pre-fill buyer details by appending query parameters to sale_url, for example ?first_name=First&last_name=Last&email=test@example.com. Card fields cannot be pre-filled.
Use sale_url exactly as returned. It has no fixed expiry: it works while the sale is initial, and after a declined attempt, when the sale is failed and a good card can still complete it.
To try a decline, pay with 4000000000000002: the result is HTTP 200 with status_code: 1 and error 20004. Other decline cards are on Test Cards and Payment Methods.
After a successful payment the buyer is redirected (GET) to your sale_return_url with the sale details as query parameters:
https://your-site.example.com/payment/success?payme_status=success&payme_signature=75e99dbcb25cdfbe1c62f0b9376f4144&payme_sale_id=XXXXXXXX-XXXXXXXX-XXXXXXXX-XXXXXXXX&payme_transaction_id=XXXXXXXX-XXXXXXXX-XXXXXXXX-XXXXXXXX&price=1000¤cy=ILS&transaction_id=order-1001&is_token_sale=0&is_foreign_card=0
Use the redirect only to show the buyer a result page. Use the callback (step 3) to update your order.
Step 3 — Receive the callback
When the sale is paid, PayMe sends a POST with an x-www-form-urlencoded body to sale_callback_url. Key fields:
| Field | Example | Meaning |
|---|---|---|
notify_type |
sale-complete |
What happened. See Callbacks. |
status_code |
0 |
0 success, 1 error |
payme_sale_id |
XXXXXXXX-… |
PayMe's sale ID |
transaction_id |
order-1001 |
Your order ID |
sale_status |
completed |
See Sale Statuses |
price, currency |
1000, ILS |
Amount in minor units and currency |
payme_signature |
75e99dbcb25cdfbe1c62f0b9376f4144 |
Signature |
To test your handler before you have a sandbox account, send yourself a callback with the documented shape:
curl -X POST https://your-server.example.com/payme/callback \
-H 'Content-Type: application/x-www-form-urlencoded' \
--data-urlencode 'status_code=0' \
--data-urlencode 'notify_type=sale-complete' \
--data-urlencode 'sale_created=2016-01-01 15:15:15' \
--data-urlencode 'transaction_id=order-1001' \
--data-urlencode 'payme_sale_id=XXXXXXXX-XXXXXXXX-XXXXXXXX-XXXXXXXX' \
--data-urlencode 'payme_sale_code=12345678' \
--data-urlencode 'payme_transaction_id=XXXXXXXX-XXXXXXXX-XXXXXXXX-XXXXXXXX' \
--data-urlencode 'price=1000' \
--data-urlencode 'currency=ILS' \
--data-urlencode 'sale_status=completed' \
--data-urlencode 'installments=1' \
--data-urlencode 'is_token_sale=0' \
--data-urlencode 'payme_signature=75e99dbcb25cdfbe1c62f0b9376f4144'
Your handler should:
- Reply
200within 5 seconds. Any status below 400 counts as delivered; anything else, or a timeout, makes PayMe retry — up to 3 attempts in total, then the callback is dropped. - Ignore repeats — de-duplicate on
notify_type+payme_sale_id+payme_transaction_id. - Verify
payme_signature— the recipe is on Callbacks (section "Verifying a callback"). - Confirm the sale before fulfilling — treat the callback's status and amount as a notification, not proof of payment: call
POST /get-saleswithsale_payme_idand checksale_statusandsale_price.POST /get-transactionsworks too, and shows each charge and refund as a row.
Step 4 — Refund the sale
Endpoint: POST /refund-sale. Omit sale_refund_amount for a full refund; send it for a partial refund (minimum 500). You can refund several times as long as the total does not exceed the sale amount.
curl -X POST https://sandbox.payme.io/api/refund-sale \
-H 'Content-Type: application/json' \
-d '{
"seller_payme_id": "MPLDEMO-MPLDEMO-MPLDEMO-1234567",
"payme_sale_id": "SALEDEMO-XXXXXXXX-XXXXXXXX-XXXXXXXX",
"sale_refund_amount": 500,
"language": "en"
}'
payme_client_key is not needed here: a merchant can refund with seller_payme_id alone. Partners (platforms) may also send their payme_client_key, in which case the seller must belong to that partner.
Successful response (abridged):
{
"status_code": 0,
"status_error_code": 0,
"payme_status": "success",
"sale_status": "partial-refund",
"sale_refund_buffer": 500,
"payme_transaction_total": 500,
"payme_transaction_id": "TRANDEMO-XXXXXXXX-XXXXXXXX-XXXXXXXX",
"payme_signature": "b71e**************ca5a"
}
PayMe also sends a callback with notify_type refund to the callback URL; its payme_transaction_total is the amount of this refund and sale_refund_buffer the amount still refundable.
Do not blindly retry a refund that timed out: a repeated partial refund runs again and refunds a second time. Read Idempotency and retries first.
Next steps
- Callbacks — every notification type and how to handle it.
- Errors — error codes and messages.
- To charge a saved card later, see Save a card and charge it later; to authorize now and capture later, see Capture sale.