Quickstart

Prerequisites

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:

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"
}

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&currency=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:

  1. Reply 200 within 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.
  2. Ignore repeats — de-duplicate on notify_type + payme_sale_id + payme_transaction_id.
  3. Verify payme_signature — the recipe is on Callbacks (section "Verifying a callback").
  4. Confirm the sale before fulfilling — treat the callback's status and amount as a notification, not proof of payment: call POST /get-sales with sale_payme_id and check sale_status and sale_price. POST /get-transactions works 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