# Payments - [Accepting Payments](https://docs.payme.io/payments/accepting-payments): Hosted Payment Page, Hosted Fields - JSAPI, Direct API, iOS SDK, Android SDK, Point of Sale (POS), Post Sale Actions # Accepting Payments Choose how the buyer's card details reach PayMe, then manage the sale after payment: refund it, void or capture an authorization, or cancel a template sale. Not sure which integration fits? Compare them on [Integration options](https://docs.payme.io/payments/getting-started/integration-options). - [Wallets & APMs](https://docs.payme.io/payments/wallets-apms): Apple Pay, Google Pay, IL Direct Debit # Wallets & APMs Choose the payment method with `sale_payment_method` in [generate-sale](https://docs.payme.io/payments/hosted-payment-page/post-generate-sale). This table lists the values you can send, cards included. The sections below cover the wallets and alternative payment methods that have their own setup. | Payment method | Type | `sale_payment_method` | |---|---|---| | Credit card | Card payment | `credit-card` | | Multi | The buyer chooses among the methods enabled on the account. See [Let the buyer choose how to pay](https://docs.payme.io/accepting-payments/checkout-and-in-person/let-the-buyer-choose) | `multi` | | Bank transfer | Bank transfer | `bank-transfer` | | PayPal | Card or wallet. See [Accept PayPal payments](https://docs.payme.io/accepting-payments/payment-methods/paypal) | `paypal` | | Alipay QR | Wallet | `alipay-qr` | | Alipay Online | Wallet | `alipay-online` | | Funds transfer | Bank transfer | `funds-transfer` | | Cash | Cash | `cash` | | Cheque | Cheque | `cheque` | | eCheck | Online bank transfer | `echeck` | | Bit | Wallet. See [Accept Bit payments](https://docs.payme.io/accepting-payments/payment-methods/bit) | `bit` | | BACS | Online bank transfer | `bacs` | | SEPA | Online bank transfer | `sepa` | | Apple Pay | Wallet | `apple-pay` | | IL Direct Debit | Online bank transfer | `il-direct-debit` | | Verifone Prepaid | Prepaid card | `verifone-prepaid` | | Google Pay | Wallet | `google-pay` | Installments are available only for card payments: with `sale_payment_method` `credit-card`, `multi` or `pos`. Any other method with more than one installment returns error `351`. On a `multi` page that lets the buyer choose the number of installments, a buyer who pays with Apple Pay or Google Pay pays in a single payment. A seller installs Apple Pay, Google Pay or Bit from the dashboard app store (חנות אפליקציות); a partner enables them with `vas-enable`. See [Enable payment methods and services for your sellers](https://docs.payme.io/marketplaces-and-platforms/seller-onboarding/enable-services). ## The method actually used on a `multi` sale When a sale is opened with `multi`, `sale_payment_method` keeps the value `multi` even after payment; that is by design. To see what the buyer paid with, read `transaction_payment_method` on the transaction from [`get-transactions`](https://docs.payme.io/payments/query-apis/post-get-transactions): `credit-card`, `bit`, `apple-pay`, `google-pay` or another supported method. - [Saved Cards & Recurring](https://docs.payme.io/payments/saved-cards-recurring): Tokenization, Subscriptions # Saved Cards & Recurring Save a buyer's card as a token to charge it again later, on its own or on a schedule with subscriptions. Step-by-step guides: [Save a card and charge it later](https://docs.payme.io/accepting-payments/capture-and-saved-cards/save-a-card-and-charge-it-later) and [Build recurring billing with subscriptions](https://docs.payme.io/accepting-payments/capture-and-saved-cards/build-recurring-billing). Endpoint reference: [Generate](https://docs.payme.io/payments/subscriptions/post-generate-subscription), [Pay](https://docs.payme.io/payments/subscriptions/post-generate-subscription-2), [Cancel](https://docs.payme.io/payments/subscriptions/postcancel-subscription), [Pause](https://docs.payme.io/payments/subscriptions/post-pause-subscription), [Resume](https://docs.payme.io/payments/subscriptions/patch-subscriptions-sub-payme-id-resume), [Update Price](https://docs.payme.io/payments/subscriptions/patch-subscriptions-sub-id-set-price), [List Subscriptions](https://docs.payme.io/payments/query-apis/post-get-subscriptions). Statuses: [Subscription Statuses](https://docs.payme.io/payments/codes-statuses/subscription-statuses). ## How charging works - A subscription created with `generate-subscription` starts in status `1` (initial). Entering the card on `sub_url` activates it (status `2`) and saves the card. - PayMe's billing engine checks active subscriptions continuously and charges a subscription when its `sub_next_date` arrives. After a successful charge the iteration counter advances and `sub_next_date` is recomputed from `sub_iteration_type`. The next charge date is always readable on the subscription object. - The charge itself, including the first one, is made by a background job that runs once a minute. A first charge up to about 60 seconds after the card is entered is normal; there is no mode in which the first charge happens inside the card-entry request. - The first charge date is `sub_start_date` (default: today). A monthly subscription must start on a day between 1 and 28. - Each successful charge creates a sale with its own `payme_sale_id`. ## Failed charges and retries - If the card-validation transaction fails when the buyer pays the subscription, the subscription moves to status `4` (failed) and PayMe sends `sub-failure`. PayMe does not retry this step. You can pay the subscription again with `pay-subscription`. - A failed scheduled charge, including the first one, moves the subscription to status `7` (failed, pending automatic retry) and pushes `sub_next_date` one day ahead, but only when another attempt is allowed. A daily subscription, and the seventh consecutive failure, instead move to status `5` and send `sub-cancel`, without `sub-failure`. - Retries run **once a day**. At most **7 attempts** are made (the original plus 6 retries); after the last failure the subscription is cancelled automatically: `sub_status` becomes `5` and `sub_next_date` becomes `null`. - A **daily** subscription (`sub_iteration_type` `1`) is not retried: it is cancelled on its first failure. - The 7-attempt limit is a fixed system setting and cannot be changed per account or per subscription. - This charge retry is separate from the callback *delivery* retry (3 attempts within about 90 seconds), described on [Callbacks](https://docs.payme.io/payments/getting-started/callbacks). - To re-run a failed iteration yourself, call [`pay-subscription`](https://docs.payme.io/payments/subscriptions/post-generate-subscription-2) with `sub_payme_id`. It works only while the status is initial, failed or failed-retry, and a lock prevents a double run: an active subscription is never charged again by it. ## Subscription callbacks Set `sub_callback_url` on `generate-subscription`. If it is empty, the account's default callback URL is used (the same `merchant_callback_url` that serves as the fallback for sale callbacks). - `sub-iteration-success` is sent after every successful charge (first, regular or after a retry) and carries `payme_sale_id` and `payme_sale_code`. Its body is identical whether or not a failure came before it. The time of a successful charge is `sub_prev_date`. - `sub-failure` is sent after a failed card-validation transaction when the buyer pays the subscription, and after every failed scheduled charge that leads to a retry. It is not sent for a failure that cancels the subscription; you receive `sub-cancel` instead. It carries the subscription object with `sub_error_text` (the decline text with the code in brackets). It carries **no sale id, no attempt id and no failed-attempt counter**: the iteration counters count successful charges only, and the exact time of a failed attempt is on the transaction created for that attempt. - `sub-cancel` is sent when the subscription is cancelled, by hand or automatically after the last failed attempt, with `sub_status` `5`. It always contains `notify_type`, `seller_payme_id`, `seller_id`, `sub_payme_id` and `sub_payme_code`; `subscription_id` appears only if you set it at creation. - Callback handlers must be idempotent. Re-query [`get-subscriptions`](https://docs.payme.io/payments/query-apis/post-get-subscriptions) before acting, as with sale callbacks. - All dates are Asia/Jerusalem local time. ## Tokens and `buyer_key` - To skip card entry on `sub_url`, pass an existing `buyer_key` to `generate-subscription` (not with `sub_type` template). - The token must be **permanent**: when you create it with [`capture-buyer-token`](https://docs.payme.io/payments/tokenization/post-capture-buyer-token), send `buyer_is_permanent: true`. A one-time token is rejected by the subscription. - A token saved with `capture-buyer-token` without `buyer_is_permanent: true` is single-use for any charge: the first `generate-sale` charge deactivates it, and later charges fail with error `604`. - With the Card Updater service active on the seller's account, PayMe updates saved cards when an Israeli card company reports a replacement card. - `buyer_is_private` is sent on the call that captures the card (`generate-sale` with `capture_buyer`, or `capture-buyer-token`). With `true` the token belongs to that one seller (MPL); without it the token is stored at account level and a lookup with `seller_payme_id` fails with "Merchant not allowed to use this buyer". `generate-subscription` itself does not take `buyer_is_private`. - Subscription calls and callbacks (`get-subscriptions`, the callbacks, the `generate-subscription` response) never expose the `buyer_key`; they return the card mask, name, email, phone and ID only. The one way to read the `buyer_key` of a subscription created on `sub_url` is [`get-buyer-key`](https://docs.payme.io/payments/tokenization/post-get-buyer-key) with `sub_payme_id`. `get-transactions` returns `buyer_key` for sale-type transactions only, not for subscription charges. - A one-off charge on a subscription's `buyer_key` is allowed: `generate-sale` with the `buyer_key` creates a standalone sale that does not read or change the subscription. `buyer_key` combined with `sale_type` token or template is blocked. - 3D Secure does not apply to subscription iterations, only to single transactions. ## Common flows **Charge now, then monthly, without a double charge.** Capture the card once (`capture_buyer`), charge the first payment as a one-off sale with that `buyer_key`, then call `generate-subscription` with the same `buyer_key` and `sub_start_date` in the next period. A future `sub_start_date` means no subscription charge before then. **Changing the price.** [`set-price`](https://docs.payme.io/payments/subscriptions/patch-subscriptions-sub-id-set-price) changes future charges only. It does not touch `sub_next_date`, `sub_start_date`, `sub_prev_date`, the iteration counters or the status, charges nothing, and sends the buyer an information email. The billing day stays anchored to `sub_start_date`. **Mid-cycle upgrade.** There is no built-in proration. Compute the difference ((new price minus old price) times days left divided by cycle length), charge it once with `generate-sale` and the existing `buyer_key`, then call `set-price` with the new price; the next cycle charges the full new price on the same billing day. Do not cancel and re-create the subscription: that resets `sub_start_date` and the counters. **Changing the card.** There is no `buyer_key` swap and no endpoint for an active subscription. While the status is initial, failed or failed-retry, replace the card by paying the subscription again with a new payment method: `PATCH /api/subscriptions/{sub_payme_id}` with a `payment` object, or `pay-subscription` with `sub_payme_id`. This creates a new buyer token and attaches it. **Joining a subscription link after its start date.** Nothing is charged retroactively. The first charge moves into the current period: daily today; weekly the same weekday this week; monthly the same day this month (capped at the month's length); yearly the same day and month this year. A start date still in the future is kept. **Cancelling.** End customers have no self-cancel link: the seller cancels, in the dashboard or with [`cancel-subscription`](https://docs.payme.io/payments/subscriptions/postcancel-subscription). The seller receives an email when a subscription is cancelled (by hand or automatically), on every successful charge and when it completes, subject to the account's notification settings. ## Your own reference: `subscription_id` `subscription_id` is your free-form reference (max 50 characters, alphanumeric). It is **not enforced unique**: a repeated value on `generate-subscription` creates a second subscription and is neither rejected nor returned as "existing", so de-duplicate on your side. `get-subscriptions` accepts it as a filter (a single value or an array) and returns it on each item. PayMe's own identifiers are `sub_payme_id` (the GUID used in the API) and the numeric `sub_payme_code`. ## Wallets Google Pay is for one-time payments only and cannot pay a subscription. Apple Pay can: either pass a `buyer_key` captured earlier with Apple Pay to `generate-subscription`, or create the subscription and pay it with the Apple Pay token (`pay-subscription`, or `PATCH /api/subscriptions/{sub_payme_id}` with `payment.method` `apple-pay`). Off-session Apple Pay charges need a merchant token issued when the payment runs as recurring, and PayMe-side configuration of your account: contact PayMe Partners (). `capture_buyer` on a wallet payment returns the same kind of `buyer_key` as a card. ## How to create a subscription ![image.png](https://docs.payme.io/marketplaces-and-platforms/_files/how-to-create-subscription.png) - [Documents](https://docs.payme.io/payments/documents): Invoices # Documents The Documents API creates and reads invoices, receipts and other tax documents through PayMe's invoicing service. It is deprecated: contact PayMe Partners () before building on it. To issue documents for your sales, see [Issue invoices and receipts for your sales](https://docs.payme.io/accepting-payments/after-the-sale/issue-invoices-and-receipts). - [3D Secure](https://docs.payme.io/payments/3d-secure): Generate a Sale with 3D Secure, Standalone 3D Secure service # 3D Secure Authenticate cards with 3D Secure 2, either as part of a PayMe sale or as a separate step with the standalone service when another gateway charges the card. For how 3D Secure works across every integration, see [How 3D Secure works on PayMe](https://docs.payme.io/accepting-payments/3d-secure/how-3d-secure-works). - [Platforms & Marketplaces](https://docs.payme.io/payments/platforms-marketplaces): Merchants Management, Buyers Management # Platforms & Marketplaces A partner (a platform or marketplace) creates and manages sellers through the API, takes a platform fee on their sales, and pays them out. Partner calls use your `payme_client_key` together with the seller's `seller_payme_id` (MPL). See [Authentication](https://docs.payme.io/payments/getting-started/authentication). New to this? Start with [Start here: build a platform or marketplace on PayMe](https://docs.payme.io/marketplaces-and-platforms/start-here/how-platforms-work). ## Guides - [Start here: build a platform or marketplace on PayMe](https://docs.payme.io/marketplaces-and-platforms/start-here/how-platforms-work) - [Onboard a seller, from creation to first payout](https://docs.payme.io/marketplaces-and-platforms/seller-onboarding/onboard-a-seller) - [Enable payment methods and services for your sellers](https://docs.payme.io/marketplaces-and-platforms/seller-onboarding/enable-services) - [Platform fees](https://docs.payme.io/marketplaces-and-platforms/fees-and-payouts/platform-fees) - [Withdrawals](https://docs.payme.io/marketplaces-and-platforms/fees-and-payouts/withdrawals) - [Reporting across your sellers](https://docs.payme.io/marketplaces-and-platforms/reporting/reporting-across-your-sellers) ## Default URLs When PayMe opens your partner account, you give two default URLs: | URL | Use | | --- | --- | | Callback URL | Receives seller and withdrawal callbacks, and the callbacks of sales and subscriptions created without their own callback URL, as `x-www-form-urlencoded` `POST` requests. The full rules are in [Start here: build a platform or marketplace on PayMe](https://docs.payme.io/marketplaces-and-platforms/start-here/how-platforms-work); the payloads are on [Callbacks](https://docs.payme.io/payments/getting-started/callbacks). | | Return URL | Where PayMe sends the buyer after a successful payment, unless the sale sets its own `sale_return_url`. The redirect is a `GET` request with the sale's parameters. | ## Value-added services Sellers can have value-added services (VAS), such as invoices, Apple Pay and Google Pay. To turn them on and off, see [Enable payment methods and services for your sellers](https://docs.payme.io/marketplaces-and-platforms/seller-onboarding/enable-services). To see a seller's services, call [List a seller's services](https://docs.payme.io/payments/merchants-management/post-get-vas-seller). The service types are on [VAS types](https://docs.payme.io/marketplaces-and-platforms/seller-reference/vas-types). - [Data & Reporting](https://docs.payme.io/payments/data-reporting): Query APIs, Codes & Statuses # Data & Reporting ## Guides - [Find the right data](https://docs.payme.io/accepting-payments/reporting/find-the-right-data): which query answers which business question. - [Reconcile sales and withdrawals](https://docs.payme.io/accepting-payments/reporting/reconcile-sales-and-withdrawals): match a seller's payouts to its sales. ## Getting Started - [Start Here](https://docs.payme.io/payments/getting-started/start-here): PayMe's Payments API lets platforms and merchants accept payments via a hosted payment page, hosted fields (JSAPI) or a direct API, with tokenization, subscriptions, refunds and capture, 3D Secure, invoices and POS. Read in order: Authentication, Environments (sandbox.payme.io/api, live.payme.io/api), Test Cards, Quickstart, Callbacks; then Errors and Idempotency & Retries. Requests are JSON, callbacks form-encoded; amounts in minor units (500-4000000); send language en. Other APIs: B2B Payments, Keep, Products & Customers. To build an integration, follow the AI Toolkit. ## Related - [Authentication](https://docs.payme.io/payments/getting-started/authentication) - [Environments](https://docs.payme.io/payments/getting-started/environments) - [Test Cards and Payment Methods](https://docs.payme.io/payments/getting-started/test-cards-and-payment-methods) - [Quickstart](https://docs.payme.io/payments/getting-started/quickstart) - [Callbacks](https://docs.payme.io/payments/getting-started/callbacks) - [Errors](https://docs.payme.io/payments/getting-started/errors) - [Idempotency and Retries](https://docs.payme.io/payments/getting-started/idempotency-and-retries) - [Integration Options](https://docs.payme.io/payments/getting-started/integration-options) # Start Here PayMe's Payments API is "designed to allow platforms to offer a full payment solution as part of their product." You `POST` JSON to PayMe's URLs and get JSON replies, so you can use any programming language. ## Building an integration? The [AI Toolkit](https://docs.payme.io/agents) has the whole procedure, for a person or an AI agent: your test account, the rules, each step in order, test cases and reference code, the go-live checklist and an answer for each common error. It starts by helping you choose between integrating as a [partner](https://docs.payme.io/agents/partner/payme-partner-integration) and as a [direct seller](https://docs.payme.io/agents/seller/payme-seller-integration). Start there if you are building, and use the pages here as the reference. ## Read these first Read these five pages, in this order, before you write integration code. | # | Page | What you learn | |---|------|----------------| | 1 | [Authentication](https://docs.payme.io/payments/getting-started/authentication) | Which credential goes where — `seller_payme_id` (MPL), `payme_client_key`, the public key — and how to open a sandbox account and find your keys. | | 2 | [Environments](https://docs.payme.io/payments/getting-started/environments) | Sandbox vs production base URLs, and the hosts you will see in `sale_url`, 3D Secure redirects and browser scripts. | | 3 | [Test Cards and Payment Methods](https://docs.payme.io/payments/getting-started/test-cards-and-payment-methods) | Sandbox test cards (including cards that force each decline), wallet cards, bank accounts and test-seller values. | | 4 | [Quickstart](https://docs.payme.io/payments/getting-started/quickstart) | One complete sale in the sandbox with `curl`: create a sale, pay it, receive the callback, refund it. | | 5 | [Callbacks](https://docs.payme.io/payments/getting-started/callbacks) | How PayMe notifies your server, what the payload contains, and how to handle it. | After those, read [Errors](https://docs.payme.io/payments/getting-started/errors) and [Idempotency and retries](https://docs.payme.io/payments/getting-started/idempotency-and-retries) before going live. ## Three facts that trip up most integrations 1. **Amounts are in minor units.** A price of 50.75 is sent as `5075`, and the minimum `sale_price` is `500`. 2. **Callbacks are not JSON.** PayMe sends a `POST` with an `application/x-www-form-urlencoded` body to your callback URL, even though your requests to PayMe are JSON. 3. **Error messages default to Hebrew.** Send `"language": "en"` to get English error messages. ## What PayMe offers With the Payments API you can: - create and manage merchants on your platform; - accept credit-card payments and other payment methods; - create recurring payments (subscriptions); - use hosted (secured) payment pages; - tokenize cards for delayed and future payments; - charge a platform (market) fee on each transaction; - query sellers, transactions, subscriptions and withdrawals. ### APIs in this documentation | API | What it covers | |-----|----------------| | [Payments](https://docs.payme.io/payments) | Sales (hosted payment page, hosted fields, direct API), Apple Pay, Google Pay, Israeli direct debit, tokenization, subscriptions, refunds / capture / void, 3D Secure (including a standalone 3D Secure service), invoices, point-of-sale devices, merchant management for partners, and query APIs. | | [B2B Payments](https://docs.payme.io/b2b-payments/contracts/overview) | Payment contracts (send a payment or a payment request between businesses) and transfers between wallets. | | [Keep](https://docs.payme.io/keep/partner-authorization/prerequisites) | APIs for PayMe's accounting product: sellers, income documents (invoices, receipts), expenses, tax and VAT. | | [Products and Customers](https://docs.payme.io/products-and-customers/authentication/hosts-authentication-and-errors) | Create, list, update and delete products and customers. | Mobile: open the [Hosted Payment Page](https://docs.payme.io/payments/hosted-payment-page) in a secure in-app browser. Legacy [iOS](https://docs.payme.io/payments/ios-sdk/ios-sdk) and [Android](https://docs.payme.io/payments/android-sdk/android-sdk) SDKs remain available but aren't recommended for new integrations. ## Integration options There are three ways to take a payment: the **Hosted Payment Page** (the buyer pays on PayMe's secure page, `sale_url`, shown as an IFRAME or a redirect), **Hosted Fields (JSAPI)** (payment fields embedded in your page with PayMe's JavaScript library) and the **Direct API** (your server sends card details to PayMe). [Integration Options](https://docs.payme.io/payments/getting-started/integration-options) compares them. ## Payment methods The full list of `sale_payment_method` values, with their codes, is on [Available Payment Methods](https://docs.payme.io/payments/wallets-apms). Use `multi` to let the buyer choose on one checkout page. If `sale_payment_method` is omitted, the sale is created as `credit-card`; `multi` must be sent explicitly. Card networks named in the docs: Visa, Mastercard, American Express, Diners, Discover, JCB and Isracard (test cards). Google Pay supports Visa, Mastercard, American Express, Discover and JCB. Installments: a fixed number from `1` to `12`, or `1NN` (`102`–`112`) to let the buyer choose up to NN, for example `106` for up to 6. Fixed values above 12 are accepted when the sale is created, but the payment fails unless PayMe has enabled more installments on your account. Installments are for card payments only (`credit-card` or `multi`). ## Currencies Sale currency is a 3-letter ISO 4217 code. Supported currencies, subject to your account configuration: 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, HKD. - Each account has its own allowed set; any other currency returns error `252`. - PayMe does not convert currencies: each sale is paid out in the currency it was cleared in, so there is no conversion fee. A payout in USD needs a USD bank account on the record. - ILS only: Israeli direct debit, Bit, and any sale with more than one installment. Which currencies each sandbox test card accepts is on [Test Cards and Payment Methods](https://docs.payme.io/payments/getting-started/test-cards-and-payment-methods). ## Countries The documentation is Israel-centred: Israeli bank codes, Israeli business incorporation types, Israeli social ID fields, and Israeli direct debit. Test data also exists for SEPA and BACS accounts. The payment page collects a ZIP code for cards issued in the USA, Canada and the United Kingdom. ## Amounts and limits - Default `sale_price` range: `500`–`4000000` minor units, the same in every currency and payment method (so `500` is 5.00 ILS or USD but 500 JPY). PayMe can set a different range for a partner, and it then applies to all of that partner's sellers. Out of range returns error `352`. Token sales (`sale_type` `token` or `seller-token`) are always created with a price of `100`: send any numeric `sale_price` (a missing or non-numeric value returns `352`). Token sales are not range-checked. A partial refund amount (`sale_refund_amount`) must be within the same range. - An authorization (J5) reserves funds for up to 168 hours; capture is allowed once. - Rate limit: `generate-sale`, `pay-sale`, `capture-sale` and several other payment calls share a per-seller limit; over the limit returns HTTP 429. The default values and the full list are under [Rate limits](https://docs.payme.io/payments/getting-started/idempotency-and-retries#rate-limits). PayMe can set different limits for a partner. To request a higher limit, write to ; what to include in the request is listed under [Rate limits](https://docs.payme.io/payments/getting-started/idempotency-and-retries#rate-limits). ## Compliance - With the Hosted Payment Page, responsibility for PCI DSS lies with PayMe. - With the Direct API, the merchant must meet PCI DSS level 1. PCI compliant and want to use the direct credit-card API? [Let PayMe know](https://payme.io/contact-us/). - Tokenization reduces the scope of PCI DSS requirements for recurring payments. - 3D Secure is supported, including as a standalone service. ## Contact Our [Status Page](https://status.payme.io/) is available 24/7, you can now subscribe and receive notifications regarding maintenance, issues or general updates to your inbox. - Integration and API questions: . - Help center (merchant dashboard, plugins, account questions): . - General contact form: - Adding Google Pay card networks: `support@payme.io` - Keep API keys come from your Account Manager; see [Keep prerequisites](https://docs.payme.io/keep/partner-authorization/prerequisites). ## Machine-readable docs Every page is available as Markdown by appending `.md` to its URL; each API section publishes one OpenAPI file at `///openapi.json`, and `//openapi.json` returns a 404 that lists them; the site index for AI agents is `/llms.txt`. ## Identifiers | Shape | Field | Meaning | |-------|-------|---------| | `MPL….-….-….-….` | `seller_payme_id` | The seller (merchant) identifier, also called the MPL. It is an identifier that authenticates seller-level calls, not an API key, but treat it as a credential. | | `SALE….` | `payme_sale_id` | Sale ID; `payme_sale_code` is its short numeric form. | | `SUB….` | `sub_payme_id` | Subscription ID; `sub_payme_code` is its short numeric form. | | `BUYER….` | `buyer_key` | Saved-card token. Secret: encrypt it at rest; it replaces the card number. | | `TRAN….` | `payme_transaction_id` | Transaction ID (reporting, withdrawals). | | `VASL….` | `vas_payme_id` | Value-added-service ID. | | free string | `transaction_id`, `subscription_id` | Your own references, echoed back. Not enforced unique. | | `411111******1111` | `buyer_card_mask` | First 6 and last 4 digits of the card. | - [Authentication](https://docs.payme.io/payments/getting-started/authentication): Payments API requests carry credentials in the JSON body, not an Authorization header. seller_payme_id (the MPL) identifies and authenticates the seller on its own, so keep it server-side. payme_client_key is the partner (platform) key held only by partners; merchants can call refund-sale without it. The per-seller public key (PayMe-Public-Key) is for browser code. Sandbox and production keys are separate. Keep, B2B Payments and Products & Customers authentication is documented with those APIs. ## Related - [Environments](https://docs.payme.io/payments/getting-started/environments) - [Quickstart](https://docs.payme.io/payments/getting-started/quickstart) - [Callbacks](https://docs.payme.io/payments/getting-started/callbacks) - [Authorization Flow](https://docs.payme.io/keep/partner-authorization/authorization-flow) - [Authentication](https://docs.payme.io/products-and-customers/authentication) - [Contracts](https://docs.payme.io/b2b-payments/contracts) # Authentication The Payments API does **not** use an `Authorization` header. You identify yourself with keys inside the JSON request body (and, on some endpoints, in custom headers). Always send `Content-Type: application/json`. ## The credentials at a glance | Credential | Who has it | What it does | Where it goes | Keep it | |------------|-----------|--------------|---------------|---------| | `seller_payme_id` (the **MPL**) | Every seller (merchant) | Identifies the seller **and, on its own, authenticates** most seller-level calls: creating sales, refunding, querying sales, updating the seller. | JSON body field `seller_payme_id` (required in the body on `generate-sale`), or header `PayMe-Merchant-Key` on the endpoints listed under *Header-based endpoints* | **Secret** — server-side only | | `payme_client_key` | **Partners** (platforms and marketplaces) only | The partner key. Needed for partner-level calls such as creating sellers and querying across sellers. | JSON body field `payme_client_key`, or header `PayMe-Partner-Key` | **Secret** — server-side only | | Public key | Every seller; one per seller per environment | Designed for browser code: tokenizing cards (Hosted Fields), Apple Pay and Google Pay flows, and reading a filtered list of the seller's transactions. | Header `PayMe-Public-Key`; first argument of `PayMe.create(apiKey, …)` | May be exposed in the browser — but note it can read transactions | Example MPL format: `MPLDEMO-MPLDEMO-MPLDEMO-1234567`. **`seller_payme_secret` is not a credential.** `create-seller` returns it, but it is a random value that PayMe never stores or checks. Ignore it. ## Merchants and partners - **A merchant** (a single seller) authenticates with `seller_payme_id`. It can call `refund-sale` with `seller_payme_id` alone — PayMe finds the partner from the seller. - **A partner** (a platform managing many sellers) also holds `payme_client_key`, sent in the body or the `PayMe-Partner-Key` header. If a partner sends both keys, the seller must belong to that partner; otherwise the request fails with error `20` ("Merchant-Seller inconsistency"). A partner can also identify the seller by the `seller_id` it set when creating the seller, together with `payme_client_key`. Partner-only endpoints documented with `payme_client_key` include `create-seller`, `update-seller`, `upload-seller-files`, `get-vas-seller`, `vas-enable`, `vas-disable`, and POS `authenticate` and `pair`. `withdraw-balance` takes either a partner's `payme_client_key` with the seller's `seller_payme_id`, or the seller's own `seller_payme_id`. The query APIs `get-sales`, `get-subscriptions`, `get-sellers` and `get-withdrawals` are not partner-only. A partner sends `payme_client_key` (or the `PayMe-Partner-Key` header). A seller without a partner key sends `seller_payme_id` in the JSON body; results are limited to that seller. `merchant_key` and `merchant_password` do not exist on a seller account: they are partner-level credentials. A seller that puts its own MPL in `payme_client_key` gets HTTP 500 with code `200` "Merchant was not found": remove the field and send `seller_payme_id` alone. Error codes you may see while setting up keys: `1` — no key sent at all; `200` — the `payme_client_key` matches no partner; `201` — the partner is inactive; `251` — the `seller_payme_id` matches no seller; `163` — the seller is inactive. ### Header-based endpoints | Header | Carries | Used on (examples) | |--------|---------|--------------------| | `PayMe-Merchant-Key` | The seller's MPL | `GET /buyers/{buyer_guid}`, `GET /documents`, 3D Secure hash resolution, `PATCH /subscriptions/{sub_payme_id}/resume` | | `PayMe-Partner-Key` | The partner's client key | `GET /sellers/{seller_payme_id}/public-keys`, `GET /banks/{country_iso_code}` | | `PayMe-Public-Key` | The seller's public key | `POST /sales/{payme_sale_id}/3ds` (called from the browser) | | `PayMe-Signature` | A static value PayMe provides on request | `/sellers/{mpl_key}/individuals`, `/sellers/{mpl_key}/mids` | `PayMe-Signature` is not computed per request: it is a static secret value that PayMe gives you on request. Keep it secret and never paste it into code samples or tickets. ### The public key Each seller has its own public key, issued separately in each environment. A partner can look it up with `GET /sellers/{seller_payme_id}/public-keys` (header `PayMe-Partner-Key`), and `create-seller` returns it as `seller_public_key`. The public key is meant for browser code, but it can read a filtered list of the seller's transactions. Use it only where you need it in the browser. In the merchant dashboard, the public key, the MPL and the Hosted Fields JSAPI credentials are on **Admin → API & Integration** (API ואינטגרציה). The Hosted Fields public key is in the section **Hosted Fields JSAPI Credentials** on that page, and it differs between the sandbox and production. `PayMe.create` takes the public key only: never put the MPL (`seller_payme_id`) in browser code. `GET /sellers/{seller_payme_id}/public-keys` is partner-only. ## Getting credentials - **Payments API — sandbox:** 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 → "הרשמה" (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. - **Where the keys are:** **Admin → API & Integration** shows the MPL (`seller_payme_id`, with a test/production toggle), the public key, both base URLs and the Hosted Fields JSAPI credentials. If the page is missing, install the API service from the dashboard app store (חנות אפליקציות) first; depending on your account it may carry a charge. - **Payments API — production:** the same page in production mode. Sandbox and production are separate accounts with separate credentials: a sandbox key is rejected by `live.payme.io` and vice versa. - **Partner key (`payme_client_key`):** issued to partners by PayMe Partners (). It is never given to individual sellers, even for refunds — a seller refunds with `seller_payme_id` alone. - Questions about credentials: . ## Other APIs - **B2B Payments** uses the Payments API keys: [Hosts and authentication](https://docs.payme.io/b2b-payments/contracts/overview#hosts-and-authentication). - **Keep** uses OAuth 2.0 client credentials: [Authorization Flow](https://docs.payme.io/keep/partner-authorization/authorization-flow). - **Products & Customers** uses a JWT: [Hosts, Authentication and Errors](https://docs.payme.io/products-and-customers/authentication/hosts-authentication-and-errors#authentication). ## Keeping credentials secret - Keep `seller_payme_id`, `payme_client_key`, the client password (called `payme_merchant_secret` in older PayMe documentation; see [Callbacks](https://docs.payme.io/payments/getting-started/callbacks)) and `PayMe-Signature` on your **server**. Never put them in browser or mobile code, logs, or public repositories such as GitHub. - Only the public key belongs in browser code. The 3D Secure guide makes the same split: the browser call uses the public key, the hash-resolution call "should be called from your backend". - Store tokens securely and encrypted. ### If a key leaks There is no self-service key regeneration or rotation. If you believe a key has leaked, contact PayMe support immediately. - [Environments](https://docs.payme.io/payments/getting-started/environments): PayMe has two environments: Sandbox at https://sandbox.payme.io/api/ and Production at https://live.payme.io/api/; they are separate accounts and each issues its own keys. sale_url is the environment's host (without /api) plus /sale/generate/; use it exactly as returned. 3D Secure redirect pages are served from paymeservice.com. Browser scripts load from cdn.paymeservice.com (also cdn.payme.io); Hosted Fields uses testMode: true for the sandbox. Test data is on Test Cards and Payment Methods. ## Related - [Test Cards and Payment Methods](https://docs.payme.io/payments/getting-started/test-cards-and-payment-methods) - [Authentication](https://docs.payme.io/payments/getting-started/authentication) - [Quickstart](https://docs.payme.io/payments/getting-started/quickstart) - [Errors](https://docs.payme.io/payments/getting-started/errors) # Environments ## Base URLs | Environment | Base URL | |-------------|----------| | Sandbox | `https://sandbox.payme.io/api/` | | Production | `https://live.payme.io/api/` | Point every request at the correct environment **with that environment's credentials**. Endpoint pages show both URLs. A full endpoint URL is the base URL plus the path, for example `https://sandbox.payme.io/api/generate-sale` and `https://live.payme.io/api/refund-sale`. Sandbox and production are separate accounts with separate credentials: a sandbox key is rejected by `live.payme.io` and vice versa. The sandbox is free and asks for no signatures. A test account cannot be converted into a live account. What works in the sandbox, and how to test what does not, is on [Test Cards and Payment Methods](https://docs.payme.io/payments/getting-started/test-cards-and-payment-methods). ### Other APIs B2B Payments, Keep and Products & Customers document their hosts with their own APIs: [B2B Payments](https://docs.payme.io/b2b-payments/contracts/overview#hosts-and-authentication), [Keep](https://docs.payme.io/keep/partner-authorization/authorization-flow#base-url), [Products & Customers](https://docs.payme.io/products-and-customers/authentication/hosts-authentication-and-errors#hosts). ## Hosts you will see besides the API ### The payment page (`sale_url`) `generate-sale` returns a `sale_url` — the secured payment page to show the buyer. It is the environment's host without `/api` (for example `https://sandbox.payme.io`) followed by `/sale/generate/`, or `/sale/template/` for template sales. **Use `sale_url` exactly as returned**; do not build it yourself or hard-code its host. Examples on some pages show other hosts (for example `preprod.paymeservice.com`); never copy a host from an example into your code or allow-lists — read it from the response. ### 3D Secure redirect pages 3D Secure redirect pages are served from a `paymeservice.com` address, for example `https://sandbox.paymeservice.com/3ds/redirect/?pa=`, not from `payme.io`. Allow-lists and Content Security Policies must include the host of the `redirect_url` you receive, or 3D Secure breaks. ### Browser scripts Load the Hosted Fields script from `cdn.payme.io`; its protected fields load in iframes from `hf.payme.io`. In the sandbox, a page whose policy set only `script-src https://cdn.payme.io` (plus what its own inline code needed) and `frame-src https://hf.payme.io` tokenized a card with no policy errors. The same files are also served from `cdn.paymeservice.com` (both hosts returned the identical Hosted Fields script on 2026-10-29), so if you load from there, allow-list that host instead. The Apple Pay and Google Pay guides load `hostedfields.js` from `cdn.paymeservice.com`; the Hosted Fields guide shows `cdn.payme.io/hf/v1/hostedfields.js`. Load the Hosted Fields script from the URL given on the [Hosted Fields guide](https://docs.payme.io/accepting-payments/checkout-and-in-person/hosted-fields-jsapi-guide); the same URL is used for sandbox and production, and `testMode` selects the environment. In browser code, sandbox vs production is chosen with `testMode` (default `false`): `PayMe.create(apiKey, { testMode: true })` for the sandbox. Setting it to `false` sends requests to production. ## Testing in the sandbox Use test data **only in the sandbox**. Test cards (including cards that force a decline), wallet cards, bank accounts and the values for creating test sellers are on [Test Cards and Payment Methods](https://docs.payme.io/payments/getting-started/test-cards-and-payment-methods). ### Merchant dashboard `create-seller` returns a sign-up link to the merchant dashboard in `seller_dashboard_signup_link`. The test account is opened from the dashboard (click your name at the top → **Switch to test account**); where its keys are is on [Authentication](https://docs.payme.io/payments/getting-started/authentication#getting-credentials). Test mode shows a white top bar and production a green one; switch back with your name → **Switch to live account**. Test sales appear in the test account's dashboard. - [Integration Options](https://docs.payme.io/payments/getting-started/integration-options): PayMe offers three integration options: the Hosted Payment Page (your server calls generate-sale and the buyer pays on PayMe's sale_url; PayMe carries PCI DSS), Hosted Fields JSAPI (PayMe's card iframes inside your own form; the browser gets a token and your server charges it with generate-sale and buyer_key; your CSP must allow cdn.payme.io and hf.payme.io), and the Direct API (your server sends card details to pay-sale; PCI DSS level 1 required and PayMe must enable it). ## Related - [Start Here](https://docs.payme.io/payments/getting-started/start-here) - [Quickstart](https://docs.payme.io/payments/getting-started/quickstart) - [Create a sale (hosted payment page)](https://docs.payme.io/payments/hosted-payment-page/post-generate-sale) # Integration Options Building with an AI agent? Start with the [AI Toolkit](https://docs.payme.io/agents). There are three ways to take a payment. They differ in who renders the card form and how much of PCI DSS falls on you. | Option | How it works | Choose it when | Trade-offs | |---|---|---|---| | [Hosted Payment Page](https://docs.payme.io/payments/hosted-payment-page/post-generate-sale) | Your server calls `generate-sale`; the buyer pays on PayMe's page (`sale_url`) in an iframe or a redirect. | You want the fastest integration, every payment method on one page (`multi`), and PayMe to carry PCI DSS. | Limited control over the page design. | | [Hosted Fields (JSAPI)](https://docs.payme.io/accepting-payments/checkout-and-in-person/hosted-fields-jsapi-guide) | PayMe's card inputs (iframes) sit inside your own form; the browser gets a token and your server charges it with `generate-sale` and `buyer_key`. | You want your own checkout design without card data touching your servers. | More front-end work; your Content Security Policy must allow `cdn.payme.io` and `hf.payme.io`. | | [Direct API](https://docs.payme.io/payments/direct-api) | Your server sends card details to `pay-sale`. | You are PCI DSS level 1 compliant and need full control. | You carry PCI DSS compliance; PayMe must enable the API for you. | - [Test Cards and Payment Methods](https://docs.payme.io/payments/getting-started/test-cards-and-payment-methods): Use only in the sandbox. Main cards (expiry 12/30, Social ID 008336174): 4557430402053431 CVV 200 (international, one installment), 375516193000090 CVV 0957, 5326105300985846 CVV 658 (local, ILS only). Decline cards such as 4000000000000002 return HTTP 200 with status_code 1 and codes 20004 or 21001-21008. 3D Secure challenges foreign cards, amounts from the account's threshold, or 3 or more installments; challenge test card 4918914107195005 with OTP 555. Also Apple Pay cards, Israeli direct debit, SEPA and BACS accounts and test-seller values. ## Related - [Environments](https://docs.payme.io/payments/getting-started/environments) - [Errors](https://docs.payme.io/payments/getting-started/errors) - [Quickstart](https://docs.payme.io/payments/getting-started/quickstart) # Test Cards and Payment Methods Use these test details only in the sandbox. Google Pay and Apple Pay work in the sandbox; the invoicing service (iCount documents) does not, so test documents on a minimal live sale with an immediate refund. Live testing without a sandbox is possible with minimum amounts and an immediate refund, or with authorization-only sales. ## Main credit card numbers for testing EMV supported credit cards: Credit Card |Details ---|--- **Card Number:** `4557430402053431` **Expiration:** `12/30` **CVV:**`200` **Social ID:**`008336174`|**Limitations**: Acts as an international non-Israeli card. Accepts sales with only one installment. Accepts sales in ILS, USD, EUR. **Card Number:** `375516193000090` **Expiration:** `12/30` **CVV:** `0957` **Social ID:**`008336174`| **Limitations**: Acts as an international Israeli card. Accepts sales with multiple installments. Accepts sales in ILS, USD, EUR. **Card Number:** `5326105300985846` **Expiration:** `12/30` **CVV:** `658` **Social ID:**`008336174`| **Limitations**: Acts as a local Israeli card. Accepts sales with multiple installments. Accepts sales in ILS only. ## Secondary credit card numbers for testing Credit Card Type |Credit Card Number ---|--- Visa| `4111111111111111` `4200000000000000` Mastercard| `5555555555554444` `5454545454545454` AmericanExpress| `378282246310005` `377777777777770` Diners |`38520000023237` Discover| `6011000990139424` JCB |`3530111333300000` Isracard|`12312312` ## Credit card numbers for testing specific responses and errors These cards work only in the sandbox, where they always fail. A charge (`pay-sale`, or a charge with a `buyer_key`) returns **HTTP 200** with `status_code: 1` and the error below; tokenizing a decline card with `capture-buyer-token` returns **HTTP 500** with the same `status_code`, `status_error_code` and `status_error_details`. Card Number |Description|`status_error_code`|Message (with `language: "en"`) ---|---|---|--- `4000000000000002`| Payment is declined with a card declined error|`20004`|Refusal by credit company. Please try a different card `4000000000000051`| Payment is declined with a card blocked error|`21001`|The card is blocked `4000000000000085`| Payment is declined with a card stolen error|`21002`|The card is stolen `4000000000000069`| Payment is declined with a card expired error|`21004`|The card is expired `4000000000000101`| Payment is declined with a required CVV error|`21007`|CVV/ID is required but was not entered `4000000000000127`| Payment is declined with an incorrect CVV|`21008`|Incorrect CVV or ID `4000000000000135`| Payment is declined with a credit limit reached error|`21006`|The credit limit has been reached `4242424242424241`| Payment is declined with an incorrect card number error|`21005`|Incorrect card number `4000000000000036`| Token capture succeeds only through Hosted Fields `tokenize()` or `capture-buyer-token`; a later charge with the token is then declined. On a hosted payment page it is declined at once, with `capture_buyer` or `sale_type: token`, and no token exists|`20004`|Refusal by credit company. Please try a different card ## 3D Secure in the sandbox The sandbox applies the same selection rules as production. A sale gets the 3D Secure challenge when the card is foreign (issued in a country other than the seller's registered country), when the amount is at least the account's 3D Secure threshold, or when it has 3 or more installments. The amount rule compares `sale_price` in minor units with the threshold, without converting currencies. Whether a local card is challenged depends on the account's 3D Secure rules, so use a foreign card to test the challenge reliably. | Card | Behavior | |---|---| | `4918914107195005` | Challenge: the issuer page asks for a one-time code. Enter `555` to pass; any other code (for example `111`) fails authentication. | | `4907639999909022` | Frictionless approve: no challenge, authentication succeeds. | | `5283901906612672` | Frictionless decline: no challenge, authentication fails. | These cards use expiry `07/28` and CVV `123`. They produce a challenge only when the sale is selected for 3D Secure (see the rules above). ## Apple Pay Testing Information Card Brand | Card Number | Card Expiry Date | Card CVV ---|---|---|--- Visa | 4051 0693 0220 0121 | 12/27 | 340 Mastercard | 5204 2452 5052 2095 | 12/30 | 111 American Express | 37272 79248 51007 | 12/28 | 1111 Discover | FPAN: 6011 0009 9475 4889 | 12/30 | 111 ## Israeli Direct Debit Testing Information Bank Account Information (Bank, Branch, Account Number) |Description ---|--- `54, 112, 2222111` |Bank Authorization is approved after 60 seconds `54, 113, 4444333`|Bank Authorization is declined after 60 seconds `54, 111, 1112223`|Bank Authorization is declined immediately `54, 114, 5555111`|Bank Authorization stays pending (no status update is sent) Any other bank account is approved immediately. In the sandbox you only receive bank-authorization statuses 1 or 2. ## SEPA Payment Method Testing Information Account Number |Description ---|--- `DE89370400440532013000`| The Payment status transitions from `initial` to `completed` immediately. `DE08370400440532013003`|The Payment status transitions from `initial` to `completed` after 3 minutes. `DE62370400440532013001` |The Payment status transitions from `initial` to `failed` immediately. `DE78370400440532013004`|The Payment status transitions from `initial` to `failed` after 3 minutes. `DE35370400440532013002`|The Payment status transitions from `initial` to `completed` and then immediately to `chargeback`. ## BACS Payment Method Testing Information SORT CODE |Account Number| Description ---|---|--- `108800`| `00012345`| The Payment status transitions from `initial` to `completed` immediately. `108800`| `90012345`| The Payment status transitions from `initial` to `completed` after 3 minutes. `108800`| `33333335`| The Payment status transitions from `initial` to `completed` and then immediately to `failed`. ## Creating test sellers (partners) `seller_social_id` `9999999999`, `seller_email` `random@paymeservice.com` (suppresses automatic emails), `seller_bank_code` `54`, any 3-digit branch, any 6-digit account. ## Tokens in the sandbox Tokenization works in the sandbox out of the box. A token is scoped by the call that captures it: with `"buyer_is_private": true` it belongs to the seller (MPL); without it, it is account-level: any seller of the same partner can charge it, and a [`get-buyer-key`](https://docs.payme.io/payments/tokenization/post-get-buyer-key) call that sends `seller_payme_id` fails with error `603` ("Merchant not allowed to use this buyer"). Charging a token outside its scope (a seller-level token by another seller, or any token by a seller of another partner) fails with error `605` ("The buyer was not captured using the provided seller"). Capture and charge a sandbox token on the sandbox with sandbox credentials. - [Quickstart](https://docs.payme.io/payments/getting-started/quickstart): End-to-end sandbox walkthrough. 1) POST https://sandbox.payme.io/api/generate-sale with seller_payme_id, sale_price (minor units, min 500), currency, product_name, transaction_id, sale_callback_url, sale_return_url, language en; response has sale_url and payme_sale_id. 2) Open sale_url and pay with test card 5326105300985846 12/30 CVV 658. 3) PayMe POSTs a form-encoded callback with notify_type sale-complete; reply 200 within 5 s. 4) POST /refund-sale with seller_payme_id, payme_sale_id and optional sale_refund_amount. ## Prerequisites - Sandbox seller_payme_id (MPL) - A public HTTPS URL that can receive POST requests (not localhost or a private IP) ## Related - [Create a sale (hosted payment page)](https://docs.payme.io/payments/hosted-payment-page/post-generate-sale) - [Refund a sale](https://docs.payme.io/payments/post-sale-actions/post-refund-sale) - [Test Cards and Payment Methods](https://docs.payme.io/payments/getting-started/test-cards-and-payment-methods) - [Callbacks](https://docs.payme.io/payments/getting-started/callbacks) - [Errors](https://docs.payme.io/payments/getting-started/errors) # Quickstart 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](https://docs.payme.io/payments/getting-started/authentication). Keep it on your server: on its own it authenticates seller-level calls; - a public URL that accepts `POST` requests, for the callback. It may not be `localhost` or 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 → "הרשמה" (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 (); it is never issued to individual sellers. Integration questions: . ## Step 1 — Create the sale Endpoint: [`POST /generate-sale`](https://docs.payme.io/payments/hosted-payment-page/post-generate-sale). No payment happens yet. ```bash 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): ```json { "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_code` `0` means success, `1` means error. - Save `payme_sale_id` (PayMe's sale ID) next to your `transaction_id`. You need it to refund. - Responses also carry a `session` value; quote it when you contact PayMe. - If `status_code` is `1`, read `status_error_code` and `status_error_details` — see [Errors](https://docs.payme.io/payments/getting-started/errors). Errors usually come back with HTTP 500, so check `status_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](https://docs.payme.io/payments/getting-started/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](https://docs.payme.io/payments/getting-started/test-cards-and-payment-methods#credit-card-numbers-for-testing-specific-responses-and-errors). 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](https://docs.payme.io/payments/getting-started/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](https://docs.payme.io/payments/codes-statuses/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: ```bash 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](https://docs.payme.io/payments/getting-started/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`](https://docs.payme.io/payments/query-apis/post-get-sales) with `sale_payme_id` and check `sale_status` and `sale_price`. [`POST /get-transactions`](https://docs.payme.io/payments/query-apis/post-get-transactions) works too, and shows each charge and refund as a row. ## Step 4 — Refund the sale Endpoint: [`POST /refund-sale`](https://docs.payme.io/payments/post-sale-actions/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. ```bash 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): ```json { "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](https://docs.payme.io/payments/getting-started/idempotency-and-retries) first. ## Next steps - [Callbacks](https://docs.payme.io/payments/getting-started/callbacks) — every notification type and how to handle it. - [Errors](https://docs.payme.io/payments/getting-started/errors) — error codes and messages. - To charge a saved card later, see [Save a card and charge it later](https://docs.payme.io/accepting-payments/capture-and-saved-cards/save-a-card-and-charge-it-later); to authorize now and capture later, see [Capture sale](https://docs.payme.io/accepting-payments/capture-and-saved-cards/capture-sale). - [Callbacks](https://docs.payme.io/payments/getting-started/callbacks): PayMe callbacks are form-encoded POSTs to sale_callback_url (or the partner's default callback URL, if one is set). Any status below 400 counts as delivered; each attempt times out after 5 s; up to 3 attempts within about 90 seconds, then dropped. Duplicates happen and ordering is not guaranteed: de-duplicate on notify_type + payme_sale_id + payme_transaction_id. payme_signature = lowercase hex MD5 of payme_client_key + client password + payme_transaction_id + payme_sale_id. Before fulfilling an order, confirm the sale's status and amount with POST /get-sales. ## Related - [Callback types reference](https://docs.payme.io/payments/getting-started/callback-types) - [Sale Statuses](https://docs.payme.io/payments/codes-statuses/sale-statuses) - [List sales](https://docs.payme.io/payments/query-apis/post-get-sales) - [Idempotency and Retries](https://docs.payme.io/payments/getting-started/idempotency-and-retries) - [Quickstart](https://docs.payme.io/payments/getting-started/quickstart) # Callbacks A callback (PayMe also calls it an "IPN") is a request PayMe's server sends to yours when something happens to a sale, a subscription or a seller. **In short:** reply quickly with HTTP 200, expect repeats and out-of-order delivery, verify `payme_signature`, and confirm the sale's status and amount with [`POST /get-sales`](https://docs.payme.io/payments/query-apis/post-get-sales) before you fulfil an order. ## Format - Method and encoding: `POST` with an `x-www-form-urlencoded` body — not JSON. - Destination: the `sale_callback_url` you sent. If you omit it, PayMe uses your partner's default callback URL, if your partner has one; a seller has no dashboard setting for it, so always send `sale_callback_url` (and `sub_callback_url` for subscriptions). One sale can notify two URLs: the sale's callback URL and the partner's sale callback URL (one delivery per host). - The `language` field of the request sets the language of the callback. ### Callback URL rules - `http://` and `https://` are both accepted. Use HTTPS. - Non-standard ports are allowed (for example `:8443`). - Rejected, with error `21` for the whole call: `localhost` and other hosts without a dot, IP addresses in private or loopback ranges, all IPv6 addresses, and hosts whose top-level domain isn't letters only. Ports must be 2–5 digits. - PayMe doesn't resolve the host, so a valid-looking name is accepted even if it doesn't exist. `sale_return_url` follows the same rules. The callback is separate from the **return URL** redirect. The return URL is a browser `GET` that takes the buyer to your result page; the callback is server-to-server. ## Sale notification types (`notify_type`) Every `notify_type` PayMe sends, with when it fires and its key fields, is listed on [Callback types reference](https://docs.payme.io/payments/getting-started/callback-types). | `notify_type` | Meaning | |---------------|---------| | `sale-complete` | The sale was paid successfully | | `sale-authorized` | The sale was authorized successfully | | `refund` | The sale was refunded — full refund, partial refund, or void of an authorization | | `sale-failure` | A payment attempt failed | | `sale-chargeback` | The sale was charged back | | `sale-chargeback-refund` | The chargeback was reverted | | `sale-create` | The sale was created. Sent only when `generate-sale` included `sale_send_creation_callback: true`; carries `sale_url`. | | `sale-paid` | Israeli direct debit only: the debit was submitted to the bank. | | `sale-il-direct-debit-update` | Israeli direct debit only: the bank authorization status changed. | - **`sale-failure` is sent once per failed attempt**, not once per sale. A buyer can retry on the payment page; each failure sends another `sale-failure` with a different `payme_transaction_id`. They stop once the sale completes. So `failed` isn't final: the sale can still move to `completed`, or `authorized` for a capture sale. - **Refund callbacks:** `payme_transaction_total` is the amount of this refund, `price` is the original sale price, `sale_refund_buffer` is the amount still refundable, and `payme_transaction_id` / `payme_signature` refer to the refund transaction. After a partial refund `sale_status` is `partial-refund`. A sale fully refunded in parts stays `partial-refund` and never moves to `refunded`, so track the refunded total yourself. ## Sale callback payload | Field | Example | Description | |-------|---------|-------------| | `status_code` | `0` | `0` success, `1` error | | `status_error_code` | | In case of an error, PayMe's error code | | `status_error_details` | | In case of an error, the error message | | `notify_type` | `sale-complete` | Notification type (table above) | | `sale_created` | `2016-01-01 15:15:15` | Sale creation time | | `transaction_id` | `12345` | Your order ID | | `payme_sale_id` | `XXXXXXXX-XXXXXXXX-XXXXXXXX-XXXXXXXX` | PayMe's sale ID | | `payme_sale_code` | `12345678` | Sale code, for display only | | `payme_transaction_id` | `XXXXXXXX-XXXXXXXX-XXXXXXXX-XXXXXXXX` | PayMe's ID for this transaction (payment, capture, refund or failed attempt) | | `price` | `1000` | Amount in minor units (50.75 → `5075`) | | `currency` | `USD` | ISO 4217 code | | `sale_status` | `completed` | See [Sale Statuses](https://docs.payme.io/payments/codes-statuses/sale-statuses) | | `payme_transaction_card_brand` | `Visa` | Card brand | | `payme_transaction_auth_number` | `01A2B3C` | Authorization number from the card company | | `buyer_card_mask` | `458045******4580` | Masked card number | | `buyer_card_exp` | `0118` | Card expiry | | `buyer_name`, `buyer_email`, `buyer_phone`, `buyer_social_id` | | Buyer details | | `buyer_key` | `XXXXXXXX-…` | Token for future payments; only when `capture_buyer` was set | | `installments` | `1` | Number of installments | | `sale_paid_date` | `2016-01-01 15:16:15` | When the payment happened (not when the callback was sent) | | `sale_release_date` | `2016-01-08 15:15:15` | Release date | | `is_token_sale` | `0` | `0` false, `1` true | | `payme_signature` | `75e99dbcb25cdfbe1c62f0b9376f4144` | Signature (see below) | | `sale_invoice_url` | `https://www.example.com/XXXXXX.pdf` | Invoice URL, if the seller enabled invoices | | `sale_payment_method` | `credit-card` | Payment method name; see [Available Payment Methods](https://docs.payme.io/payments/wallets-apms) | | `sale_type` | `Sale` | Sale type name: `Sale` (also for authorizations), `Token`, `SaleFromTemplate`, `SaleFromSubscription`, … See [Sale Types](https://docs.payme.io/payments/codes-statuses/sale-types) | | `payme_transaction_total` | `1000` | Amount of this transaction, in minor units | | `buyer_card_is_foreign` | `0` | `1` when the card was issued outside Israel | | `sale_3ds` | `0` | `1` when the payment went through 3D Secure | | `buyer_status` | `1` | With `buyer_key`: the status of the saved token | Fields with no value are left out of the body. ## Other callbacks ### Subscriptions Sent to `sub_callback_url`; if it is empty, to your partner's default callback URL (`merchant_callback_url`), if one is set. **Subscription callbacks carry no `payme_signature`.** | `notify_type` | When | |---------------|------| | `sub-create` | The subscription was created | | `sub-active` | The subscription became active | | `sub-iteration-success` | A charge succeeded: first, regular or after a retry, with an identical body in every case (adds `payme_sale_id` and `payme_sale_code`; the charge time is `sub_prev_date`) | | `sub-iteration-skipped` | A billing iteration was skipped | | `sub-failure` | A payment attempt failed. If the card-validation transaction failed when the buyer paid the subscription, its status is `4` and PayMe does not retry. If a scheduled charge failed and will be retried, its status is `7` and `sub_next_date` moves one day. Carries `sub_error_text`, but no sale id, attempt id or failed-attempt counter | | `sub-pause` | The subscription was paused | | `sub-cancel` | The subscription was cancelled, by hand or automatically after the last failed attempt (status `5`). Always contains `seller_payme_id`, `seller_id`, `sub_payme_id`, `sub_payme_code`; `subscription_id` only if you set it | | `sub-complete` | The subscription completed | The payload includes `sub_payme_id`, `sub_status`, `sub_price`, iteration counters and buyer fields (card mask, name, email, phone and ID; never the `buyer_key`). The iteration counters count successful charges only. Each successful iteration also creates a sale, which sends its own `sale-complete` or `sale-failure`. Handlers must be idempotent: re-query [`get-subscriptions`](https://docs.payme.io/payments/query-apis/post-get-subscriptions) before acting. Charge retries (once a day, up to 7 attempts) are described on [Recurring Payments](https://docs.payme.io/payments/saved-cards-recurring). `sub_callback_url` is sent on every successful charge while the subscription is active and on every failed attempt that leads to a retry. #### Subscription callback payload | Field | Example | Description | |-------|---------|-------------| | `notify_type` | `sub-iteration-success` | Notification type (table above) | | `status_code` | `0` | `0` success, `1` error | | `status_error_code` | | In case of an error, PayMe's error code | | `sub_error_text` | | In case of an error, the error message | | `seller_payme_id` | `MPLDEMO-MPLDEMO-MPLDEMO-1234567` | PayMe's seller ID | | `seller_id` | `12345` | Your seller ID | | `sub_payme_id` | `XXXXXXXX-XXXXXXXX-XXXXXXXX-XXXXXXXX` | PayMe's subscription ID | | `sub_payme_code` | `1234` | PayMe's subscription code | | `sub_created` | `2016-01-01 15:15:15` | Subscription creation time | | `sub_payment_date` | `2016-01-01 18:32:23` | Subscription payment time | | `sub_start_date` | `2016-01-02 00:00:00` | When the first iteration was charged | | `sub_next_date` | `2016-01-03 00:00:00` | Next iteration time | | `sub_status` | `1` | See [Subscription Statuses](https://docs.payme.io/payments/codes-statuses/subscription-statuses) | | `sub_iteration_type` | `1` | See [Subscription Iteration Types](https://docs.payme.io/payments/codes-statuses/subscription-iteration-types) | | `sub_currency` | `USD` | ISO 4217 code | | `sub_price` | `10000` | Price of one iteration in minor units (50.75 → `5075`) | | `sub_iterations` | `4` | Number of iterations | | `sub_iterations_completed` | `4` | Completed iterations | | `sub_iterations_left` | `4` | Remaining iterations | | `buyer_card_mask` | `458045******4580` | Masked card number | | `buyer_name`, `buyer_email`, `buyer_phone`, `buyer_social_id` | | Buyer details | ### Israeli direct debit - `sale-paid` when the debit is submitted. Take the token (`buyer_key`) from `sale-il-direct-debit-update` or `get-sales`, not from `sale-paid`. - When the bank authorization status changes: `sale-complete` or `sale-failure`, then `sale-il-direct-debit-update` with `authorization_status` and `authorization_error_code`. The `authorization_status` values are listed on [Errors](https://docs.payme.io/payments/getting-started/errors) (section "Israeli direct debit"). An Israeli direct-debit *payment* sends `sale-paid` when submitted, then `sale-complete` about 8 days later, or `sale-failure` if the bank returns the debit before that. ### Sellers (partners) Sent to the partner's callback URL with all `seller_*` and `fee_*` fields: `seller-create` (adds `seller_public_key`), `seller-update`, `seller-approve`. Related partner notifications: `withdrawal-complete`, `charge-complete`, and `point-of-sale-action-*` (for example after a POS device is paired). #### Seller callback payload | Field | Example | Description | |-------|---------|-------------| | `status_code` | `0` | `0` success, `1` error | | `status_error_code` | | In case of an error, PayMe's error code | | `status_error_details` | | In case of an error, the error message | | `notify_type` | `seller-create` | Notification type (above) | | `seller_payme_id` | `MPLDEMO-MPLDEMO-MPLDEMO-1234567` | PayMe's seller ID | | `seller_id` | `12345` | Your seller ID | | `seller_created` | `2016-01-01 15:15:15` | Seller creation time | | `seller_first_name` | `First` | First name of the account owner | | `seller_last_name` | `Last` | Last name of the account owner | | `seller_social_id` | `999999999` | Social ID of the account owner | | `seller_birthdate` | `1989-05-06` | Birth date, `yyyy-mm-dd` (the request sends DD/MM/YYYY) | | `seller_gender` | `0` | `0` male, `1` female | | `seller_email` | `personal@example.com` | Seller's personal email | | `seller_contact_email` | `contact@example.com` | Contact email shown to buyers | | `seller_phone` | `0500000042` | Seller's personal phone | | `seller_contact_phone` | `031234567` | Contact phone shown to buyers | | `seller_inc` | `2` | See [Seller Incorporation Types (IL)](https://docs.payme.io/marketplaces-and-platforms/seller-reference/seller-incorporation-types-il) | | `seller_inc_code` | `123456` | Business ID (ח.פ, ע.מ) | | `seller_merchant_name` | `Baby Ducks` | Merchant name | | `seller_site_url` | `www.babyducks.com` | Site URL | | `seller_address_city` | `Tel Aviv` | Business address: city | | `seller_address_street` | `Rothschild` | Business address: street | | `seller_address_street_number` | `45` | Business address: street number | | `seller_address_country` | `IL` | Business address: country (ISO 3166-1 alpha-2) | | `seller_active` | `1` | `0` inactive, `1` active | | `seller_approved` | `1` | `0` not approved, `1` approved | | `seller_currencies` | `[ILS, USD, EUR]` | Allowed currencies | ### Bank transfer A bank transfer reaching `PAID` is reported with a callback. There is no bank-transfer-specific `notify_type`: the standard sale callbacks apply (`sale-complete` when the transfer is paid, `sale-failure` otherwise). ### B2B payment contracts Documented with the B2B Payments API: [Contracts: getting started → Callbacks](https://docs.payme.io/b2b-payments/contracts/overview#callbacks). ## Verifying a callback (`payme_signature`) ### How it is computed Partners, who hold `payme_client_key`, verify callbacks with this formula; a seller without a partner key re-queries the sale instead (see below). `payme_signature` is the **lowercase hexadecimal MD5** hash of four values joined with **no separator**, in this order: 1. `payme_client_key` (the partner key) 2. the client password issued together with the client key: the partner's `merchant_password` (called `payme_merchant_secret` in older PayMe documentation) 3. `payme_transaction_id` (from the payload) 4. `payme_sale_id` (from the payload) It is a plain MD5 hash, not an HMAC. The signature always uses your primary client key. If PayMe is moving you to a new client key, your API calls can already use the new key, but the signature stays on the primary key until PayMe completes the switch. Worked example (fake values): | Input | Value | |-------|-------| | `payme_client_key` | `demo_partner_KEY12345` | | client password | `demoPassw0rd` | | `payme_transaction_id` | `TRAN1700-000000AA-EXAMPLE1-TXN00001` | | `payme_sale_id` | `SALE1700-000000AA-EXAMPLE1-SALE0001` | Joined string: `demo_partner_KEY12345demoPassw0rdTRAN1700-000000AA-EXAMPLE1-TXN00001SALE1700-000000AA-EXAMPLE1-SALE0001` `payme_signature` = `f8ffc5bb45fe6c3ad326c439f1a21c28` ```python import hashlib, hmac def payme_signature_ok(form, client_key, client_password): expected = hashlib.md5( (client_key + client_password + form["payme_transaction_id"] + form["payme_sale_id"]).encode() ).hexdigest() return hmac.compare_digest(expected, form.get("payme_signature", "")) ``` The client password is issued together with your partner credentials by PayMe Partners (). A merchant that has no `payme_client_key` cannot compute the signature: verify the sale instead with [`POST /get-sales`](https://docs.payme.io/payments/query-apis/post-get-sales) or [`POST /get-transactions`](https://docs.payme.io/payments/query-apis/post-get-transactions), which is also the check PayMe support recommends. ### Where the same signature appears The same formula is used in sale callbacks, the return-URL redirect (including when `payme_status=error`), and the `capture-sale` and `refund-sale` responses. In each case `payme_transaction_id` is the transaction in that payload — the payment, the capture or the refund. Exceptions: - Seller callbacks and `withdrawal-complete` have no signature. Ignore the body and re-read with `get-sellers` or `get-withdrawals`. - Subscription callbacks have no signature. The subscription **return URL** is signed: the MD5 of the client key, the client password, the URL's `transaction_id` (PayMe's transaction ID; this URL has no `payme_transaction_id`) and `sub_payme_id`. - `verify_only` refunds return `payme_signature: null`. - B2B payment contracts use a shorter formula: the MD5 of the client key, the client password and the contract's `guid`. See [B2B Payments](https://docs.payme.io/b2b-payments/contracts/overview#callbacks). ### Confirm the sale before you fulfil A valid signature tells you the callback refers to a real PayMe sale and transaction. Treat the status and amount in a callback as a notification, not as proof of payment. **Safe practice:** before you fulfil an order, call [`POST /get-sales`](https://docs.payme.io/payments/query-apis/post-get-sales) with `sale_payme_id` and check `sale_status` and `sale_price` against your order. [`POST /get-transactions`](https://docs.payme.io/payments/query-apis/post-get-transactions) works too, and shows each charge and refund as a row, which is why the [AI Toolkit](https://docs.payme.io/agents) steps use it. Find the order by the `payme_sale_id` you stored when you created the sale, and match it on your own order ID as well as the amount. Otherwise a real, cheap sale's ID could be replayed in a forged callback against an expensive order. If you confirm with `get-transactions` instead, send `transaction_type: 40` for a sale that is authorized and not yet captured: the default query doesn't return it. PayMe does not publish a fixed list of callback source addresses, so do not allow-list by IP. Authenticate callbacks by their signature and confirm the sale with `get-sales`. ## Delivery, retries, duplicates and ordering ### What counts as delivered - Any status below 400 counts as delivered. The response body is ignored. - Each attempt times out after **5 seconds**. Reply `200` immediately and do the slow work (emails, fulfilment) afterwards. ### Retries - PayMe makes **up to 3 attempts**: the first, a retry about 30 seconds later, and a last retry about 60 seconds after that. - A 4xx or 5xx response, a timeout, or a connection error triggers a retry. - After the last attempt the callback is **dropped**. It cannot be replayed through the API. - If your host keeps returning 5xx, 408 or 429 responses, timing out or refusing connections, PayMe pauses deliveries to that host for a short time. Callbacks during the pause are not delivered or retried. - A pause is triggered by 5xx responses, `429`, `408`, timeouts and connection errors on your host; an ordinary 4xx (for example a signature or authentication rejection by your code) never causes one. It lifts by itself once your endpoint answers. You can't reset it yourself; if you need it cleared at once, contact PayMe support with the callback host. There is no test ping. Acknowledge first (cold starts included) and process in the background. - Order is not guaranteed: act on `notify_type` and the sale status, not on the order of arrival. **Do not rely on callbacks alone.** Reconcile with [`POST /get-sales`](https://docs.payme.io/payments/query-apis/post-get-sales). ### Duplicates The same callback can arrive more than once — typically when your endpoint processes it but replies after the 5-second timeout. There is no event ID. De-duplicate on **`notify_type` + `payme_sale_id` + `payme_transaction_id`**; each refund, capture and failed attempt has its own `payme_transaction_id`. ### Ordering Callbacks are **not** guaranteed to arrive in order: they are sent by parallel workers with retry delays, so a `refund` can arrive before a `sale-complete` that is still being retried, and there is no sequence number or event timestamp. Never let a later-arriving callback overwrite a final state you already recorded, and query the sale when in doubt. ## Handling checklist 1. Parse the body as form data and reply `200` within 5 seconds. 2. If you are a partner, verify `payme_signature` (sale callbacks). 3. Ignore it if you already processed this `notify_type` + `payme_sale_id` + `payme_transaction_id`. 4. Before fulfilling, confirm `sale_status` and `sale_price` with `POST /get-sales`. 5. Run a periodic reconciliation with `get-sales`, because callbacks can be dropped after 3 attempts. - [Callback types reference](https://docs.payme.io/payments/getting-started/callback-types): Sale callback URL, signed except sale-create: sale-create (opt-in), sale-complete, sale-authorized, sale-failure (per attempt), refund (refunds and voids), sale-chargeback, sale-chargeback-refund, sale-paid, sale-il-direct-debit-update. sub_callback_url, unsigned: sub-create, sub-active, sub-iteration-success, sub-iteration-skipped, sub-failure, sub-pause, sub-cancel, sub-complete. Partner URL, unsigned: seller-create, seller-update, seller-approve, point-of-sale-action-pair-update, point-of-sale-action-authenticate-update, withdrawal-complete, charge-complete. B2B: payment-contract-*. ## Related - [Callbacks](https://docs.payme.io/payments/getting-started/callbacks) - [Understand the sale lifecycle](https://docs.payme.io/payments/codes-statuses/sale-lifecycle) - [List sales](https://docs.payme.io/payments/query-apis/post-get-sales) - [List subscriptions](https://docs.payme.io/payments/query-apis/post-get-subscriptions) - [List sellers](https://docs.payme.io/payments/query-apis/post-get-sellers) - [List withdrawals](https://docs.payme.io/payments/query-apis/post-get-withdrawals) - [Withdrawals](https://docs.payme.io/marketplaces-and-platforms/fees-and-payouts/withdrawals) - [Take in-person payments with a POS device](https://docs.payme.io/accepting-payments/checkout-and-in-person/point-of-sale) - [Contracts](https://docs.payme.io/b2b-payments/contracts) # Callback types reference This page lists every `notify_type` PayMe sends to your servers: who receives it, when it fires, its key fields, and whether it is signed. How callbacks are delivered (a form-encoded `POST`, the 5-second timeout, retries, duplicates and the signature formula) is on [Callbacks](https://docs.payme.io/payments/getting-started/callbacks). ## How to read this page **Where it goes.** Each group below names its destination: | Destination | What it is | |---|---| | Sale callback URL | The sale's `sale_callback_url`. If you left it out, your partner's default callback URL. If your partner also has a separate sale callback URL, that URL gets a copy; PayMe sends one delivery per host. | | Subscription callback URL | The subscription's `sub_callback_url`. If you left it out, your partner's callback URL at the time the subscription was created. | | Partner callback URL | Your partner's callback URL, set by PayMe. If your partner account has none, these callbacks aren't sent. | | Contract callback URL | The B2B payment contract's `callback_url`. | **Signed.** A signed callback carries `payme_signature`, which a partner verifies with the formula on [Callbacks](https://docs.payme.io/payments/getting-started/callbacks#verifying-a-callback-payme_signature). For an unsigned callback, re-read the object with its query call before you act on it. **Body.** Every callback carries `notify_type`. Fields with no value are left out. ## Sales Sent to the sale callback URL. Signed, except `sale-create`. The body has the fields of the [sale callback payload](https://docs.payme.io/payments/getting-started/callbacks#sale-callback-payload), plus the key fields below. | `notify_type` | When it fires | Key fields | |---|---|---| | `sale-create` | Right after `generate-sale`, only when you sent `sale_send_creation_callback: true` | `sale_url`. No payment fields yet, and no `payme_signature` | | `sale-complete` | The sale was paid, or an authorization was captured. A token sale (`sale_type: token`) sends it when the card is saved | `sale_status` `completed`. `buyer_key` and `buyer_status` when the card was saved. `is_token_sale` `1` on a token sale. `sale_invoice_url` when the invoicing service issued a document | | `sale-authorized` | An `authorize` sale was authorized | `sale_status` `authorized`. `buyer_key` when the card was saved | | `sale-failure` | A payment or capture attempt failed. Sent once per failed attempt | `status_code` `1`, `payme_status` `error`, `status_error_code`, `status_error_details`. Each attempt has its own `payme_transaction_id` | | `refund` | A refund, a partial refund, or a full or partial void of an authorization succeeded | `payme_transaction_total` (the amount of this refund or void), `sale_refund_buffer` (the amount still refundable), `sale_status`, `refunded_from_creditcard`. `payme_transaction_id` and `payme_signature` refer to the refund transaction | | `sale-chargeback` | The card issuer charged the payment back, in full or in part | `sale_status` `chargeback` or `partial-chargeback`. `inquiry_number` and `inquiry_code` (the references of the chargeback inquiry), `card_last_four_digits`, `vas_3ds_exists` (`1` when the seller has the 3D Secure service) | | `sale-chargeback-refund` | A chargeback was reversed in the seller's favor | `sale_status`: `completed` once every chargeback on the sale is reversed | | `sale-paid` | Israeli direct debit: the debit was submitted to the bank | Take the token (`buyer_key`) from `sale-il-direct-debit-update` or `get-sales`, not from this callback | | `sale-il-direct-debit-update` | Israeli direct debit: the bank authorization of a direct-debit token changed. Sent right after the `sale-complete` or `sale-failure` for that token | `authorization_status`, `authorization_error_code`, `buyer_key`, `buyer_name`. The `authorization_status` values are on [Errors](https://docs.payme.io/payments/getting-started/errors#israeli-direct-debit) | How each callback moves the sale's status is on [Understand the sale lifecycle](https://docs.payme.io/payments/codes-statuses/sale-lifecycle). ## Subscriptions Sent to the subscription callback URL. **Not signed**: re-read the subscription with [`get-subscriptions`](https://docs.payme.io/payments/query-apis/post-get-subscriptions) before you act. The body is the [subscription callback payload](https://docs.payme.io/payments/getting-started/callbacks#subscription-callback-payload): `sub_payme_id`, `sub_status`, `sub_price`, the iteration counters and the buyer fields, never the `buyer_key`. | `notify_type` | When it fires | |---|---| | `sub-create` | The subscription was created | | `sub-active` | The subscription became active | | `sub-iteration-success` | A charge succeeded: the first, a regular one, or one after a retry. Adds `payme_sale_id` and `payme_sale_code` of the charge's sale | | `sub-iteration-skipped` | A billing iteration was skipped | | `sub-failure` | A charge failed. Carries `sub_error_text` | | `sub-pause` | The subscription was paused | | `sub-cancel` | The subscription was canceled, by hand or after the last failed retry | | `sub-complete` | The subscription completed | Each charge also creates a sale, which sends its own `sale-complete` or `sale-failure`. Retry rules and statuses are on [Callbacks](https://docs.payme.io/payments/getting-started/callbacks#subscriptions) and [Recurring Payments](https://docs.payme.io/payments/saved-cards-recurring). ## Sellers For partners. Sent to the partner callback URL. **Not signed**: re-read the seller with [`get-sellers`](https://docs.payme.io/payments/query-apis/post-get-sellers) before you act. The body has all the `seller_*` and `fee_*` fields of the [seller callback payload](https://docs.payme.io/payments/getting-started/callbacks#seller-callback-payload). | `notify_type` | When it fires | Key fields | |---|---|---| | `seller-create` | A seller was created under your partner account | `seller_public_key`: the seller's public key, for Hosted Fields and other browser calls, with `uuid` (the key itself), `description` and `is_active` | | `seller-update` | A seller's details or status changed: for example through `update-seller`, in the dashboard, or when PayMe approves the seller or withdraws the approval | `seller_active`, `seller_approved` | | `seller-approve` | PayMe approved the seller | `seller_approved` `1`, `partner_name` | | `point-of-sale-action-pair-update` | A POS device was paired with the seller | `pos_id` (the device ID you use with `pos` payments), `pos_name` | | `point-of-sale-action-authenticate-update` | The paired POS device was authenticated with its 6-digit code and is now active | `pos_id`, `pos_name` | The POS flow is on [Point of sale](https://docs.payme.io/accepting-payments/checkout-and-in-person/point-of-sale). ## Seller balance For partners. Sent to the partner callback URL. **Not signed**: re-read with [`get-withdrawals`](https://docs.payme.io/payments/query-apis/post-get-withdrawals) or [`get-transactions`](https://docs.payme.io/payments/query-apis/post-get-transactions) before you act. Both use the same `tran_*` fields: | `notify_type` | When it fires | Key fields | |---|---|---| | `withdrawal-complete` | A withdrawal from the seller's balance was recorded. It is sent before the bank transfer arrives | `tran_payme_code` (the same number as `withdrawal_payme_code` in `get-withdrawals`), `tran_total`, `tran_currency`, `tran_type` `40`, `tran_created`. The full table is on [Withdrawals](https://docs.payme.io/marketplaces-and-platforms/fees-and-payouts/withdrawals#callback) | | `charge-complete` | PayMe debited or credited the seller's balance with a separate charge, for example a chargeback fee or a manual adjustment | `tran_total` in minor units: positive when PayMe takes money from the balance, negative when it credits it. `tran_currency`, `tran_description` (free text), `tran_type` (PayMe's charge type code), `tran_created`, `sale_payme_code` (the related sale, when there is one) | Both also carry `seller_payme_id`, `seller_id`, `payme_status` `success`, `status_code` `0` and `status_error_code` `0`. ## B2B payment contracts Sent to the contract callback URL whenever a contract's status changes: nine `payment-contract-*` types, from `payment-contract-created` to `payment-contract-payment-completed`. They are signed with a shorter formula than sale callbacks. The types and the signature are on [B2B payment contracts](https://docs.payme.io/b2b-payments/contracts#callbacks). ## Types you won't receive PayMe also uses other `notify_type` values for its own systems. They go to PayMe's internal endpoints, never to your callback URLs, so don't wait for a type that isn't on this page. - [Errors](https://docs.payme.io/payments/getting-started/errors): Payments API errors return status_code 1 with status_error_code, status_error_details (Hebrew unless language is en; he, en, es, ru, ar accepted) and status_additional_info (often the field name). Branch on status_code and status_error_code, never on HTTP status: card declines return HTTP 200, many request errors HTTP 500, some 400/403/422/429/503. Common codes: 1 missing parameter, 200 unknown client key, 251 seller not found, 252 currency not allowed, 305 wrong sale status, 352 invalid price, 998 too many or duplicate requests, 20xxx/21xxx card declines. ## Related - [Idempotency and Retries](https://docs.payme.io/payments/getting-started/idempotency-and-retries) - [Environments](https://docs.payme.io/payments/getting-started/environments) - [Test Cards and Payment Methods](https://docs.payme.io/payments/getting-started/test-cards-and-payment-methods) - [Sale Statuses](https://docs.payme.io/payments/codes-statuses/sale-statuses) - [Quickstart](https://docs.payme.io/payments/getting-started/quickstart) # Errors ## Error response shape ```json { "status_code": 1, "status_error_details": "Seller was not found", "status_additional_info": "seller_payme_id", "status_error_code": 251 } ``` | Field | Meaning | |-------|---------| | `status_code` | `0` success, `1` error. | | `status_error_code` | PayMe's numeric error code. `0` on success. | | `status_error_details` | The error message, in the language you asked for. | | `status_additional_info` | Extra detail — usually the name of the field at fault. Alternatives are joined with ` / `, for example `seller_payme_id / seller_id`. | | `payme_status` | `success` or `error` (on some responses and on the return-URL redirect). | Error bodies also include a `session` field. ## HTTP status vs `status_error_code` The two numbers are separate: `status_error_code` is never used as the HTTP status. | Situation | HTTP status | |-----------|-------------| | Card declined (codes `20xxx` / `21xxx`) | **200**, with `status_code: 1` | | Most request errors — for example missing parameter (`1`), unknown client key (`200`), unknown seller (`251`), wrong sale status (`305`) | **500** | | Some access and input errors | 400, 403 or 422 | | Too many requests, or a duplicate call still running (`998`) | 429 | | Service temporarily read-only | 503 | **Decide what happened from `status_code` and `status_error_code`, not from the HTTP status.** A `200` can be a decline. A `500` with `status_code: 1` and an error code is a refusal: your request usually needs fixing, and it doesn't mean PayMe is down. In a few cases the outcome is **unknown**, and PayMe may have acted. Check the sale before repeating a call that moves money ([how](https://docs.payme.io/payments/getting-started/idempotency-and-retries#before-retrying-check-the-sale)): - codes `991` and `20002`, at any HTTP status: contact was lost part-way, and the sale can show `failed` even so. Code `999` gives no information; - HTTP 429 (`998`): this call was turned away, but a matching call may still be running; - a timeout, a dropped connection, a body that isn't JSON, a gateway error page, or a body with no error code. ## Getting messages in English If you omit `language`, messages come back in **Hebrew**. Send `"language": "en"` on every call. `he` and `en` are fully supported; `es`, `ru` and `ar` are accepted, but messages and the payment page are then mostly in English. Values are case-insensitive. Any other value, or an empty string, returns error `51`. A few very early errors, such as a malformed key format, may still come back in Hebrew. ## Common error codes The tables below cover the codes integrators meet most often. ### Request and credential errors | Code | Meaning | What to do | |------|---------|------------| | `1` | Required parameter is missing. `status_additional_info` names it. Also returned when no client key and no seller key are sent. | Add the named field. | | `10` | `installments` or `market_fee` is not numeric | Send a number such as `1` or `"1"`. | | `19` | Please provide all required fields (some endpoints) | Check the endpoint's required fields. | | `20` | Validation error. Also "Merchant-Seller inconsistency" (HTTP 400): the seller belongs to a different partner from the `payme_client_key` sent. Also " contains invalid data" (HTTP 400): on `generate-sale`, `pay-sale`, `capture-buyer-token`, `POST /sales`, `pay-subscription` and `PATCH /subscriptions/{id}`, a field other than the card fields, `transaction_id` and `order_number` contains a 14–19-digit number that passes the card checksum. | Fix the fields listed in `status_additional_info`. Never put card-like numbers in descriptive fields. | | `51` | Unsupported or empty `language` value | Use `he` or `en` (`es`, `ru` and `ar` are accepted but mostly shown in English). | | `163` | "Account settings problem - please contact Customer Support": the MPL exists but is inactive, or a test MPL was sent to production | Check that `seller_payme_id` and the base URL are from the same environment; if they are, contact PayMe. | | `200` | Merchant was not found (HTTP 500): the `payme_client_key` (or `PayMe-Partner-Key`) matches no partner, usually because a seller sent its own MPL there or a production key was sent to the sandbox. `status_additional_info` is `payme_client_key`. | A seller removes the field and authenticates with `seller_payme_id` alone; a partner checks the key and the environment. | | `201` | The partner is inactive | Contact PayMe. | | `251` | Seller was not found: the `seller_payme_id` / `seller_id` matches no seller. Also returned for an unknown public key during card tokenization. | Check the MPL or public key and the environment. | | `252` | Currency not allowed for this account | Use a currency enabled on the account. | | `312` | More than 1 installment in a non-ILS currency | Installments are available for ILS sales only. | | `351` | `installments` outside the accepted ranges, or more than one installment with a payment method other than `credit-card`, `multi` or `pos` | Send `1`–`12`, or `102`–`112` to let the buyer choose. Installments are for card payments only. | | `358` | ILS price lower than the number of installments | Raise the price or lower the installments. | | `352` | `sale_price` is missing, not numeric or outside the allowed range. On `capture-sale`, also `0` or more than the authorization allows | Send minor units within the allowed range. | | `353` | `product_name` is missing | Add `product_name`. | | `357` | Invalid sale type: `sale_type` is not one of `sale`, `authorize`, `token`, `seller-token`, `credit`, `template`, `multi-capture`, or it can't be combined with the request (for example `multi-capture` with `buyer_key`). `status_additional_info` holds the value sent. | Send a listed value. For recurring payments, create a subscription with `generate-subscription` (see [Recurring Payments](https://docs.payme.io/payments/saved-cards-recurring)). | | `24` | Unknown `sale_payment_method` value | Use a value from [Available Payment Methods](https://docs.payme.io/payments/wallets-apms). | | `320` | The currency isn't supported for this payment method: BACS needs GBP, SEPA needs EUR, and an Israeli direct debit charge needs ILS | Send the method's currency. | | `368` | `sale_payment_method` was sent as an array (HTTP 400) | Send one value, as a string. | | `601` / `602` / `606` | `buyer_key` combined with `capture_buyer` (`601`), a `token` or `seller-token` sale type (`602`), or `template` (`606`) | Charge a saved token with `sale_type` `sale` or `authorize`. | | `608` | `buyer_perform_validation: true` without `capture_buyer` or a token sale | Send it only when you capture a token. | ### Sale-state, retry and rate-limit errors | Code | Meaning | What to do | |------|---------|------------| | `305` | Cannot perform action due to an incorrect status. `status_additional_info` holds the sale's current status. Returned, for example, when a paid sale is paid again or a fully refunded sale is refunded again. | Check the sale with `get-sales`; do not retry. | | `517` | The refund amount is bigger than the sale's price | Refund no more than the sale's price, less what you already refunded. | | `991` | A network problem, part-way through | The outcome is unknown. Check the sale, and quote `session` to PayMe. | | `20002` | A network problem reaching the card company | The outcome is unknown. Check the sale, and quote `session` to PayMe. | | `999` | No information provided | The outcome is unknown. Check the sale, and quote `session` to PayMe. | | `998` | HTTP 429. Either "Too Many Attempts." (rate limit) or "Duplicated action detected, please retry later" (the same action on the same sale is still running). Tell them apart by `status_additional_info`; `status_error_details` is "Operation is not permitted" in both. | Wait (`Retry-After` header) and check the sale before retrying. | ### Codes PayMe support sees most often The cases below come from PayMe's support knowledge base; the fix is what support will ask you to check first. | Code or message | Usual cause | What to do | |-----------------|-------------|------------| | `251` / `ERR-020` "seller not found" | Wrong MPL, or a test key sent to the production URL (or the reverse) | Copy the MPL from the dashboard (**Admin → API & Integration**) and check that key and base URL belong to the same environment. | | `130` "Seller is over sale limit, unable to create new sales" | This sale would take the seller over its processing limit | Complete any pending verification in the dashboard, then ask to review the seller's processing limit (send `seller_payme_id`). | | `720` service not activated | Apple Pay, Google Pay, Bit, B2B transfers or another value-added service is not enabled on the account | A seller installs Apple Pay, Google Pay or Bit itself from the dashboard app store (חנות אפליקציות); the method is active as soon as it is installed. A partner enables it for its seller with `vas-enable`. For B2B transfers and other services, ask (give your MPL). | | `603` from `get-buyer-key` | You sent `seller_payme_id` to read an account-level token (one captured without `buyer_is_private`). Only `get-buyer-key` returns `603`; charging an account-level token works for any seller of the same partner | Call `get-buyer-key` with `payme_client_key` instead, or capture new tokens with `"buyer_is_private": true`. A sandbox token works only on the sandbox, with sandbox credentials. | | `357` "Invalid sale type: recurring" | `recurring` isn't a sale type | Recurring payments are subscriptions: create one with `generate-subscription` (see [Recurring Payments](https://docs.payme.io/payments/saved-cards-recurring)). | | `401` / `403` | Invalid credentials | Check the key against the environment it belongs to. There is no self-service key regeneration; a correct key that is still refused points at the account — contact PayMe. | | Garbled Hebrew or `?` characters in responses | Request not sent as UTF-8, or fields containing Hebrew quotation marks (for example בע"מ) | Send UTF-8; test with an ASCII-only value to isolate the field. | | "Merchant not allowed to use this buyer" | The token was captured at account level, not for this seller | Re-capture the card with `"buyer_is_private": true` on the capturing call (`generate-sale` with `capture_buyer`, or `capture-buyer-token`). | | Callbacks not arriving | URL, firewall, slow reply or signature problems | Send `sale_callback_url` on every `generate-sale` (and `sub_callback_url` on `generate-subscription`); there is no dashboard callback setting for a seller; make the endpoint publicly reachable (no VPN or firewall); reply `200` within the timeout; verify the signature as described on [Callbacks](https://docs.payme.io/payments/getting-started/callbacks). | ### Card declines Declines return HTTP 200 with `status_code: 1`. Codes `21xxx` are card problems; `20xxx` are refusals from the card company or gateway. | Code | Message | |------|---------| | `20004` | Refusal by credit company. Please try a different card | | `21001` | The card is blocked | | `21002` | The card is stolen | | `21004` | The card is expired | | `21005` | Incorrect card number | | `21006` | The credit limit has been reached | | `21007` | CVV/ID is required but was not entered | | `21008` | Incorrect CVV or ID | | `21017` | 3D Secure authentication failed. The buyer didn't complete the challenge, or the issuer rejected it | The sandbox test cards that produce each one are on [Test Cards and Payment Methods](https://docs.payme.io/payments/getting-started/test-cards-and-payment-methods#credit-card-numbers-for-testing-specific-responses-and-errors). ### Bit Bit requests end with their own codes. They are per-transaction outcomes, not account problems. | Code | Meaning | What to do | |------|---------|------------| | `23001` | The buyer rejected the Bit request | Let the buyer retry or choose another method. | | `23002` | The Bit request was canceled | Retry. | | `23003` | The Bit request expired before the buyer approved it | Retry, and ask the buyer to approve it in the Bit app straight away. | ### Setup, seller and saved-card errors | Code | Meaning | What to do | |------|---------|------------| | [`21`](https://docs.payme.io/agents/errors/error-21) | A callback or return URL was refused, often a local address. The whole call fails | Leave the field out when the address is local, or use a public one. | | [`25`](https://docs.payme.io/agents/errors/error-25) | Phone number refused | Send `seller_phone` in international format, such as `+972501234567`. | | [`42`](https://docs.payme.io/agents/errors/error-42) | A value that must be whole has decimals, for example `sale_price` on `capture-sale` | Send integer minor units. | | [`114`](https://docs.payme.io/agents/errors/error-114) | Business type doesn't fit the seller's details | Read the message. For sole proprietors, `seller_inc_code` must equal `seller_social_id`. | | [`116`](https://docs.payme.io/agents/errors/error-116) | `seller_birthdate` is unreadable, or the person is under 16 | Send `dd/mm/yyyy`. | | [`118`](https://docs.payme.io/agents/errors/error-118) | `seller_social_id_issued` is unreadable or in the future | Send `dd/mm/yyyy`. | | [`121`](https://docs.payme.io/agents/errors/error-121) | `seller_inc_code` isn't numeric | Send digits only. | | [`174`](https://docs.payme.io/agents/errors/error-174) | Not supported for this seller type, usually a partner's own MPL used on `generate-sale` | Use the seller's MPL. | | `303` | "Could not access sale": the sale isn't this seller's or this partner's | Check `seller_payme_id`, `payme_client_key` and the sale ID. | | [`304`](https://docs.payme.io/agents/errors/error-304) | `market_fee` is negative (a non-numeric `market_fee` returns `10`) | Send a number from `0` to `60`. | | [`308`](https://docs.payme.io/agents/errors/error-308) | The fee is above 60% | Keep it at 60% or below. | | `367` | The sale has expired, after its `sale_expiry_seconds` | Create a new sale. | | [`420`](https://docs.payme.io/agents/errors/error-420) | No connected terminal accepts this payment | If every card fails, no terminal is connected: ask PayMe. If only some payments fail, the account's terminals don't accept something in this one: the currency, the card brand, a foreign card, the amount, the number of installments, or the account's processing limit. Fewer installments or a currency the account allows can fix it; otherwise quote `session` to PayMe. | | [`604`](https://docs.payme.io/agents/errors/error-604) | The saved-card token is inactive, often a single-use token charged again | Capture the card again. | | [`605`](https://docs.payme.io/agents/errors/error-605) | The token doesn't belong to this seller | Charge it on a seller that can use it. | | [`790`](https://docs.payme.io/agents/errors/error-790) | The plan requires or refuses the field named in `status_additional_info`, often `seller_id` | Add or remove that field. | | `907` | The seller is on an automatic withdrawal plan, so manual withdrawals aren't allowed | PayMe pays out on the plan's schedule. | ### Answers for common errors These codes each have a page with causes and fixes: [`10`](https://docs.payme.io/agents/errors/error-10), [`21`](https://docs.payme.io/agents/errors/error-21), [`25`](https://docs.payme.io/agents/errors/error-25), [`42`](https://docs.payme.io/agents/errors/error-42), [`109`](https://docs.payme.io/agents/errors/error-109), [`114`](https://docs.payme.io/agents/errors/error-114), [`116`](https://docs.payme.io/agents/errors/error-116), [`118`](https://docs.payme.io/agents/errors/error-118), [`121`](https://docs.payme.io/agents/errors/error-121), [`130`](https://docs.payme.io/agents/errors/error-130), [`163`](https://docs.payme.io/agents/errors/error-163), [`174`](https://docs.payme.io/agents/errors/error-174), [`200`](https://docs.payme.io/agents/errors/error-200), [`201`](https://docs.payme.io/agents/errors/error-201), [`251`](https://docs.payme.io/agents/errors/error-251), [`252`](https://docs.payme.io/agents/errors/error-252), [`304`](https://docs.payme.io/agents/errors/error-304), [`305`](https://docs.payme.io/agents/errors/error-305), [`308`](https://docs.payme.io/agents/errors/error-308), [`352`](https://docs.payme.io/agents/errors/error-352), [`420`](https://docs.payme.io/agents/errors/error-420), [`516`](https://docs.payme.io/agents/errors/error-516), [`604`](https://docs.payme.io/agents/errors/error-604), [`605`](https://docs.payme.io/agents/errors/error-605), [`790`](https://docs.payme.io/agents/errors/error-790), [`998`](https://docs.payme.io/agents/errors/error-998). [Troubleshooting by Symptom](https://docs.payme.io/agents/errors/troubleshooting) helps when the code doesn't explain it. The address is predictable: `/agents/errors/error-` followed by the code. ### Other codes Other codes shown on endpoint pages: `356` invalid credit-card expiry (3D Secure initialize, capture-buyer-token); `600` buyer not found (get-buyer-key); `720` the service was not activated on the account, with the service name in `status_additional_info` (Apple Pay, Google Pay, B2B transfer); `901` invalid JSON (get-transactions); `906` withdrawal not found (credit-match). ### Codes seen in real integrations (from PayMe support) | Code | Meaning | What to do | |------|---------|------------| | `4` | "Not implemented" (HTTP 500) on `POST /sales`: no payment block, or `sale_type: credit` on a non-card method | Send a payment block; use `credit` only with cards. | | `109` | Seller not validated or approved | Complete the account verification. | | `516` | Capture more than 7 days after the authorization | The authorization can no longer be captured; it is not voided by this error. Release it with `refund-sale`, otherwise the card issuer releases it on its own schedule. | | `518` | "Cannot find authorization transaction": the authorization is no longer open (already captured, voided or failed). A capture with `sale_price: 0` returns `352`, not `518` | Check the sale with `get-sales`. A capture isn't a way to release a hold; use `refund-sale` on the authorized sale. | | `752` | "Invoice document generation failed": the invoicing provider rejected the document, usually its credentials | Check the invoicing service settings on the account. | | `20001` | The acquirer declined a forwarded void or refund | Contact PayMe with `payme_sale_id` and the time. | ### Israeli direct debit When a bank authorization changes, the `sale-il-direct-debit-update` callback carries `authorization_status` and `authorization_error_code`. | `authorization_status` | Meaning | Effect | |------------------------|---------|--------| | `1` | Success | Authorization active | | `2` | Failed | Failed | | `3` | Canceled | Canceled | | `4` | Unknown | Failed | | `5` | Moved from previous account | Failed | | `6` | Account changed | Failed | | `13` | Frozen authorization reactivated | Authorization active | | `14` | Sent to the bank | Pending | | `15` | Sent to the bank again | Pending | | `16` | Details missing | Failed | | `17` | Details incorrect | Failed | | `18` | Already processed (success) | Authorization active | `authorization_error_code` is passed through unchanged from the bank side. Statuses `14` and `15` keep the authorization pending and normally send no callback. ## Other APIs Error formats of the other APIs are documented with them: [B2B payment contracts](https://docs.payme.io/b2b-payments/contracts/overview#errors), [Keep](https://docs.payme.io/keep/partners-api/overview#errors-and-rate-limits), [Products & Customers](https://docs.payme.io/products-and-customers/authentication/hosts-authentication-and-errors#errors). ## Related status lists Not errors, but often needed when handling them: [Sale Statuses](https://docs.payme.io/payments/codes-statuses/sale-statuses), [Transaction Statuses](https://docs.payme.io/payments/codes-statuses/transaction-statuses), [Subscription Statuses](https://docs.payme.io/payments/codes-statuses/subscription-statuses). - [Idempotency and Retries](https://docs.payme.io/payments/getting-started/idempotency-and-retries): PayMe has no idempotency key and does not de-duplicate transaction_id: two generate-sale calls create two sales. A second pay-sale, refund-sale or capture-sale for the same sale while the first is running gets HTTP 429 code 998; once it finished, a retry runs again (a repeated partial refund is a second refund; a paid sale paid again gets 305). After a timeout, check sale_status via POST /get-sales (filter by sale_payme_id or transaction_id) before retrying. generate-sale, pay-sale, capture-sale and other payment calls share a per-seller rate limit, 100 requests per 10 s by default. ## Related - [Errors](https://docs.payme.io/payments/getting-started/errors) - [Callbacks](https://docs.payme.io/payments/getting-started/callbacks) - [Refund a sale](https://docs.payme.io/payments/post-sale-actions/post-refund-sale) - [List sales](https://docs.payme.io/payments/query-apis/post-get-sales) - [Authorize now, capture later](https://docs.payme.io/accepting-payments/capture-and-saved-cards/capture-sale) # Idempotency and Retries "Idempotent" means that sending the same request twice has the same effect as sending it once. **PayMe has no idempotency key**, so you must make retries safe yourself. ## What happens when a request runs twice | Request | Second call while the first is **still running** | Second call **after** the first finished | |---------|-----------------------------------------------|------------------------------------------| | `generate-sale` | A second, separate sale | A second, separate sale — `transaction_id` is **not** checked for uniqueness | | `generate-sale` with `buyer_key` / token (creates **and charges**) | A second charge is possible | A second charge is possible | | `pay-sale` | Rejected: HTTP 429, code `998` "Duplicated action detected, please retry later" | If the first succeeded: rejected with HTTP 500, code `305`, current status in `status_additional_info`. If the first failed: accepted as a **new charge attempt**. | | `refund-sale` — partial | Rejected: HTTP 429, code `998` | **Runs again** — a second refund, as long as refundable balance remains | | `refund-sale` — full | Rejected: HTTP 429, code `998` | Rejected with code `305` | | `capture-sale` | Rejected: HTTP 429, code `998` | An authorization can be captured only once. | Notes: - **`transaction_id` is your own reference.** PayMe stores and returns it but does not reject duplicates: each `generate-sale` creates a new sale with its own `payme_sale_id`. - **`generate-sale` with `buyer_key`** creates a new sale on every call before it charges the token, so a refused charge still leaves a sale behind. - **Template sales:** each `pay-sale` on a template creates a new sale, so the protections above do not apply to template sales. - PayMe does not promise that a retried payment can never charge twice. Check before you retry. - An authorization lasts up to 168 hours; a capture after that fails. A void can release the full authorized amount or part of it. ## Before retrying, check the sale If a request timed out and you do not know whether it ran, look the sale up instead of resending it. [`POST /get-sales`](https://docs.payme.io/payments/query-apis/post-get-sales) accepts these filters: - `sale_payme_id` — PayMe's sale ID (one sale); - `transaction_id` — your order ID. Because `transaction_id` is not unique, this can return several sales. **By default `get-sales` leaves out unpaid sales** (status `initial`). To find an unpaid sale, pass `sale_status` including `initial`. `get-sales` works with `seller_payme_id` alone; partners can also use `payme_client_key`. **How to tell whether a timed-out operation ran:** read `sale_status` from `get-sales` — a capture shows `completed` (not `authorized` or `failed`), a full refund `refunded`, a void a voided status. After a partial refund the status is `partial-refund`, and it stays `partial-refund` even once partial refunds reach the full amount, so track the refunded total yourself. `sale_status` alone cannot show whether a **retried partial refund** already ran: compare `sale_refund_buffer` (the amount still refundable, returned by `refund-sale` and sent in each `refund` callback — `get-sales` does not return it) or count the `refund` callbacks, each of which has its own `payme_transaction_id`. ## Retrying safely 1. Retry only on network errors, timeouts, HTTP 429 code `998`, or codes `991`, `20002` and `999`, whose outcome is unknown. Never retry a response with `status_code` `1` that names a problem with your input. 2. On `998`, wait (honour the `Retry-After` header), then **check the sale** before retrying. 3. Before retrying anything that moves money (`pay-sale`, `refund-sale`, `capture-sale`, `generate-sale` with `buyer_key`), check the sale's current state as above. 4. Store PayMe's `payme_sale_id` as soon as `generate-sale` returns, so every later step refers to one sale. 5. Treat callbacks as confirmation, and process each one once — see [Callbacks](https://docs.payme.io/payments/getting-started/callbacks). ## PayMe's own retries - **Callbacks:** up to 3 attempts within about 90 seconds (30 s, then 60 s), then dropped. Details on [Callbacks](https://docs.payme.io/payments/getting-started/callbacks). - **Subscriptions:** a failed scheduled charge, including the first, puts the subscription in status `7` ("Failed - Pending automatic retry") only when another attempt is allowed. PayMe retries once a day, up to 7 attempts in total. A daily subscription and the seventh consecutive failure instead put it in status `5` and send `sub-cancel`, without `sub-failure`. Details on [Recurring Payments](https://docs.payme.io/payments/saved-cards-recurring). ## Rate limits - One **per-seller** limit is shared by `generate-sale`, `pay-sale`, `capture-sale`, `POST /sales`, `capture-buyer-token`, `POST /tokens`, the 3D Secure calls and `get-future-withdrawals`. By default it allows **100 requests per 10 seconds**. `get-transactions` has the same limit; it is counted per partner when you send `payme_client_key`. - PayMe can set a different limit for a partner. It then applies to each of the partner's sellers separately. Partners can read theirs from `GET /partners` (`technical.rate_limit_max_attempts`, `technical.rate_limit_decay_seconds`). - Over the limit: **HTTP 429**, `status_error_code` `998`, `status_additional_info` `"Too Many Attempts."`, and the headers `X-RateLimit-Limit`, `X-RateLimit-Remaining`, `Retry-After` and `X-RateLimit-Reset`. - `refund-sale` and `get-sales` have no rate limit. The default applies to both environments unless PayMe has set a different limit for your partner. To request a higher limit, write to with the limit you need, whether it is a burst or a permanent need, and your current plan; increases are reviewed by PayMe's technical team. Until then, handle `429` with exponential backoff and request spacing. Keep's rate limit is documented on [Keep → Partner API overview](https://docs.payme.io/keep/partners-api/overview#errors-and-rate-limits). - [Get API access and go live: from sandbox to production](https://docs.payme.io/payments/getting-started/go-live): Launch path for the PayMe Payments API. Keys: seller_payme_id (MPL, server only) and the public key (browser) are on Admin → API & Integration; install the API service if it's missing. Partners also get payme_client_key and a client password. Sandbox: Switch to test account → Create test account; no account: register at paid.co.il (הרשמה). Test on sandbox.payme.io/api; go live on live.payme.io/api with production keys, testMode false, the production Apple Pay domain file, services active (720), public callback URLs (21) and get-sales checks. ## Prerequisites - A PayMe account, or a registration at paid.co.il ## Related - [Authentication](https://docs.payme.io/payments/getting-started/authentication) - [Environments](https://docs.payme.io/payments/getting-started/environments) - [Test Cards and Payment Methods](https://docs.payme.io/payments/getting-started/test-cards-and-payment-methods) - [Quickstart](https://docs.payme.io/payments/getting-started/quickstart) - [Callbacks](https://docs.payme.io/payments/getting-started/callbacks) - [Errors](https://docs.payme.io/payments/getting-started/errors) - [Idempotency and Retries](https://docs.payme.io/payments/getting-started/idempotency-and-retries) - [Hosted Fields JSAPI guide](https://docs.payme.io/accepting-payments/checkout-and-in-person/hosted-fields-jsapi-guide) - [Accept Apple Pay](https://docs.payme.io/accepting-payments/payment-methods/apple-pay) - [Accept Google Pay](https://docs.payme.io/accepting-payments/payment-methods/google-pay) # Get API access and go live: from sandbox to production This guide puts the launch steps in order: get the right credentials, open your sandbox account, test what you built, then switch to production with the checklist below. Each step links to the reference page with the details. ## Step 1: Know which credentials you need | Credential | Who has it | What it's for | Where to find it | |---|---|---|---| | `seller_payme_id` (the MPL) | Every seller | Identifies and authenticates the seller on server calls such as `generate-sale` and `refund-sale`. Keep it on your server. | Dashboard: **Admin → API & Integration** (API ואינטגרציה) | | Public key | Every seller, one per environment | Browser code: `PayMe.create(publicKey, …)` for Hosted Fields, Apple Pay and Google Pay | The same page, section **Hosted Fields JSAPI Credentials** | | `payme_client_key` | Partners (platforms and marketplaces) only | Partner calls such as `create-seller`, and queries across your sellers | Issued by PayMe Partners () | | Client password | Partners only | Verifying `payme_signature` on callbacks | Issued together with `payme_client_key` | - A seller account has no `merchant_key`, `merchant_password` or `payme_client_key`. A seller that puts its own MPL in `payme_client_key` gets error `200`: remove the field and send `seller_payme_id` alone. - Every credential belongs to one environment. The sandbox and production are separate accounts, and a sandbox key is rejected in production, and the reverse. - Only the public key may appear in browser or mobile code. Where each credential goes in a request: [Authentication](https://docs.payme.io/payments/getting-started/authentication). ### If the API & Integration page is missing The page appears once the API service is installed on the account. Install it from the dashboard app store (חנות אפליקציות). Depending on your account, it may carry a charge. ## Step 2: Open your sandbox account The sandbox is free and asks for no signatures. - **You already have a PayMe account:** in the dashboard, click your name at the top, then **Switch to test account** → **Create test account**. - **You have no account yet:** register at → "הרשמה" (Register), then open 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 test account shows a white top bar, and production a green one. To switch back, click your name → **Switch to live account**. While the test account is open, **Admin → API & Integration** shows your sandbox MPL and public key. A test account can't be converted into a live account. Sandbox tokens (`buyer_key`) and sandbox MPLs don't work in production. If you can't open the test account, contact PayMe: for dashboard and account questions, for integration questions. ## Step 3: Build and test in the sandbox Send every sandbox call to `https://sandbox.payme.io/api/` with your sandbox credentials. Send `"language": "en"` to get error messages in English. The [Quickstart](https://docs.payme.io/payments/getting-started/quickstart) runs the first checks below with `curl`. ```bash 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", "sale_callback_url": "https://your-server.example.com/payme/callback", "sale_return_url": "https://your-site.example.com/payment/success", "language": "en" }' ``` The callback URL must be a public address even in the sandbox. `localhost`, private and loopback IP addresses and IPv6 addresses fail the whole call with error `21`. See [Callback URL rules](https://docs.payme.io/payments/getting-started/callbacks#callback-url-rules). Run these checks before you go live: | Check | How | What you should see | |---|---|---| | Create a sale | [generate-sale](https://docs.payme.io/payments/hosted-payment-page/post-generate-sale), as above | `status_code` `0`, a `sale_url` and a `payme_sale_id`. Store `payme_sale_id` with your order. | | Pay it | Open `sale_url` and pay with `5326105300985846`, expiry `12/30`, CVV `658`, ID `008336174` | The buyer is redirected to `sale_return_url` | | Receive the callback | Your `sale_callback_url` | A form-encoded `POST` with `notify_type` `sale-complete`. Reply `200` within 5 seconds. | | Confirm the sale | [get-sales](https://docs.payme.io/payments/query-apis/post-get-sales) with `sale_payme_id` | `sale_status` `completed` and the `sale_price` of your order | | Handle a decline | Pay with `4000000000000002` | Error `20004`, and a `sale-failure` callback | | Refund | [refund-sale](https://docs.payme.io/payments/post-sale-actions/post-refund-sale) with `seller_payme_id` and `payme_sale_id` | `status_code` `0`, and a `refund` callback | If your sales go through 3D Secure, test the challenge too: the cards and the rules that select a sale are on [3D Secure in the sandbox](https://docs.payme.io/payments/getting-started/test-cards-and-payment-methods#3d-secure-in-the-sandbox). The challenge code is `555`. All test data, including the other decline cards, Apple Pay cards and bank accounts, is on [Test Cards and Payment Methods](https://docs.payme.io/payments/getting-started/test-cards-and-payment-methods). ### What the sandbox doesn't cover - **Invoices and receipts:** the invoicing service doesn't run in the sandbox. Test documents on a small live sale that you refund straight away. - **Apple Pay on your own page:** ask PayMe which environment to test it in. See [Accept Apple Pay](https://docs.payme.io/accepting-payments/payment-methods/apple-pay). ## Step 4: Go-live checklist Work through every item before your first live sale. ### Credentials and URLs - [ ] Every server call goes to `https://live.payme.io/api/`. - [ ] You use the production MPL and the production public key. Partners also use the production `payme_client_key` and client password. - [ ] Credentials come from your server's configuration, not from code. The MPL, `payme_client_key` and client password never reach the browser or a mobile app. A credential from the other environment fails: a sandbox MPL in production returns `163` or `251`, and a partner key from the other environment returns `200`. See [Errors](https://docs.payme.io/payments/getting-started/errors). ### Browser code - [ ] `PayMe.create(publicKey, { testMode: false })`, with the production public key. `testMode` is the only switch: load the same Hosted Fields script URL in both environments. See [Hosted Fields](https://docs.payme.io/accepting-payments/checkout-and-in-person/hosted-fields-jsapi-guide). - [ ] With 3D Secure on Hosted Fields: `PayMe.clientData(false)`, or no argument. See [3DS with Hosted Fields](https://docs.payme.io/accepting-payments/3d-secure/3ds-with-hosted-fields). - [ ] With Google Pay on your own page: `PayMe.isGooglePayAvailable(false)`. - [ ] If your site sets a Content Security Policy, it allows the production hosts that the Hosted Fields, Apple Pay and Google Pay pages list, and the host of the 3D Secure `redirect_url` you receive (a `paymeservice.com` address). See [Environments](https://docs.payme.io/payments/getting-started/environments). ### Test data - [ ] Test card numbers, test bank accounts and test seller values (such as `9999999999` and `random@paymeservice.com`) are gone from production code, configuration and forms. - [ ] Nothing from the sandbox, such as tokens or MPLs, is reused in production. ### Payment methods and services - [ ] Every payment method you offer is active on the production account. A seller installs Apple Pay, Google Pay or Bit from the production dashboard's app store. A partner calls `vas-enable` against `live.payme.io`. A missing service fails with error `720`. - [ ] 3D Secure, if you need it, is enabled on the production account. PayMe enables it, so confirm with PayMe before launch. Google Pay cards saved in the buyer's Google account always go through 3D Secure, and fail with error `21017` without the service. - [ ] **Apple Pay on your own page:** every domain that shows the button serves the **production** domain file, downloaded from `https://live.payme.io/.well-known/apple-developer-merchantid-domain-association`, and the domains are registered in production. The sandbox file is different, and a mismatch fails the call with error `703`. See [Host PayMe's domain file](https://docs.payme.io/accepting-payments/payment-methods/apple-pay#step-1-host-paymes-domain-file). Apple Pay on PayMe's Hosted Payment Page needs no file. - [ ] **Google Pay on your own page:** your registration in the Google Pay & Wallet Console is complete, and PayMe Partners confirmed it. See [Accept Google Pay](https://docs.payme.io/accepting-payments/payment-methods/google-pay). - [ ] The production account allows each currency you charge (error `252`) and the number of installments you offer. More than 12 installments must be enabled by PayMe. ### Callbacks - [ ] Every `generate-sale` sends `sale_callback_url`, and every subscription sends `sub_callback_url`, pointing at your production endpoint. A seller has no dashboard setting for a default. - [ ] The endpoint is public, uses HTTPS and replies `200` within 5 seconds. - [ ] Partners verify `payme_signature` with the production `payme_client_key` and client password. - [ ] Your handler ignores repeats (`notify_type` + `payme_sale_id` + `payme_transaction_id`) and confirms the sale with `get-sales` before you fulfil an order. - [ ] You don't allow-list callbacks by IP address: PayMe doesn't publish a fixed list. Details: [Callbacks](https://docs.payme.io/payments/getting-started/callbacks). ### Retries, limits and monitoring - [ ] A timed-out call that moves money is checked with `get-sales` before it is retried. PayMe has no idempotency key. - [ ] HTTP 429 with error `998` is handled with backoff. Payment calls share a per-seller rate limit: see [Rate limits](https://docs.payme.io/payments/getting-started/idempotency-and-retries#rate-limits). - [ ] A scheduled job reconciles your orders with `get-sales`, because a callback is dropped after 3 failed attempts. - [ ] You log the `session` value of each response, so you can quote it to PayMe. ### First live payment Run one real sale for a small amount with your own card, and refund it. Check that the callback arrived and that `get-sales` shows the sale. If PayMe issues invoices for your sales, check the document on this sale too. ## If a key leaks There is no self-service key rotation. If you think a key has leaked, contact PayMe support at once. If PayMe moves a partner to a new client key, your API calls can use the new key straight away. The callback signature stays on your primary client key until PayMe completes the switch. ## After launch - **A callback didn't arrive:** look the sale up with `get-sales`. By default it leaves out unpaid sales (status `initial`), so add `initial` to `sale_status` to see them. If your endpoint keeps failing or timing out, PayMe pauses deliveries to your host for a while; see [Retries](https://docs.payme.io/payments/getting-started/callbacks#retries). - **An error you don't recognize:** look the code up on [Errors](https://docs.payme.io/payments/getting-started/errors). - **Need help:** write to for integration questions and quote the `session` value. PayMe's [Status Page](https://status.payme.io/) shows incidents and maintenance. ## Partners If you are a platform or marketplace: - PayMe Partners issues your `payme_client_key` and client password. - Each of your sellers has its own MPL and public key in each environment. Production sellers are created with `create-seller` on `live.payme.io`, which returns their production MPL and public key. - Create test sellers in the sandbox with the values on [Creating test sellers](https://docs.payme.io/payments/getting-started/test-cards-and-payment-methods#creating-test-sellers-partners). The whole partner flow is on [Start here: build a platform or marketplace on PayMe](https://docs.payme.io/marketplaces-and-platforms/start-here/how-platforms-work). - [Move your PayMe account to a new website or platform](https://docs.payme.io/payments/getting-started/connect-a-new-website): A PayMe account isn't tied to a website: sales, payouts, services and API keys (MPL and public key, per environment) carry over. Plugin sites (Wix, Shopify and similar): follow the plugin's setup or contact PayMe support. Own site: keys on Admin → API & Integration (install the API service if missing), MPL on the server only, Quickstart, go-live. Errors 200, 251/163, 1, 21, 720. Several sites: send sale_callback_url and sale_return_url on every sale; Apple Pay and Google Pay on your own page are set up per domain. Automations: webhook URL as sale_callback_url, confirm with get-sales. ## Prerequisites - A PayMe seller account with access to the dashboard ## Related - [Authentication](https://docs.payme.io/payments/getting-started/authentication) - [Quickstart](https://docs.payme.io/payments/getting-started/quickstart) - [Get API access and go live: from sandbox to production](https://docs.payme.io/payments/getting-started/go-live) - [Callbacks](https://docs.payme.io/payments/getting-started/callbacks) - [Callback types reference](https://docs.payme.io/payments/getting-started/callback-types) - [Errors](https://docs.payme.io/payments/getting-started/errors) - [Create a sale (hosted payment page)](https://docs.payme.io/payments/hosted-payment-page/post-generate-sale) - [List sales](https://docs.payme.io/payments/query-apis/post-get-sales) - [Accept Apple Pay](https://docs.payme.io/accepting-payments/payment-methods/apple-pay) - [Accept Google Pay](https://docs.payme.io/accepting-payments/payment-methods/google-pay) # Move your PayMe account to a new website or platform Your PayMe account isn't tied to one website. When you move to a new site, or add another one, you connect the same account there. How you connect depends on how the new site takes payments: through a plugin of the site's platform, or through your own code with the PayMe API. This page covers both, running one account on several sites, and sending payment events to automation tools such as Make or Zapier. ## What stays with your account - Your sales, payouts, payment methods and services (such as Apple Pay, Google Pay and Bit) belong to your PayMe account, not to a website. You manage them in the PayMe dashboard, whatever site you use. - Your API credentials belong to the account and to an environment (the sandbox or production), not to a website. The same `seller_payme_id` (MPL) and public key work on your new site. - Apple Pay and Google Pay **on your own page** are the exception: they are set up per domain. See [Run one account on several sites](#run-one-account-on-several-sites). ## Step 1: Choose how the new site connects | Your new site | How it connects to PayMe | |---|---| | Runs on a platform where you add PayMe as a plugin or app, such as Wix or Shopify | Through that plugin. Follow the plugin's own setup, or contact [PayMe support](https://help.payme.io). | | Your own code, or a site builder or AI tool that lets you run code on a server | The PayMe API: [step 2](#step-2-connect-your-own-site-with-the-api) | Plugin setup, including which PayMe details a plugin asks for, is in the plugin's own instructions. If they aren't clear, contact PayMe support before you enter any PayMe key into a plugin. ## Step 2: Connect your own site with the API 1. **Find your credentials.** In the PayMe dashboard, open **Admin → API & Integration** (API ואינטגרציה). It shows your MPL and your public key. If the page is missing, install the API service from the dashboard app store (חנות אפליקציות) first; depending on your account, it may carry a charge. 2. **Put each key where it belongs.** The MPL identifies and authenticates your account on server calls, so it stays on your server. Only the public key may appear in browser code. See [Authentication](https://docs.payme.io/payments/getting-started/authentication). 3. **Build and test in the sandbox.** Open your test account from the dashboard and follow the [Quickstart](https://docs.payme.io/payments/getting-started/quickstart): create a sale, pay it with a test card, receive the callback and refund it. 4. **Go live** with the checklist in [Get API access and go live](https://docs.payme.io/payments/getting-started/go-live). ### If an AI tool or site builder writes your code - Create sales from server-side code, such as a backend or serverless function. Your MPL must never appear in the page's code. - `sale_callback_url` and `sale_return_url` must be public addresses. A preview on `localhost` or a private IP address fails the whole call with error `21`. See [Callback URL rules](https://docs.payme.io/payments/getting-started/callbacks#callback-url-rules). - Give the tool PayMe's [AI Toolkit](https://docs.payme.io/agents) and the pages linked here, rather than older examples from elsewhere. ### When the key "doesn't work" on the new site | What you see | Usual cause | Fix | |---|---|---| | Error `200` "Merchant was not found" | Your MPL was sent as `payme_client_key` | Remove `payme_client_key` and send `seller_payme_id` alone. A seller account has no `payme_client_key` | | Error `251` or `163` | A sandbox MPL sent to production, or the reverse | Use the MPL of the environment you call: `https://sandbox.payme.io/api` or `https://live.payme.io/api` | | Error `1` | No key in the request | Send `seller_payme_id` in the JSON body | | Error `21` | A callback or return URL that isn't a public address | Use your site's public HTTPS address | | Error `720` | The payment method isn't active on your account | Install it from the dashboard app store | | Hosted Fields don't accept the key | The public key of the other environment, or the wrong `testMode` | Use the public key of the same environment as `testMode` | More codes are on [Errors](https://docs.payme.io/payments/getting-started/errors). ## Run one account on several sites One PayMe account can take payments on several sites at once. They share one account: one balance, one set of payouts and one set of services. - **Send both URLs on every sale.** Each `generate-sale` carries its own `sale_callback_url` and `sale_return_url`, so each site gets its own callbacks and its own result page. A seller account has no dashboard setting for a default callback URL. - **Tell the sites' orders apart.** Give each site its own `transaction_id` format, for example `siteA-1001`, or its own callback URL, and store each sale's `payme_sale_id` with the order. `get-sales` filters are exact matches, so look a sale up by its `payme_sale_id`, not by a prefix. - **Apple Pay on PayMe's payment page** (the `sale_url`) needs no domain setup, on any site. - **Apple Pay on your own page** (the browser SDK) needs PayMe's domain file on every domain and subdomain that shows the button, and each domain registered. A seller without a partner asks PayMe Partners () to register its domains. See [Accept Apple Pay](https://docs.payme.io/accepting-payments/payment-methods/apple-pay). - **Google Pay on your own page:** approved domains are managed in the Google Pay & Wallet Console, not in PayMe. Add the new site's domain there. See [Accept Google Pay](https://docs.payme.io/accepting-payments/payment-methods/google-pay). ## Send payment events to an automation tool Tools such as Make and Zapier can start a workflow from a PayMe callback. 1. In the automation tool, create a webhook trigger and copy its URL. 2. Send that URL as `sale_callback_url` when you create each sale. PayMe sends a form-encoded `POST` with fields such as `notify_type`, `payme_sale_id`, `sale_status` and `price`. A paid sale sends `notify_type` `sale-complete`. Every type is on [Callback types reference](https://docs.payme.io/payments/getting-started/callback-types). 3. Before the workflow acts (ships an order, adds a customer to your CRM), confirm the sale. Add an HTTP step that calls [`get-sales`](https://docs.payme.io/payments/query-apis/post-get-sales) with your MPL and the callback's `payme_sale_id`, and check that `sale_status` is `completed` and `sale_price` matches. A seller without a partner key can't verify the callback's `payme_signature`, so this check is your verification. ```json { "seller_payme_id": "MPLDEMO-MPLDEMO-MPLDEMO-1234567", "sale_payme_id": "SALE1767-704312AB-CD3FGH12-JKLM4567" } ``` - Store your MPL in the tool's secure credential settings, not in the text of a shared workflow. - PayMe makes up to 3 attempts to deliver a callback, then drops it. Add a scheduled workflow that lists the day's sales with `get-sales` (`sale_created_min`, `sale_status`) to catch any you missed. - If a plugin creates your sales, the plugin sets their callback URL, and you can't add your own. Check the plugin's own options for notifications, or use the scheduled `get-sales` workflow. ## Switch-over checklist - [ ] The new site is connected: through its plugin's setup, or through the API with production keys kept on the server. - [ ] With the API: every sale the new site creates sends `sale_callback_url` and `sale_return_url` that point to the new site. - [ ] Apple Pay or Google Pay on your own page: the new domains are set up. - [ ] Automations listen to the new site's events. - [ ] Payment pages your old site already created stay payable until they are paid or expire, and their callbacks still go to the old site's callback URL. Keep that URL working until those sales are settled. - [ ] You no longer use the old site: remove PayMe from it as its plugin's instructions describe, or ask PayMe support. - [ ] You ran one small live payment on the new site, checked the callback and `get-sales`, and refunded it. ## Hosted Payment Page - [Hosted Payment Page](https://docs.payme.io/payments/hosted-payment-page): A payment page hosted by PayMe: create a sale with generate-sale and show the returned sale_url in an iframe or a redirect. Card and bank details never reach your servers. # Hosted Payment Page PayMe hosts the payment page, so card and bank details never reach your servers and PCI DSS stays with PayMe. Create a sale with [`generate-sale`](https://docs.payme.io/payments/hosted-payment-page/post-generate-sale), then show the returned `sale_url` to the buyer in an iframe or a redirect. One page can offer every payment method enabled on the account: send `sale_payment_method: multi` ([Create a multi-method checkout sale](https://docs.payme.io/payments/hosted-payment-page/post-generate-sale-2)). - [Create a sale (hosted payment page)](https://docs.payme.io/payments/hosted-payment-page/post-generate-sale): POST /generate-sale — Create a sale (hosted payment page) # Create a sale (hosted payment page) - 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-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. - Request body field `payme_client_key` (optional): 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`. ## Overview Creates a sale and returns `sale_url`, PayMe's payment page for it. Show `sale_url` to the buyer in an iframe or a redirect. PayMe sends the result to `sale_callback_url` and redirects the buyer to `sale_return_url`. `POST https://sandbox.payme.io/api/generate-sale` (production: `https://live.payme.io/api/generate-sale`), with a JSON body (`Content-Type: application/json`). | To | Send | |---|---| | Charge now (J4) | `sale_type: sale` (default) | | Authorize now, capture later (J5, up to 168 hours) | `sale_type: authorize`; then [capture-sale](/accepting-payments/capture-and-saved-cards/capture-sale) | | Let many buyers pay one link | `sale_type: template` ([Template sales](/accepting-payments/checkout-and-in-person/multi-payment-page)) | | Save the card while charging | `capture_buyer: 1` | | Save the card without charging | `sale_type: token` ([Save a card](/payments/tokenization/post-generate-sale-tokenization)) | | Charge a saved card now (no page) | `buyer_key` ([Save a card and charge it later](/accepting-payments/capture-and-saved-cards/save-a-card-and-charge-it-later)) | | Offer every payment method on one page | `sale_payment_method: multi` ([Multi-method checkout](/payments/hosted-payment-page/post-generate-sale-2)) | All sale types are on [Sale Types](/payments/codes-statuses/sale-types), and all payment methods on [Available Payment Methods](/payments/wallets-apms). ### 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](/payments/getting-started/authentication). ### Rules for every request - Amounts are in minor units (`1000` = 10.00). - Never put card numbers in any field. A value (other than `transaction_id` and `order_number`) that contains a 14–19-digit number passing the card checksum is refused with error `20` (HTTP 400), " contains invalid data". - Don't send the legacy `price` field: it is in major units and, when numeric, overrides `sale_price`. - PayMe doesn't de-duplicate `transaction_id`: every call creates a new sale. See [Idempotency and Retries](/payments/getting-started/idempotency-and-retries). - Errors return `status_code: 1` with `status_error_code`, most with HTTP 500. See [Errors](/payments/getting-started/errors). ### 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](/payments/getting-started/callbacks). ### `sale_url` validity and embedding `sale_url` has no fixed expiry. The payment page stays usable while the sale is unpaid: `initial`, or `failed` after a declined attempt. A good card on the same page then completes a `failed` sale, so `failed` isn't final, and opening a second sale gives the buyer two payable pages. The same rule applies to card, Bit, Apple Pay and Google Pay sales. For a hard deadline, send `sale_expiry_seconds` when you create the sale: it closes a `failed` page too. An ordinary open sale has no cancel call. `sale_url` can be shown inside an iframe, 3D Secure included. Some issuing banks block their own 3D Secure screen inside an iframe, so keep a fallback that opens the page in a full window. The page reports completion with a `postMessage` to the parent window and by the redirect to `sale_return_url`. ### Charging a saved card (`buyer_key`) With `buyer_key`, the call charges the token at once: there is no payment page and no `sale_url`. On success the response holds the sale and transaction fields, the same as the callback. A declined charge also returns **HTTP 200**, with `status_code: 1`, so always check `status_code`. Each call creates a new sale, even when the charge is refused. The token's own payment method is used, whatever `sale_payment_method` you send. Errors: a token of another seller returns `605`; an inactive or already-used single-use token returns `604`; a charge over the seller's processing limit returns `130`. ### Issuing an invoice With the invoicing service active on the account, a paid sale issues a document and a refund automatically issues a credit document. To skip the document for one sale, send `"services": [{"name": "invoice", "settings": {"active": false}}]` in the request; dashboard and payment-link sales keep issuing. When you charge a saved card (`buyer_key`) and the invoicing service is active, you can issue the invoice to a business: send `buyer_business_name` (the business name) and `buyer_business_code` (its VAT identifier). 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`. | | `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](https://en.wikipedia.org/wiki/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) or `0`: one payment. `2`–`12`: that fixed number. `102`–`112`: the buyer chooses on the page, up to the last two digits (`106` = up to 6). More than one installment is ILS only (`312`) and works only with `credit-card` or `multi` (other methods return `351`). On a `multi` page that lets the buyer choose, a buyer who pays with Apple Pay or Google Pay pays in one payment. Fixed values above 12 are accepted when the sale is created, but the payment fails unless PayMe has enabled more installments on your account. A non-numeric value returns `10`, any other unaccepted value `351`, and 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`](/accepting-payments/capture-and-saved-cards/capture-sale) (J5). `token` – save the card without charging (the price is set to `100`). `template` – one link that many buyers can pay. `credit` – pay money to the card (needs the Credit Sale service). `multi-capture` – capture part of an authorization (needs `origin_sale_id`). The full list is on [Sale Types](/payments/codes-statuses/sale-types); any other value returns `357`. | | `sale_payment_method` | string | no | Payment method; see [Available Payment Methods](/payments/wallets-apms). Default `credit-card`. Send `multi` to let the buyer choose among every method enabled on the account. Case-insensitive. An unknown value returns `24`; a method not enabled on the account returns `720` with the method name; `bacs` needs `GBP` and `sepa` needs `EUR` (`320`). Send a string: an array returns `368` (HTTP 400). | | `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](/payments/getting-started/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. | | `sale_return_url` | string | no | Where PayMe redirects the buyer (the iframe or the full page) after a successful payment, with the sale details as query parameters; see [Hosted Payment Page options](/accepting-payments/checkout-and-in-person/hosted-payment-page-options). If omitted, your partner's default return URL is used, if one is set. Same address rules as `sale_callback_url` (error `21`). | | `cancel_url` | string | no | Where to send the buyer when 3D Secure authentication fails, instead of back to the payment page. Also the PayPal cancel address. Must be a public URL (error `21`). | | `sale_send_notification` | boolean | no | `true`: PayMe sends the buyer a payment request with the payment link, by email to `sale_email` and by SMS to `sale_mobile`. Default `false`. | | `sale_email` | string | no | Buyer's email. Pre-fills the payment page and receives the payment request when `sale_send_notification` is `true`. | | `sale_mobile` | string | no | Buyer's mobile number. Pre-fills the payment page and receives the SMS payment request when `sale_send_notification` is `true` and the SMS service is active on the account. | | `sale_name` | string | no | Buyer's full name. Pre-fills the payment page (split at the first space into first and last name) and is used in notifications. | | `sale_send_creation_callback` | boolean | no | `true`: PayMe also sends a `sale-create` callback, with `sale_url`, as soon as the sale is created. Default `false`. | | `sale_expiry_seconds` | integer | no | How many seconds the sale stays payable after it is created. After that, the payment page answers HTTP 403 and paying the sale fails with error `367`. Without it, `sale_url` has no fixed expiry. | | `capture_buyer` | string | no | `1` or `true` to save the buyer's card as a token after the payment; the token arrives as `buyer_key` in the callback. Omit it, or send `0`, to skip. Works with `credit-card`, `apple-pay`, `il-direct-debit` and `multi` (other methods return `4`). Can't be combined with `buyer_key` (`601`). | | `buyer_is_private` | boolean | no | With `capture_buyer` or a token sale: `true` ties the token to this seller, so `get-buyer-key` works with the seller's MPL. Without it the token is account-level: any seller of the same partner can charge it, and a `get-buyer-key` call that sends `seller_payme_id` fails with error `603`. | | `buyer_perform_validation` | boolean | no | With `capture_buyer` or a token sale: whether PayMe validates the card with the issuer before saving the token. Default `true`. Sending `true` without `capture_buyer` or a token sale returns `608`. | | `buyer_key` | string | no | Charges a saved token at once: no payment page and no `sale_url` (see the "Token charged" response). The token comes from a callback, [`get-buyer-key`](/payments/tokenization/post-get-buyer-key) or Hosted Fields `tokenize()`. Can't be combined with `capture_buyer` (`601`), `sale_type` `token`/`seller-token` (`602`) or `template` (`606`). | | `buyer_business_name` | string | no | With `buyer_key` and 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 `buyer_key` and the invoicing service: the business code (VAT identifier) the invoice is issued to. Send it together with `buyer_business_name`, or neither. | | `layout` | string | no | Payment page layout: `dynamic` (default), `dynamic-loose` (no social ID or CVV validation), `qr-sms` (Bit: QR code or SMS), `token-capture` (save a card without a charge; requires `sale_type: token`). Other values fall back to `dynamic`. | | `sale_should_be_opened_once` | boolean | no | `true`: with `layout: token-capture`, the page can be opened only once. Ignored otherwise. | | `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`. | | `services` | array | no | Per-sale settings for services on the account, as objects `{"name": "", "settings": {...}}`. For example `[{"name": "invoice", "settings": {"active": false}}]` skips the invoice for this sale, and `[{"name": "3DSecure", "settings": {"active": true}}]` forces 3D Secure. Each object needs `settings` (error `1`). Unknown or inactive services are ignored. | | `sale_deferred_months` | integer | no | Deferred charge: the number of months, `1`–`12`, by which the card charge is deferred. Only for `credit-card` sales of `sale_type` `sale` (other types or methods return `4`); a value outside `1`–`12` returns `365`. PayMe must enable deferred charges on your account. | | `order_number` | string | no | Purchase order number, used for level 2 and level 3 card data. Up to 15 digits. | | `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. | | `fees` | object | no | Amounts included in the payment, for level 2 and level 3 card data. Each is in minor units, up to 12 digits. | | `fees.tax` | number | no | Tax included in the payment. | | `fees.duty` | number | no | International duties included in the payment. | | `fees.discount` | number | no | Total discount given on the payment. | | `fees.shipping` | number | no | Shipping cost included in the payment. | | `shipping_details` | object | no | Where the order is shipped. Stored with the sale. | | `shipping_details.name` | string | no | Addressee's full name or company name, up to 50 characters. | | `shipping_details.email` | string | no | Addressee's email, up to 100 characters. | | `shipping_details.phone` | string | no | Addressee's phone number, up to 50 characters. | | `shipping_details.address` | object | no | The shipping address. | | `shipping_details.address.line1` | string | no | First line of the shipping address. | | `shipping_details.address.line2` | string | no | Second line of the shipping address. | | `shipping_details.address.postal_code` | string | no | Postal code of the shipping address. | | `shipping_details.address.city` | string | no | City of the shipping address. | | `shipping_details.address.state` | string | no | State or region of the shipping address. | | `shipping_details.address.country` | string | no | Two-letter ISO 3166-1 country code, for example `IL`. Other values are ignored. | | `billing_details` | object | no | The payer's billing details. Stored with the sale. | | `billing_details.name` | string | no | Payer's full name or company name. | | `billing_details.email` | string | no | Payer's email. | | `billing_details.phone` | string | no | Payer's phone number. | | `billing_details.address` | object | no | The billing address. | | `billing_details.address.line1` | string | no | First line of the billing address. | | `billing_details.address.line2` | string | no | Second line of the billing address. | | `billing_details.address.postal_code` | string | no | Postal code of the billing address. | | `billing_details.address.city` | string | no | City of the billing address. | | `billing_details.address.state` | string | no | State or region of the billing address. | | `billing_details.address.country` | string | no | Two-letter ISO 3166-1 country code, for example `IL`. Other values are ignored. | ### Request example ```json { "seller_payme_id": "MPLDEMO-MPLDEMO-MPLDEMO-1234567", "sale_price": 1000, "currency": "ILS", "product_name": "Smartphone", "transaction_id": "order-1001", "installments": "1", "sale_type": "sale", "sale_payment_method": "credit-card", "sale_callback_url": "https://your-server.example.com/payme/callback", "sale_return_url": "https://your-site.example.com/payment/success", "sale_name": "First Last", "sale_email": "buyer@example.com", "sale_mobile": "+972500000040", "language": "en" } ``` ## Code samples ### curl ```bash curl -X POST 'https://sandbox.payme.io/api/generate-sale' \ -H 'Content-Type: application/json' \ --data-raw '{ "seller_payme_id": "MPLDEMO-MPLDEMO-MPLDEMO-1234567", "sale_price": 1000, "currency": "ILS", "product_name": "Smartphone", "transaction_id": "order-1001", "installments": "1", "sale_type": "sale", "sale_payment_method": "credit-card", "sale_callback_url": "https://your-server.example.com/payme/callback", "sale_return_url": "https://your-site.example.com/payment/success", "sale_name": "First Last", "sale_email": "buyer@example.com", "sale_mobile": "+972500000040", "language": "en" }' ``` ### Node.js ```javascript 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", "sale_price": 1000, "currency": "ILS", "product_name": "Smartphone", "transaction_id": "order-1001", "installments": "1", "sale_type": "sale", "sale_payment_method": "credit-card", "sale_callback_url": "https://your-server.example.com/payme/callback", "sale_return_url": "https://your-site.example.com/payment/success", "sale_name": "First Last", "sale_email": "buyer@example.com", "sale_mobile": "+972500000040", "language": "en" }), }); console.log(await response.text()); ``` ### Python ```python import requests response = requests.post( "https://sandbox.payme.io/api/generate-sale", json={ "seller_payme_id": "MPLDEMO-MPLDEMO-MPLDEMO-1234567", "sale_price": 1000, "currency": "ILS", "product_name": "Smartphone", "transaction_id": "order-1001", "installments": "1", "sale_type": "sale", "sale_payment_method": "credit-card", "sale_callback_url": "https://your-server.example.com/payme/callback", "sale_return_url": "https://your-site.example.com/payment/success", "sale_name": "First Last", "sale_email": "buyer@example.com", "sale_mobile": "+972500000040", "language": "en", }, ) print(response.text) ``` ### PHP ```php 'POST', CURLOPT_RETURNTRANSFER => true, CURLOPT_HTTPHEADER => [ 'Content-Type: application/json', ], CURLOPT_POSTFIELDS => $body, ]); $response = curl_exec($ch); curl_close($ch); echo $response; ``` ## Responses ### 200 — Sale created (success) | Field | Type | Description | | --- | --- | --- | | `status_code` | integer | `0` success, `1` error. | | `sale_url` | string | PayMe's payment page for this sale. Show it to the buyer in an iframe or a redirect, exactly as returned. It stays payable while the sale is `initial` or `failed`, until `sale_expiry_seconds` passes if you sent it. | | `payme_sale_id` | string | PayMe's sale ID. Store it: refunds, captures and queries use it. | | `payme_sale_code` | integer | Short numeric sale code, for display only. | | `price` | integer | Sale amount in minor units (`100` for a token sale). | | `transaction_id` | string | Your order reference, as sent. | | `currency` | string | Sale currency (ISO 4217). | | `sale_payment_method` | string | Payment method of the sale, for example `credit-card` or `multi`. | | `session` | string | Request ID. Quote it when you contact PayMe. | ```json { "status_code": 0, "session": "AtsJ0as5", "sale_url": "https://sandbox.payme.io/sale/generate/SALE1700-000000AA-EXAMPLE1-SALE0001", "payme_sale_id": "SALE1700-000000AA-EXAMPLE1-SALE0001", "payme_sale_code": 12345678, "price": 1000, "transaction_id": "order-1001", "currency": "ILS", "sale_payment_method": "credit-card" } ``` ### 200 — Token charged (`buyer_key`). The response holds the sale and transaction fields, the same as the callback, and has no `sale_url`. A declined charge also returns HTTP 200, with `status_code: 1`, `status_error_code` and `status_error_details`: always check `status_code`. (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](/payments/getting-started/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](/payments/codes-statuses/sale-statuses): `completed` for a charge, `authorized` for `sale_type: authorize`. | | `sale_type` | string | Sale type name, for example `Sale`; see [Sale Types](/payments/codes-statuses/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](/payments/getting-started/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. | ```json { "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 } ``` ### 500 — Request refused. Most request errors return HTTP 500 with `status_code: 1`; some return 400, 403, 422 or 429. See [Errors](/payments/getting-started/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. | ```json { "status_code": 1, "status_error_details": "Seller was not found", "status_additional_info": "seller_payme_id", "status_error_code": 251, "session": "AtsJ0as5" } ``` - [Create a multi-method checkout sale](https://docs.payme.io/payments/hosted-payment-page/post-generate-sale-2): POST /generate-sale — Create a multi-method checkout sale # Create a multi-method checkout sale - 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-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. - Request body field `payme_client_key` (optional): 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`. ## Overview Creates a sale whose payment page lets the buyer choose any payment method enabled on the account: card, Bit, Apple Pay, Google Pay and others. Send `sale_payment_method: multi`; without it the sale is created as `credit-card`. Show the returned `sale_url` to the buyer in an iframe or a redirect. `POST https://sandbox.payme.io/api/generate-sale` (production: `https://live.payme.io/api/generate-sale`), with a JSON body (`Content-Type: application/json`). | To | Send | |---|---| | Charge now (J4) | `sale_type: sale` (default) | | Authorize now, capture later (J5, up to 168 hours) | `sale_type: authorize`; then [capture-sale](/accepting-payments/capture-and-saved-cards/capture-sale) | | Let many buyers pay one link | `sale_type: template` ([Template sales](/accepting-payments/checkout-and-in-person/multi-payment-page)) | This page lists the fields that matter on a multi-method page. Every other `generate-sale` field, and the `sale_url` validity rules, are on [Create a sale](/payments/hosted-payment-page/post-generate-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](/payments/getting-started/authentication). ### Rules for every request - Amounts are in minor units (`1000` = 10.00). - Never put card numbers in any field. A value (other than `transaction_id` and `order_number`) that contains a 14–19-digit number passing the card checksum is refused with error `20` (HTTP 400), " contains invalid data". - Don't send the legacy `price` field: it is in major units and, when numeric, overrides `sale_price`. - PayMe doesn't de-duplicate `transaction_id`: every call creates a new sale. See [Idempotency and Retries](/payments/getting-started/idempotency-and-retries). - Errors return `status_code: 1` with `status_error_code`, most with HTTP 500. See [Errors](/payments/getting-started/errors). ### 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](/payments/getting-started/callbacks). ## 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`. | | `sale_payment_method` | string | yes | Required for this page: `multi`. The page lists every payment method enabled on the account. Without it the sale is created as `credit-card`. | | `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](https://en.wikipedia.org/wiki/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) or `0`: one payment. `2`–`12`: that fixed number. `102`–`112`: the buyer chooses on the page, up to the last two digits (`106` = up to 6). More than one installment is ILS only (`312`) and works only with `credit-card` or `multi` (other methods return `351`). On a `multi` page that lets the buyer choose, a buyer who pays with Apple Pay or Google Pay pays in one payment. Fixed values above 12 are accepted when the sale is created, but the payment fails unless PayMe has enabled more installments on your account. A non-numeric value returns `10`, any other unaccepted value `351`, and 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`](/accepting-payments/capture-and-saved-cards/capture-sale) (J5). `template` – one link that many buyers can pay. The full list is on [Sale Types](/payments/codes-statuses/sale-types); any other value returns `357`. | | `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](/payments/getting-started/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. | | `sale_return_url` | string | no | Where PayMe redirects the buyer (the iframe or the full page) after a successful payment, with the sale details as query parameters; see [Hosted Payment Page options](/accepting-payments/checkout-and-in-person/hosted-payment-page-options). If omitted, your partner's default return URL is used, if one is set. Same address rules as `sale_callback_url` (error `21`). | | `cancel_url` | string | no | Where to send the buyer when 3D Secure authentication fails, instead of back to the payment page. Also the PayPal cancel address. Must be a public URL (error `21`). | | `sale_send_notification` | boolean | no | `true`: PayMe sends the buyer a payment request with the payment link, by email to `sale_email` and by SMS to `sale_mobile`. Default `false`. | | `sale_email` | string | no | Buyer's email. Pre-fills the payment page and receives the payment request when `sale_send_notification` is `true`. | | `sale_mobile` | string | no | Buyer's mobile number. Pre-fills the payment page and receives the SMS payment request when `sale_send_notification` is `true` and the SMS service is active on the account. | | `sale_name` | string | no | Buyer's full name. Pre-fills the payment page (split at the first space into first and last name) and is used in notifications. | | `sale_send_creation_callback` | boolean | no | `true`: PayMe also sends a `sale-create` callback, with `sale_url`, as soon as the sale is created. Default `false`. | | `sale_expiry_seconds` | integer | no | How many seconds the sale stays payable after it is created. After that, the payment page answers HTTP 403 and paying the sale fails with error `367`. Without it, `sale_url` has no fixed expiry. | | `capture_buyer` | string | no | `1` or `true` to save the buyer's card as a token after the payment; the token arrives as `buyer_key` in the callback. Omit it, or send `0`, to skip. Works with `credit-card`, `apple-pay`, `il-direct-debit` and `multi` (other methods return `4`). Can't be combined with `buyer_key` (`601`). | | `buyer_is_private` | boolean | no | With `capture_buyer` or a token sale: `true` ties the token to this seller, so `get-buyer-key` works with the seller's MPL. Without it the token is account-level: any seller of the same partner can charge it, and a `get-buyer-key` call that sends `seller_payme_id` fails with error `603`. | | `buyer_perform_validation` | boolean | no | With `capture_buyer` or a token sale: whether PayMe validates the card with the issuer before saving the token. Default `true`. Sending `true` without `capture_buyer` or a token sale returns `608`. | | `layout` | string | no | Payment page layout: `dynamic` (default), `dynamic-loose` (no social ID or CVV validation), `qr-sms` (Bit: QR code or SMS), `token-capture` (save a card without a charge; requires `sale_type: token`). Other values fall back to `dynamic`. | | `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`. | | `services` | array | no | Per-sale settings for services on the account, as objects `{"name": "", "settings": {...}}`. For example `[{"name": "invoice", "settings": {"active": false}}]` skips the invoice for this sale, and `[{"name": "3DSecure", "settings": {"active": true}}]` forces 3D Secure. Each object needs `settings` (error `1`). Unknown or inactive services are ignored. | | `order_number` | string | no | Purchase order number, used for level 2 and level 3 card data. Up to 15 digits. | | `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. | | `fees` | object | no | Amounts included in the payment, for level 2 and level 3 card data. Each is in minor units, up to 12 digits. | | `fees.tax` | number | no | Tax included in the payment. | | `fees.duty` | number | no | International duties included in the payment. | | `fees.discount` | number | no | Total discount given on the payment. | | `fees.shipping` | number | no | Shipping cost included in the payment. | | `shipping_details` | object | no | Where the order is shipped. Stored with the sale. | | `shipping_details.name` | string | no | Addressee's full name or company name, up to 50 characters. | | `shipping_details.email` | string | no | Addressee's email, up to 100 characters. | | `shipping_details.phone` | string | no | Addressee's phone number, up to 50 characters. | | `shipping_details.address` | object | no | The shipping address. | | `shipping_details.address.line1` | string | no | First line of the shipping address. | | `shipping_details.address.line2` | string | no | Second line of the shipping address. | | `shipping_details.address.postal_code` | string | no | Postal code of the shipping address. | | `shipping_details.address.city` | string | no | City of the shipping address. | | `shipping_details.address.state` | string | no | State or region of the shipping address. | | `shipping_details.address.country` | string | no | Two-letter ISO 3166-1 country code, for example `IL`. Other values are ignored. | | `billing_details` | object | no | The payer's billing details. Stored with the sale. | | `billing_details.name` | string | no | Payer's full name or company name. | | `billing_details.email` | string | no | Payer's email. | | `billing_details.phone` | string | no | Payer's phone number. | | `billing_details.address` | object | no | The billing address. | | `billing_details.address.line1` | string | no | First line of the billing address. | | `billing_details.address.line2` | string | no | Second line of the billing address. | | `billing_details.address.postal_code` | string | no | Postal code of the billing address. | | `billing_details.address.city` | string | no | City of the billing address. | | `billing_details.address.state` | string | no | State or region of the billing address. | | `billing_details.address.country` | string | no | Two-letter ISO 3166-1 country code, for example `IL`. Other values are ignored. | ### Request example ```json { "seller_payme_id": "MPLDEMO-MPLDEMO-MPLDEMO-1234567", "sale_payment_method": "multi", "sale_price": 1000, "currency": "ILS", "product_name": "Smartphone", "transaction_id": "order-1001", "installments": "1", "sale_type": "sale", "sale_callback_url": "https://your-server.example.com/payme/callback", "sale_return_url": "https://your-site.example.com/payment/success", "sale_name": "First Last", "sale_email": "buyer@example.com", "language": "en" } ``` ## Code samples ### curl ```bash curl -X POST 'https://sandbox.payme.io/api/generate-sale' \ -H 'Content-Type: application/json' \ --data-raw '{ "seller_payme_id": "MPLDEMO-MPLDEMO-MPLDEMO-1234567", "sale_payment_method": "multi", "sale_price": 1000, "currency": "ILS", "product_name": "Smartphone", "transaction_id": "order-1001", "installments": "1", "sale_type": "sale", "sale_callback_url": "https://your-server.example.com/payme/callback", "sale_return_url": "https://your-site.example.com/payment/success", "sale_name": "First Last", "sale_email": "buyer@example.com", "language": "en" }' ``` ### Node.js ```javascript 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", "sale_payment_method": "multi", "sale_price": 1000, "currency": "ILS", "product_name": "Smartphone", "transaction_id": "order-1001", "installments": "1", "sale_type": "sale", "sale_callback_url": "https://your-server.example.com/payme/callback", "sale_return_url": "https://your-site.example.com/payment/success", "sale_name": "First Last", "sale_email": "buyer@example.com", "language": "en" }), }); console.log(await response.text()); ``` ### Python ```python import requests response = requests.post( "https://sandbox.payme.io/api/generate-sale", json={ "seller_payme_id": "MPLDEMO-MPLDEMO-MPLDEMO-1234567", "sale_payment_method": "multi", "sale_price": 1000, "currency": "ILS", "product_name": "Smartphone", "transaction_id": "order-1001", "installments": "1", "sale_type": "sale", "sale_callback_url": "https://your-server.example.com/payme/callback", "sale_return_url": "https://your-site.example.com/payment/success", "sale_name": "First Last", "sale_email": "buyer@example.com", "language": "en", }, ) print(response.text) ``` ### PHP ```php 'POST', CURLOPT_RETURNTRANSFER => true, CURLOPT_HTTPHEADER => [ 'Content-Type: application/json', ], CURLOPT_POSTFIELDS => $body, ]); $response = curl_exec($ch); curl_close($ch); echo $response; ``` ## Responses ### 200 — Sale created (success) | Field | Type | Description | | --- | --- | --- | | `status_code` | integer | `0` success, `1` error. | | `sale_url` | string | PayMe's payment page for this sale. Show it to the buyer in an iframe or a redirect, exactly as returned. It stays payable while the sale is `initial` or `failed`, until `sale_expiry_seconds` passes if you sent it. | | `payme_sale_id` | string | PayMe's sale ID. Store it: refunds, captures and queries use it. | | `payme_sale_code` | integer | Short numeric sale code, for display only. | | `price` | integer | Sale amount in minor units (`100` for a token sale). | | `transaction_id` | string | Your order reference, as sent. | | `currency` | string | Sale currency (ISO 4217). | | `sale_payment_method` | string | Payment method of the sale, for example `credit-card` or `multi`. | | `session` | string | Request ID. Quote it when you contact PayMe. | ```json { "status_code": 0, "session": "AtsJ0as5", "sale_url": "https://sandbox.payme.io/sale/generate/SALE1700-000000AA-EXAMPLE1-SALE0001", "payme_sale_id": "SALE1700-000000AA-EXAMPLE1-SALE0001", "payme_sale_code": 12345678, "price": 1000, "transaction_id": "order-1001", "currency": "ILS", "sale_payment_method": "multi" } ``` ### 500 — Request refused. Most request errors return HTTP 500 with `status_code: 1`; some return 400, 403, 422 or 429. See [Errors](/payments/getting-started/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. | ```json { "status_code": 1, "status_error_details": "Seller was not found", "status_additional_info": "seller_payme_id", "status_error_code": 251, "session": "AtsJ0as5" } ``` ## Hosted Fields - JSAPI - [Hosted Fields - JSAPI](https://docs.payme.io/payments/hosted-fields-jsapi): Put PayMe's card inputs in your own checkout form with the browser SDK, then charge the token from your server with generate-sale. # Hosted Fields - JSAPI Hosted Fields put PayMe's card inputs inside your own checkout form as PayMe iframes. The browser SDK (`window.PayMe`) returns a token, and your server charges it with `generate-sale` and `buyer_key`. Start with the [Hosted Fields JSAPI guide](https://docs.payme.io/accepting-payments/checkout-and-in-person/hosted-fields-jsapi-guide). - [Charge a Hosted Fields token](https://docs.payme.io/payments/hosted-fields-jsapi/post-generate-sale-hosted-fields-jsapi): POST /generate-sale — Charge a Hosted Fields token # 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-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. - Request body field `payme_client_key` (optional): 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`. ## 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](/accepting-payments/checkout-and-in-person/hosted-fields-jsapi-guide). The same call charges any saved token; see [Save a card and charge it later](/accepting-payments/capture-and-saved-cards/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](/accepting-payments/capture-and-saved-cards/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](/payments/getting-started/authentication). ### What to expect - Success: `status_code: 0` and the sale and transaction fields, the same as the callback. - Decline: **HTTP 200** with `status_code: 1`, `status_error_code` (for example `20004`) and `status_error_details`. - Every call creates a new sale, even when the charge is refused. Check the sale before you retry; see [Idempotency and Retries](/payments/getting-started/idempotency-and-retries). - The token's own payment method is used. - Errors: `buyer_key` with `capture_buyer` returns `601`, with `sale_type` `token`/`seller-token` `602`, with `template` `606`, and with `multi-capture` `357`. A token of another seller returns `605`; an inactive or already-used single-use token returns `604`; a charge over the seller's processing limit returns `130`. - Never put card numbers in any field (error `20`), and don't send the legacy `price` field (major units; it overrides `sale_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](/payments/getting-started/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](https://en.wikipedia.org/wiki/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`](/accepting-payments/capture-and-saved-cards/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](/payments/getting-started/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 ```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" } ``` ## Code samples ### curl ```bash 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 ```javascript 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 ```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 '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](/payments/getting-started/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](/payments/codes-statuses/sale-statuses): `completed` for a charge, `authorized` for `sale_type: authorize`. | | `sale_type` | string | Sale type name, for example `Sale`; see [Sale Types](/payments/codes-statuses/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](/payments/getting-started/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. | ```json { "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](/payments/getting-started/errors). | | `status_error_details` | string | The message, in the requested `language`. | | `payme_sale_id` | string | The sale this call created. | ```json { "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](/payments/getting-started/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. | ```json { "status_code": 1, "status_error_details": "Seller was not found", "status_additional_info": "seller_payme_id", "status_error_code": 251, "session": "AtsJ0as5" } ``` ## Direct API - [Direct API](https://docs.payme.io/payments/direct-api): Charge cards and save them as tokens from your own server. For partners certified PCI DSS Level 1. # Direct API The Direct API is for partners certified PCI DSS Level 1, who may handle raw card details on their own servers. - Charge a card on a sale you created: [`pay-sale`](https://docs.payme.io/payments/direct-api/post-pay-sale). - Save a card as a token without charging it: [`capture-buyer-token`](https://docs.payme.io/payments/tokenization/post-capture-buyer-token). - Charge a saved card: [`generate-sale`](https://docs.payme.io/payments/hosted-payment-page/post-generate-sale) with `buyer_key`. Without that certification, use the [Hosted Payment Page](https://docs.payme.io/payments/hosted-payment-page) or [Hosted Fields](https://docs.payme.io/payments/hosted-fields-jsapi), so card details never reach your servers. PayMe Partners () can send the step-by-step Direct API guide on request. - [Pay a sale](https://docs.payme.io/payments/direct-api/post-pay-sale): POST /pay-sale — Pay a sale # Pay a sale - Sandbox: `POST https://sandbox.payme.io/api/pay-sale` - Production: `POST https://live.payme.io/api/pay-sale` ## Credentials - Request body field `token` (optional): A partner-level token to pay with instead of the card fields: the `uuid` from [Create a partner-level token](/payments/tokenization/post-sellers-mpl-tokens). ## Overview Charges a card, or a saved card, on a sale you created with [`generate-sale`](/payments/hosted-payment-page/post-generate-sale). Use it in the [Direct API](/payments/direct-api) (PCI DSS Level 1 partners only) and to finish a [Hosted Fields](/payments/hosted-fields-jsapi) payment. This call takes no credentials: PayMe finds the sale by `payme_sale_id`, and the price, currency and callback URLs come from the sale. Treat `payme_sale_id` like the payment link: share it only with the buyer who pays it. Send either the card fields (`credit_card_number`, `credit_card_exp`, `credit_card_cvv`) with `buyer_name` and `buyer_email`, or a saved card in `buyer_key` (or a partner-level `token`). With `buyer_key` or `token`, PayMe uses the saved card's details and needs no CVV. ### Reading the result The response is synchronous. PayMe also sends the sale [callbacks](/payments/getting-started/callbacks). Read `status_code`: | `status_code` | Meaning | What to do | |---|---|---| | `0` | Paid. On a sale created with `sale_type: "authorize"`, authorized: charge it later with [`capture-sale`](/payments/post-sale-actions/post-capture-sale). On a `token` sale, the card is saved and not charged. | Read `sale_status`. | | `1` | Declined, with HTTP 200. `status_error_code` and `status_error_details` give the reason. The sale becomes `failed` and can be paid again. | Ask the buyer for another card. | | `5` | The card issuer asks for a 3D Secure challenge. | Send the buyer's browser to `redirect_url`. The result arrives in the sale callback. | ### Before you call - The sale must be `initial` or `failed`; otherwise the call returns error `305` with the sale's status in `status_additional_info`. An expired sale returns `367`. - Only card sales can be paid here: a sale created for another payment method returns error `2`. - A value that looks like a card number in any field other than `credit_card_number` is rejected with HTTP 400, error `20`. - Send one call per sale at a time. A second call while the first is still running returns HTTP 429, error `998`. ## Parameters This endpoint takes no path, query or header parameters. ## Request body Content type: `application/json` | Field | Type | Required | Description | | --- | --- | --- | --- | | `payme_sale_id` | string | yes | The sale to pay: the `payme_sale_id` that `generate-sale` returned. | | `credit_card_number` | string | no | Card number, digits only. Required unless you send `buyer_key` or `token`. | | `credit_card_exp` | string | no | Card expiry as `MMYY` (`MM/YY` and `MMYYYY` are also accepted). Required unless you send `buyer_key` or `token`. | | `credit_card_cvv` | string | no | CVV, 3 or 4 digits. Required with the card fields unless `token_terminal` is `true`. On a sale whose `layout` is `token-capture` or `dynamic-loose`, leaving it out sends the payment to a token terminal. | | `token_terminal` | boolean | no | `true` to charge the card fields without a CVV, on a token terminal. Default `false`. | | `buyer_key` | string | no | A saved card to pay with instead of the card fields. See [Save a card as a token](/payments/tokenization/post-capture-buyer-token). | | `token` | string | no | A partner-level token to pay with instead of the card fields: the `uuid` from [Create a partner-level token](/payments/tokenization/post-sellers-mpl-tokens). | | `buyer_name` | string | no | Buyer's full name. Required, with `buyer_email`, when you pay with the card fields, unless the sale's `layout` is `token-capture` or `dynamic-loose`. | | `buyer_email` | string | no | Buyer's email address. Same rule as `buyer_name`. | | `buyer_phone` | string | no | Buyer's phone number. | | `buyer_social_id` | string | no | Buyer's national ID number, digits only. Ignored when you pay with `buyer_key` or `token`. | | `buyer_zip_code` | string | no | Buyer's zip code, letters and digits only; anything else returns error `37`. | | `buyer_business_code` | string | no | For a business buyer: its registration number. Send it with `buyer_business_name`, or neither. | | `buyer_business_name` | string | no | For a business buyer: its name. Send it with `buyer_business_code`, or neither. | | `installments` | integer | no | Number of installments the buyer chose. Required only when the sale lets the buyer choose (a sale created with `installments` above `100`, such as `106`); otherwise the sale's own value is used. | | `payment_method` | string | no | On a sale that offers several payment methods: the method being paid. Default `credit-card`. | | `manual_auth_number` | string | no | An authorization code from the card issuer (voice authorization), to re-run a `failed` sale. Send it with `buyer_key` or `token`. | | `xid` | string | no | If you ran 3D Secure yourself: its transaction ID. With `xid`, PayMe doesn't run its own 3D Secure. | | `eci` | string | no | If you ran 3D Secure yourself: the ECI value. Send it with `xid`. | | `cavv` | string | no | If you ran 3D Secure yourself: the CAVV value. Send it with `xid`. | | `3ds_version` | string | no | If you ran 3D Secure yourself: the protocol version. Send it with `xid`. | | `meta_data` | object | no | Browser data for 3D Secure, as an object. Send this or `meta_data_jwt`. See [3DS with Hosted Fields](/accepting-payments/3d-secure/3ds-with-hosted-fields). | | `meta_data_jwt` | string | no | Browser data for 3D Secure, as the JWT Hosted Fields gives you. Send this or `meta_data`. See [3DS with Hosted Fields](/accepting-payments/3d-secure/3ds-with-hosted-fields). | | `sale_additional_data` | object | no | Extra data to store on the sale. | | `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 ```json { "payme_sale_id": "SALEDEMO-XXXXXXXX-XXXXXXXX-XXXXXXXX", "credit_card_number": "5326105300985846", "credit_card_exp": "1230", "credit_card_cvv": "658", "buyer_name": "Israel Israeli", "buyer_email": "buyer@example.com", "buyer_social_id": "008336174", "language": "en" } ``` ## Code samples ### curl ```bash curl -X POST 'https://sandbox.payme.io/api/pay-sale' \ -H 'Content-Type: application/json' \ --data-raw '{ "payme_sale_id": "SALEDEMO-XXXXXXXX-XXXXXXXX-XXXXXXXX", "credit_card_number": "5326105300985846", "credit_card_exp": "1230", "credit_card_cvv": "658", "buyer_name": "Israel Israeli", "buyer_email": "buyer@example.com", "buyer_social_id": "008336174", "language": "en" }' ``` ### Node.js ```javascript const response = await fetch("https://sandbox.payme.io/api/pay-sale", { method: "POST", headers: { "Content-Type": "application/json", }, body: JSON.stringify({ "payme_sale_id": "SALEDEMO-XXXXXXXX-XXXXXXXX-XXXXXXXX", "credit_card_number": "5326105300985846", "credit_card_exp": "1230", "credit_card_cvv": "658", "buyer_name": "Israel Israeli", "buyer_email": "buyer@example.com", "buyer_social_id": "008336174", "language": "en" }), }); console.log(await response.text()); ``` ### Python ```python import requests response = requests.post( "https://sandbox.payme.io/api/pay-sale", json={ "payme_sale_id": "SALEDEMO-XXXXXXXX-XXXXXXXX-XXXXXXXX", "credit_card_number": "5326105300985846", "credit_card_exp": "1230", "credit_card_cvv": "658", "buyer_name": "Israel Israeli", "buyer_email": "buyer@example.com", "buyer_social_id": "008336174", "language": "en", }, ) print(response.text) ``` ### PHP ```php '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 payment result: paid (`status_code` `0`), declined (`1`) or a 3D Secure challenge (`5`). A decline also returns HTTP 200. (success) | Field | Type | Description | | --- | --- | --- | | `status_code` | integer | `0`: paid (or authorized, or the card saved on a `token` sale). `1`: declined. `5`: 3D Secure challenge; send the buyer to `redirect_url`. | | `status_error_code` | integer | `0` on success; the decline code when `status_code` is `1`. | | `status_error_details` | string | The decline reason, when `status_code` is `1`. | | `redirect_url` | string | With `status_code` `5`: the 3D Secure page to send the buyer to. On a paid sale: the sale's return URL, or `null`. | | `status_message` | string | With `status_code` `5`: a message you can show the buyer. | | `cancel_url` | string | The sale's cancel URL, or `null`. | | `payme_status` | string | Legacy field. Read `status_code` instead. | | `payme_sale_id` | string | The sale's ID. | | `payme_sale_code` | integer | The sale's numeric code. | | `sale_created` | string | When the sale was created, `YYYY-MM-DD HH:MM:SS` (Israel time). | | `sale_status` | string | The sale's status, for example `completed`, `authorized` or `failed`. See [Sale Statuses](/payments/codes-statuses/sale-statuses). | | `payme_sale_status` | string | Same as `sale_status`. | | `sale_type` | string | The sale type as responses name it, for example `Sale` (also for an authorization) or `Token`. | | `sale_payment_method` | string | Payment method, for example `credit-card`. | | `currency` | string | Sale currency, an ISO 4217 code such as `ILS`. | | `price` | integer | Sale price in minor units (`10000` = 100.00). | | `transaction_id` | string | Your own reference for the sale. | | `sale_description` | string | The sale's description. | | `sale_deferred_months` | integer | Deferred months on the sale, or `null`. | | `is_token_sale` | boolean | `true` for a `token` sale, which saves the card without charging it. | | `payme_signature` | string | PayMe's signature for this payment. | | `payme_transaction_id` | string | PayMe's ID of the payment transaction. | | `payme_transaction_total` | string | Amount of the transaction, in minor units. | | `payme_transaction_card_brand` | string | Card brand, for example `Mastercard`. | | `payme_transaction_auth_number` | string | Authorization number from the card issuer. | | `payme_transaction_voucher` | string | Voucher number of the transaction. | | `payme_transaction_emv_uid` | string | EMV UID of the transaction, when the acquirer returns one; usually `null`. | | `payme_transaction_acquirer` | string | The acquirer, for example `PayMe`. | | `payme_transaction_auth_source` | string | Authorization source reported for the transaction. | | `payme_transaction_card_issuer` | string | Card issuer, for example `Isracard`. | | `payme_transaction_credit_type` | string | Credit type, for example `RegularCredit`. | | `buyer_name` | string | Buyer's full name. | | `buyer_email` | string | Buyer's email address. | | `buyer_phone` | string | Buyer's phone number, or `null`. | | `buyer_card_mask` | string | Masked card number, for example `532610******5846`. | | `buyer_card_exp` | string | Card expiry, `MMYY`. | | `buyer_card_is_foreign` | boolean | `true` for a card issued outside Israel. | | `buyer_social_id` | string | Buyer's national ID number, or `null`. | | `installments` | integer | Number of installments. | | `transaction_first_payment` | integer | First installment, in minor units. | | `transaction_periodical_payment` | integer | Each later installment, in minor units; `0` for a single payment. | | `transaction_arn` | string | Acquirer reference (EMV UID) when the acquirer returns one; usually `null`. | | `sale_paid_date` | string | When the payment was made, `YYYY-MM-DD HH:MM:SS` (Israel time). | | `sale_release_date` | string | Date the funds are released to the seller, `YYYY-MM-DD`, or `null`. | | `sale_3ds` | boolean | `true` when the payment passed 3D Secure. | | `session` | string | PayMe's ID for this request. Quote it when you contact PayMe. | ```json { "status_code": 0, "status_error_code": 0, "payme_status": "success", "payme_sale_id": "SALEDEMO-XXXXXXXX-XXXXXXXX-XXXXXXXX", "payme_sale_code": 1111111, "sale_created": "2026-11-09 10:15:02", "sale_status": "completed", "payme_sale_status": "completed", "sale_type": "Sale", "sale_payment_method": "credit-card", "currency": "ILS", "price": 10000, "transaction_id": "order-1234", "sale_description": "Shirt", "sale_deferred_months": null, "is_token_sale": false, "payme_signature": "b71e**************ca5a", "payme_transaction_id": "TRANDEMO-XXXXXXXX-XXXXXXXX-XXXXXXXX", "payme_transaction_total": "10000", "payme_transaction_card_brand": "Mastercard", "payme_transaction_auth_number": "0123456", "payme_transaction_voucher": "111111", "payme_transaction_emv_uid": null, "payme_transaction_acquirer": "PayMe", "payme_transaction_auth_source": "VoiceMail", "payme_transaction_card_issuer": "Isracard", "payme_transaction_credit_type": "RegularCredit", "buyer_name": "Israel Israeli", "buyer_email": "buyer@example.com", "buyer_phone": null, "buyer_card_mask": "532610******5846", "buyer_card_exp": "1230", "buyer_card_is_foreign": false, "buyer_social_id": "008336174", "installments": 1, "transaction_first_payment": 10000, "transaction_periodical_payment": 0, "transaction_arn": null, "sale_paid_date": "2026-11-09 10:16:40", "sale_release_date": null, "sale_3ds": false, "session": "Ab12Cd34", "redirect_url": null, "cancel_url": null } ``` ### 400 — Error `20`: a card-like number in a field other than `credit_card_number`. Error `367`: the sale has expired. (error) | Field | Type | Description | | --- | --- | --- | | `status_code` | integer | `1`: the request failed. | | `status_error_code` | integer | PayMe's error code. See [Errors](/payments/getting-started/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. | ```json { "status_code": 1, "status_error_details": "The sale has expired", "status_additional_info": "", "status_error_code": 367, "session": "Ab12Cd34" } ``` ### 429 — Error `998`: another call for this sale is still running, or too many requests. 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](/payments/getting-started/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. | ```json { "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 (named in `status_additional_info`). `350`: no sale has this `payme_sale_id`. `305`: the sale isn't `initial` or `failed`. `354`, `355`, `356`: invalid CVV, card number or expiry. `37`: invalid `buyer_zip_code`. `351`: invalid `installments`. `2`: the sale isn't a card sale. `357`: `buyer_key` or `token` sent on a `token` sale. `600`, `604`, `605`: the saved card doesn't exist, is no longer active, or belongs to another seller. (error) | Field | Type | Description | | --- | --- | --- | | `status_code` | integer | `1`: the request failed. | | `status_error_code` | integer | PayMe's error code. See [Errors](/payments/getting-started/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. | ```json { "status_code": 1, "status_error_details": "Cannot perform action due to an incorrect status", "status_additional_info": "completed", "status_error_code": 305, "session": "Ab12Cd34" } ``` ## iOS SDK - [iOS SDK](https://docs.payme.io/payments/ios-sdk): Legacy SDK, not recommended for new integrations: use the Hosted Payment Page in a secure in-app browser instead. The PayMe iOS SDK collects card details in your app and embeds your seller_payme_id. The guide covers importing PMLib.framework, initializing the SDK, and paying a sale, paying a subscription and capturing a buyer token. # iOS SDK > **Legacy SDK.** This SDK is no longer recommended for new integrations. It isn't actively updated, it requires your app to collect card details, and it puts your `seller_payme_id` (MPL), a server-side credential, in the app. For new apps, open the [Hosted Payment Page](https://docs.payme.io/payments/hosted-payment-page) in a secure in-app browser (`SFSafariViewController` on iOS), so card details never pass through your app. You can also offer [Apple Pay](https://docs.payme.io/payments/apple-pay) and [Google Pay](https://docs.payme.io/payments/google-pay). > > How to: [Accept payments in a mobile app](https://docs.payme.io/accepting-payments/checkout-and-in-person/mobile-apps). To get the SDK, ask PayMe Partners (partners@payme.io) for access. ## Getting started ### Get the PayMe package Build the framework from sources: 1. Open the PayMe project. 2. Build the project. 3. The new framework is generated automatically in the Products directory of `PMLib.xcodeproj`: `PMLib.framework`. 4. Right-click → **Show in Finder** to get the path of the framework. ### Import the PayMe SDK framework 1. Open the project that needs to import the framework. 2. Select your project's **Targets → General → Embedded Binaries** (or **Build Phases → Embedded Frameworks**). 3. Press **Add (+)** and go to the path of `PMLib.framework`. 4. Build the project. ## Initialize the SDK Create a shared `PayMe` instance, for example in your app delegate: ```objc #import #define SELLERKEY @"/* Your seller_payme_id */" #define WEBSERVICE [PayMe sharedInstant:SELLERKEY stage:STAGING] ``` `stage` sets the environment. The sample uses `STAGING`; ask PayMe Partners for the value to use in production. The samples below call `WEBSERVICE` and leave the success and failure handling to you. ## Integrate with the PayMe API Each API request requires appropriate `PayMeRequest` and `TransactionListener` instances. ### Pay a sale First, create the sale on your server with [generate-sale](https://docs.payme.io/payments/hosted-payment-page/post-generate-sale) and send its `payme_sale_id` to your app. Then create a `PaySaleRequest` and send it: ```objc PaySaleRequest *request = [[PaySaleRequest alloc] init]; //payme_sale_id - Required - From your server request.paymeSaleId = /* payme_sale_id */; //Installments - Required request.installments = installments; //ID - Required only for Israeli cards request.buyerSocialID = buyerSocialID; //Email - Required request.buyerEmail = buyerEmail; //Name - Required request.buyerName = buyerName; //Credit Card Number - Required request.creditCardNumber = creditCardNumber; //CreditCard CVV - Required request.creditCardCVV = creditCardCVV; //Credit Card Expiration - Required request.creditCardExp = creditCardExp; [WEBSERVICE paySale:request success:^(PaySaleResponse *responseObject) { if(responseObject != nil) { //Handle success request } } failure:^(PayMeError *error) { if(error != nil) { //Handle failed request } }]; ``` ### Pay a subscription First, create the subscription on your server with [generate-subscription](https://docs.payme.io/payments/subscriptions/post-generate-subscription) and send its `sub_payme_id` to your app. Then create a `PaySubscriptionRequest` and send it: ```objc PaySubscriptionRequest *request = [[PaySubscriptionRequest alloc] init]; //Name - Required request.buyerName = buyerName; //ID - Required only for Israeli cards request.buyerSocialId = buyerSocialId; //Phone request.buyerPhone = buyerPhone; //Email - Required request.buyerEmail = buyerEmail; //sub_payme_id - Required - From your server request.subPaymeId = /* sub_payme_id */; //Credit Card Number - Required request.creditCardNumber = creditCardNumber; //CreditCard CVV - Required request.creditCardCVV = creditCardCVV; //Credit Card Expiration - Required request.creditCardExp = creditCardExp; [WEBSERVICE paySubscription:request success:^(PaySubscriptionResponse *responseObject) { if(responseObject != nil) { //Handle success request } } failure:^(PayMeError *error) { if(error != nil) { //Handle failed request } }]; ``` ### Capture a buyer token ```objc CaptureBuyerRequest *request = [[CaptureBuyerRequest alloc] init]; //Name - Required request.buyerName = buyerName; //Phone - Required request.buyerPhone = buyerPhone; //Email - Required request.buyerEmail = buyerEmail; //ID - Required only for Israeli cards request.buyerSocialId = buyerSocialId; //SellerID - Required request.sellerPaymeId = /* Your seller_payme_id */; //Permanent request.buyerIsPermanent = buyerIsPermanent; //Credit Card Number - Required request.creditCardNumber = creditCardNumber; //CreditCard CVV - Required request.creditCardCvv = creditCardCVV; //Credit Card Expiration - Required request.creditCardExp = creditCardExp; [WEBSERVICE captureBuyer:request success:^(CaptureBuyerResponse *responseObject) { if(responseObject != nil) { //Handle success request } } failure:^(PayMeError *error) { if(error != nil) { //Handle failed request } }]; ``` ## Android SDK - [Android SDK](https://docs.payme.io/payments/android-sdk): Legacy SDK, not recommended for new integrations: use the Hosted Payment Page in a secure in-app browser instead. The PayMe Android SDK collects card details in your app and embeds your seller_payme_id. The guide covers building and importing the AAR with Gradle, initializing the SDK, paying a sale, paying a subscription, capturing a buyer token, and the reporting calls, which belong on your server. # Android SDK > **Legacy SDK.** This SDK is no longer recommended for new integrations. It isn't actively updated, it requires your app to collect card details, and it puts your `seller_payme_id` (MPL), a server-side credential, in the app. For new apps, open the [Hosted Payment Page](https://docs.payme.io/payments/hosted-payment-page) in a secure in-app browser (`Custom Tabs` on Android), so card details never pass through your app. You can also offer [Apple Pay](https://docs.payme.io/payments/apple-pay) and [Google Pay](https://docs.payme.io/payments/google-pay). > > How to: [Accept payments in a mobile app](https://docs.payme.io/accepting-payments/checkout-and-in-person/mobile-apps). To get the SDK, ask PayMe Partners (partners@payme.io) for access. ## Getting started ### Build the AAR from sources 1. Open the SDK project and build it. 2. The new AAR is generated automatically at `library/build/outputs/library-release.aar`. 3. Rename the file to `isracard-global-##.aar`, where `##` is the version. ### Import the SDK with Gradle 1. Copy `isracard-global-##.aar` into your project's `libs` folder. 2. Add the folder to the repositories in `build.gradle`, and add the SDK to the dependencies: ```groovy repositories { flatDir { dirs 'libs' } } dependencies { implementation(name:'isracard-global-1.0', ext:'aar') } ``` ## Initialize the SDK Extend your `Application` and initialize the SDK: ```java package com.paymeservice.example; import android.app.Application; import com.paymeservice.android.PayMe; import com.paymeservice.android.model.Settings; import static com.paymeservice.android.model.Settings.Environment.STAGING; public class PayMeApplication extends Application { @Override public void onCreate() { super.onCreate(); // Setting the Android SDK PayMe.initialize(new Settings(/* Your seller_payme_id */, STAGING)); } } ``` `Settings.Environment` sets the environment. The sample uses `STAGING`; ask PayMe Partners for the value to use in production. ## Integrate with the PayMe API Each API request needs the matching request object and a `TransactionListener`. Create sales and read reports from your server, never from the app: `generateSale`, `getFinancialTransactions`, `getSales`, `getStatistics` and `getGraphPoinsts` (the SDK's spelling) run with your MPL. In the app, use only the calls that take the buyer's card: `paySale`, `paySubscription` and `captureBuyer`. ### Generate a sale Prefer [generate-sale](https://docs.payme.io/payments/hosted-payment-page/post-generate-sale) on your server. ```java final GenerateSaleRequest request = new GenerateSaleRequest(); //Sale price - Required request.setSalePrice(Long.parseLong(edtSalePrice.getText().toString())); //Currency request.setSaleCurrency(edtSaleCurrency.getText().toString()); //Installments - Required request.setSaleInstallments(Integer.parseInt(edtSaleInstallments.getText().toString())); //Product name - Required request.setSaleProductName(edtSaleProductName.getText().toString()); //Capture Buyer request.setCaptureBuyer(Boolean.parseBoolean(cbxCaptureBuyer.getText().toString())); //Transaction ID request.setSaleTransactionId(edtSaleTransactionId.getText().toString()); if (!isValid(request)) { //Stop execution if request is not valid return; } PayMe.generateSale(request, new PayMe.TransactionListener() { @Override public void onSuccess(GenerateSaleResponse response) { //Handle success request } @Override public void onFailed(Exception exception, PayMeError error) { //Handle failed request } }); ``` ### Pay a sale First, create the sale on your server with [generate-sale](https://docs.payme.io/payments/hosted-payment-page/post-generate-sale) and send its `payme_sale_id` to your app. Then create a `PaySaleRequest` and send it: ```java final PaySaleRequest request = new PaySaleRequest(); //Name - Required request.setBuyerName(edtBuyerName.getText().toString()); //Email - Required request.setBuyerEmail(edtEmail.getText().toString()); //Phone request.setBuyerPhone(edtBuyerPhone.getText().toString()); //ID request.setBuyerSocialID(edtSocialId.getText().toString()); //payme_sale_id - Required - From your server request.setPaymeSaleId(/* payme_sale_id */); //Credit Card Number - Required request.setCreditCardNumber(edtCreditCardNumber.getText().toString()); //CreditCard CVV - Required request.setCreditCardCVV(edtCreditCardCvv.getText().toString()); //Credit Card Expiration - Required request.setCreditCardExp(edtCreditCardExp.getText().toString()); if (!isValid(request)) { //Stop execution if request is not valid return; } PayMe.paySale(request, new PayMe.TransactionListener() { @Override public void onSuccess(PaySaleResponse response) { //Handle success request } @Override public void onFailed(Exception exception, PayMeError error) { //Handle failed request } }); ``` ### Pay a subscription First, create the subscription on your server with [generate-subscription](https://docs.payme.io/payments/subscriptions/post-generate-subscription) and send its `sub_payme_id` to your app. Then create a `PaySubscriptionRequest` and send it: ```java PaySubscriptionRequest request = new PaySubscriptionRequest(); //Name - Required request.setBuyerName(edtBuyerName.getText().toString()); //Email - Required request.setBuyerEmail(edtEmail.getText().toString()); //ID request.setBuyerSocialID(edtSocialId.getText().toString()); //sub_payme_id - Required - From your server request.setSubPaymeId(/* sub_payme_id */); //Credit Card Number - Required request.setCreditCardNumber(edtCreditCardNumber.getText().toString()); //CreditCard CVV - Required request.setCreditCardCVV(edtCreditCardCvv.getText().toString()); //Credit Card Expiration - Required request.setCreditCardExp(edtCreditCardExp.getText().toString()); if (!isValid(request)) { //Stop execution if request is not valid return; } PayMe.paySubscription(request, new PayMe.TransactionListener() { @Override public void onSuccess(PaySubscriptionResponse response) { //Handle success request } @Override public void onFailed(Exception exception, PayMeError error) { //Handle failed request } }); ``` ### Capture a buyer token ```java CaptureBuyerRequest request = new CaptureBuyerRequest(); //Name - Required request.setBuyerName(edtBuyerName.getText().toString()); //Phone - Required request.setBuyerPhone(edtPhone.getText().toString()); //Email - Required request.setBuyerEmail(edtEmail.getText().toString()); //ID request.setBuyerSocialID(edtSocialId.getText().toString()); //Permanent request.setBuyerIsPermanent(editIsPermanent.isChecked()); //Credit Card Number - Required request.setCreditCardNumber(edtCreditCardNumber.getText().toString()); //CreditCard CVV - Required request.setCreditCardCVV(edtCreditCardCvv.getText().toString()); //Credit Card Expiration - Required request.setCreditCardExp(edtCreditCardExp.getText().toString()); if (!isValid(request)) { //Stop execution if request is not valid return; } PayMe.captureBuyer(request, new PayMe.TransactionListener() { @Override public void onSuccess(CaptureBuyerResponse response) { //Handle success request } @Override public void onFailed(Exception exception, PayMeError error) { //Handle failed request } }); ``` ### List financial transactions Run this on your server instead: see [get-transactions](https://docs.payme.io/payments/query-apis/post-get-transactions). ```java GetFinancialTransactionsRequest request = new GetFinancialTransactionsRequest(); //Seller ID request.setSellerId(edtSellerId.getText().toString()); //Transaction created request.setTranCreated(edtTranCreated.getText().toString()); //Transaction created max request.setTranCreatedMax(edtTranCreatedMax.getText().toString()); //Transaction created min request.setTranCreatedMin(edtTranCreatedMin.getText().toString()); //Transaction currency request.setTranCurrency(edtTranCurrency.getText().toString()); //Transaction total request.setTranTotal(Long.parseLong(edtTranTotal.getText().toString())); //Transaction type request.setTranType(Integer.parseInt(edtTranType.getText().toString())); if (!isValid(request)) { //Stop execution if request is not valid return; } PayMe.getFinancialTransactions(request, new PayMe.TransactionListener() { @Override public void onSuccess(GetFinancialTransactionsResponse response) { //Handle success request } @Override public void onFailed(Exception exception, PayMeError error) { //Handle failed request } }); ``` ### List sales Run this on your server instead: see [get-sales](https://docs.payme.io/payments/query-apis/post-get-sales). ```java GetSalesRequest request = new GetSalesRequest(); //Seller ID request.setSellerId(edtSellerId.getText().toString()); //Sale Payme Code request.setSalePaymeCode(Long.parseLong(edtSalePaymeCode.getText().toString())); //Sale Payme ID request.setSalePaymeId(edtSalePaymeId.getText().toString()); //Transaction ID request.setTransactionId(edtTransactionId.getText().toString()); //Sale Created request.setSaleCreated(edtSaleCreated.getText().toString()); //Sale Created Min request.setSaleCreatedMin(edtSaleCreatedMin.getText().toString()); //Sale Created Max request.setSaleCreatedMax(edtSaleCreatedMax.getText().toString()); //Sale Status request.setSaleStatus(edtSaleStatus.getText().toString()); //Sale Price request.setSalePrice(Long.parseLong(edtSalePrice.getText().toString())); //Sale Currency request.setSaleCurrency(edtSaleCurrency.getText().toString()); //Sale Auth Number request.setSaleAuthNumber(edtSaleAuthNumber.getText().toString()); //Buyer Card Mask request.setBuyerCardMask(edtBuyerCardMask.getText().toString()); //Buyer Card Last Four Digits request.setBuyerCardLastFourDigits(edtBuyerCardLastFourDigits.getText().toString()); //Buyer Name request.setBuyerName(edtBuyerName.getText().toString()); //Buyer Email request.setBuyerEmail(edtBuyerEmail.getText().toString()); //Buyer Phone request.setBuyerPhone(edtBuyerPhone.getText().toString()); //Buyer Social Id request.setBuyerSocialId(edtBuyerSocialId.getText().toString()); //Buyer Card is Foreign request.setBuyerCardisForeign(chxBuyerCardIsForeign.isChecked()); if (!isValid(request)) { //Stop execution if request is not valid return; } PayMe.getSales(request, new PayMe.TransactionListener() { @Override public void onSuccess(GetSalesResponse response) { //Handle success request } @Override public void onFailed(Exception exception, PayMeError error) { //Handle failed request } }); ``` ### Get statistics ```java GetStatisticsRequest request = new GetStatisticsRequest(); //Time Frame - Required request.setTimeFrame(edtTimeFrame.getText().toString()); //Date Format - Required request.setDateFormat(edtDateFormat.getText().toString()); if (!isValid(request)) { //Stop execution if request is not valid return; } PayMe.getStatistics(request, new PayMe.TransactionListener() { @Override public void onSuccess(GetStatisticsResponse response) { //Handle success request } @Override public void onFailed(Exception exception, PayMeError error) { //Handle failed request } }); ``` ### Get graph points ```java GetGraphPointsRequest request = new GetGraphPointsRequest(); //Time Frame - Required request.setTimeFrame(edtTimeFrame.getText().toString()); //Date Format - Required request.setDateFormat(edtDateFormat.getText().toString()); if (!isValid(request)) { //Stop execution if request is not valid return; } PayMe.getGraphPoinsts(request, new PayMe.TransactionListener() { @Override public void onSuccess(GetGraphPointsResponse response) { //Handle success request } @Override public void onFailed(Exception exception, PayMeError error) { //Handle failed request } }); ``` ## Point of Sale (POS) - [Point of Sale (POS)](https://docs.payme.io/payments/point-of-sale-pos): Take card-present EMV payments on a POS device: prerequisites, device setup and pairing, payments and refunds. # Point of Sale (POS) The POS module lets platforms, sellers and PSPs take card-present EMV payments on a physical payment device and get the result through the Payments API. How to: [Take in-person payments with a POS device](https://docs.payme.io/accepting-payments/checkout-and-in-person/point-of-sale) walks through the whole flow, including pairing a device yourself (`pos/pair`, `pos/authenticate`) and transmitting the day's transactions (`pos/transmit`). ## Supported payment methods The device accepts payment cards (Visa, Mastercard, American Express, Diners Club). Other methods depend on the device; ask PayMe Partners () for the current list. ## Before you start | Item | Description | |---|---| | `seller_payme_id` | The seller's MPL. It authenticates payments and refunds. | | `payme_client_key` | Partners only. Needed to order devices with `vas-enable`. A seller can take payments with `seller_payme_id` alone. | | Active POS service | The seller must have an active POS service; otherwise payment calls return error `720`. | | A paired device | A supported POS device, paired and authenticated. Its `pos_id` names the device in each payment request. | ## Set up a device 1. Order the devices with [Order POS devices](https://docs.payme.io/payments/point-of-sale-pos/post-vas-enable). A new terminal takes up to 5 business days. 2. PayMe pairs the device and then authenticates it. Each step sends a callback: `point-of-sale-action-pair-update`, which carries the `pos_id`, then `point-of-sale-action-authenticate-update`. The device can't take payments until both steps are done. 3. The device ships to the seller. ## Take a payment Call [Create a POS payment](https://docs.payme.io/payments/point-of-sale-pos/post-payment) (`POST /sales`) with `payment.method` `pos` and the device's `payment.pos_id`. PayMe pushes the payment to the device and waits for the buyer. The result comes back in the same response; there is nothing to poll. A declined or canceled payment returns HTTP 200 with `status_code` `1`. Always check `status_code`, not the HTTP status. You can also do it in two steps: create the sale with [`generate-sale`](https://docs.payme.io/payments/hosted-payment-page/post-generate-sale) and `sale_payment_method` `pos`, then push it to the device with `PUT /sales/{payme_sale_id}`, sending `seller_payme_id` and a `payment` object with `method` `pos` and `pos_id`. ## Refund a payment Call [Refund a POS sale](https://docs.payme.io/payments/point-of-sale-pos/put-sales) (`PUT /sales/{payme_sale_id}`) with `payment.action` `refund`. The refund is sent to the device. ## Base URLs | Environment | Base URL | |---|---| | Sandbox | `https://sandbox.payme.io/api` | | Production | `https://live.payme.io/api` | - [Order POS devices](https://docs.payme.io/payments/point-of-sale-pos/post-vas-enable): POST /vas-enable — Order POS devices # Order POS devices - Sandbox: `POST https://sandbox.payme.io/api/vas-enable` - Production: `POST https://live.payme.io/api/vas-enable` ## Credentials - Request body field `payme_client_key` (required): Your partner key. - Request body field `seller_payme_id` (required): The seller's MPL. ## Overview Partners only. Orders POS devices for a seller by enabling the POS services with `vas-enable`. The process is manual: PayMe requests a new terminal (up to 5 business days), prepares the devices and ships them. PayMe pairs each device and sends you a `point-of-sale-action-pair-update` callback with its `pos_id`. Depending on how the service is set up, PayMe either opens a support ticket for the order (response `status_code` `2`, `Zendesk ticket created`) or enables the service at once and returns its details. ### Step 1: enable the POS payment method Call `vas-enable` with the `vas_payme_id` of the POS payment method service. ```json { "payme_client_key": "", "seller_payme_id": "MPLDEMO-MPLDEMO-MPLDEMO-1234567", "vas_payme_id": "VASL1545-8192915E-8192915E-8192915E" } ``` ### Step 2: order the devices Call `vas-enable` with the `vas_payme_id` of the POS device service and the device list in `vas_data`. ```json { "payme_client_key": "", "seller_payme_id": "MPLDEMO-MPLDEMO-MPLDEMO-1234567", "vas_payme_id": "VASL1545-8192915E-5NTSEUM1-03YNFWNU", "vas_data": { "number_of_devices": 2, "items": [ { "pos_id": "001", "shipping_address": "1 Example St, Tel Aviv", "name": "Front counter" }, { "pos_id": "002", "shipping_address": "1 Example St, Tel Aviv", "name": "Back counter" } ] } } ``` ### Adding devices later Call step 2 again with only the new devices and `vas_data.extend_items` `true`. Without `extend_items`, the list you send replaces the devices already stored. ```json { "payme_client_key": "", "seller_payme_id": "MPLDEMO-MPLDEMO-MPLDEMO-1234567", "vas_payme_id": "VASL1545-8192915E-5NTSEUM1-03YNFWNU", "vas_data": { "extend_items": true, "number_of_devices": 1, "items": [ { "pos_id": "003", "shipping_address": "1 Example St, Tel Aviv", "name": "Terrace" } ] } } ``` ## Errors Errors return `status_code` `1`. | HTTP | Code | When | |---|---|---| | 500 | `1` | `payme_client_key`, `seller_payme_id` or `vas_payme_id` is missing. | | 400 | `703` | Your partner account has no permission for this service (`Partner has no permission for this VAS`). | | 500 | `720` | No service has this `vas_payme_id`. | | 500 | `200` | The partner key is unknown. | | 500 | `251` | The seller key is unknown. | ## Parameters This endpoint takes no path, query or header parameters. ## Request body Content type: `application/json` | Field | Type | Required | Description | | --- | --- | --- | --- | | `payme_client_key` | string | yes | Your partner key. | | `seller_payme_id` | string | yes | The seller's MPL. | | `vas_payme_id` | string | yes | The service to enable: the POS payment method service (step 1) or the POS device service (step 2). | | `vas_payer_type` | integer | no | Who pays the service fees: `1` partner, `2` seller, `3` reseller. Used only when the service is first created for the seller. Default: the payer set on your partner's service. | | `vas_data` | object | no | The device order. Send it in step 2. | | `vas_data.number_of_devices` | integer | yes | Number of devices ordered. It must equal the number of `items`. | | `vas_data.items` | array | yes | One entry per device. | | `vas_data.items[].pos_id` | string | yes | The device's POS ID. Payment requests address the device by this ID (`payment.pos_id`). | | `vas_data.items[].shipping_address` | string | yes | Where to ship the device. | | `vas_data.items[].name` | string | yes | A name for the device, used during setup. | | `vas_data.extend_items` | boolean | no | `true` adds `items` to the devices already ordered for this seller. Default: the list you send replaces them. | ### Request example ```json { "payme_client_key": "", "seller_payme_id": "MPLDEMO-MPLDEMO-MPLDEMO-1234567", "vas_payme_id": "VASL1545-8192915E-5NTSEUM1-03YNFWNU", "vas_data": { "number_of_devices": 2, "items": [ { "pos_id": "001", "shipping_address": "1 Example St, Tel Aviv", "name": "Front counter" }, { "pos_id": "002", "shipping_address": "1 Example St, Tel Aviv", "name": "Back counter" } ] } } ``` ## Code samples ### curl ```bash curl -X POST 'https://sandbox.payme.io/api/vas-enable' \ -H 'Content-Type: application/json' \ --data-raw '{ "payme_client_key": "", "seller_payme_id": "MPLDEMO-MPLDEMO-MPLDEMO-1234567", "vas_payme_id": "VASL1545-8192915E-5NTSEUM1-03YNFWNU", "vas_data": { "number_of_devices": 2, "items": [ { "pos_id": "001", "shipping_address": "1 Example St, Tel Aviv", "name": "Front counter" }, { "pos_id": "002", "shipping_address": "1 Example St, Tel Aviv", "name": "Back counter" } ] } }' ``` ### Node.js ```javascript const response = await fetch("https://sandbox.payme.io/api/vas-enable", { method: "POST", headers: { "Content-Type": "application/json", }, body: JSON.stringify({ "payme_client_key": "", "seller_payme_id": "MPLDEMO-MPLDEMO-MPLDEMO-1234567", "vas_payme_id": "VASL1545-8192915E-5NTSEUM1-03YNFWNU", "vas_data": { "number_of_devices": 2, "items": [ { "pos_id": "001", "shipping_address": "1 Example St, Tel Aviv", "name": "Front counter" }, { "pos_id": "002", "shipping_address": "1 Example St, Tel Aviv", "name": "Back counter" } ] } }), }); console.log(await response.text()); ``` ### Python ```python import requests response = requests.post( "https://sandbox.payme.io/api/vas-enable", json={ "payme_client_key": "", "seller_payme_id": "MPLDEMO-MPLDEMO-MPLDEMO-1234567", "vas_payme_id": "VASL1545-8192915E-5NTSEUM1-03YNFWNU", "vas_data": { "number_of_devices": 2, "items": [ { "pos_id": "001", "shipping_address": "1 Example St, Tel Aviv", "name": "Front counter", }, { "pos_id": "002", "shipping_address": "1 Example St, Tel Aviv", "name": "Back counter", }, ], }, }, ) print(response.text) ``` ### PHP ```php ", "seller_payme_id": "MPLDEMO-MPLDEMO-MPLDEMO-1234567", "vas_payme_id": "VASL1545-8192915E-5NTSEUM1-03YNFWNU", "vas_data": { "number_of_devices": 2, "items": [ { "pos_id": "001", "shipping_address": "1 Example St, Tel Aviv", "name": "Front counter" }, { "pos_id": "002", "shipping_address": "1 Example St, Tel Aviv", "name": "Back counter" } ] } } BODY; $ch = curl_init('https://sandbox.payme.io/api/vas-enable'); 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 — PayMe opened a ticket for the order (`status_code` `2`), or enabled the service (`status_code` `0`). (success) | Field | Type | Description | | --- | --- | --- | | `status_code` | integer | `2` PayMe opened a support ticket for the order. `0` the service was enabled; the service fields below are returned. | | `seller_payme_id` | string | The seller's MPL. | | `message` | string | `Zendesk ticket created`, when `status_code` is `2`. | | `vas_payme_id` | string | The `vas_payme_id` you sent, when `status_code` is `0`. | | `vas_guid` | string | ID of the seller's service, when `status_code` is `0`. | | `vas_is_active` | boolean | `true` if the seller's service is active. | | `vas_type` | string | Service type. | | `vas_description` | string | Service description. | | `vas_payer_type` | integer | Who pays the service fees: `1` partner, `2` seller, `3` reseller. | | `vas_data` | object | The stored device list, without hidden fields. | ```json { "status_code": 2, "seller_payme_id": "MPLDEMO-MPLDEMO-MPLDEMO-1234567", "message": "Zendesk ticket created" } ``` ### 500 — The request was refused. See the error table. (error) | Field | Type | Description | | --- | --- | --- | | `status_code` | integer | `1` on failure. | | `status_error_details` | string | What went wrong, in the language you asked for (Hebrew by default). | | `status_additional_info` | string | The field or value concerned. Can be `null`. | | `status_error_code` | integer | PayMe error code. See the error table above and [Errors](/payments/getting-started/errors). | | `session` | string | PayMe session ID. Quote it when you contact support. | ```json { "status_code": 1, "status_error_details": "Seller was not found", "status_additional_info": "seller_payme_id", "status_error_code": 251, "session": "FhT3aXe7" } ``` - [Create a POS payment](https://docs.payme.io/payments/point-of-sale-pos/post-payment): POST /sales — Create a POS payment # Create a POS payment - Sandbox: `POST https://sandbox.payme.io/api/sales` - Production: `POST https://live.payme.io/api/sales` ## Credentials - Request body field `seller_payme_id` (required): The seller's MPL. - Request body field `payme_client_key` (optional): Partners only: your partner key. You can send it in the `PayMe-Partner-Key` header instead. ## Overview Creates a sale and sends it to a paired POS device, then waits for the buyer to pay on the device. The result comes back in the same response; there is nothing to poll. To refund, see [Refund a POS sale](/payments/point-of-sale-pos/put-sales). A declined or canceled payment returns **HTTP 200** with `status_code` `1`, `status_error_code` and `status_error_details`. Always check `status_code`, not the HTTP status. For example: ```json { "status_code": 1, "payme_status": "error", "status_error_code": 20003, "status_error_details": "Transaction declined", "payme_sale_id": "SALE1700-000000AA-EXAMPLE1-SALE0001", "payme_sale_status": "failed" } ``` - The seller must have an active POS service (error `720`), and the device must be paired and active. - `sale_type` `sale` (default) charges the card; `authorize` only authorizes it. `token` returns error `357`. - This call takes the same sale fields as [generate-sale](/payments/hosted-payment-page/post-generate-sale), for example `installments`. - Setup, pairing and the two-step flow: [POS module overview](/payments/point-of-sale-pos). ## Authentication Send `seller_payme_id` (the seller's MPL) in the JSON body. Partners also send `payme_client_key`, in the body or the `PayMe-Partner-Key` header. ## Errors | HTTP | Code | When | |---|---|---| | 200 | Decline code | The payment was declined or canceled on the device. `status_code` is `1`. | | 500 | `1` | A required field is missing, for example `seller_payme_id` or `currency`. `status_additional_info` names it. | | 400 | `357` | `sale_type` `token` isn't supported here. | | 400 | `720` | The POS service isn't active for this seller. | | 400 | `26014` | `payment.pos_id` is missing, or the seller has no device with this ID. | | 400 | `26017` | The device has no POS record. | | 400 | `26018` | The device isn't active. | | 500 | `251` | The seller key is unknown. | ## 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. | | `payme_client_key` | string | no | Partners only: your partner key. You can send it in the `PayMe-Partner-Key` header instead. | | `sale_price` | integer | yes | Amount in minor units (`10000` = 100.00). | | `currency` | string | yes | ISO 4217 currency code, for example `ILS`. | | `product_name` | string | yes | What the buyer is paying for. | | `payment` | object | yes | Where to send the payment. | | `payment.method` | string | yes | `pos`. | | `payment.pos_id` | string | yes | The device's ID, from the seller's POS service. The `point-of-sale-action-pair-update` callback also returns it. | | `sale_type` | string | no | `sale` (default) charges the card. `authorize` only authorizes it. `token` returns error `357`. | | `installments` | integer | no | Number of installments. | | `transaction_id` | string | no | Your own reference for the sale. | | `sale_callback_url` | string | no | URL for sale callbacks. Default: your partner's default callback URL, if one is set. | | `customer` | object | no | Buyer details. Every field is optional. | | `customer.name` | string | no | Buyer's name. | | `customer.email` | string | no | Buyer's email. | | `customer.phone` | string | no | Buyer's mobile number. | | `customer.social_id` | string | no | Buyer's national ID. | | `customer.zip_code` | string | no | Zip code. | | `customer.country` | string | no | Two-letter ISO country code. | | `customer.state` | string | no | State or region. | | `customer.city` | string | no | City. | | `customer.line1` | string | no | Address line 1. | | `customer.line2` | string | no | Address line 2. | | `customer.business_name` | string | no | The buyer's business name. Send it together with `business_code`. | | `customer.business_code` | string | no | The buyer's business registration number. | | `language` | string | no | Language of messages: `he` (default), `en`, `es`, `ru` or `ar`. | ### Request example ```json { "seller_payme_id": "MPLDEMO-MPLDEMO-MPLDEMO-1234567", "sale_price": 10000, "currency": "ILS", "product_name": "Coffee beans 1kg", "transaction_id": "order-1001", "sale_callback_url": "https://www.example.com/payment/callback", "payment": { "method": "pos", "pos_id": "001" }, "customer": { "name": "Israel Israeli", "email": "buyer@example.com", "phone": "0500000000" }, "language": "en" } ``` ## Code samples ### curl ```bash curl -X POST 'https://sandbox.payme.io/api/sales' \ -H 'Content-Type: application/json' \ --data-raw '{ "seller_payme_id": "MPLDEMO-MPLDEMO-MPLDEMO-1234567", "sale_price": 10000, "currency": "ILS", "product_name": "Coffee beans 1kg", "transaction_id": "order-1001", "sale_callback_url": "https://www.example.com/payment/callback", "payment": { "method": "pos", "pos_id": "001" }, "customer": { "name": "Israel Israeli", "email": "buyer@example.com", "phone": "0500000000" }, "language": "en" }' ``` ### Node.js ```javascript const response = await fetch("https://sandbox.payme.io/api/sales", { method: "POST", headers: { "Content-Type": "application/json", }, body: JSON.stringify({ "seller_payme_id": "MPLDEMO-MPLDEMO-MPLDEMO-1234567", "sale_price": 10000, "currency": "ILS", "product_name": "Coffee beans 1kg", "transaction_id": "order-1001", "sale_callback_url": "https://www.example.com/payment/callback", "payment": { "method": "pos", "pos_id": "001" }, "customer": { "name": "Israel Israeli", "email": "buyer@example.com", "phone": "0500000000" }, "language": "en" }), }); console.log(await response.text()); ``` ### Python ```python import requests response = requests.post( "https://sandbox.payme.io/api/sales", json={ "seller_payme_id": "MPLDEMO-MPLDEMO-MPLDEMO-1234567", "sale_price": 10000, "currency": "ILS", "product_name": "Coffee beans 1kg", "transaction_id": "order-1001", "sale_callback_url": "https://www.example.com/payment/callback", "payment": { "method": "pos", "pos_id": "001", }, "customer": { "name": "Israel Israeli", "email": "buyer@example.com", "phone": "0500000000", }, "language": "en", }, ) print(response.text) ``` ### PHP ```php '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 device returned a result: paid (`status_code` `0`) or declined (`status_code` `1`). (success) | Field | Type | Description | | --- | --- | --- | | `status_code` | integer | `0` paid. `1` declined or canceled (still HTTP 200). | | `payme_status` | string | `success`, or `error` when the payment failed. | | `status_error_code` | integer | `0` on success; otherwise the decline code. | | `status_error_details` | string | Why the payment failed, when `status_code` is `1`. | | `payme_sale_id` | string | PayMe's sale ID. Use it to refund. | | `payme_sale_code` | integer | PayMe's numeric sale ID. | | `sale_created` | string | When the sale was created. | | `payme_sale_status` | string | Sale status, for example `completed`. See [Sale statuses](/payments/codes-statuses/sale-statuses). | | `sale_status` | string | Same as `payme_sale_status`. | | `currency` | string | ISO 4217 currency code. | | `transaction_id` | string | Your reference, as sent. | | `is_token_sale` | boolean | `true` if the sale was paid with a saved token. | | `price` | integer | Sale amount in minor units. | | `payme_signature` | string | Signature of the sale. See [Callbacks](/payments/getting-started/callbacks). | | `sale_description` | string | The `product_name` you sent. | | `sale_deferred_months` | integer | Deferred months, or `null`. | | `payme_transaction_id` | string | PayMe's transaction ID. | | `payme_transaction_total` | string | Amount charged, in minor units. | | `payme_transaction_card_brand` | string | Card brand. | | `payme_transaction_auth_number` | string | Authorization number. | | `payme_transaction_voucher` | string | Voucher number, or `null`. | | `payme_transaction_emv_uid` | string | EMV transaction ID from the device. | | `payme_transaction_acquirer` | string | The acquirer. | | `payme_transaction_auth_source` | string | Who authorized the transaction, for example `CreditCompany`. | | `payme_transaction_card_issuer` | string | The card issuer. | | `payme_transaction_credit_type` | string | Credit type, for example `RegularCredit`. | | `buyer_name` | string | Buyer's name. | | `buyer_email` | string | Buyer's email. | | `buyer_phone` | string | Buyer's phone number. | | `buyer_card_mask` | string | Masked card number. | | `buyer_card_exp` | string | Card expiry, `MMYY`. | | `buyer_card_is_foreign` | boolean | `true` if the card was issued outside the seller's country. | | `buyer_social_id` | string | Buyer's national ID, or `null`. | | `installments` | integer | Number of installments. | | `transaction_first_payment` | string | First installment amount, in minor units. | | `transaction_periodical_payment` | integer | Amount of each later installment, in minor units. `0` for a single payment. | | `transaction_arn` | string | Acquirer reference number (ARN). | | `sale_paid_date` | string | When the sale was paid. | | `sale_release_date` | string | When the funds are released to the seller, or `null`. | | `sale_3ds` | boolean | `true` if 3D Secure was used. | | `redirect_url` | string | The sale's return URL, or `null`. | ```json { "status_code": 0, "payme_status": "success", "status_error_code": 0, "payme_sale_id": "SALE1700-000000AA-EXAMPLE1-SALE0001", "payme_sale_code": 12346578, "sale_created": "2026-11-09 13:33:54", "payme_sale_status": "completed", "sale_status": "completed", "currency": "ILS", "transaction_id": "order-1001", "is_token_sale": false, "price": 10000, "payme_signature": "db1c276**********c5b39", "sale_description": "Coffee beans 1kg", "sale_deferred_months": null, "payme_transaction_id": "TRAN1688-034834SZ-OYNALKNE-DWOXFEUZ", "payme_transaction_total": "10000", "payme_transaction_card_brand": "Mastercard", "payme_transaction_auth_number": "12345678", "payme_transaction_voucher": null, "payme_transaction_emv_uid": "2306**********102613", "payme_transaction_acquirer": "PayMe", "payme_transaction_auth_source": "CreditCompany", "payme_transaction_card_issuer": "Isracard", "payme_transaction_credit_type": "RegularCredit", "buyer_name": "Israel Israeli", "buyer_email": "buyer@example.com", "buyer_phone": "0500000000", "buyer_card_mask": "532610******5846", "buyer_card_exp": "0426", "buyer_card_is_foreign": false, "buyer_social_id": null, "installments": 1, "transaction_first_payment": "10000", "transaction_periodical_payment": 0, "transaction_arn": "2306**********2613", "sale_paid_date": "2026-11-09 13:34:20", "sale_release_date": null, "sale_3ds": false, "redirect_url": null } ``` ### 400 — The device or the POS service can't take the payment. See the error table. (error) | Field | Type | Description | | --- | --- | --- | | `status_code` | integer | `1` on failure. | | `status_error_details` | string | What went wrong, in the language you asked for (Hebrew by default). | | `status_additional_info` | string | The field or value concerned. Can be `null`. | | `status_error_code` | integer | PayMe error code. See the error table above and [Errors](/payments/getting-started/errors). | | `session` | string | PayMe session ID. Quote it when you contact support. | ```json { "status_code": 1, "status_error_details": "Desired device is inactive", "status_additional_info": null, "status_error_code": 26018, "session": "FhT3aXe7" } ``` ### 500 — The request was refused. See the error table. (error) | Field | Type | Description | | --- | --- | --- | | `status_code` | integer | `1` on failure. | | `status_error_details` | string | What went wrong, in the language you asked for (Hebrew by default). | | `status_additional_info` | string | The field or value concerned. Can be `null`. | | `status_error_code` | integer | PayMe error code. See the error table above and [Errors](/payments/getting-started/errors). | | `session` | string | PayMe session ID. Quote it when you contact support. | ```json { "status_code": 1, "status_error_details": "Required parameter is missing", "status_additional_info": "currency", "status_error_code": 1, "session": "FhT3aXe7" } ``` - [Refund a POS sale](https://docs.payme.io/payments/point-of-sale-pos/put-sales): PUT /sales/{sale_guid} — Refund a POS sale # Refund a POS sale - Sandbox: `PUT https://sandbox.payme.io/api/sales/{sale_guid}` - Production: `PUT https://live.payme.io/api/sales/{sale_guid}` ## Credentials - Request body field `seller_payme_id` (required): The seller's MPL. The sale must belong to this seller. - Request body field `payme_client_key` (optional): Partners only: your partner key. You can send it in the `PayMe-Partner-Key` header instead. ## Overview Refunds a sale paid on a POS device. PayMe sends the refund to the device in `payment.pos_id` and returns the result in the same response. Example: `PUT https://sandbox.payme.io/api/sales/SALE1700-000000AA-EXAMPLE1-SALE0001`. - Send `payment.action` `refund`. Without it, this endpoint pays the sale instead of refunding it (see [POS module overview](/payments/point-of-sale-pos)). - Leave out `payment.amount` to refund everything that can still be refunded, or send a smaller amount for a partial refund. - `payment.verify_only` `true` runs the checks and returns without refunding. - `refunded_from_creditcard` is `true` when the seller's balance didn't cover the refund and PayMe charged the seller's card on file for the difference. ## Authentication Send `seller_payme_id` (the seller's MPL) in the JSON body. The sale must belong to this seller. Partners also send `payme_client_key`, in the body or the `PayMe-Partner-Key` header. ## Errors | HTTP | Code | When | |---|---|---| | 500 | `1` | A required field is missing: `seller_payme_id`, `payment` or `payment.method`. | | 500 | `350` | No sale has this ID. | | 500 | `4` | `payment.method` isn't the sale's payment method (`pos`). | | 400 | `720` | The POS service isn't active for this seller. | | 400 | `26014` | `payment.pos_id` is missing, or the seller has no device with this ID. | | 400 | `26017` | The device has no POS record. | | 400 | `26018` | The device isn't active. | | 500 | Decline code | The device or the card company declined the refund. | ## Parameters | Name | In | Type | Required | Description | | --- | --- | --- | --- | --- | | `sale_guid` | path | string | yes | The sale's `payme_sale_id`. | ## Request body Content type: `application/json` | Field | Type | Required | Description | | --- | --- | --- | --- | | `seller_payme_id` | string | yes | The seller's MPL. The sale must belong to this seller. | | `payme_client_key` | string | no | Partners only: your partner key. You can send it in the `PayMe-Partner-Key` header instead. | | `payment` | object | yes | The refund to send to the device. | | `payment.method` | string | yes | `pos`. It must match the sale's payment method. | | `payment.action` | string | yes | `refund`. Without it, the call pays the sale instead of refunding it. | | `payment.pos_id` | string | yes | The device that processes the refund. | | `payment.amount` | integer | no | Amount to refund, in minor units. Default: everything that can still be refunded. | | `payment.verify_only` | boolean | no | `true` runs the checks without refunding. | | `language` | string | no | Language of messages: `he` (default), `en`, `es`, `ru` or `ar`. | ### Request example ```json { "seller_payme_id": "MPLDEMO-MPLDEMO-MPLDEMO-1234567", "payment": { "method": "pos", "action": "refund", "pos_id": "001" }, "language": "en" } ``` ## Code samples ### curl ```bash curl -X PUT 'https://sandbox.payme.io/api/sales/' \ -H 'Content-Type: application/json' \ --data-raw '{ "seller_payme_id": "MPLDEMO-MPLDEMO-MPLDEMO-1234567", "payment": { "method": "pos", "action": "refund", "pos_id": "001" }, "language": "en" }' ``` ### Node.js ```javascript const response = await fetch("https://sandbox.payme.io/api/sales/", { method: "PUT", headers: { "Content-Type": "application/json", }, body: JSON.stringify({ "seller_payme_id": "MPLDEMO-MPLDEMO-MPLDEMO-1234567", "payment": { "method": "pos", "action": "refund", "pos_id": "001" }, "language": "en" }), }); console.log(await response.text()); ``` ### Python ```python import requests response = requests.put( "https://sandbox.payme.io/api/sales/", json={ "seller_payme_id": "MPLDEMO-MPLDEMO-MPLDEMO-1234567", "payment": { "method": "pos", "action": "refund", "pos_id": "001", }, "language": "en", }, ) print(response.text) ``` ### PHP ```php '); curl_setopt_array($ch, [ CURLOPT_CUSTOMREQUEST => 'PUT', 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 processed. (success) | Field | Type | Description | | --- | --- | --- | | `status_code` | integer | `0` on success. | | `payme_status` | string | `success`. | | `payme_sale_id` | string | PayMe's sale ID. | | `payme_sale_code` | integer | PayMe's numeric sale ID. | | `payme_sale_status` | string | `refunded`, or `partial-refund` after a partial refund. | | `sale_status` | string | Same as `payme_sale_status`. | | `currency` | string | ISO 4217 currency code. | | `price` | integer | The original sale amount, in minor units. | | `transaction_id` | string | Your reference for the sale. | | `sale_refund_buffer` | integer | Amount that can still be refunded, in minor units. | | `payme_transaction_id` | string | ID of the refund transaction. | | `payme_transaction_total` | integer | Amount refunded, in minor units. | | `payme_transaction_card_brand` | string | Card brand. | | `payme_transaction_auth_number` | string | Authorization number of the refund. | | `payme_signature` | string | Signature of the refund. See [Callbacks](/payments/getting-started/callbacks). | | `refunded_from_creditcard` | boolean | `true` if PayMe charged the seller's card on file because the balance didn't cover the refund. | | `sale_invoice_number` | string | Number of the credit document, if the invoicing service issued one. Otherwise `null`. | | `sale_invoice_url` | string | Link to the credit document, if one was issued. Otherwise `null`. | ```json { "status_code": 0, "payme_status": "success", "payme_sale_id": "SALE1700-000000AA-EXAMPLE1-SALE0001", "payme_sale_code": 12346578, "payme_sale_status": "refunded", "sale_status": "refunded", "currency": "ILS", "price": 10000, "transaction_id": "order-1001", "sale_refund_buffer": 0, "payme_transaction_id": "TRAN1700-000000AA-EXAMPLE1-TRAN0002", "payme_transaction_total": 10000, "payme_transaction_card_brand": "Mastercard", "payme_transaction_auth_number": "0123456", "payme_signature": "db1c276**********c5b39", "refunded_from_creditcard": false, "sale_invoice_number": null, "sale_invoice_url": null } ``` ### 400 — The device or the POS service can't take the refund. See the error table. (error) | Field | Type | Description | | --- | --- | --- | | `status_code` | integer | `1` on failure. | | `status_error_details` | string | What went wrong, in the language you asked for (Hebrew by default). | | `status_additional_info` | string | The field or value concerned. Can be `null`. | | `status_error_code` | integer | PayMe error code. See the error table above and [Errors](/payments/getting-started/errors). | | `session` | string | PayMe session ID. Quote it when you contact support. | ```json { "status_code": 1, "status_error_details": "Desired device is inactive", "status_additional_info": null, "status_error_code": 26018, "session": "FhT3aXe7" } ``` ### 500 — The request was refused or the refund was declined. See the error table. (error) | Field | Type | Description | | --- | --- | --- | | `status_code` | integer | `1` on failure. | | `status_error_details` | string | What went wrong, in the language you asked for (Hebrew by default). | | `status_additional_info` | string | The field or value concerned. Can be `null`. | | `status_error_code` | integer | PayMe error code. See the error table above and [Errors](/payments/getting-started/errors). | | `session` | string | PayMe session ID. Quote it when you contact support. | ```json { "status_code": 1, "status_error_details": "Sale was not found", "status_additional_info": "SALE1700-000000AA-EXAMPLE1-SALE0001", "status_error_code": 350, "session": "FhT3aXe7" } ``` ## Post Sale Actions - [Refund a sale](https://docs.payme.io/payments/post-sale-actions/post-refund-sale): POST /refund-sale — Refund a sale # Refund a sale - Sandbox: `POST https://sandbox.payme.io/api/refund-sale` - Production: `POST https://live.payme.io/api/refund-sale` ## Credentials - Request body field `payme_client_key` (optional): Partners: your partner key. You can send it in the `PayMe-Partner-Key` header instead. A seller leaves it out. - Request body field `seller_payme_id` (optional): 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. ## 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](/payments/post-sale-actions/void-sale). ### 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 - The sale's status must be `completed` or `partial-refund`. Any other status, including `chargeback`, returns error `305` with the current status in `status_additional_info`. While a chargeback is open the dispute returns the money, so no refund is possible. - Leave out `sale_refund_amount` to refund everything that is left. Never send `0`. - You can refund several times, up to the sale price. Each partial refund, including the last one, must be at least the account's minimum sale value (500 by default). - After a partial refund, `sale_status` stays `partial-refund` even when nothing is left. Read `sale_refund_buffer` for the amount that remains. - If the seller's balance doesn't cover the refund, PayMe takes the shortfall from the seller's card on file and returns `refunded_from_creditcard: true`. - A refund can't be undone. - Sales paid by POS, eCheck or a Verifone prepaid card aren't refunded with this call (error `4`). - Send `verify_only: true` to check a refund without making it. ### 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](/payments/getting-started/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 ```json { "seller_payme_id": "MPLDEMO-MPLDEMO-MPLDEMO-1234567", "payme_sale_id": "SALEDEMO-XXXXXXXX-XXXXXXXX-XXXXXXXX", "sale_refund_amount": 1000, "language": "en" } ``` ## Code samples ### curl ```bash 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 ```javascript 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 ```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 '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. | ```json { "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](/payments/getting-started/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. | ```json { "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](/payments/getting-started/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. | ```json { "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](/payments/getting-started/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. | ```json { "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](/payments/getting-started/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. | ```json { "status_code": 1, "status_error_details": "Cannot perform action due to an incorrect status", "status_additional_info": "chargeback", "status_error_code": 305, "session": "Ab12Cd34" } ``` - [Void an authorization](https://docs.payme.io/payments/post-sale-actions/void-sale): POST /refund-sale — Void an authorization # Void an authorization - Sandbox: `POST https://sandbox.payme.io/api/refund-sale` - Production: `POST https://live.payme.io/api/refund-sale` ## Credentials - Request body field `payme_client_key` (optional): Partners: your partner key. You can send it in the `PayMe-Partner-Key` header instead. A seller leaves it out. - Request body field `seller_payme_id` (optional): 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. ## Overview Releases the hold of an `authorized` sale, in full or in part. It is the same call as [`refund-sale`](/payments/post-sale-actions/post-refund-sale): PayMe voids instead of refunding because the sale is `authorized`. ### Credentials The same as `refund-sale`: send `seller_payme_id`, or `seller_id` with your partner key (`payme_client_key`). A partner key on its own fails with error `1`. ### Rules - The sale's status must be `authorized`, or `partial-void` to release more of the hold. Otherwise the call returns error `305`. - Leave out `sale_refund_amount` to release the whole hold; the sale becomes `voided`. - Send an amount to release part of the hold; the sale becomes `partial-void` and can no longer be captured. To charge less than you authorized, capture with a lower `sale_price` instead. After a partial void, `sale_refund_buffer` shows the hold that remains. - An authorization that [multi-capture](/accepting-payments/capture-and-saved-cards/multi-capture) has already captured from can't be voided (HTTP 400, error `369`). - PayMe never voids an authorization on its own. If you don't void it, the card issuer releases the hold on its own schedule. PayMe sends the same `refund` callback as for a refund. See [Callbacks](/payments/getting-started/callbacks). ## 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 authorized sale. | | `sale_refund_amount` | integer | no | Amount of the hold to release, in minor units (`1000` = 10.00). Leave it out to release the whole hold. 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 ```json { "seller_payme_id": "MPLDEMO-MPLDEMO-MPLDEMO-1234567", "payme_sale_id": "SALEDEMO-XXXXXXXX-XXXXXXXX-XXXXXXXX", "language": "en" } ``` ## Code samples ### curl ```bash 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", "language": "en" }' ``` ### Node.js ```javascript 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", "language": "en" }), }); console.log(await response.text()); ``` ### Python ```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", "language": "en", }, ) print(response.text) ``` ### PHP ```php '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 hold was released, in full or in part. (success) | Field | Type | Description | | --- | --- | --- | | `status_code` | integer | `0`: success. | | `status_error_code` | integer | `0` on success. | | `payme_status` | string | `success`. | | `refunded_from_creditcard` | boolean | Always `false` on a void. | | `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 | The part of the hold that is still authorized, in minor units. | | `sale_status` | string | The sale's status after the call: `voided`, or `partial-void` after a partial void. | | `payme_transaction_total` | integer | Amount released from the hold, in minor units. | | `payme_transaction_total_aft_deduction` | integer | Same as `payme_transaction_total` on a void. | | `payme_transaction_id` | string | PayMe's ID of the void 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. | ```json { "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": 0, "sale_status": "voided", "payme_transaction_total": 10000, "payme_transaction_total_aft_deduction": 10000, "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 `369`: multi-capture has already captured part of this authorization. (error) | Field | Type | Description | | --- | --- | --- | | `status_code` | integer | `1`: the request failed. | | `status_error_code` | integer | PayMe's error code. See [Errors](/payments/getting-started/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. | ```json { "status_code": 1, "status_error_details": "Authorization cannot be voided", "status_additional_info": "", "status_error_code": 369, "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](/payments/getting-started/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. | ```json { "status_code": 1, "status_error_details": "Could not access sale", "status_additional_info": "", "status_error_code": 303, "session": "Ab12Cd34" } ``` ### 500 — Request errors. `305`: the sale isn't `authorized` or `partial-void`. `357`: this sale type can't be voided. `519`: the amount is above the sale price. `352`: a partial amount outside the account's limits. `363`: already fully voided. `520`: more than the hold that remains. `251`: unknown seller. `350`: no sale has this ID. (error) | Field | Type | Description | | --- | --- | --- | | `status_code` | integer | `1`: the request failed. | | `status_error_code` | integer | PayMe's error code. See [Errors](/payments/getting-started/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. | ```json { "status_code": 1, "status_error_details": "Cannot perform action due to an incorrect status", "status_additional_info": "completed", "status_error_code": 305, "session": "Ab12Cd34" } ``` - [Capture an authorized sale](https://docs.payme.io/payments/post-sale-actions/post-capture-sale): POST /capture-sale — Capture an authorized sale # Capture an authorized sale - Sandbox: `POST https://sandbox.payme.io/api/capture-sale` - Production: `POST https://live.payme.io/api/capture-sale` ## Credentials - Request body field `payme_client_key` (optional): Partners: your partner key. You can send it in the `PayMe-Partner-Key` header instead. A seller leaves it out. - Request body field `seller_payme_id` (optional): The seller's MPL. Required unless you send `seller_id` with `payme_client_key`. ## Overview Charges a sale that was authorized with `sale_type: "authorize"`. Capture once, for the authorized amount or less, within 7 days of the authorization. To capture in several parts, use [multi-capture](/accepting-payments/capture-and-saved-cards/multi-capture). The whole flow is in [Authorize now, capture later](/accepting-payments/capture-and-saved-cards/capture-sale). ### Credentials The same as [`refund-sale`](/payments/post-sale-actions/post-refund-sale): send `seller_payme_id`, or `seller_id` with your partner key (`payme_client_key`). A partner key on its own fails with error `1`. The sale must belong to the seller you name. ### Rules - The sale must be `authorized`. A sale whose capture was declined (`failed`) can be captured again while the authorization is still valid. Any other status returns error `305`, with the status in `status_additional_info`. - Leave out `sale_price` to capture the full authorized amount; send a lower `sale_price` to capture less. - `sale_price` must be at least the account's minimum sale value (500 by default) and at most the authorized amount, unless PayMe has set a higher capture limit on your account. `0` or an amount outside these limits returns `352`; a decimal returns `42`. - More than 7 days (168 hours) after the authorization, the call fails with `516`. The error doesn't release the hold: void it with [`refund-sale`](/payments/post-sale-actions/void-sale). - `518` means the sale's authorization is no longer open, for example because the authorization failed. ### Result A successful capture returns the sale with `sale_status: "completed"`, and PayMe sends a `sale-complete` callback. A declined capture returns HTTP 200 with `status_code: 1`, `status_error_code` and `status_error_details`, and the sale becomes `failed`; you can retry while the authorization is still valid and within the 7 days. ## 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`. | | `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 authorized sale. | | `sale_price` | integer | no | Amount to capture, in minor units (`10000` = 100.00). Leave it out to capture the full authorized amount. At least the account's minimum sale value (500 by default); at most the authorized amount, unless PayMe has set a higher capture limit on your account. | | `installments` | integer | no | Number of installments, `1`–`36`. Leave it out to keep the sale's installments. | | `transaction_id` | string | no | Your own reference for the sale. Replaces the `transaction_id` you sent on `generate-sale`. | | `sale_additional_data` | object | no | Extra data to store on the sale. | | `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 ```json { "seller_payme_id": "MPLDEMO-MPLDEMO-MPLDEMO-1234567", "payme_sale_id": "SALEDEMO-XXXXXXXX-XXXXXXXX-XXXXXXXX", "sale_price": 8000, "language": "en" } ``` ## Code samples ### curl ```bash curl -X POST 'https://sandbox.payme.io/api/capture-sale' \ -H 'Content-Type: application/json' \ --data-raw '{ "seller_payme_id": "MPLDEMO-MPLDEMO-MPLDEMO-1234567", "payme_sale_id": "SALEDEMO-XXXXXXXX-XXXXXXXX-XXXXXXXX", "sale_price": 8000, "language": "en" }' ``` ### Node.js ```javascript const response = await fetch("https://sandbox.payme.io/api/capture-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_price": 8000, "language": "en" }), }); console.log(await response.text()); ``` ### Python ```python import requests response = requests.post( "https://sandbox.payme.io/api/capture-sale", json={ "seller_payme_id": "MPLDEMO-MPLDEMO-MPLDEMO-1234567", "payme_sale_id": "SALEDEMO-XXXXXXXX-XXXXXXXX-XXXXXXXX", "sale_price": 8000, "language": "en", }, ) print(response.text) ``` ### PHP ```php '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 capture result: captured (`status_code` `0`) or declined (`1`). A decline also returns HTTP 200. (success) | Field | Type | Description | | --- | --- | --- | | `status_code` | integer | `0`: captured. `1`: the capture was declined; the sale is now `failed`. | | `status_error_code` | integer | `0` on success; the decline code when `status_code` is `1`. | | `status_error_details` | string | The decline reason, when `status_code` is `1`. | | `payme_status` | string | Legacy field. Read `status_code` instead. | | `payme_sale_id` | string | The sale's ID. | | `payme_sale_code` | integer | The sale's numeric code. | | `sale_created` | string | When the sale was created, `YYYY-MM-DD HH:MM:SS` (Israel time). | | `sale_status` | string | The sale's status, for example `completed`, `authorized` or `failed`. See [Sale Statuses](/payments/codes-statuses/sale-statuses). | | `payme_sale_status` | string | Same as `sale_status`. | | `sale_type` | string | The sale type as responses name it, for example `Sale` (also for an authorization) or `Token`. | | `sale_payment_method` | string | Payment method, for example `credit-card`. | | `currency` | string | Sale currency, an ISO 4217 code such as `ILS`. | | `price` | integer | Sale price in minor units (`10000` = 100.00). | | `transaction_id` | string | Your own reference for the sale. | | `sale_description` | string | The sale's description. | | `sale_deferred_months` | integer | Deferred months on the sale, or `null`. | | `is_token_sale` | boolean | `true` for a `token` sale, which saves the card without charging it. | | `payme_signature` | string | PayMe's signature for this payment. | | `payme_transaction_id` | string | PayMe's ID of the payment transaction. | | `payme_transaction_total` | string | Amount of the transaction, in minor units. | | `payme_transaction_card_brand` | string | Card brand, for example `Mastercard`. | | `payme_transaction_auth_number` | string | Authorization number from the card issuer. | | `payme_transaction_voucher` | string | Voucher number of the transaction. | | `payme_transaction_emv_uid` | string | EMV UID of the transaction, when the acquirer returns one; usually `null`. | | `payme_transaction_acquirer` | string | The acquirer, for example `PayMe`. | | `payme_transaction_auth_source` | string | Authorization source reported for the transaction. | | `payme_transaction_card_issuer` | string | Card issuer, for example `Isracard`. | | `payme_transaction_credit_type` | string | Credit type, for example `RegularCredit`. | | `buyer_name` | string | Buyer's full name. | | `buyer_email` | string | Buyer's email address. | | `buyer_phone` | string | Buyer's phone number, or `null`. | | `buyer_card_mask` | string | Masked card number, for example `532610******5846`. | | `buyer_card_exp` | string | Card expiry, `MMYY`. | | `buyer_card_is_foreign` | boolean | `true` for a card issued outside Israel. | | `buyer_social_id` | string | Buyer's national ID number, or `null`. | | `installments` | integer | Number of installments. | | `transaction_first_payment` | integer | First installment, in minor units. | | `transaction_periodical_payment` | integer | Each later installment, in minor units; `0` for a single payment. | | `transaction_arn` | string | Acquirer reference (EMV UID) when the acquirer returns one; usually `null`. | | `sale_paid_date` | string | When the payment was made, `YYYY-MM-DD HH:MM:SS` (Israel time). | | `sale_release_date` | string | Date the funds are released to the seller, `YYYY-MM-DD`, or `null`. | | `sale_3ds` | boolean | `true` when the payment passed 3D Secure. | | `session` | string | PayMe's ID for this request. Quote it when you contact PayMe. | ```json { "status_code": 0, "status_error_code": 0, "payme_status": "success", "payme_sale_id": "SALEDEMO-XXXXXXXX-XXXXXXXX-XXXXXXXX", "payme_sale_code": 1111111, "sale_created": "2026-11-09 10:15:02", "sale_status": "completed", "payme_sale_status": "completed", "sale_type": "Sale", "sale_payment_method": "credit-card", "currency": "ILS", "price": 8000, "transaction_id": "order-1234", "sale_description": "Shirt", "sale_deferred_months": null, "is_token_sale": false, "payme_signature": "b71e**************ca5a", "payme_transaction_id": "TRANDEMO-XXXXXXXX-XXXXXXXX-XXXXXXXX", "payme_transaction_total": "8000", "payme_transaction_card_brand": "Mastercard", "payme_transaction_auth_number": "0123456", "payme_transaction_voucher": "111111", "payme_transaction_emv_uid": null, "payme_transaction_acquirer": "PayMe", "payme_transaction_auth_source": "VoiceMail", "payme_transaction_card_issuer": "Isracard", "payme_transaction_credit_type": "RegularCredit", "buyer_name": "Israel Israeli", "buyer_email": "buyer@example.com", "buyer_phone": null, "buyer_card_mask": "532610******5846", "buyer_card_exp": "1230", "buyer_card_is_foreign": false, "buyer_social_id": "008336174", "installments": 1, "transaction_first_payment": 8000, "transaction_periodical_payment": 0, "transaction_arn": null, "sale_paid_date": "2026-11-09 10:16:40", "sale_release_date": null, "sale_3ds": false, "session": "Ab12Cd34" } ``` ### 400 — Error `1`: no seller named (a partner key on its own). Error `352`: `sale_price` is above the authorized amount (or your capture limit). 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](/payments/getting-started/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. | ```json { "status_code": 1, "status_error_details": "Invalid price, out of min-max bounds", "status_additional_info": "12000", "status_error_code": 352, "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](/payments/getting-started/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. | ```json { "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, or too many requests. 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](/payments/getting-started/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. | ```json { "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. `350`: no sale has this ID. `305`: the sale isn't `authorized` or `failed`. `518`: the authorization is no longer open. `516`: more than 7 days since the authorization. `352`: `sale_price` below the account minimum. `42`: `sale_price` isn't a whole number. `351`: invalid `installments`. `251`: unknown seller. (error) | Field | Type | Description | | --- | --- | --- | | `status_code` | integer | `1`: the request failed. | | `status_error_code` | integer | PayMe's error code. See [Errors](/payments/getting-started/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. | ```json { "status_code": 1, "status_error_details": "Sale authorization has been expired", "status_additional_info": "", "status_error_code": 516, "session": "Ab12Cd34" } ``` - [Cancel a multi-payment page](https://docs.payme.io/payments/post-sale-actions/post-cancel-template): POST /cancel-template — Cancel a multi-payment page # Cancel a multi-payment page - Sandbox: `POST https://sandbox.payme.io/api/cancel-template` - Production: `POST https://live.payme.io/api/cancel-template` ## Credentials - Request body field `seller_payme_id` (optional): The MPL of the seller that owns the page. Required unless you send `payme_client_key`. - Request body field `payme_client_key` (optional): Partners: your partner key, instead of `seller_payme_id`. You can send it in the `PayMe-Partner-Key` header instead. ## Overview Closes a [multi-payment page](/accepting-payments/checkout-and-in-person/multi-payment-page) so no more buyers can pay on its link. The page must still be open (`initial`); its status becomes `canceled`. Nothing is refunded: sales already paid through the page stay as they are. Send the page's ID in **`sale_payme_id`**. This call uses that name, unlike the other post-sale calls, which take `payme_sale_id`. ### Credentials Send `seller_payme_id` of the seller that owns the page. Partners can send `payme_client_key` (or the `PayMe-Partner-Key` header) instead. The page must belong to the seller or partner you name; otherwise the call returns HTTP 403, error `303`. This call works only on multi-payment pages (`template` sales); any other sale returns error `357`. There is no cancel call for an ordinary sale. ## Parameters This endpoint takes no path, query or header parameters. ## Request body Content type: `application/json` | Field | Type | Required | Description | | --- | --- | --- | --- | | `seller_payme_id` | string | no | The MPL of the seller that owns the page. Required unless you send `payme_client_key`. | | `payme_client_key` | string | no | Partners: your partner key, instead of `seller_payme_id`. You can send it in the `PayMe-Partner-Key` header instead. | | `sale_payme_id` | string | yes | The multi-payment page's ID: the `payme_sale_id` that `generate-sale` returned for it. Note the field name. | | `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 ```json { "seller_payme_id": "MPLDEMO-MPLDEMO-MPLDEMO-1234567", "sale_payme_id": "SALEDEMO-XXXXXXXX-XXXXXXXX-XXXXXXXX", "language": "en" } ``` ## Code samples ### curl ```bash curl -X POST 'https://sandbox.payme.io/api/cancel-template' \ -H 'Content-Type: application/json' \ --data-raw '{ "seller_payme_id": "MPLDEMO-MPLDEMO-MPLDEMO-1234567", "sale_payme_id": "SALEDEMO-XXXXXXXX-XXXXXXXX-XXXXXXXX", "language": "en" }' ``` ### Node.js ```javascript const response = await fetch("https://sandbox.payme.io/api/cancel-template", { method: "POST", headers: { "Content-Type": "application/json", }, body: JSON.stringify({ "seller_payme_id": "MPLDEMO-MPLDEMO-MPLDEMO-1234567", "sale_payme_id": "SALEDEMO-XXXXXXXX-XXXXXXXX-XXXXXXXX", "language": "en" }), }); console.log(await response.text()); ``` ### Python ```python import requests response = requests.post( "https://sandbox.payme.io/api/cancel-template", json={ "seller_payme_id": "MPLDEMO-MPLDEMO-MPLDEMO-1234567", "sale_payme_id": "SALEDEMO-XXXXXXXX-XXXXXXXX-XXXXXXXX", "language": "en", }, ) print(response.text) ``` ### PHP ```php '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 page is canceled. (success) | Field | Type | Description | | --- | --- | --- | | `status_code` | integer | `0`: the page is canceled. | | `session` | string | PayMe's ID for this request. Quote it when you contact PayMe. | ```json { "status_code": 0, "session": "Ab12Cd34" } ``` ### 403 — Error `303`: the page 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](/payments/getting-started/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. | ```json { "status_code": 1, "status_error_details": "Could not access sale", "status_additional_info": "", "status_error_code": 303, "session": "Ab12Cd34" } ``` ### 500 — Request errors. `1`: a required field is missing (for example `sale_payme_id`) or no credential was sent. `200`: unknown partner key. `251`: unknown seller. `350`: no sale has this ID. `357`: the sale isn't a multi-payment page (`status_additional_info` holds its sale type number). `305`: the page isn't `initial` (its status, such as `canceled`, is in `status_additional_info`). (error) | Field | Type | Description | | --- | --- | --- | | `status_code` | integer | `1`: the request failed. | | `status_error_code` | integer | PayMe's error code. See [Errors](/payments/getting-started/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. | ```json { "status_code": 1, "status_error_details": "Cannot perform action due to an incorrect status", "status_additional_info": "canceled", "status_error_code": 305, "session": "Ab12Cd34" } ``` ## Apple Pay - [Apple Pay](https://docs.payme.io/payments/apple-pay): Accept Apple Pay on PayMe's Hosted Payment Page, or on your own page with the browser SDK's appleSale(). # Apple Pay Accept Apple Pay. On PayMe's Hosted Payment Page it needs nothing beyond enabling the service: a seller installs Apple Pay from the dashboard app store (חנות אפליקציות), and a partner enables it for its seller with [vas-enable](https://docs.payme.io/payments/apple-pay/post-vas-enable-apple-pay). On your own page, the browser SDK's `appleSale()` shows the Apple Pay sheet, and your domains must be registered with `vas-enable`. See the [Apple Pay guide](https://docs.payme.io/accepting-payments/payment-methods/apple-pay). - [Enable Apple Pay for a seller](https://docs.payme.io/payments/apple-pay/post-vas-enable-apple-pay): POST /vas-enable — Enable Apple Pay for a seller # Enable Apple Pay for a seller - Sandbox: `POST https://sandbox.payme.io/api/vas-enable` - Production: `POST https://live.payme.io/api/vas-enable` ## Credentials - Request body field `payme_client_key` (required): Your partner key. Keep it on your server. - Request body field `seller_payme_id` (required): The seller's PayMe ID (MPL). The seller must belong to your partner. Enables Apple Pay for one of your sellers and registers the domains that show the Apple Pay button on your own pages. Partner-only: authenticate with `payme_client_key`. A seller can install Apple Pay itself from the dashboard app store (חנות אפליקציות). Base URL: `https://sandbox.payme.io/api` in the sandbox, `https://live.payme.io/api` in production. ## What happens For each domain in `vas_data.websites`, PayMe fetches `https:///.well-known/apple-developer-merchantid-domain-association` and compares it byte for byte with PayMe's file for the environment you call. The sandbox and production files differ: see [Host PayMe's domain file](/accepting-payments/payment-methods/apple-pay#step-1-host-paymes-domain-file). If every domain passes, PayMe registers the domains with Apple in the same call and returns the approved ones in `vas_data.websites`, together with PayMe's own host. - Up to 99 domains per call. A domain can be sent with or without `https://`. - To add domains later, call `vas-enable` again with the new ones. Approved domains stay approved. (Partners can also use `vas-update`; contact PayMe support for its details.) ## Errors | HTTP | `status_error_code` | When | |---|---|---| | 400 | `703` | A domain's file is missing or different. `status_additional_info` names each site: `: Certificate does not match, please reconfigure.` or `: Cannot locate certificate.` Also when you send more than 99 domains. Fix the file and send the call again: nothing is left pending. | | 400 | `20` | "Validation error": Apple refused the registration, and `status_additional_info` is `Domain is not registered`. | | 500 | `720` | The service was not activated. | See [Accept Apple Pay](/accepting-payments/payment-methods/apple-pay) for the whole setup. ## Parameters This endpoint takes no path, query or header parameters. ## Request body Content type: `application/json` | Field | Type | Required | Description | | --- | --- | --- | --- | | `payme_client_key` | string | yes | Your partner key. Keep it on your server. | | `seller_payme_id` | string | yes | The seller's PayMe ID (MPL). The seller must belong to your partner. | | `vas_payme_id` | string | yes | Your partner's Apple Pay service ID (`VASL…`). | | `vas_data` | object | yes | The service's settings. | | `vas_data.websites` | array | yes | The domains that show the Apple Pay button, e.g. `shop.example.com`, with or without `https://`. Each must serve PayMe's domain file before the call. Up to 99. | | `language` | string | no | Language of the error messages: `he` (default) or `en`. | ### Request example ```json { "payme_client_key": "payme_partner_key", "seller_payme_id": "MPLDEMO-MPLDEMO-MPLDEMO-1234567", "vas_payme_id": "VASLDEMO-VASLDEMO-VASLDEMO-1234567", "vas_data": { "websites": [ "example.com", "shop.example.com" ] }, "language": "en" } ``` ## Code samples ### curl ```bash curl -X POST 'https://sandbox.payme.io/api/vas-enable' \ -H 'Content-Type: application/json' \ --data-raw '{ "payme_client_key": "payme_partner_key", "seller_payme_id": "MPLDEMO-MPLDEMO-MPLDEMO-1234567", "vas_payme_id": "VASLDEMO-VASLDEMO-VASLDEMO-1234567", "vas_data": { "websites": [ "example.com", "shop.example.com" ] }, "language": "en" }' ``` ### Node.js ```javascript const response = await fetch("https://sandbox.payme.io/api/vas-enable", { method: "POST", headers: { "Content-Type": "application/json", }, body: JSON.stringify({ "payme_client_key": "payme_partner_key", "seller_payme_id": "MPLDEMO-MPLDEMO-MPLDEMO-1234567", "vas_payme_id": "VASLDEMO-VASLDEMO-VASLDEMO-1234567", "vas_data": { "websites": [ "example.com", "shop.example.com" ] }, "language": "en" }), }); console.log(await response.text()); ``` ### Python ```python import requests response = requests.post( "https://sandbox.payme.io/api/vas-enable", json={ "payme_client_key": "payme_partner_key", "seller_payme_id": "MPLDEMO-MPLDEMO-MPLDEMO-1234567", "vas_payme_id": "VASLDEMO-VASLDEMO-VASLDEMO-1234567", "vas_data": { "websites": [ "example.com", "shop.example.com", ], }, "language": "en", }, ) print(response.text) ``` ### PHP ```php 'POST', CURLOPT_RETURNTRANSFER => true, CURLOPT_HTTPHEADER => [ 'Content-Type: application/json', ], CURLOPT_POSTFIELDS => $body, ]); $response = curl_exec($ch); curl_close($ch); echo $response; ``` ## Responses ### 200 — Apple Pay is enabled and the domains are registered. (success) | Field | Type | Description | | --- | --- | --- | | `status_code` | number | `0` on success. | | `seller_payme_id` | string | The seller's PayMe ID (MPL). | | `vas_payme_id` | string | The `vas_payme_id` you sent. | | `vas_guid` | string | The ID of the seller's own service, created or re-enabled by this call. | | `vas_description` | string | The service's description. | | `vas_type` | string | The service type, `AlternativePaymentMethod`. See [VAS Types](/marketplaces-and-platforms/seller-reference/vas-types). | | `vas_name` | string | The plan name, for creation-plan services only; `null` here. | | `vas_api_key` | string | The service's public API ID, if it has one; otherwise empty. | | `vas_is_active` | boolean | `true` when the service is active for the seller. | | `vas_payer_type` | number | Who pays for the service: `1` partner, `2` seller, `3` reseller. | | `vas_price_currency` | string | The currency the service is charged in. | | `vas_price_setup_fixed` | number | The service's setup price, fixed part. | | `vas_price_periodic_fixed` | number | The service's periodic price, fixed part. | | `vas_price_periodic_variable` | string | The service's periodic price, variable part. | | `vas_price_usage_fixed` | number | The service's price per use, fixed part. | | `vas_price_usage_variable` | string | The service's price per use, variable part. | | `vas_market_fee` | number | The market fee on the service, if one is set; otherwise `null`. | | `vas_period` | number | How often the service is charged: `1` instant, `2` daily, `3` monthly, `4` yearly. | | `vas_data` | object | The service's settings. | | `vas_data.websites` | array | The approved domains, PayMe's own host included. | ```json { "status_code": 0, "seller_payme_id": "MPLDEMO-MPLDEMO-MPLDEMO-1234567", "vas_payme_id": "VASLDEMO-VASLDEMO-VASLDEMO-1234567", "vas_guid": "VASLDEMO-VASLDEMO-VASLDEMO-7654321", "vas_type": "AlternativePaymentMethod", "vas_name": null, "vas_is_active": true, "vas_payer_type": 2, "vas_price_currency": "ILS", "vas_price_setup_fixed": 0, "vas_price_periodic_fixed": 0, "vas_price_periodic_variable": "0.00", "vas_price_usage_fixed": 0, "vas_price_usage_variable": "0.00", "vas_market_fee": null, "vas_period": 1, "vas_data": { "websites": [ "example.com", "shop.example.com" ] } } ``` ### 400 — A domain failed the check (`703`), or Apple refused the registration (`20`). (error) | Field | Type | Description | | --- | --- | --- | | `status_code` | number | `1` for a failed request. | | `status_error_code` | number | PayMe's error code. See [Errors](/payments/getting-started/errors). | | `status_error_details` | string | The error message, in the request's `language`. | | `status_additional_info` | string | More detail when there is any, for example the field or the site that failed; otherwise `null`. | ```json { "status_code": 1, "status_error_details": "Action is not permitted", "status_additional_info": "shop.example.com: Certificate does not match, please reconfigure.", "status_error_code": 703 } ``` ### 500 — The service was not activated (`720`). (error) | Field | Type | Description | | --- | --- | --- | | `status_code` | number | `1` for a failed request. | | `status_error_code` | number | PayMe's error code. See [Errors](/payments/getting-started/errors). | | `status_error_details` | string | The error message, in the request's `language`. | | `status_additional_info` | string | More detail when there is any, for example the field or the site that failed; otherwise `null`. | ```json { "status_code": 1, "status_error_details": "The service was not activated", "status_additional_info": null, "status_error_code": 720 } ``` - [Create a Apple Pay sale](https://docs.payme.io/payments/apple-pay/post-generate-sale-apple-pay): POST /generate-sale — Create a Apple Pay sale # Create a Apple Pay sale - 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 PayMe ID (MPL). Creates a sale for Apple Pay. Send the buyer to `sale_url`, where PayMe's page shows Apple Pay, or pass `payme_sale_id` as `saleGuid` to `instance.appleSale()` to show Apple Pay on your own page: see [Accept Apple Pay](/accepting-payments/payment-methods/apple-pay). The seller needs the Apple Pay service: a seller installs it from the dashboard app store (חנות אפליקציות), and a partner enables it with [vas-enable](/payments/apple-pay/post-vas-enable-apple-pay). Without it, the call fails with error `720`. Apple Pay pays in a single payment: more than one `installments` fails with error `351`. **Auth:** `seller_payme_id` in the body. Call it from your server, never from the browser. Base URL: `https://sandbox.payme.io/api` in the sandbox, `https://live.payme.io/api` in production. This page lists the fields a wallet sale needs. `generate-sale` takes more optional fields, such as `transaction_id`, `sale_callback_url` and `sale_return_url`: see [generate-sale](/payments/hosted-payment-page/post-generate-sale). ## 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 PayMe ID (MPL). | | `sale_price` | integer | yes | Amount in minor units: `1000` = 10.00. | | `currency` | string | yes | ISO 4217 currency code, e.g. `ILS`. | | `product_name` | string | yes | What the payment is for. | | `sale_payment_method` | string | yes | `apple-pay`. | | `sale_type` | string | no | Default `sale`. See [Sale Types](/payments/codes-statuses/sale-types). | | `language` | string | no | Language of the payment page and the error messages: `he` (default) or `en`. | ### Request example ```json { "seller_payme_id": "MPLDEMO-MPLDEMO-MPLDEMO-1234567", "sale_price": 1000, "currency": "ILS", "product_name": "Order 1234", "sale_payment_method": "apple-pay", "language": "en" } ``` ## Code samples ### curl ```bash curl -X POST 'https://sandbox.payme.io/api/generate-sale' \ -H 'Content-Type: application/json' \ --data-raw '{ "seller_payme_id": "MPLDEMO-MPLDEMO-MPLDEMO-1234567", "sale_price": 1000, "currency": "ILS", "product_name": "Order 1234", "sale_payment_method": "apple-pay", "language": "en" }' ``` ### Node.js ```javascript 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", "sale_price": 1000, "currency": "ILS", "product_name": "Order 1234", "sale_payment_method": "apple-pay", "language": "en" }), }); console.log(await response.text()); ``` ### Python ```python import requests response = requests.post( "https://sandbox.payme.io/api/generate-sale", json={ "seller_payme_id": "MPLDEMO-MPLDEMO-MPLDEMO-1234567", "sale_price": 1000, "currency": "ILS", "product_name": "Order 1234", "sale_payment_method": "apple-pay", "language": "en", }, ) print(response.text) ``` ### PHP ```php '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 sale was created. (success) | Field | Type | Description | | --- | --- | --- | | `status_code` | number | `0` on success. | | `sale_url` | string | PayMe's payment page for this sale. It shows Apple Pay. | | `payme_sale_id` | string | The sale's ID. Pass it to `instance.appleSale()` as `saleGuid`. | | `payme_sale_code` | number | A short numeric sale code, for display only. | | `price` | number | The amount, in minor units. | | `transaction_id` | string | Your own order ID, if you sent `transaction_id`; otherwise empty. | | `currency` | string | The sale's currency. | | `sale_payment_method` | string | `apple-pay`. | ```json { "status_code": 0, "sale_url": "https://sandbox.payme.io/sale/generate/SALE1655-3843870J-NTPYLJNW-SOWRLK9X", "payme_sale_id": "SALE1655-3843870J-NTPYLJNW-SOWRLK9X", "payme_sale_code": 1032526, "price": 1000, "transaction_id": "", "currency": "ILS", "sale_payment_method": "apple-pay" } ``` ### 400 — The request is invalid. For example, error `351` when `installments` is more than 1. (error) | Field | Type | Description | | --- | --- | --- | | `status_code` | number | `1` for a failed request. | | `status_error_code` | number | PayMe's error code. See [Errors](/payments/getting-started/errors). | | `status_error_details` | string | The error message, in the request's `language`. | | `status_additional_info` | string | More detail when there is any, for example the field or the site that failed; otherwise `null`. | ```json { "status_code": 1, "status_error_details": "Please verify installments amount", "status_additional_info": "installments are not allowed for apple-pay", "status_error_code": 351 } ``` ### 500 — The request failed. For example, error `720` "The service was not activated" when the seller has no active Apple Pay service. (error) | Field | Type | Description | | --- | --- | --- | | `status_code` | number | `1` for a failed request. | | `status_error_code` | number | PayMe's error code. See [Errors](/payments/getting-started/errors). | | `status_error_details` | string | The error message, in the request's `language`. | | `status_additional_info` | string | More detail when there is any, for example the field or the site that failed; otherwise `null`. | ```json { "status_code": 1, "status_error_details": "The service was not activated", "status_additional_info": "apple-pay", "status_error_code": 720 } ``` ## Google Pay - [Google Pay](https://docs.payme.io/payments/google-pay): Accept Google Pay on PayMe's Hosted Payment Page, or on your own page with the browser SDK's googleSale(). # Google Pay Accept Google Pay. On PayMe's Hosted Payment Page it needs only the service enabled: a seller installs Google Pay from the dashboard app store (חנות אפליקציות), and a partner enables it for its seller with [vas-enable](https://docs.payme.io/payments/google-pay/post-vas-enable-google-pay). On your own page, the browser SDK's `googleSale()` renders the Google Pay button. See the [Google Pay guide](https://docs.payme.io/accepting-payments/payment-methods/google-pay). - [Enable Google Pay for a seller](https://docs.payme.io/payments/google-pay/post-vas-enable-google-pay): POST /vas-enable — Enable Google Pay for a seller # Enable Google Pay for a seller - Sandbox: `POST https://sandbox.payme.io/api/vas-enable` - Production: `POST https://live.payme.io/api/vas-enable` ## Credentials - Request body field `payme_client_key` (required): Your partner key. Keep it on your server. - Request body field `seller_payme_id` (required): The seller's PayMe ID (MPL). The seller must belong to your partner. Enables Google Pay for one of your sellers. Partner-only: authenticate with `payme_client_key`. A seller can install Google Pay itself from the dashboard app store (חנות אפליקציות). Base URL: `https://sandbox.payme.io/api` in the sandbox, `https://live.payme.io/api` in production. To show Google Pay on your own page, register your domain in the Google Pay & Wallet Console first: see [Accept Google Pay](/accepting-payments/payment-methods/google-pay). ## Errors | HTTP | `status_error_code` | When | |---|---|---| | 500 | `720` | The service was not activated. | ## Parameters This endpoint takes no path, query or header parameters. ## Request body Content type: `application/json` | Field | Type | Required | Description | | --- | --- | --- | --- | | `payme_client_key` | string | yes | Your partner key. Keep it on your server. | | `seller_payme_id` | string | yes | The seller's PayMe ID (MPL). The seller must belong to your partner. | | `vas_payme_id` | string | yes | Your partner's Google Pay service ID (`VASL…`). | | `language` | string | no | Language of the error messages: `he` (default) or `en`. | ### Request example ```json { "payme_client_key": "payme_partner_key", "seller_payme_id": "MPLDEMO-MPLDEMO-MPLDEMO-1234567", "vas_payme_id": "VASLDEMO-GOOGLEPAY-VASLDEMO-1234567", "language": "en" } ``` ## Code samples ### curl ```bash curl -X POST 'https://sandbox.payme.io/api/vas-enable' \ -H 'Content-Type: application/json' \ --data-raw '{ "payme_client_key": "payme_partner_key", "seller_payme_id": "MPLDEMO-MPLDEMO-MPLDEMO-1234567", "vas_payme_id": "VASLDEMO-GOOGLEPAY-VASLDEMO-1234567", "language": "en" }' ``` ### Node.js ```javascript const response = await fetch("https://sandbox.payme.io/api/vas-enable", { method: "POST", headers: { "Content-Type": "application/json", }, body: JSON.stringify({ "payme_client_key": "payme_partner_key", "seller_payme_id": "MPLDEMO-MPLDEMO-MPLDEMO-1234567", "vas_payme_id": "VASLDEMO-GOOGLEPAY-VASLDEMO-1234567", "language": "en" }), }); console.log(await response.text()); ``` ### Python ```python import requests response = requests.post( "https://sandbox.payme.io/api/vas-enable", json={ "payme_client_key": "payme_partner_key", "seller_payme_id": "MPLDEMO-MPLDEMO-MPLDEMO-1234567", "vas_payme_id": "VASLDEMO-GOOGLEPAY-VASLDEMO-1234567", "language": "en", }, ) print(response.text) ``` ### PHP ```php 'POST', CURLOPT_RETURNTRANSFER => true, CURLOPT_HTTPHEADER => [ 'Content-Type: application/json', ], CURLOPT_POSTFIELDS => $body, ]); $response = curl_exec($ch); curl_close($ch); echo $response; ``` ## Responses ### 200 — Google Pay is enabled for the seller. (success) | Field | Type | Description | | --- | --- | --- | | `status_code` | number | `0` on success. | | `seller_payme_id` | string | The seller's PayMe ID (MPL). | | `vas_payme_id` | string | The `vas_payme_id` you sent. | | `vas_guid` | string | The ID of the seller's own service, created or re-enabled by this call. | | `vas_description` | string | The service's description. | | `vas_type` | string | The service type, `AlternativePaymentMethod`. See [VAS Types](/marketplaces-and-platforms/seller-reference/vas-types). | | `vas_name` | string | The plan name, for creation-plan services only; `null` here. | | `vas_api_key` | string | The service's public API ID, if it has one; otherwise empty. | | `vas_is_active` | boolean | `true` when the service is active for the seller. | | `vas_payer_type` | number | Who pays for the service: `1` partner, `2` seller, `3` reseller. | | `vas_price_currency` | string | The currency the service is charged in. | | `vas_price_setup_fixed` | number | The service's setup price, fixed part. | | `vas_price_periodic_fixed` | number | The service's periodic price, fixed part. | | `vas_price_periodic_variable` | string | The service's periodic price, variable part. | | `vas_price_usage_fixed` | number | The service's price per use, fixed part. | | `vas_price_usage_variable` | string | The service's price per use, variable part. | | `vas_market_fee` | number | The market fee on the service, if one is set; otherwise `null`. | | `vas_period` | number | How often the service is charged: `1` instant, `2` daily, `3` monthly, `4` yearly. | | `vas_data` | object | The service's settings. | ```json { "status_code": 0, "seller_payme_id": "MPLDEMO-MPLDEMO-MPLDEMO-1234567", "vas_payme_id": "VASLDEMO-GOOGLEPAY-VASLDEMO-1234567", "vas_guid": "VASLDEMO-VASLDEMO-VASLDEMO-7654321", "vas_type": "AlternativePaymentMethod", "vas_name": null, "vas_is_active": true, "vas_payer_type": 2, "vas_price_currency": "ILS", "vas_price_setup_fixed": 0, "vas_price_periodic_fixed": 0, "vas_price_periodic_variable": "0.00", "vas_price_usage_fixed": 0, "vas_price_usage_variable": "0.00", "vas_market_fee": null, "vas_period": 1 } ``` ### 500 — The service was not activated (`720`). (error) | Field | Type | Description | | --- | --- | --- | | `status_code` | number | `1` for a failed request. | | `status_error_code` | number | PayMe's error code. See [Errors](/payments/getting-started/errors). | | `status_error_details` | string | The error message, in the request's `language`. | | `status_additional_info` | string | More detail when there is any, for example the field or the site that failed; otherwise `null`. | ```json { "status_code": 1, "status_error_details": "The service was not activated", "status_additional_info": null, "status_error_code": 720 } ``` - [Create a Google Pay sale](https://docs.payme.io/payments/google-pay/post-generate-sale-google-pay): POST /generate-sale — Create a Google Pay sale # Create a Google Pay sale - 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 PayMe ID (MPL). Creates a sale for Google Pay. Send the buyer to `sale_url`, where PayMe's page shows Google Pay, or pass `payme_sale_id` as `saleGuid` to `instance.googleSale()` to show Google Pay on your own page: see [Accept Google Pay](/accepting-payments/payment-methods/google-pay). The seller needs the Google Pay service: a seller installs it from the dashboard app store (חנות אפליקציות), and a partner enables it with [vas-enable](/payments/google-pay/post-vas-enable-google-pay). Without it, the call fails with error `720`. Google Pay pays in a single payment: more than one `installments` fails with error `351`. A Google Pay payment can need 3D Secure, which ends at your `sale_callback_url` and `sale_return_url`: set both when you create the sale. **Auth:** `seller_payme_id` in the body. Call it from your server, never from the browser. Base URL: `https://sandbox.payme.io/api` in the sandbox, `https://live.payme.io/api` in production. This page lists the fields a wallet sale needs. `generate-sale` takes more optional fields, such as `transaction_id`, `sale_callback_url` and `sale_return_url`: see [generate-sale](/payments/hosted-payment-page/post-generate-sale). ## 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 PayMe ID (MPL). | | `sale_price` | integer | yes | Amount in minor units: `1000` = 10.00. | | `currency` | string | yes | ISO 4217 currency code, e.g. `ILS`. | | `product_name` | string | yes | What the payment is for. | | `sale_payment_method` | string | yes | `google-pay`. Send `multi` instead to let the buyer choose among the methods enabled on the account. | | `sale_type` | string | no | Default `sale`. See [Sale Types](/payments/codes-statuses/sale-types). | | `language` | string | no | Language of the payment page and the error messages: `he` (default) or `en`. | ### Request example ```json { "seller_payme_id": "MPLDEMO-MPLDEMO-MPLDEMO-1234567", "sale_price": 1000, "currency": "ILS", "product_name": "Order 1234", "sale_payment_method": "google-pay", "language": "en" } ``` ## Code samples ### curl ```bash curl -X POST 'https://sandbox.payme.io/api/generate-sale' \ -H 'Content-Type: application/json' \ --data-raw '{ "seller_payme_id": "MPLDEMO-MPLDEMO-MPLDEMO-1234567", "sale_price": 1000, "currency": "ILS", "product_name": "Order 1234", "sale_payment_method": "google-pay", "language": "en" }' ``` ### Node.js ```javascript 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", "sale_price": 1000, "currency": "ILS", "product_name": "Order 1234", "sale_payment_method": "google-pay", "language": "en" }), }); console.log(await response.text()); ``` ### Python ```python import requests response = requests.post( "https://sandbox.payme.io/api/generate-sale", json={ "seller_payme_id": "MPLDEMO-MPLDEMO-MPLDEMO-1234567", "sale_price": 1000, "currency": "ILS", "product_name": "Order 1234", "sale_payment_method": "google-pay", "language": "en", }, ) print(response.text) ``` ### PHP ```php '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 sale was created. (success) | Field | Type | Description | | --- | --- | --- | | `status_code` | number | `0` on success. | | `sale_url` | string | PayMe's payment page for this sale. It shows Google Pay. | | `payme_sale_id` | string | The sale's ID. Pass it to `instance.googleSale()` as `saleGuid`. | | `payme_sale_code` | number | A short numeric sale code, for display only. | | `price` | number | The amount, in minor units. | | `transaction_id` | string | Your own order ID, if you sent `transaction_id`; otherwise empty. | | `currency` | string | The sale's currency. | | `sale_payment_method` | string | `google-pay`. | ```json { "status_code": 0, "sale_url": "https://sandbox.payme.io/sale/generate/SALE1655-3843870J-NTPYLJNW-SOWRLK9X", "payme_sale_id": "SALE1655-3843870J-NTPYLJNW-SOWRLK9X", "payme_sale_code": 1032526, "price": 1000, "transaction_id": "", "currency": "ILS", "sale_payment_method": "google-pay" } ``` ### 400 — The request is invalid. For example, error `351` when `installments` is more than 1. (error) | Field | Type | Description | | --- | --- | --- | | `status_code` | number | `1` for a failed request. | | `status_error_code` | number | PayMe's error code. See [Errors](/payments/getting-started/errors). | | `status_error_details` | string | The error message, in the request's `language`. | | `status_additional_info` | string | More detail when there is any, for example the field or the site that failed; otherwise `null`. | ```json { "status_code": 1, "status_error_details": "Please verify installments amount", "status_additional_info": "installments are not allowed for google-pay", "status_error_code": 351 } ``` ### 500 — The request failed. For example, error `720` "The service was not activated" when the seller has no active Google Pay service. (error) | Field | Type | Description | | --- | --- | --- | | `status_code` | number | `1` for a failed request. | | `status_error_code` | number | PayMe's error code. See [Errors](/payments/getting-started/errors). | | `status_error_details` | string | The error message, in the request's `language`. | | `status_additional_info` | string | More detail when there is any, for example the field or the site that failed; otherwise `null`. | ```json { "status_code": 1, "status_error_details": "The service was not activated", "status_additional_info": "google-pay", "status_error_code": 720 } ``` ## IL Direct Debit - [Create an Israeli direct debit authorization](https://docs.payme.io/payments/il-direct-debit/post-generate-sale-il-direct-debit): POST /generate-sale — Create an Israeli direct debit authorization # Create an Israeli direct debit authorization - 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, in the JSON body. The authorization is given to this seller. - Request body field `payme_client_key` (optional): 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`. ## Overview > **Availability.** Israeli Direct Debit is offered to high-volume sellers only. It is enabled per account after approval by your PayMe sales representative; it is not self-service. Until then, `generate-sale` returns `720`. Israeli direct debit works in two phases: 1. Set up the bank authorization (this page): the buyer signs a debit authorization on PayMe's page, and PayMe saves it as a token (`buyer_key`). 2. [Charge the authorization](/payments/il-direct-debit/post-generate-sale-2-il-direct-debit) with `buyer_key`. `POST https://sandbox.payme.io/api/generate-sale` (production: `https://live.payme.io/api/generate-sale`), with a JSON body (`Content-Type: application/json`). ### Set up the authorization Call `generate-sale` with `sale_type: token` and `sale_payment_method: il-direct-debit`. Show the returned `sale_url` to the buyer: the page collects the account owner's identity, the bank account and a signature. Nothing is charged; the setup sale is always created with a price of `100`. The token stays inactive until the bank confirms the authorization. Wait for the callbacks below before you charge it. ### 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](/payments/getting-started/authentication). ### Callbacks PayMe sends form-encoded callbacks to `sale_callback_url`: 1. `sale-complete` – the bank approved the authorization; the token (`buyer_key`) is now active and can be charged. `sale-failure` – the bank rejected it. 2. `sale-il-direct-debit-update` – the authorization status, with `authorization_status`, `authorization_error_code`, `buyer_name` and `buyer_key`, plus the usual sale fields. ``` notify_type=sale-il-direct-debit-update&payme_sale_id=SALE1700-000000AA-EXAMPLE1-SALE0001&sale_status=completed&authorization_status=1&authorization_error_code=&buyer_key=BUYERDEMO-BUYERDEMO-BUYERDEMO-1234567&buyer_name=First%20Last&… ``` The `authorization_status` values are on [Errors → Israeli direct debit](/payments/getting-started/errors). The bank can revoke an authorization later; the token then becomes inactive and charges fail. ### Testing Sandbox bank accounts are on [Test Cards and Payment Methods](/payments/getting-started/test-cards-and-payment-methods#israeli-direct-debit-testing-information). In the sandbox you receive only authorization statuses `1` (success) and `2` (failure). ## 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, in the JSON body. The authorization is given to this seller. | | `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`. | | `sale_type` | string | yes | Must be `token`. | | `sale_payment_method` | string | yes | Must be `il-direct-debit`. | | `sale_price` | integer | yes | Any numeric value. The setup sale is always created with `100` and nothing is charged. A missing or non-numeric value returns `352`. | | `currency` | string | no | Send `ILS`. Without it the account's default currency is used. | | `product_name` | string | yes | Any short description, for example `Direct debit authorization`. It doesn't affect the setup. Missing returns `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. | | `sale_callback_url` | string | no | Where PayMe sends the `sale-complete` / `sale-failure` and `sale-il-direct-debit-update` callbacks. If omitted, your partner's default callback URL is used, if one is set; a seller has no dashboard setting for it, so send it. Must be a public address: `localhost`, private or loopback IP addresses and IPv6 addresses are refused with error `21`, which fails the whole call. | | `sale_return_url` | string | no | Where PayMe redirects the buyer after the setup page. Same address rules as `sale_callback_url` (error `21`). | | `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`. | ### Request example ```json { "seller_payme_id": "MPLDEMO-MPLDEMO-MPLDEMO-1234567", "sale_type": "token", "sale_payment_method": "il-direct-debit", "sale_price": 100, "currency": "ILS", "product_name": "Direct debit authorization", "transaction_id": "ildd-setup-1001", "sale_callback_url": "https://your-server.example.com/payme/callback", "sale_return_url": "https://your-site.example.com/ildd/done", "language": "en" } ``` ## Code samples ### curl ```bash curl -X POST 'https://sandbox.payme.io/api/generate-sale' \ -H 'Content-Type: application/json' \ --data-raw '{ "seller_payme_id": "MPLDEMO-MPLDEMO-MPLDEMO-1234567", "sale_type": "token", "sale_payment_method": "il-direct-debit", "sale_price": 100, "currency": "ILS", "product_name": "Direct debit authorization", "transaction_id": "ildd-setup-1001", "sale_callback_url": "https://your-server.example.com/payme/callback", "sale_return_url": "https://your-site.example.com/ildd/done", "language": "en" }' ``` ### Node.js ```javascript 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", "sale_type": "token", "sale_payment_method": "il-direct-debit", "sale_price": 100, "currency": "ILS", "product_name": "Direct debit authorization", "transaction_id": "ildd-setup-1001", "sale_callback_url": "https://your-server.example.com/payme/callback", "sale_return_url": "https://your-site.example.com/ildd/done", "language": "en" }), }); console.log(await response.text()); ``` ### Python ```python import requests response = requests.post( "https://sandbox.payme.io/api/generate-sale", json={ "seller_payme_id": "MPLDEMO-MPLDEMO-MPLDEMO-1234567", "sale_type": "token", "sale_payment_method": "il-direct-debit", "sale_price": 100, "currency": "ILS", "product_name": "Direct debit authorization", "transaction_id": "ildd-setup-1001", "sale_callback_url": "https://your-server.example.com/payme/callback", "sale_return_url": "https://your-site.example.com/ildd/done", "language": "en", }, ) print(response.text) ``` ### PHP ```php 'POST', CURLOPT_RETURNTRANSFER => true, CURLOPT_HTTPHEADER => [ 'Content-Type: application/json', ], CURLOPT_POSTFIELDS => $body, ]); $response = curl_exec($ch); curl_close($ch); echo $response; ``` ## Responses ### 200 — Setup sale created (success) | Field | Type | Description | | --- | --- | --- | | `status_code` | integer | `0` success, `1` error. | | `sale_url` | string | PayMe's payment page for this sale. Show it to the buyer in an iframe or a redirect, exactly as returned. It stays payable while the sale is `initial` or `failed`, until `sale_expiry_seconds` passes if you sent it. | | `payme_sale_id` | string | PayMe's sale ID. Store it: refunds, captures and queries use it. | | `payme_sale_code` | integer | Short numeric sale code, for display only. | | `price` | integer | Sale amount in minor units (`100` for a token sale). | | `transaction_id` | string | Your order reference, as sent. | | `currency` | string | Sale currency (ISO 4217). | | `sale_payment_method` | string | Payment method of the sale, for example `credit-card` or `multi`. | | `session` | string | Request ID. Quote it when you contact PayMe. | ```json { "status_code": 0, "session": "AtsJ0as5", "sale_url": "https://sandbox.payme.io/sale/generate/SALE1700-000000AA-EXAMPLE1-SALE0001", "payme_sale_id": "SALE1700-000000AA-EXAMPLE1-SALE0001", "payme_sale_code": 12345678, "price": 100, "transaction_id": "ildd-setup-1001", "currency": "ILS", "sale_payment_method": "il-direct-debit" } ``` ### 500 — Request refused. Most request errors return HTTP 500 with `status_code: 1`; some return 400, 403, 422 or 429. See [Errors](/payments/getting-started/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. | ```json { "status_code": 1, "status_error_details": "Seller was not found", "status_additional_info": "seller_payme_id", "status_error_code": 251, "session": "AtsJ0as5" } ``` - [Charge an Israeli direct debit authorization](https://docs.payme.io/payments/il-direct-debit/post-generate-sale-2-il-direct-debit): POST /generate-sale — Charge an Israeli direct debit authorization # Charge an Israeli direct debit authorization - 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, in the JSON body. - Request body field `payme_client_key` (optional): 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`. ## Overview > **Availability.** Israeli Direct Debit is offered to high-volume sellers only. It is enabled per account after approval by your PayMe sales representative; it is not self-service. Until then, `generate-sale` returns `720`. Israeli direct debit works in two phases: 1. [Set up the bank authorization](/payments/il-direct-debit/post-generate-sale-il-direct-debit) and receive its token (`buyer_key`). 2. Charge the authorization (this page). `POST https://sandbox.payme.io/api/generate-sale` (production: `https://live.payme.io/api/generate-sale`), with a JSON body (`Content-Type: application/json`). ### Charge the authorization Call `generate-sale` with: 1. `buyer_key` – the token from the authorization setup; 2. `sale_type: sale`; 3. `sale_payment_method: il-direct-debit`. The call submits the debit at once: there is no payment page and no `sale_url`. The token's own payment method is used either way. Constraints: - `currency` must be `ILS` (otherwise error `320`). - The token must be active: the setup's `sale-complete` callback has arrived. A token whose authorization isn't active yet, was rejected or was revoked returns `604`. - Installments aren't allowed (`351`). ### 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](/payments/getting-started/authentication). ### Callbacks | `notify_type` | When | |---|---| | `sale-paid` | The debit was submitted to the bank. | | `sale-complete` | About 8 days later: the debit is final. | | `sale-failure` | The bank returned the debit. | The fields are on [Callbacks](/payments/getting-started/callbacks#israeli-direct-debit). ### Testing Sandbox bank accounts are on [Test Cards and Payment Methods](/payments/getting-started/test-cards-and-payment-methods#israeli-direct-debit-testing-information). ## 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, in the JSON body. | | `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`. | | `buyer_key` | string | yes | The token from the authorization setup. It must be active: the setup's `sale-complete` callback has arrived (otherwise error `604`). | | `sale_type` | string | no | `sale` (default). | | `sale_payment_method` | string | no | `il-direct-debit`. The token's own method is used either way. | | `sale_price` | integer | yes | Amount to debit, in minor units. The default allowed range is `500`–`4000000` (error `352`). | | `currency` | string | yes | `ILS` (anything else returns `320`). | | `product_name` | string | yes | Shown on the seller's records and invoice. Missing returns `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. | | `sale_callback_url` | string | no | Where PayMe sends `sale-paid`, `sale-complete` and `sale-failure`. If omitted, your partner's default callback URL is used, if one is set; a seller has no dashboard setting for it, so send it. 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`. | ### Request example ```json { "seller_payme_id": "MPLDEMO-MPLDEMO-MPLDEMO-1234567", "buyer_key": "BUYERDEMO-BUYERDEMO-BUYERDEMO-1234567", "sale_type": "sale", "sale_payment_method": "il-direct-debit", "sale_price": 1000, "currency": "ILS", "product_name": "Monthly membership", "transaction_id": "order-1003", "sale_callback_url": "https://your-server.example.com/payme/callback", "language": "en" } ``` ## Code samples ### curl ```bash 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_type": "sale", "sale_payment_method": "il-direct-debit", "sale_price": 1000, "currency": "ILS", "product_name": "Monthly membership", "transaction_id": "order-1003", "sale_callback_url": "https://your-server.example.com/payme/callback", "language": "en" }' ``` ### Node.js ```javascript 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_type": "sale", "sale_payment_method": "il-direct-debit", "sale_price": 1000, "currency": "ILS", "product_name": "Monthly membership", "transaction_id": "order-1003", "sale_callback_url": "https://your-server.example.com/payme/callback", "language": "en" }), }); console.log(await response.text()); ``` ### Python ```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_type": "sale", "sale_payment_method": "il-direct-debit", "sale_price": 1000, "currency": "ILS", "product_name": "Monthly membership", "transaction_id": "order-1003", "sale_callback_url": "https://your-server.example.com/payme/callback", "language": "en", }, ) print(response.text) ``` ### PHP ```php 'POST', CURLOPT_RETURNTRANSFER => true, CURLOPT_HTTPHEADER => [ 'Content-Type: application/json', ], CURLOPT_POSTFIELDS => $body, ]); $response = curl_exec($ch); curl_close($ch); echo $response; ``` ## Responses ### 200 — Debit submitted. The response holds the sale and transaction fields and has no `sale_url`. A refused charge also returns HTTP 200, with `status_code: 1`: always check `status_code`. (success) | Field | Type | Description | | --- | --- | --- | | `status_code` | integer | `0` the debit was submitted; `1` it was refused. | | `payme_status` | string | `success` or `error`. | | `payme_sale_id` | string | PayMe's sale ID. | | `payme_sale_code` | integer | Short numeric sale code, for display only. | | `sale_status` | string | `initial` until the debit completes (`completed`, about 8 days later) or fails. | | `sale_payment_method` | string | `il-direct-debit`. | | `price` | integer | Amount in minor units. | | `currency` | string | `ILS`. | | `transaction_id` | string | Your order reference, as sent. | | `payme_transaction_id` | string | PayMe's ID for this debit. | | `payme_transaction_total` | integer | Amount of this transaction, in minor units. | | `payme_signature` | string | Signature, computed as described on [Callbacks](/payments/getting-started/callbacks). | | `sale_paid_date` | string | When the debit was submitted. | ```json { "status_code": 0, "payme_status": "success", "payme_sale_id": "SALE1700-000000AA-EXAMPLE1-SALE0001", "payme_sale_code": 12345678, "sale_status": "initial", "sale_payment_method": "il-direct-debit", "price": 1000, "currency": "ILS", "transaction_id": "order-1003", "payme_transaction_id": "TRAN1700-000000AA-EXAMPLE1-TXN00001", "payme_transaction_total": 1000, "payme_signature": "f8ffc5bb45fe6c3ad326c439f1a21c28", "sale_paid_date": "2026-11-09 10:15:02" } ``` ### 500 — Request refused. Most request errors return HTTP 500 with `status_code: 1`; some return 400, 403, 422 or 429. See [Errors](/payments/getting-started/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. | ```json { "status_code": 1, "status_error_details": "Seller was not found", "status_additional_info": "seller_payme_id", "status_error_code": 251, "session": "AtsJ0as5" } ``` ## Tokenization - [Save a card as a token](https://docs.payme.io/payments/tokenization/post-capture-buyer-token): POST /capture-buyer-token — Save a card as a token # Save a card as a token - Sandbox: `POST https://sandbox.payme.io/api/capture-buyer-token` - Production: `POST https://live.payme.io/api/capture-buyer-token` ## Credentials - Request body field `seller_payme_id` (required): The seller's MPL. ## Overview Saves a card and returns a `buyer_key` you can charge later. Nothing is charged. You send raw card details, so call it from your server only if you are PCI DSS Level 1 certified. Otherwise save cards with [Hosted Fields](/payments/hosted-fields-jsapi) or a [`token` sale](/accepting-payments/capture-and-saved-cards/save-a-card-and-charge-it-later). Name the seller with `seller_payme_id`. (Hosted Fields sends the seller's public key in the `PayMe-Public-Key` header instead.) ### Two flags decide what the token is - `buyer_is_permanent: true` makes a token you can charge any number of times. Without it the token is single-use: the first `generate-sale` charge with it deactivates it, later charges fail with error `604`, and subscriptions reject it. - `buyer_is_private: true` ties the token to this seller (MPL). Without it the token belongs to your account, and any seller of the same partner can charge it. To read such a token back with [`get-buyer-key`](/payments/tokenization/post-get-buyer-key) you need `payme_client_key`. ### Charging the token Send the `buyer_key` with [`generate-sale`](/payments/hosted-payment-page/post-generate-sale) to charge the card at once, with no payment page and no CVV. These charges run without 3D Secure. A permanent token doesn't expire in PayMe, but a charge can still fail if the card has expired or the issuer declines it, so handle the `sale-failure` callback. Store `buyer_key` encrypted: it stands in for the card number. Saving the same card again for the same buyer and seller can return the existing `buyer_key`. ### Errors A declined card returns HTTP 500, with the decline code in `status_error_code` (for example `20004`) and the masked card number in `status_additional_info`. This differs from `pay-sale`, which returns HTTP 200 for a decline. A value that looks like a card number in any field other than `credit_card_number` returns HTTP 400, error `20`. ## 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. | | `credit_card_number` | string | yes | Card number, digits only. | | `credit_card_exp` | string | yes | Card expiry as `MMYY` (`MM/YY` and `MMYYYY` are also accepted). An expired or invalid date returns error `356`. | | `credit_card_cvv` | string | no | CVV, 3 or 4 digits. Required unless `token_terminal` is `true`. | | `token_terminal` | boolean | no | `true` to save the card without a CVV, on a token terminal. Default `false`. | | `buyer_name` | string | no | Buyer's full name. | | `buyer_email` | string | no | Buyer's email address. | | `buyer_phone` | string | no | Buyer's phone number. | | `buyer_social_id` | string | no | Buyer's national ID number, digits only. | | `buyer_zip_code` | string | no | Buyer's zip code, letters and digits only; anything else returns error `37`. | | `buyer_business_code` | string | no | For a business buyer: its registration number. Send it with `buyer_business_name`, or neither. | | `buyer_business_name` | string | no | For a business buyer: its name. Send it with `buyer_business_code`, or neither. | | `buyer_is_permanent` | boolean | no | `true`: a permanent token you can charge any number of times. Default `false`: a single-use token; the first `generate-sale` charge deactivates it and later charges fail with error `604`. Subscriptions accept permanent tokens only. | | `buyer_is_private` | boolean | no | `true`: only this seller (MPL) can charge the token. Default `false`: the token belongs to your account, and any seller of the same partner can charge it. | | `buyer_perform_validation` | boolean | no | Check the card with the issuer before saving it. Default `true`. | | `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 ```json { "seller_payme_id": "MPLDEMO-MPLDEMO-MPLDEMO-1234567", "credit_card_number": "5326105300985846", "credit_card_exp": "1230", "credit_card_cvv": "658", "buyer_name": "Israel Israeli", "buyer_email": "buyer@example.com", "buyer_phone": "+972500000000", "buyer_social_id": "008336174", "buyer_is_permanent": true, "language": "en" } ``` ## Code samples ### curl ```bash curl -X POST 'https://sandbox.payme.io/api/capture-buyer-token' \ -H 'Content-Type: application/json' \ --data-raw '{ "seller_payme_id": "MPLDEMO-MPLDEMO-MPLDEMO-1234567", "credit_card_number": "5326105300985846", "credit_card_exp": "1230", "credit_card_cvv": "658", "buyer_name": "Israel Israeli", "buyer_email": "buyer@example.com", "buyer_phone": "+972500000000", "buyer_social_id": "008336174", "buyer_is_permanent": true, "language": "en" }' ``` ### Node.js ```javascript const response = await fetch("https://sandbox.payme.io/api/capture-buyer-token", { method: "POST", headers: { "Content-Type": "application/json", }, body: JSON.stringify({ "seller_payme_id": "MPLDEMO-MPLDEMO-MPLDEMO-1234567", "credit_card_number": "5326105300985846", "credit_card_exp": "1230", "credit_card_cvv": "658", "buyer_name": "Israel Israeli", "buyer_email": "buyer@example.com", "buyer_phone": "+972500000000", "buyer_social_id": "008336174", "buyer_is_permanent": true, "language": "en" }), }); console.log(await response.text()); ``` ### Python ```python import requests response = requests.post( "https://sandbox.payme.io/api/capture-buyer-token", json={ "seller_payme_id": "MPLDEMO-MPLDEMO-MPLDEMO-1234567", "credit_card_number": "5326105300985846", "credit_card_exp": "1230", "credit_card_cvv": "658", "buyer_name": "Israel Israeli", "buyer_email": "buyer@example.com", "buyer_phone": "+972500000000", "buyer_social_id": "008336174", "buyer_is_permanent": True, "language": "en", }, ) print(response.text) ``` ### PHP ```php '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 card is saved. (success) | Field | Type | Description | | --- | --- | --- | | `status_code` | integer | `0`: the card is saved. | | `buyer_key` | string | The token. Send it as `buyer_key` on `generate-sale`. | | `buyer_name` | string | Buyer's full name. | | `buyer_email` | string | Buyer's email address. | | `buyer_phone` | string | Buyer's phone number. | | `buyer_card_mask` | string | Masked card number, for example `532610******5846`. | | `buyer_card_exp` | string | Card expiry, `MMYY`. | | `buyer_social_id` | string | Buyer's national ID number. | | `buyer_is_permanent` | boolean | `true` for a permanent token, `false` for a single-use token. | | `session` | string | PayMe's ID for this request. Quote it when you contact PayMe. | ```json { "status_code": 0, "buyer_key": "BUYERDEMO-BUYERDEMO-BUYERDEMO-1234567", "buyer_name": "Israel Israeli", "buyer_email": "buyer@example.com", "buyer_phone": "+972500000000", "buyer_card_mask": "532610******5846", "buyer_card_exp": "1230", "buyer_social_id": "008336174", "buyer_is_permanent": true, "session": "Ab12Cd34" } ``` ### 400 — Error `20`: a card-like number in a field other than `credit_card_number`. (error) | Field | Type | Description | | --- | --- | --- | | `status_code` | integer | `1`: the request failed. | | `status_error_code` | integer | PayMe's error code. See [Errors](/payments/getting-started/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. | ```json { "status_code": 1, "status_error_details": "Validation error", "status_additional_info": "buyer_name contains invalid data", "status_error_code": 20, "session": "Ab12Cd34" } ``` ### 500 — Request errors and declines. `1`: a required field is missing (named in `status_additional_info`). `251`: unknown seller. `354`, `355`, `356`: invalid CVV, card number or expiry. `37`: invalid `buyer_zip_code`. A decline returns its decline code, such as `20004`, with the masked card number in `status_additional_info`. (error) | Field | Type | Description | | --- | --- | --- | | `status_code` | integer | `1`: the request failed. | | `status_error_code` | integer | PayMe's error code. See [Errors](/payments/getting-started/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. | ```json { "status_code": 1, "status_error_details": "Refusal by credit company. Please try a different card", "status_additional_info": "400000******0002", "status_error_code": 20004, "session": "Ab12Cd34" } ``` - [Save a card (token sale)](https://docs.payme.io/payments/tokenization/post-generate-sale-tokenization): POST /generate-sale — Save a card (token sale) # Save a card (token sale) - 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-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. - Request body field `payme_client_key` (optional): 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`. ## Overview Saves the buyer's card as a token (`buyer_key`) for later server-to-server charges. Send `sale_type: token` to save the card without charging (PayMe sets the price to `100`, which is not charged), or `capture_buyer: 1` on a normal sale to charge and save. The token arrives as `buyer_key` in the callback; you can also read it with [`get-buyer-key`](/payments/tokenization/post-get-buyer-key). `POST https://sandbox.payme.io/api/generate-sale` (production: `https://live.payme.io/api/generate-sale`), with a JSON body (`Content-Type: application/json`). | To | Send | |---|---| | Save the card without charging | `sale_type: token` | | Charge and save the card | `sale_type: sale` (default) and `capture_buyer: 1` | | Save a card on a page that can be opened only once | `sale_type: token`, `layout: token-capture` and `sale_should_be_opened_once: true` | | Charge a saved card later | `buyer_key` on a new `generate-sale`; see [Create a sale](/payments/hosted-payment-page/post-generate-sale) | To charge and save, send the same request as the example with `"sale_type": "sale"`, your real `sale_price` and `"capture_buyer": 1`. Rules: - Send `buyer_is_private: true` to tie the token to this seller. Without it the token is account-level: any seller of the same partner can charge it, and a `get-buyer-key` call that sends `seller_payme_id` fails with error `603`. - Token capture works with `credit-card`, `apple-pay`, `il-direct-debit` and `multi`; other methods return `4`. - `product_name` and a numeric `sale_price` are required even when nothing is charged. - Store `buyer_key` encrypted: it replaces the card number. ### 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](/payments/getting-started/authentication). ### 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](/payments/getting-started/callbacks). ## 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`. | | `sale_type` | string | no | `token` – save the card without charging (the price is set to `100`). `sale` (default) – charge; add `capture_buyer: 1` to save the card too. Token capture works with `credit-card`, `apple-pay`, `il-direct-debit` and `multi` (other methods return `4`). The full list is on [Sale Types](/payments/codes-statuses/sale-types). | | `sale_price` | integer | yes | Amount in minor units. Required, but for a token sale any numeric value works: PayMe replaces it with `100` and charges nothing. A missing or non-numeric value returns `352`. For a charge-and-save sale, the default allowed range is `500`–`4000000`. | | `currency` | string | no | Sale currency, a 3-letter ISO 4217 code. Optional for a token sale (the account's default currency is used); required to charge. | | `product_name` | string | yes | Short description shown to the buyer and in the seller's records, up to 500 characters. Required, also for token sales (missing returns `353`). | | `capture_buyer` | string | no | `1` or `true` to save the buyer's card as a token after the payment; the token arrives as `buyer_key` in the callback. Omit it, or send `0`, to skip. Works with `credit-card`, `apple-pay`, `il-direct-debit` and `multi` (other methods return `4`). Can't be combined with `buyer_key` (`601`). | | `buyer_is_private` | boolean | no | With `capture_buyer` or a token sale: `true` ties the token to this seller, so `get-buyer-key` works with the seller's MPL. Without it the token is account-level: any seller of the same partner can charge it, and a `get-buyer-key` call that sends `seller_payme_id` fails with error `603`. | | `buyer_perform_validation` | boolean | no | With `capture_buyer` or a token sale: whether PayMe validates the card with the issuer before saving the token. Default `true`. Sending `true` without `capture_buyer` or a token sale returns `608`. | | `sale_payment_method` | string | no | Payment method; see [Available Payment Methods](/payments/wallets-apms). Default `credit-card`. Send `multi` to let the buyer choose among every method enabled on the account. Case-insensitive. An unknown value returns `24`; a method not enabled on the account returns `720` with the method name; `bacs` needs `GBP` and `sepa` needs `EUR` (`320`). Send a string: an array returns `368` (HTTP 400). | | `layout` | string | no | Payment page layout: `dynamic` (default), `dynamic-loose` (no social ID or CVV validation), `qr-sms` (Bit: QR code or SMS), `token-capture` (save a card without a charge; requires `sale_type: token`). Other values fall back to `dynamic`. | | `sale_should_be_opened_once` | boolean | no | `true`: with `layout: token-capture`, the page can be opened only once. Ignored otherwise. | | `buyer_key` | string | no | To charge a saved token later, on a new `generate-sale`: the call charges it at once, with no payment page. Can't be combined with `capture_buyer` (`601`) or `sale_type: token` (`602`). | | `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. | | `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](/payments/getting-started/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. | | `sale_return_url` | string | no | Where PayMe redirects the buyer (the iframe or the full page) after a successful payment, with the sale details as query parameters; see [Hosted Payment Page options](/accepting-payments/checkout-and-in-person/hosted-payment-page-options). If omitted, your partner's default return URL is used, if one is set. Same address rules as `sale_callback_url` (error `21`). | | `sale_send_notification` | boolean | no | `true`: PayMe sends the buyer a payment request with the payment link, by email to `sale_email` and by SMS to `sale_mobile`. Default `false`. | | `sale_email` | string | no | Buyer's email. Pre-fills the payment page and receives the payment request when `sale_send_notification` is `true`. | | `sale_mobile` | string | no | Buyer's mobile number. Pre-fills the payment page and receives the SMS payment request when `sale_send_notification` is `true` and the SMS service is active on the account. | | `sale_name` | string | no | Buyer's full name. Pre-fills the payment page (split at the first space into first and last name) and is used in notifications. | | `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`. | ### Request example ```json { "seller_payme_id": "MPLDEMO-MPLDEMO-MPLDEMO-1234567", "sale_type": "token", "sale_price": 100, "currency": "ILS", "product_name": "Save card", "buyer_is_private": true, "sale_callback_url": "https://your-server.example.com/payme/callback", "language": "en" } ``` ## Code samples ### curl ```bash curl -X POST 'https://sandbox.payme.io/api/generate-sale' \ -H 'Content-Type: application/json' \ --data-raw '{ "seller_payme_id": "MPLDEMO-MPLDEMO-MPLDEMO-1234567", "sale_type": "token", "sale_price": 100, "currency": "ILS", "product_name": "Save card", "buyer_is_private": true, "sale_callback_url": "https://your-server.example.com/payme/callback", "language": "en" }' ``` ### Node.js ```javascript 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", "sale_type": "token", "sale_price": 100, "currency": "ILS", "product_name": "Save card", "buyer_is_private": true, "sale_callback_url": "https://your-server.example.com/payme/callback", "language": "en" }), }); console.log(await response.text()); ``` ### Python ```python import requests response = requests.post( "https://sandbox.payme.io/api/generate-sale", json={ "seller_payme_id": "MPLDEMO-MPLDEMO-MPLDEMO-1234567", "sale_type": "token", "sale_price": 100, "currency": "ILS", "product_name": "Save card", "buyer_is_private": True, "sale_callback_url": "https://your-server.example.com/payme/callback", "language": "en", }, ) print(response.text) ``` ### PHP ```php '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 sale created (success) | Field | Type | Description | | --- | --- | --- | | `status_code` | integer | `0` success, `1` error. | | `sale_url` | string | PayMe's payment page for this sale. Show it to the buyer in an iframe or a redirect, exactly as returned. It stays payable while the sale is `initial` or `failed`, until `sale_expiry_seconds` passes if you sent it. | | `payme_sale_id` | string | PayMe's sale ID. Store it: refunds, captures and queries use it. | | `payme_sale_code` | integer | Short numeric sale code, for display only. | | `price` | integer | Sale amount in minor units (`100` for a token sale). | | `transaction_id` | string | Your order reference, as sent. | | `currency` | string | Sale currency (ISO 4217). | | `sale_payment_method` | string | Payment method of the sale, for example `credit-card` or `multi`. | | `session` | string | Request ID. Quote it when you contact PayMe. | ```json { "status_code": 0, "session": "AtsJ0as5", "sale_url": "https://sandbox.payme.io/sale/generate/SALE1700-000000AA-EXAMPLE1-SALE0001", "payme_sale_id": "SALE1700-000000AA-EXAMPLE1-SALE0001", "payme_sale_code": 12345678, "price": 100, "transaction_id": null, "currency": "ILS", "sale_payment_method": "credit-card" } ``` ### 500 — Request refused. Most request errors return HTTP 500 with `status_code: 1`; some return 400, 403, 422 or 429. See [Errors](/payments/getting-started/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. | ```json { "status_code": 1, "status_error_details": "Seller was not found", "status_additional_info": "seller_payme_id", "status_error_code": 251, "session": "AtsJ0as5" } ``` - [Get the buyer key of a sale or subscription](https://docs.payme.io/payments/tokenization/post-get-buyer-key): POST /get-buyer-key — Get the buyer key of a sale or subscription # Get the buyer key of a sale or subscription - Sandbox: `POST https://sandbox.payme.io/api/get-buyer-key` - Production: `POST https://live.payme.io/api/get-buyer-key` ## Credentials - Request body field `seller_payme_id` (optional): The seller's MPL, for a seller-level token (saved with `buyer_is_private: true`). Don't send it for an account-level token: that fails with error `603`. Send this or `payme_client_key`. - Request body field `payme_client_key` (optional): Partners: your partner key, in the JSON body. Reads both kinds of token when you send no `seller_payme_id`. ## Overview Returns the saved card (`buyer_key`) of a paid sale or of a subscription. Send `payme_sale_id` or `sub_payme_id`, not both. Use `sub_payme_id` for a subscription whose card was entered on `sub_url`: subscription calls and callbacks never return the `buyer_key`. For Israeli direct debit, approving a new authorization creates a buyer key behind the scenes; read it with this call. ### Which credential to send Send the credential in the JSON body; a `PayMe-Partner-Key` header alone isn't enough. | The token | Send | |---|---| | Saved with `buyer_is_private: true` (seller-level) | `seller_payme_id`, or (partners) `payme_client_key` | | Saved without it (the default), or a partner-level token | `payme_client_key` only. Adding `seller_payme_id` fails with HTTP 403, error `603` | A direct seller has no partner key, so it must save the token with `buyer_is_private: true` to read it back. ## Parameters This endpoint takes no path, query or header parameters. ## Request body Content type: `application/json` | Field | Type | Required | Description | | --- | --- | --- | --- | | `payme_sale_id` | string | no | The paid sale whose saved card you want. Send this or `sub_payme_id`. | | `sub_payme_id` | string | no | The subscription whose saved card you want. Send this or `payme_sale_id`. | | `seller_payme_id` | string | no | The seller's MPL, for a seller-level token (saved with `buyer_is_private: true`). Don't send it for an account-level token: that fails with error `603`. Send this or `payme_client_key`. | | `payme_client_key` | string | no | Partners: your partner key, in the JSON body. Reads both kinds of token when you send no `seller_payme_id`. | | `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 ```json { "payme_client_key": "XXXXXXXX", "payme_sale_id": "SALEDEMO-XXXXXXXX-XXXXXXXX-XXXXXXXX", "language": "en" } ``` ## Code samples ### curl ```bash curl -X POST 'https://sandbox.payme.io/api/get-buyer-key' \ -H 'Content-Type: application/json' \ --data-raw '{ "payme_client_key": "XXXXXXXX", "payme_sale_id": "SALEDEMO-XXXXXXXX-XXXXXXXX-XXXXXXXX", "language": "en" }' ``` ### Node.js ```javascript const response = await fetch("https://sandbox.payme.io/api/get-buyer-key", { method: "POST", headers: { "Content-Type": "application/json", }, body: JSON.stringify({ "payme_client_key": "XXXXXXXX", "payme_sale_id": "SALEDEMO-XXXXXXXX-XXXXXXXX-XXXXXXXX", "language": "en" }), }); console.log(await response.text()); ``` ### Python ```python import requests response = requests.post( "https://sandbox.payme.io/api/get-buyer-key", json={ "payme_client_key": "XXXXXXXX", "payme_sale_id": "SALEDEMO-XXXXXXXX-XXXXXXXX-XXXXXXXX", "language": "en", }, ) print(response.text) ``` ### PHP ```php '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 saved card. (success) | Field | Type | Description | | --- | --- | --- | | `status_code` | integer | `0`: success. | | `payme_sale_id` | string | The sale you asked about. Returned when you sent `payme_sale_id`. | | `sub_payme_id` | string | The subscription you asked about. Returned instead of `payme_sale_id` when you sent `sub_payme_id`. | | `buyer_key` | string | The saved card's token. | | `buyer_card_mask` | string | Masked card number, for example `532610******5846`. | | `buyer_card_expiry` | string | Card expiry, `MMYY`. | | `buyer_card_brand` | string | Card brand: `MasterCard`, `Visa`, `AmericanExpress`, `Diners`, `Isracard` and so on. | | `session` | string | PayMe's ID for this request. Quote it when you contact PayMe. | ```json { "status_code": 0, "payme_sale_id": "SALEDEMO-XXXXXXXX-XXXXXXXX-XXXXXXXX", "buyer_key": "BUYERDEMO-BUYERDEMO-BUYERDEMO-1234567", "buyer_card_mask": "532610******5846", "buyer_card_expiry": "1230", "buyer_card_brand": "MasterCard", "session": "Ab12Cd34" } ``` ### 400 — Error `1`: neither `payme_sale_id` nor `sub_payme_id` sent. Error `20`: both sent. Error `600`: no saved card on this sale or subscription, or the sale isn't paid (`status_additional_info` then holds its status, `initial` or `failed`). (error) | Field | Type | Description | | --- | --- | --- | | `status_code` | integer | `1`: the request failed. | | `status_error_code` | integer | PayMe's error code. See [Errors](/payments/getting-started/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. | ```json { "status_code": 1, "status_error_details": "Buyer not found", "status_additional_info": "No Buyer for Sale", "status_error_code": 600, "session": "Ab12Cd34" } ``` ### 403 — Error `603`: `seller_payme_id` sent for an account-level token. Error `303` (sale) or `370` (subscription): it belongs to another partner. (error) | Field | Type | Description | | --- | --- | --- | | `status_code` | integer | `1`: the request failed. | | `status_error_code` | integer | PayMe's error code. See [Errors](/payments/getting-started/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. | ```json { "status_code": 1, "status_error_details": "Merchant not allowed to use this buyer", "status_additional_info": "", "status_error_code": 603, "session": "Ab12Cd34" } ``` ### 500 — Request errors. `1`: neither `payme_client_key` nor `seller_payme_id` in the body. `200`: unknown partner key. `251`: unknown seller. `350`: no sale has this ID. `605`: a seller-level token read with another seller's MPL. (error) | Field | Type | Description | | --- | --- | --- | | `status_code` | integer | `1`: the request failed. | | `status_error_code` | integer | PayMe's error code. See [Errors](/payments/getting-started/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. | ```json { "status_code": 1, "status_error_details": "Required parameter is missing", "status_additional_info": "payme_client_key / seller_payme_id", "status_error_code": 1, "session": "Ab12Cd34" } ``` - [Create a partner-level token](https://docs.payme.io/payments/tokenization/post-sellers-mpl-tokens): POST /sellers/{mpl}/tokens — Create a partner-level token # Create a partner-level token - Sandbox: `POST https://sandbox.payme.io/api/sellers/{mpl}/tokens` - Production: `POST https://live.payme.io/api/sellers/{mpl}/tokens` ## Credentials - Request body field `options.validate_token` (optional): Check the card with the issuer before saving it. Default `true`. ## Overview **For PayMe partners only.** Saves a card as a token that belongs to your partner account, so you can charge it later for any of your sellers. A buyer saves a card while buying from one seller and can then pay another seller without typing it again. A seller-level token can't do that. The MPL in the path (the `seller_payme_id` of one of your sellers) identifies your account; the call takes no other key. Treat the MPL as a secret: call this endpoint from your server only, never from a browser. **This endpoint takes raw card details, so call it only if you are PCI DSS certified.** Without that certification, capture the same kind of token on a page PayMe hosts: send [`generate-sale`](/payments/hosted-payment-page/post-generate-sale) with `sale_type: "seller-token"` and show the buyer its `sale_url`. PayMe sets the price of such a sale itself. ## Using the token The token is the `uuid` in the response. Send it as `token` on `generate-sale`, with the `seller_payme_id` of the seller you are charging for. It is not a `buyer_key`: sent as `buyer_key`, it fails with error `600`. Against a seller of a different partner it fails with error `605`. The token is permanent: it doesn't expire in PayMe, and each charge with it runs at once, with no CVV and no 3D Secure. A charge can still fail if the card has expired or the issuer declines it. The response isn't PayMe's usual envelope. A success has no `status_code`, so check for HTTP 201 and a `uuid`. A failure has the usual `status_code: 1` and `status_error_code`; decide from those, not from the HTTP status. A token is a bearer credential: store it encrypted, and never log it or send it to a browser. See [Saved Cards](/agents/steps/saved-cards) for the rules. This page covers `credit-card`, the method checked in the sandbox. ## Parameters | Name | In | Type | Required | Description | | --- | --- | --- | --- | --- | | `mpl` | path | string | yes | The `seller_payme_id` (MPL) of one of your sellers. It identifies your partner account, so keep it secret and send it from your server only. The token is stored under this seller and can be charged for your other sellers too. | ## Request body Content type: `application/json` | Field | Type | Required | Description | | --- | --- | --- | --- | | `payment` | object | yes | The card to save. | | `payment.method` | string | yes | `credit-card`. | | `payment.card_number` | string | yes | Card number, digits only. | | `payment.card_expiry` | string | yes | Card expiry, `MMYY`. | | `payment.card_cvv` | string | no | CVV, 3 or 4 digits. Required unless `options.use_token_terminal` is `true`; missing, it returns error `1`. | | `customer` | object | yes | The buyer. | | `customer.name` | string | yes | Buyer's full name. Missing: error `1`. | | `customer.email` | string | yes | Buyer's email address. Missing or invalid: error `13`. | | `customer.phone` | string | yes | Buyer's phone number. Missing: error `1`. | | `customer.social_id` | string | no | Buyer's Israeli ID number. When sent, it must be a valid Israeli ID. | | `customer.zip_code` | string | no | Buyer's zip code. | | `customer.country` | string | no | Buyer's country, a two-letter code such as `IL`. | | `customer.state` | string | no | Buyer's state or region. | | `customer.city` | string | no | Buyer's city. | | `customer.line1` | string | no | Buyer's street address. | | `customer.line2` | string | no | Buyer's address, second line. | | `customer.business_code` | string | no | For a business buyer: its registration number. Send it with `customer.business_name`, or neither. | | `customer.business_name` | string | no | For a business buyer: its name. Send it with `customer.business_code`, or neither. | | `options` | object | no | Token options. | | `options.validate_token` | boolean | no | Check the card with the issuer before saving it. Default `true`. | | `options.use_token_terminal` | boolean | no | `true` to save the card without a CVV, on a token terminal. Then `payment.card_cvv` is optional. Default `false`. | ### Request example ```json { "payment": { "method": "credit-card", "card_number": "4557430402053431", "card_expiry": "1230", "card_cvv": "200" }, "customer": { "name": "First Last", "email": "buyer@example.com", "phone": "+972501234567", "social_id": "008336174" } } ``` ## Code samples ### curl ```bash curl -X POST 'https://sandbox.payme.io/api/sellers//tokens' \ -H 'Content-Type: application/json' \ --data-raw '{ "payment": { "method": "credit-card", "card_number": "4557430402053431", "card_expiry": "1230", "card_cvv": "200" }, "customer": { "name": "First Last", "email": "buyer@example.com", "phone": "+972501234567", "social_id": "008336174" } }' ``` ### Node.js ```javascript const response = await fetch("https://sandbox.payme.io/api/sellers//tokens", { method: "POST", headers: { "Content-Type": "application/json", }, body: JSON.stringify({ "payment": { "method": "credit-card", "card_number": "4557430402053431", "card_expiry": "1230", "card_cvv": "200" }, "customer": { "name": "First Last", "email": "buyer@example.com", "phone": "+972501234567", "social_id": "008336174" } }), }); console.log(await response.text()); ``` ### Python ```python import requests response = requests.post( "https://sandbox.payme.io/api/sellers//tokens", json={ "payment": { "method": "credit-card", "card_number": "4557430402053431", "card_expiry": "1230", "card_cvv": "200", }, "customer": { "name": "First Last", "email": "buyer@example.com", "phone": "+972501234567", "social_id": "008336174", }, }, ) print(response.text) ``` ### PHP ```php /tokens'); 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 ### 201 — The token was created (success) | Field | Type | Description | | --- | --- | --- | | `uuid` | string | The token. Send it as token on generate-sale. | | `customer` | object | name, email, phone and social_id | | `payment` | object | display (the masked card number), expiry, brand, club, type, organization, origin_country and is_foreign | ```json { "uuid": "00000000-0000-0000-0000-000000000000", "customer": { "name": "First Last", "email": "buyer@example.com", "phone": "+972501234567", "social_id": "008336174" }, "payment": { "display": "455743******3431", "expiry": "1230", "brand": "Visa" } } ``` ### 400 — The card was declined or failed validation. Read `status_code` and `status_error_code`. (error) | Field | Type | Description | | --- | --- | --- | | `status_code` | integer | `1`: the request failed. | | `status_error_code` | integer | PayMe's error code, such as `20004` for a declined card. | | `status_error_details` | string | The error message. | | `status_additional_info` | string | More detail, such as the masked card number. | ```json { "status_code": 1, "status_error_code": 20004, "status_error_details": "Refusal by credit company. Please try a different card", "status_additional_info": "400000******0002" } ``` ### 500 — A required field is missing or invalid (error) | Field | Type | Description | | --- | --- | --- | | `status_code` | integer | 1 | | `status_error_code` | integer | `1` for a missing field (`customer.name`, `customer.phone`, `payment.card_cvv` and so on), named in `status_additional_info`. `13` for a missing or invalid email. | | `status_error_details` | string | The error message | | `status_additional_info` | string | The field at fault, when there is one | ```json { "status_code": 1, "status_error_code": 1, "status_error_details": "Required parameter is missing", "status_additional_info": "payment.card_cvv" } ``` ## Subscriptions - [Subscriptions](https://docs.payme.io/payments/subscriptions): Recurring payments with subscriptions: the lifecycle, statuses, pausing, template subscriptions, callbacks and iteration types. # Subscriptions A subscription charges a buyer on a fixed schedule. Each iteration is charged separately: unlike an installment sale, nothing is authorized up front. For 100.00 a month over 10 months, each month is charged 100.00, not 1,000.00 at once. How charging, retries, callbacks and saved cards work in detail: [Saved cards & recurring](https://docs.payme.io/payments/saved-cards-recurring). ## Endpoints - [Create a subscription](https://docs.payme.io/payments/subscriptions/post-generate-subscription): `POST /generate-subscription` - [Pay a subscription](https://docs.payme.io/payments/subscriptions/post-generate-subscription-2): `POST /pay-subscription` - [Pause a subscription](https://docs.payme.io/payments/subscriptions/post-pause-subscription): `POST /pause-subscription` - [Resume a subscription](https://docs.payme.io/payments/subscriptions/patch-subscriptions-sub-payme-id-resume): `PATCH /subscriptions/{sub_payme_id}/resume` - [Update a subscription's price](https://docs.payme.io/payments/subscriptions/patch-subscriptions-sub-id-set-price): `PATCH /subscriptions/{sub_payme_id}/set-price` - [Cancel a subscription](https://docs.payme.io/payments/subscriptions/postcancel-subscription): `POST /cancel-subscription` - [List subscriptions](https://docs.payme.io/payments/query-apis/post-get-subscriptions): `POST /get-subscriptions` ## Lifecycle 1. Create the subscription. It starts in status `1` (Initial) and returns `sub_url`, the hosted page where the buyer enters a card. Or send a permanent `buyer_key` to attach a saved card at once. 2. When a card is attached, the status becomes `2` (Active) and PayMe sends `sub-active`. 3. A background job charges each iteration when its date arrives; the first charge runs within about a minute after `sub_start_date`. Each successful charge creates a sale and sends `sub-iteration-success`. 4. If the card check fails when the buyer pays, the status becomes `4` (Failed) and PayMe sends `sub-failure`. The subscription isn't canceled: the buyer can pay again. 5. A failed scheduled charge moves the subscription to status `7` and is retried once a day, up to 7 attempts in total. A daily subscription, and the seventh consecutive failure, are canceled instead (status `5`, `sub-cancel`). 6. After the last iteration, the status becomes `6` (Completed) and PayMe sends `sub-complete`. ## Pausing While a subscription is paused (status `3`), nothing is charged. Each iteration whose date passes is skipped: it counts in `sub_iterations_skipped`, reduces `sub_iterations_left`, and sends `sub-iteration-skipped`. Resuming doesn't charge skipped iterations and sends no callback. If every remaining iteration is skipped, the subscription becomes `6` (Completed) while still paused. ## Automatic cancellation and blocked sellers No charges run while the seller's account is blocked. PayMe cancels a subscription automatically after the last failed charge attempt. It also cancels the active subscriptions, and those waiting for a retry, of a seller whose account has been blocked for more than 30 days. ## Template subscriptions A template (`sub_type` `10`), also called a "Multilink subscription", is one shareable payment link for many buyers. You can post it on a social network, for example. Each buyer who pays it gets their own subscription with its own `sub_payme_id` (`sub_type` `2`). Send the number `10`; the text `template` is rejected. | `sub_type` | Meaning | |---|---| | `1` | Regular subscription (the default). | | `2` | A subscription created when a buyer paid a template. You don't send this value. | | `10` | Template. Its link doesn't expire. | ## Iteration types | ID | Interval | |---|---| | `1` | Daily | | `2` | Weekly | | `3` | Monthly. The start day must be between 1 and 28. | | `4` | Yearly | | `5` | Quarterly | ## Statuses | ID | Status | |---|---| | `1` | Initial: waiting for the buyer to pay. | | `2` | Active: a card is attached and charges run on schedule. | | `3` | Paused: no charges; iterations whose date passes are skipped. | | `4` | Failed: the card check failed when the buyer paid. No automatic retry; the buyer can pay again. | | `5` | Canceled: by the seller, or automatically after the last failed attempt. | | `6` | Completed: all iterations were charged or skipped. | | `7` | Failed, retry pending: a scheduled charge failed and is retried the next day. | ## Callbacks PayMe sends callbacks to `sub_callback_url`, or to your partner's default callback URL if you didn't send one. They are `POST` requests of type `x-www-form-urlencoded`. The fields are listed on [Callbacks → Subscriptions](https://docs.payme.io/payments/getting-started/callbacks#subscriptions). | `notify_type` | When | |---|---| | `sub-create` | The subscription was created. | | `sub-active` | A card was attached and the subscription is active. The first charge follows within about a minute after `sub_start_date`. | | `sub-iteration-success` | A scheduled charge succeeded. | | `sub-failure` | A charge failed: the card check when the buyer paid (status `4`), or a scheduled charge that will be retried (status `7`). | | `sub-pause` | The subscription was paused. | | `sub-iteration-skipped` | An iteration date passed while the subscription was paused. The iteration is skipped and never charged. | | `sub-complete` | The last iteration was charged or skipped. | | `sub-cancel` | The subscription was canceled, by the seller or automatically. | ## Saved cards To charge a saved card instead of sending the buyer to `sub_url`, pass a permanent `buyer_key` to [Create a subscription](https://docs.payme.io/payments/subscriptions/post-generate-subscription). How to get one: [Saved cards & recurring](https://docs.payme.io/payments/saved-cards-recurring). - [Create a subscription](https://docs.payme.io/payments/subscriptions/post-generate-subscription): POST /generate-subscription — Create a subscription # Create a subscription - Sandbox: `POST https://sandbox.payme.io/api/generate-subscription` - Production: `POST https://live.payme.io/api/generate-subscription` ## Credentials - Request body field `seller_payme_id` (required): The seller's MPL. Must be in the JSON body on this endpoint. - Request body field `payme_client_key` (optional): Partners only: your partner key. You can send it in the `PayMe-Partner-Key` header instead. A seller authenticates with `seller_payme_id` alone. ## Overview Creates a subscription that charges the buyer once per iteration. A new subscription is in status `1` (Initial), and the response returns `sub_url`, the hosted page where the buyer enters a card. To skip that page, send a permanent `buyer_key`: the card is attached at once and the subscription is created in status `2` (Active). - Each iteration is charged separately: for 50.00 a month over 12 months, each month is charged 50.00. - Nothing is charged in this call, even with `buyer_key`. A background job that runs once a minute makes every charge, including the first: it runs within about a minute after `sub_start_date` (default: today) once a card is attached. - If the card check fails when the buyer pays on `sub_url`, the subscription moves to status `4` (Failed) and PayMe sends `sub-failure`. It isn't canceled and isn't retried: the buyer can pay again. - A failed scheduled charge moves the subscription to status `7` and is retried once a day, up to 7 attempts in total. A daily subscription, and the seventh consecutive failure, move to status `5` (Canceled) and send `sub-cancel` instead. - The response and the callbacks never contain the `buyer_key`. Read it with [Get buyer key](/payments/tokenization/post-get-buyer-key) and `sub_payme_id`. - `subscription_id` isn't unique: sending the same value twice creates two subscriptions. To share one payment link with many buyers, send `sub_type` `10` (template). Each buyer who pays it gets their own subscription. Lifecycle, retries, callbacks and price changes: [Subscriptions overview](/payments/subscriptions) and [Saved cards & recurring](/payments/saved-cards-recurring). ## Authentication Send `seller_payme_id` (the seller's MPL) in the JSON body: on this endpoint the `PayMe-Merchant-Key` header alone isn't enough. Partners also send `payme_client_key`, in the body or the `PayMe-Partner-Key` header. ## Errors Errors return `status_code` `1` with HTTP 500 unless the table says otherwise. | HTTP | Code | When | |---|---|---| | 500 | `1` | A required field is missing. `status_additional_info` names it. | | 500 | `24` | `sub_type` isn't `1` or `10` (for example the text `template`). | | 500 | `251` | The `seller_payme_id` matches no seller. | | 500 | `252` | The seller can't use `sub_currency`. | | 500 | `352` | `sub_price` is outside your account's range. | | 500 | `372` | `sub_iteration_type` isn't between `1` and `5`. | | 500 | `373` | `sub_iterations` isn't `-1` or between 1 and 54. | | 500 | `374` | `sub_start_date` is before today. | | 500 | `375` | A monthly subscription starts after the 28th of the month. | | 500 | `376` | `buyer_key` is a one-time token or can't be used, or `sub_payment_method` needs a `buyer_key`. | ## 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. Must be in the JSON body on this endpoint. | | `payme_client_key` | string | no | Partners only: your partner key. You can send it in the `PayMe-Partner-Key` header instead. A seller authenticates with `seller_payme_id` alone. | | `sub_price` | integer | yes | Price of one iteration, in minor units (`5075` = 50.75). Default range 500–4,000,000; your account may have different limits. Out of range returns error `352`. | | `sub_currency` | string | yes | ISO 4217 currency code, for example `ILS`. The seller must be allowed to use it (error `252`). | | `sub_description` | string | yes | What the buyer is paying for. Up to 300 characters. | | `sub_iteration_type` | integer | yes | Billing interval: `1` Daily, `2` Weekly, `3` Monthly, `4` Yearly, `5` Quarterly. Other values return error `372`. See [Subscription iteration types](/payments/codes-statuses/subscription-iteration-types). | | `sub_start_date` | string | no | Date of the first charge, `DD/MM/YYYY` or epoch seconds. Default: today. Must be today or later (error `374`). For a monthly subscription the day must be between 1 and 28 (error `375`). Nothing is charged before this date: use it for "charge now, then monthly" after a one-off sale with the same `buyer_key`. | | `sub_iterations` | integer | no | Number of iterations. `-1` (default) means unlimited; otherwise 1–54. Other values return error `373`. | | `sub_type` | integer | no | `1` Regular (default) or `10` Template: one shareable payment link, where each buyer who pays gets their own subscription. Send the number: the text `template` is rejected with error `24`. | | `buyer_key` | string | no | A permanent buyer token to attach instead of sending the buyer to `sub_url` (create it with `buyer_is_permanent: true` on [capture-buyer-token](/payments/tokenization/post-capture-buyer-token)). The subscription is then active at once; the first charge still runs in the background. A one-time token returns error `376`. Don't combine it with `sub_type` `10`. | | `buyer_business_name` | string | no | With `buyer_key`: the buyer's business name. Send it together with `buyer_business_code`. | | `buyer_business_code` | string | no | With `buyer_key`: the buyer's business registration number. | | `sub_payment_method` | string | no | Payment method. Default: `credit-card`. A method other than `credit-card` or `multi` needs a `buyer_key` (error `376`). With `buyer_key` this field is ignored and the token's method is used. | | `subscription_id` | string | no | Your own reference, up to 50 characters. Not unique: a repeated value creates a second subscription. [List subscriptions](/payments/query-apis/post-get-subscriptions) accepts it as a filter. | | `sub_callback_url` | string | no | URL that receives the subscription callbacks (`sub-create`, `sub-active`, `sub-iteration-success`, `sub-failure` and the others listed on [Callbacks](/payments/getting-started/callbacks#subscriptions)). Default: your partner's default callback URL, if one is set. No call changes it later. | | `sub_return_url` | string | no | Where the buyer is sent after paying on `sub_url`. PayMe adds `payme_status`, `payme_signature`, `sub_payme_id`, `subscription_id`, `transaction_id`, `price`, `currency` and `is_foreign_card` to the query string. | | `sub_indicative_name` | string | no | The buyer's name, stored on the subscription. | | `sub_email_address` | string | no | Buyer email for subscription emails. When a card is attached, the card holder's email replaces it. | | `sub_indicative_mobile` | string | no | Buyer mobile number, stored for reference. When a card is attached, the card holder's phone replaces it. | | `sub_send_notification` | boolean | no | `true` emails the payment link to `sub_email_address` when the subscription is created. Default: `false`. | | `language` | string | no | Language of the payment page, buyer emails and error messages: `he` (default), `en`, `es`, `ru` or `ar`. | ### Request example ```json { "seller_payme_id": "MPLDEMO-MPLDEMO-MPLDEMO-1234567", "sub_price": 5000, "sub_currency": "ILS", "sub_description": "Monthly plan", "sub_iteration_type": 3, "sub_iterations": 12, "sub_start_date": "01/12/2026", "subscription_id": "order-1001", "sub_callback_url": "https://www.example.com/payment/callback", "sub_return_url": "https://www.example.com/payment/success", "language": "en" } ``` ## Code samples ### curl ```bash curl -X POST 'https://sandbox.payme.io/api/generate-subscription' \ -H 'Content-Type: application/json' \ --data-raw '{ "seller_payme_id": "MPLDEMO-MPLDEMO-MPLDEMO-1234567", "sub_price": 5000, "sub_currency": "ILS", "sub_description": "Monthly plan", "sub_iteration_type": 3, "sub_iterations": 12, "sub_start_date": "01/12/2026", "subscription_id": "order-1001", "sub_callback_url": "https://www.example.com/payment/callback", "sub_return_url": "https://www.example.com/payment/success", "language": "en" }' ``` ### Node.js ```javascript const response = await fetch("https://sandbox.payme.io/api/generate-subscription", { method: "POST", headers: { "Content-Type": "application/json", }, body: JSON.stringify({ "seller_payme_id": "MPLDEMO-MPLDEMO-MPLDEMO-1234567", "sub_price": 5000, "sub_currency": "ILS", "sub_description": "Monthly plan", "sub_iteration_type": 3, "sub_iterations": 12, "sub_start_date": "01/12/2026", "subscription_id": "order-1001", "sub_callback_url": "https://www.example.com/payment/callback", "sub_return_url": "https://www.example.com/payment/success", "language": "en" }), }); console.log(await response.text()); ``` ### Python ```python import requests response = requests.post( "https://sandbox.payme.io/api/generate-subscription", json={ "seller_payme_id": "MPLDEMO-MPLDEMO-MPLDEMO-1234567", "sub_price": 5000, "sub_currency": "ILS", "sub_description": "Monthly plan", "sub_iteration_type": 3, "sub_iterations": 12, "sub_start_date": "01/12/2026", "subscription_id": "order-1001", "sub_callback_url": "https://www.example.com/payment/callback", "sub_return_url": "https://www.example.com/payment/success", "language": "en", }, ) print(response.text) ``` ### PHP ```php '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 subscription was created. (success) | Field | Type | Description | | --- | --- | --- | | `sub_url` | string | The hosted payment page where the buyer enters a card. For a template, the shareable link. | | `status_code` | integer | `0` on success. | | `payme_status` | string | `success`. | | `status_error_code` | integer | `0` on success. | | `seller_payme_id` | string | The seller's MPL. | | `seller_id` | string | The partner's own reference for the seller, if the partner set one. Otherwise `null`. | | `sub_payme_id` | string | PayMe's subscription ID (`SUB…`). Use it in every other subscription call. | | `sub_payme_code` | integer | PayMe's numeric subscription ID. | | `subscription_id` | string | Your own reference, as sent when the subscription was created. `null` if you didn't send one. | | `sub_created` | string | When the subscription was created, `YYYY-MM-DD HH:MM:SS`. | | `sub_start_date` | string | Date of the first charge, `YYYY-MM-DD HH:MM:SS`. | | `sub_prev_date` | string | When the last successful charge ran. `null` until the first charge. | | `sub_next_date` | string | When the next charge is due. Ignore it on a canceled or completed subscription. | | `sub_status` | integer | Current status. See [Subscription statuses](/payments/codes-statuses/subscription-statuses). | | `sub_iteration_type` | integer | Billing interval. See [Subscription iteration types](/payments/codes-statuses/subscription-iteration-types). | | `sub_currency` | string | ISO 4217 currency code, e.g. `ILS`. | | `sub_price` | integer | Price of one iteration, in minor units (`5000` = 50.00). | | `sub_description` | string | What the buyer is paying for. | | `sub_iterations` | integer | Total number of iterations. `-1` means unlimited. | | `sub_iterations_completed` | integer | Iterations charged successfully. | | `sub_iterations_skipped` | integer | Iterations skipped while the subscription was paused. They are never charged. | | `sub_iterations_left` | integer | `sub_iterations` minus completed and skipped iterations. `-1` when unlimited. | | `sub_paid` | boolean | `true` once a card (buyer token) is attached to the subscription. It does not mean the current iteration was charged. | | `sub_error_text` | string | The last failure, pause or cancel reason. `null` if there is none. Reasons that PayMe writes are in Hebrew. | | `sub_payment_date` | string | Returned only when a card is attached: when the card was attached. | | `buyer_card_mask` | string | Returned only when a card is attached: the masked card number. | | `buyer_card_exp` | string | Returned only when a card is attached: card expiry, `MMYY`. | | `buyer_name` | string | Returned only when a card is attached: the card holder's name. | | `buyer_email` | string | Returned only when a card is attached: the card holder's email. | | `buyer_phone` | string | Returned only when a card is attached: the card holder's phone, or `null`. | | `buyer_social_id` | string | Returned only when a card is attached: the card holder's national ID, or `null`. | ```json { "sub_url": "https://sandbox.payme.io/subscription/generate/SUB16885-68336QPL-UQSSS1CC-SYKXI53N", "status_code": 0, "payme_status": "success", "status_error_code": 0, "seller_payme_id": "MPLDEMO-MPLDEMO-MPLDEMO-1234567", "seller_id": null, "sub_payme_id": "SUB16885-68336QPL-UQSSS1CC-SYKXI53N", "sub_payme_code": 477004, "subscription_id": "order-1001", "sub_created": "2026-11-09 10:15:00", "sub_start_date": "2026-12-01 00:00:00", "sub_prev_date": null, "sub_next_date": "2026-12-01 00:00:00", "sub_status": 1, "sub_iteration_type": 3, "sub_currency": "ILS", "sub_price": 5000, "sub_description": "Monthly plan", "sub_iterations": 12, "sub_iterations_completed": 0, "sub_iterations_skipped": 0, "sub_iterations_left": 12, "sub_paid": false, "sub_error_text": null } ``` ### 500 — The request was refused. See the error table. (error) | Field | Type | Description | | --- | --- | --- | | `status_code` | integer | `1` on failure. | | `status_error_details` | string | What went wrong, in the language you asked for (Hebrew by default). | | `status_additional_info` | string | The field or value concerned. Can be `null`. | | `status_error_code` | integer | PayMe error code. See the error table above and [Errors](/payments/getting-started/errors). | | `session` | string | PayMe session ID. Quote it when you contact support. | ```json { "status_code": 1, "status_error_details": "Required parameter is missing", "status_additional_info": "seller_payme_id", "status_error_code": 1, "session": "FhT3aXe7" } ``` - [Pay a subscription](https://docs.payme.io/payments/subscriptions/post-generate-subscription-2): POST /pay-subscription — Pay a subscription # Pay a subscription - Sandbox: `POST https://sandbox.payme.io/api/pay-subscription` - Production: `POST https://live.payme.io/api/pay-subscription` ## Credentials - Request body field `seller_payme_id` (optional): Not needed and not read by this call: `sub_payme_id` identifies the seller. ## Overview Attaches a card to a subscription and activates it. Use it when you collect the card in your own form instead of sending the buyer to `sub_url`, or to replace the card on a subscription in status `4` (Failed) or `7` (Failed, retry pending). - The call checks the card with a validation transaction and saves it as the subscription's buyer token. It doesn't charge an iteration: the status becomes `2` (Active), and the background job charges at `sub_next_date`. For a status-`7` subscription, that is the next retry date. - Only a subscription in status `1`, `4` or `7` can be paid. Any other status returns error `305`; an active subscription is never charged again by this call. - If the card check fails, the subscription moves to status `4` and PayMe sends `sub-failure`. Call this endpoint again with another card. - For a template (`sub_type` `10`), each successful call creates a new subscription for that buyer and returns it. - A lock stops two calls on the same subscription from running at once. There is no card swap for an active subscription. ## Authentication No API key is needed: `sub_payme_id` identifies the seller, so you can make this call from the buyer's browser, like `pay-sale`. `seller_payme_id` and `payme_client_key` aren't read here. ## Errors Errors return `status_code` `1` with HTTP 500 unless the table says otherwise. | HTTP | Code | When | |---|---|---| | 500 | `1` | A required field is missing. `status_additional_info` names it. | | 500 | `305` | The subscription isn't in status `1`, `4` or `7`. `status_additional_info` is the current status. | | 500 | `371` | No subscription has this `sub_payme_id`. | | 500 | Card error code | The card number, expiry or CVV is invalid, or the card check was declined: the response carries the card error code. | ## Parameters This endpoint takes no path, query or header parameters. ## Request body Content type: `application/json` | Field | Type | Required | Description | | --- | --- | --- | --- | | `sub_payme_id` | string | yes | The subscription (`sub_payme_id` from [Create a subscription](/payments/subscriptions/post-generate-subscription)). | | `seller_payme_id` | string | no | Not needed and not read by this call: `sub_payme_id` identifies the seller. | | `credit_card_number` | string | yes | Card number. | | `credit_card_exp` | string | yes | Card expiry, `MMYY`. | | `credit_card_cvv` | string | yes | Card CVV. | | `buyer_name` | string | yes | Card holder's full name. | | `buyer_email` | string | yes | Card holder's email. It replaces the subscription's buyer email. | | `buyer_phone` | string | no | Card holder's phone number. | | `buyer_social_id` | string | no | Card holder's national ID. | | `buyer_business_name` | string | no | The buyer's business name. Send it together with `buyer_business_code`. | | `buyer_business_code` | string | no | The buyer's business registration number. | | `payment` | object | no | The newer request shape: a `payment` object with `payment.method` and that method's fields. When you send it, the `credit_card_*`, `buyer_name` and `buyer_email` fields aren't required. | | `payment.method` | string | yes | Payment method, for example `credit-card`. | ### Request example ```json { "sub_payme_id": "SUB16885-68336QPL-UQSSS1CC-SYKXI53N", "credit_card_number": "5326105300985846", "credit_card_exp": "1230", "credit_card_cvv": "658", "buyer_name": "Israel Israeli", "buyer_email": "buyer@example.com" } ``` ## Code samples ### curl ```bash curl -X POST 'https://sandbox.payme.io/api/pay-subscription' \ -H 'Content-Type: application/json' \ --data-raw '{ "sub_payme_id": "SUB16885-68336QPL-UQSSS1CC-SYKXI53N", "credit_card_number": "5326105300985846", "credit_card_exp": "1230", "credit_card_cvv": "658", "buyer_name": "Israel Israeli", "buyer_email": "buyer@example.com" }' ``` ### Node.js ```javascript const response = await fetch("https://sandbox.payme.io/api/pay-subscription", { method: "POST", headers: { "Content-Type": "application/json", }, body: JSON.stringify({ "sub_payme_id": "SUB16885-68336QPL-UQSSS1CC-SYKXI53N", "credit_card_number": "5326105300985846", "credit_card_exp": "1230", "credit_card_cvv": "658", "buyer_name": "Israel Israeli", "buyer_email": "buyer@example.com" }), }); console.log(await response.text()); ``` ### Python ```python import requests response = requests.post( "https://sandbox.payme.io/api/pay-subscription", json={ "sub_payme_id": "SUB16885-68336QPL-UQSSS1CC-SYKXI53N", "credit_card_number": "5326105300985846", "credit_card_exp": "1230", "credit_card_cvv": "658", "buyer_name": "Israel Israeli", "buyer_email": "buyer@example.com", }, ) print(response.text) ``` ### PHP ```php '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 card was attached and the subscription is active. (success) | Field | Type | Description | | --- | --- | --- | | `status_code` | integer | `0` on success. | | `payme_status` | string | `success`. | | `status_error_code` | integer | `0` on success. | | `seller_payme_id` | string | The seller's MPL. | | `seller_id` | string | The partner's own reference for the seller, if the partner set one. Otherwise `null`. | | `sub_payme_id` | string | PayMe's subscription ID (`SUB…`). Use it in every other subscription call. | | `sub_payme_code` | integer | PayMe's numeric subscription ID. | | `subscription_id` | string | Your own reference, as sent when the subscription was created. `null` if you didn't send one. | | `sub_created` | string | When the subscription was created, `YYYY-MM-DD HH:MM:SS`. | | `sub_start_date` | string | Date of the first charge, `YYYY-MM-DD HH:MM:SS`. | | `sub_prev_date` | string | When the last successful charge ran. `null` until the first charge. | | `sub_next_date` | string | When the next charge is due. Ignore it on a canceled or completed subscription. | | `sub_status` | integer | Current status. See [Subscription statuses](/payments/codes-statuses/subscription-statuses). | | `sub_iteration_type` | integer | Billing interval. See [Subscription iteration types](/payments/codes-statuses/subscription-iteration-types). | | `sub_currency` | string | ISO 4217 currency code, e.g. `ILS`. | | `sub_price` | integer | Price of one iteration, in minor units (`5000` = 50.00). | | `sub_description` | string | What the buyer is paying for. | | `sub_iterations` | integer | Total number of iterations. `-1` means unlimited. | | `sub_iterations_completed` | integer | Iterations charged successfully. | | `sub_iterations_skipped` | integer | Iterations skipped while the subscription was paused. They are never charged. | | `sub_iterations_left` | integer | `sub_iterations` minus completed and skipped iterations. `-1` when unlimited. | | `sub_paid` | boolean | `true` once a card (buyer token) is attached to the subscription. It does not mean the current iteration was charged. | | `sub_error_text` | string | The last failure, pause or cancel reason. `null` if there is none. Reasons that PayMe writes are in Hebrew. | | `sub_payment_date` | string | Returned only when a card is attached: when the card was attached. | | `buyer_card_mask` | string | Returned only when a card is attached: the masked card number. | | `buyer_card_exp` | string | Returned only when a card is attached: card expiry, `MMYY`. | | `buyer_name` | string | Returned only when a card is attached: the card holder's name. | | `buyer_email` | string | Returned only when a card is attached: the card holder's email. | | `buyer_phone` | string | Returned only when a card is attached: the card holder's phone, or `null`. | | `buyer_social_id` | string | Returned only when a card is attached: the card holder's national ID, or `null`. | | `redirect_url` | string | `sub_return_url` with `payme_status`, `payme_signature`, `sub_payme_id`, `subscription_id`, `transaction_id`, `price`, `currency` and `is_foreign_card` added. `null` if the subscription has no return URL. | ```json { "status_code": 0, "payme_status": "success", "status_error_code": 0, "seller_payme_id": "MPLDEMO-MPLDEMO-MPLDEMO-1234567", "seller_id": null, "sub_payme_id": "SUB16885-68336QPL-UQSSS1CC-SYKXI53N", "sub_payme_code": 477004, "subscription_id": "order-1001", "sub_created": "2026-11-09 10:15:00", "sub_start_date": "2026-12-01 00:00:00", "sub_prev_date": null, "sub_next_date": "2026-12-01 00:00:00", "sub_status": 2, "sub_iteration_type": 3, "sub_currency": "ILS", "sub_price": 5000, "sub_description": "Monthly plan", "sub_iterations": 12, "sub_iterations_completed": 0, "sub_iterations_skipped": 0, "sub_iterations_left": 12, "sub_paid": true, "sub_error_text": null, "sub_payment_date": "2026-11-09 10:20:00", "buyer_card_mask": "532610******5846", "buyer_card_exp": "1230", "buyer_name": "Israel Israeli", "buyer_email": "buyer@example.com", "buyer_phone": null, "buyer_social_id": null, "redirect_url": "https://www.example.com/payment/success?payme_status=success&payme_signature=…&sub_payme_id=SUB16885-68336QPL-UQSSS1CC-SYKXI53N" } ``` ### 500 — The request was refused or the card check failed. See the error table. (error) | Field | Type | Description | | --- | --- | --- | | `status_code` | integer | `1` on failure. | | `status_error_details` | string | What went wrong, in the language you asked for (Hebrew by default). | | `status_additional_info` | string | The field or value concerned. Can be `null`. | | `status_error_code` | integer | PayMe error code. See the error table above and [Errors](/payments/getting-started/errors). | | `session` | string | PayMe session ID. Quote it when you contact support. | ```json { "status_code": 1, "status_error_details": "Required parameter is missing", "status_additional_info": "sub_payme_id", "status_error_code": 1, "session": "FhT3aXe7" } ``` - [Cancel a subscription](https://docs.payme.io/payments/subscriptions/postcancel-subscription): POST /cancel-subscription — Cancel a subscription # Cancel a subscription - Sandbox: `POST https://sandbox.payme.io/api/cancel-subscription` - Production: `POST https://live.payme.io/api/cancel-subscription` ## Credentials - Request body field `seller_payme_id` (required): The seller's MPL. You can send it in the `PayMe-Merchant-Key` header instead. - Request body field `payme_client_key` (optional): Partners only: your partner key. You can send it in the `PayMe-Partner-Key` header instead. A seller authenticates with `seller_payme_id` alone. ## Overview Cancels a subscription. No further charges run, `sub_status` becomes `5` (Canceled), and PayMe sends `sub-cancel` to the subscription's callback URL and emails the buyer. No call reactivates a canceled subscription. - You can cancel a subscription in status `1`, `2`, `4` or `7`. A paused subscription (status `3`) returns error `305`: [resume a subscription](/payments/subscriptions/patch-subscriptions-sub-payme-id-resume) first, then cancel it. - A cancellation through this endpoint keeps the old `sub_next_date`. Ignore `sub_next_date` on a canceled subscription. - Buyers have no self-service cancel link: the seller cancels, here or in the dashboard. - PayMe also cancels a subscription automatically after the last failed charge attempt. See [Saved cards & recurring](/payments/saved-cards-recurring). ## Authentication Send `seller_payme_id` (the seller's MPL) in the JSON body or the `PayMe-Merchant-Key` header. Partners also send `payme_client_key`, in the body or the `PayMe-Partner-Key` header. The subscription must belong to the seller (error `370`). ## Errors Errors return `status_code` `1` with HTTP 500 unless the table says otherwise. | HTTP | Code | When | |---|---|---| | 500 | `1` | A required field is missing, or no credential was sent. `status_additional_info` names the field. | | 500 | `251` | The `seller_payme_id` matches no seller. | | 500 | `370` | The subscription belongs to another seller. | | 500 | `371` | No subscription has this `sub_payme_id`. | | 500 | `305` | The subscription isn't in status `1`, `2`, `4` or `7`, for example it is paused. | ## 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. You can send it in the `PayMe-Merchant-Key` header instead. | | `payme_client_key` | string | no | Partners only: your partner key. You can send it in the `PayMe-Partner-Key` header instead. A seller authenticates with `seller_payme_id` alone. | | `sub_payme_id` | string | yes | The subscription (`sub_payme_id` from [Create a subscription](/payments/subscriptions/post-generate-subscription)). | | `language` | string | no | Language of error messages: `he` (default), `en`, `es`, `ru` or `ar`. | ### Request example ```json { "seller_payme_id": "MPLDEMO-MPLDEMO-MPLDEMO-1234567", "sub_payme_id": "SUB16885-68336QPL-UQSSS1CC-SYKXI53N", "language": "en" } ``` ## Code samples ### curl ```bash curl -X POST 'https://sandbox.payme.io/api/cancel-subscription' \ -H 'Content-Type: application/json' \ --data-raw '{ "seller_payme_id": "MPLDEMO-MPLDEMO-MPLDEMO-1234567", "sub_payme_id": "SUB16885-68336QPL-UQSSS1CC-SYKXI53N", "language": "en" }' ``` ### Node.js ```javascript const response = await fetch("https://sandbox.payme.io/api/cancel-subscription", { method: "POST", headers: { "Content-Type": "application/json", }, body: JSON.stringify({ "seller_payme_id": "MPLDEMO-MPLDEMO-MPLDEMO-1234567", "sub_payme_id": "SUB16885-68336QPL-UQSSS1CC-SYKXI53N", "language": "en" }), }); console.log(await response.text()); ``` ### Python ```python import requests response = requests.post( "https://sandbox.payme.io/api/cancel-subscription", json={ "seller_payme_id": "MPLDEMO-MPLDEMO-MPLDEMO-1234567", "sub_payme_id": "SUB16885-68336QPL-UQSSS1CC-SYKXI53N", "language": "en", }, ) print(response.text) ``` ### PHP ```php '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 subscription was canceled. (success) | Field | Type | Description | | --- | --- | --- | | `status_code` | integer | `0` on success. | | `payme_status` | string | `success`. | | `status_error_code` | integer | `0` on success. | | `seller_payme_id` | string | The seller's MPL. | | `seller_id` | string | The partner's own reference for the seller, if the partner set one. Otherwise `null`. | | `sub_payme_id` | string | PayMe's subscription ID (`SUB…`). Use it in every other subscription call. | | `sub_payme_code` | integer | PayMe's numeric subscription ID. | | `subscription_id` | string | Your own reference, as sent when the subscription was created. `null` if you didn't send one. | | `sub_created` | string | When the subscription was created, `YYYY-MM-DD HH:MM:SS`. | | `sub_start_date` | string | Date of the first charge, `YYYY-MM-DD HH:MM:SS`. | | `sub_prev_date` | string | When the last successful charge ran. `null` until the first charge. | | `sub_next_date` | string | When the next charge is due. Ignore it on a canceled or completed subscription. | | `sub_status` | integer | Current status. See [Subscription statuses](/payments/codes-statuses/subscription-statuses). | | `sub_iteration_type` | integer | Billing interval. See [Subscription iteration types](/payments/codes-statuses/subscription-iteration-types). | | `sub_currency` | string | ISO 4217 currency code, e.g. `ILS`. | | `sub_price` | integer | Price of one iteration, in minor units (`5000` = 50.00). | | `sub_description` | string | What the buyer is paying for. | | `sub_iterations` | integer | Total number of iterations. `-1` means unlimited. | | `sub_iterations_completed` | integer | Iterations charged successfully. | | `sub_iterations_skipped` | integer | Iterations skipped while the subscription was paused. They are never charged. | | `sub_iterations_left` | integer | `sub_iterations` minus completed and skipped iterations. `-1` when unlimited. | | `sub_paid` | boolean | `true` once a card (buyer token) is attached to the subscription. It does not mean the current iteration was charged. | | `sub_error_text` | string | The last failure, pause or cancel reason. `null` if there is none. Reasons that PayMe writes are in Hebrew. | | `sub_payment_date` | string | Returned only when a card is attached: when the card was attached. | | `buyer_card_mask` | string | Returned only when a card is attached: the masked card number. | | `buyer_card_exp` | string | Returned only when a card is attached: card expiry, `MMYY`. | | `buyer_name` | string | Returned only when a card is attached: the card holder's name. | | `buyer_email` | string | Returned only when a card is attached: the card holder's email. | | `buyer_phone` | string | Returned only when a card is attached: the card holder's phone, or `null`. | | `buyer_social_id` | string | Returned only when a card is attached: the card holder's national ID, or `null`. | ```json { "status_code": 0, "payme_status": "success", "status_error_code": 0, "seller_payme_id": "MPLDEMO-MPLDEMO-MPLDEMO-1234567", "seller_id": null, "sub_payme_id": "SUB16885-68336QPL-UQSSS1CC-SYKXI53N", "sub_payme_code": 477004, "subscription_id": "order-1001", "sub_created": "2026-11-09 10:15:00", "sub_start_date": "2026-12-01 00:00:00", "sub_prev_date": null, "sub_next_date": "2026-12-01 00:00:00", "sub_status": 5, "sub_iteration_type": 3, "sub_currency": "ILS", "sub_price": 5000, "sub_description": "Monthly plan", "sub_iterations": 12, "sub_iterations_completed": 0, "sub_iterations_skipped": 0, "sub_iterations_left": 12, "sub_paid": true, "sub_error_text": "בוטל על ידי המשתמש בתאריך 09/11/2026 10:30:00", "sub_payment_date": "2026-11-09 10:20:00", "buyer_card_mask": "532610******5846", "buyer_card_exp": "1230", "buyer_name": "Israel Israeli", "buyer_email": "buyer@example.com", "buyer_phone": null, "buyer_social_id": null } ``` ### 500 — The request was refused. See the error table. (error) | Field | Type | Description | | --- | --- | --- | | `status_code` | integer | `1` on failure. | | `status_error_details` | string | What went wrong, in the language you asked for (Hebrew by default). | | `status_additional_info` | string | The field or value concerned. Can be `null`. | | `status_error_code` | integer | PayMe error code. See the error table above and [Errors](/payments/getting-started/errors). | | `session` | string | PayMe session ID. Quote it when you contact support. | ```json { "status_code": 1, "status_error_details": "Cannot perform action due to an incorrect status", "status_additional_info": null, "status_error_code": 305, "session": "FhT3aXe7" } ``` - [Pause a subscription](https://docs.payme.io/payments/subscriptions/post-pause-subscription): POST /pause-subscription — Pause a subscription # Pause a subscription - Sandbox: `POST https://sandbox.payme.io/api/pause-subscription` - Production: `POST https://live.payme.io/api/pause-subscription` ## Credentials - Request body field `seller_payme_id` (required): The seller's MPL. You can send it in the `PayMe-Merchant-Key` header instead. - Request body field `payme_client_key` (optional): Partners only: your partner key. You can send it in the `PayMe-Partner-Key` header instead. A seller authenticates with `seller_payme_id` alone. ## Overview Pauses a subscription in status `2` (Active), `4` (Failed) or `7` (Failed, retry pending). Other statuses return error `305`. PayMe sends a `sub-pause` callback, and `sub_error_text` holds the pause reason that PayMe writes (in Hebrew). While the subscription is paused, nothing is charged. Each iteration whose date passes is skipped: it counts in `sub_iterations_skipped`, reduces `sub_iterations_left` and sends `sub-iteration-skipped`. Skipped iterations aren't charged after you resume. If every remaining iteration is skipped, the subscription becomes `6` (Completed) while paused. Resume with [Resume a subscription](/payments/subscriptions/patch-subscriptions-sub-payme-id-resume). A paused subscription can't be canceled: resume it first. A subscription in status `4` has no working card. To fix it, have the buyer pay again with [Pay a subscription](/payments/subscriptions/post-generate-subscription-2) rather than pausing and resuming it. ## Authentication Send `seller_payme_id` (the seller's MPL) in the JSON body or the `PayMe-Merchant-Key` header. Partners also send `payme_client_key`, in the body or the `PayMe-Partner-Key` header. The subscription must belong to the seller (error `370`). ## Errors Errors return `status_code` `1` with HTTP 500 unless the table says otherwise. | HTTP | Code | When | |---|---|---| | 500 | `1` | A required field is missing, or no credential was sent. `status_additional_info` names the field. | | 500 | `251` | The `seller_payme_id` matches no seller. | | 500 | `370` | The subscription belongs to another seller. | | 500 | `371` | No subscription has this `sub_payme_id`. | | 500 | `305` | The subscription isn't in status `2`, `4` or `7`. | ## 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. You can send it in the `PayMe-Merchant-Key` header instead. | | `payme_client_key` | string | no | Partners only: your partner key. You can send it in the `PayMe-Partner-Key` header instead. A seller authenticates with `seller_payme_id` alone. | | `sub_payme_id` | string | yes | The subscription to pause (`sub_payme_id` from [Create a subscription](/payments/subscriptions/post-generate-subscription)). | | `language` | string | no | Language of error messages: `he` (default), `en`, `es`, `ru` or `ar`. | ### Request example ```json { "seller_payme_id": "MPLDEMO-MPLDEMO-MPLDEMO-1234567", "sub_payme_id": "SUB16885-68336QPL-UQSSS1CC-SYKXI53N" } ``` ## Code samples ### curl ```bash curl -X POST 'https://sandbox.payme.io/api/pause-subscription' \ -H 'Content-Type: application/json' \ --data-raw '{ "seller_payme_id": "MPLDEMO-MPLDEMO-MPLDEMO-1234567", "sub_payme_id": "SUB16885-68336QPL-UQSSS1CC-SYKXI53N" }' ``` ### Node.js ```javascript const response = await fetch("https://sandbox.payme.io/api/pause-subscription", { method: "POST", headers: { "Content-Type": "application/json", }, body: JSON.stringify({ "seller_payme_id": "MPLDEMO-MPLDEMO-MPLDEMO-1234567", "sub_payme_id": "SUB16885-68336QPL-UQSSS1CC-SYKXI53N" }), }); console.log(await response.text()); ``` ### Python ```python import requests response = requests.post( "https://sandbox.payme.io/api/pause-subscription", json={ "seller_payme_id": "MPLDEMO-MPLDEMO-MPLDEMO-1234567", "sub_payme_id": "SUB16885-68336QPL-UQSSS1CC-SYKXI53N", }, ) print(response.text) ``` ### PHP ```php '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 subscription is paused. (success) | Field | Type | Description | | --- | --- | --- | | `status_code` | integer | `0` on success. | | `payme_status` | string | `success`. | | `status_error_code` | integer | `0` on success. | | `seller_payme_id` | string | The seller's MPL. | | `seller_id` | string | The partner's own reference for the seller, if the partner set one. Otherwise `null`. | | `sub_payme_id` | string | PayMe's subscription ID (`SUB…`). Use it in every other subscription call. | | `sub_payme_code` | integer | PayMe's numeric subscription ID. | | `subscription_id` | string | Your own reference, as sent when the subscription was created. `null` if you didn't send one. | | `sub_created` | string | When the subscription was created, `YYYY-MM-DD HH:MM:SS`. | | `sub_start_date` | string | Date of the first charge, `YYYY-MM-DD HH:MM:SS`. | | `sub_prev_date` | string | When the last successful charge ran. `null` until the first charge. | | `sub_next_date` | string | When the next charge is due. Ignore it on a canceled or completed subscription. | | `sub_status` | integer | Current status. See [Subscription statuses](/payments/codes-statuses/subscription-statuses). | | `sub_iteration_type` | integer | Billing interval. See [Subscription iteration types](/payments/codes-statuses/subscription-iteration-types). | | `sub_currency` | string | ISO 4217 currency code, e.g. `ILS`. | | `sub_price` | integer | Price of one iteration, in minor units (`5000` = 50.00). | | `sub_description` | string | What the buyer is paying for. | | `sub_iterations` | integer | Total number of iterations. `-1` means unlimited. | | `sub_iterations_completed` | integer | Iterations charged successfully. | | `sub_iterations_skipped` | integer | Iterations skipped while the subscription was paused. They are never charged. | | `sub_iterations_left` | integer | `sub_iterations` minus completed and skipped iterations. `-1` when unlimited. | | `sub_paid` | boolean | `true` once a card (buyer token) is attached to the subscription. It does not mean the current iteration was charged. | | `sub_error_text` | string | The last failure, pause or cancel reason. `null` if there is none. Reasons that PayMe writes are in Hebrew. | | `sub_payment_date` | string | Returned only when a card is attached: when the card was attached. | | `buyer_card_mask` | string | Returned only when a card is attached: the masked card number. | | `buyer_card_exp` | string | Returned only when a card is attached: card expiry, `MMYY`. | | `buyer_name` | string | Returned only when a card is attached: the card holder's name. | | `buyer_email` | string | Returned only when a card is attached: the card holder's email. | | `buyer_phone` | string | Returned only when a card is attached: the card holder's phone, or `null`. | | `buyer_social_id` | string | Returned only when a card is attached: the card holder's national ID, or `null`. | ```json { "status_code": 0, "payme_status": "success", "status_error_code": 0, "seller_payme_id": "MPLDEMO-MPLDEMO-MPLDEMO-1234567", "seller_id": null, "sub_payme_id": "SUB16885-68336QPL-UQSSS1CC-SYKXI53N", "sub_payme_code": 477004, "subscription_id": "order-1001", "sub_created": "2026-11-09 10:15:00", "sub_start_date": "2026-12-01 00:00:00", "sub_prev_date": null, "sub_next_date": "2026-12-01 00:00:00", "sub_status": 3, "sub_iteration_type": 3, "sub_currency": "ILS", "sub_price": 5000, "sub_description": "Monthly plan", "sub_iterations": 12, "sub_iterations_completed": 0, "sub_iterations_skipped": 0, "sub_iterations_left": 12, "sub_paid": true, "sub_error_text": "הושהה על ידי המשתמש בתאריך 09/11/2026 10:30:00", "sub_payment_date": "2026-11-09 10:20:00", "buyer_card_mask": "532610******5846", "buyer_card_exp": "1230", "buyer_name": "Israel Israeli", "buyer_email": "buyer@example.com", "buyer_phone": null, "buyer_social_id": null } ``` ### 500 — The request was refused. See the error table. (error) | Field | Type | Description | | --- | --- | --- | | `status_code` | integer | `1` on failure. | | `status_error_details` | string | What went wrong, in the language you asked for (Hebrew by default). | | `status_additional_info` | string | The field or value concerned. Can be `null`. | | `status_error_code` | integer | PayMe error code. See the error table above and [Errors](/payments/getting-started/errors). | | `session` | string | PayMe session ID. Quote it when you contact support. | ```json { "status_code": 1, "status_error_details": "Required parameter is missing", "status_additional_info": "sub_payme_id", "status_error_code": 1, "session": "FhT3aXe7" } ``` - [Resume a subscription](https://docs.payme.io/payments/subscriptions/patch-subscriptions-sub-payme-id-resume): PATCH /subscriptions/{sub_payme_id}/resume — Resume a subscription # Resume a subscription - Sandbox: `PATCH https://sandbox.payme.io/api/subscriptions/{sub_payme_id}/resume` - Production: `PATCH https://live.payme.io/api/subscriptions/{sub_payme_id}/resume` ## Credentials - Header `PayMe-Merchant-Key` (API key) - Request body field `seller_payme_id` (optional): The seller's MPL, instead of the `PayMe-Merchant-Key` header. - Request body field `payme_client_key` (optional): Partners only: your partner key, instead of the `PayMe-Partner-Key` header. ## Overview Resumes a paused subscription (status `3`) and sets it to status `2` (Active). No callback is sent. Iterations skipped while the subscription was paused aren't charged; the next charge runs at `sub_next_date`. Example: `PATCH https://sandbox.payme.io/api/subscriptions/SUB16885-68336QPL-UQSSS1CC-SYKXI53N/resume` with the header `PayMe-Merchant-Key: MPLDEMO-MPLDEMO-MPLDEMO-1234567`. ## Authentication Send the seller's MPL in the `PayMe-Merchant-Key` header, or as `seller_payme_id` in a JSON body. Partners also send `payme_client_key`, in the body or the `PayMe-Partner-Key` header. The subscription must belong to the seller (error `370`). ## Errors Errors return `status_code` `1` with HTTP 500 unless the table says otherwise. | HTTP | Code | When | |---|---|---| | 500 | `1` | A required field is missing, or no credential was sent. `status_additional_info` names the field. | | 500 | `251` | The `seller_payme_id` matches no seller. | | 500 | `370` | The subscription belongs to another seller. | | 500 | `371` | No subscription has this `sub_payme_id`. | | 400 | `305` | The subscription isn't paused. `status_additional_info` gives its current status. | ## Parameters | Name | In | Type | Required | Description | | --- | --- | --- | --- | --- | | `PayMe-Merchant-Key` | header | string | yes | The seller's MPL. Or send it as `seller_payme_id` in a JSON body instead. | | `sub_payme_id` | path | string | yes | The subscription to resume (`sub_payme_id`, for example `SUB16885-68336QPL-UQSSS1CC-SYKXI53N`). | ## Request body Content type: `application/json` Optional. Use it instead of the headers. | Field | Type | Required | Description | | --- | --- | --- | --- | | `seller_payme_id` | string | no | The seller's MPL, instead of the `PayMe-Merchant-Key` header. | | `payme_client_key` | string | no | Partners only: your partner key, instead of the `PayMe-Partner-Key` header. | ### Request example No example is documented; this template is generated from the fields — replace the placeholder values. ```json { "seller_payme_id": "", "payme_client_key": "" } ``` ## Code samples ### curl ```bash curl -X PATCH 'https://sandbox.payme.io/api/subscriptions//resume' \ -H 'Content-Type: application/json' \ -H 'PayMe-Merchant-Key: ' \ --data-raw '{}' ``` ### Node.js ```javascript const response = await fetch("https://sandbox.payme.io/api/subscriptions//resume", { method: "PATCH", headers: { "Content-Type": "application/json", "PayMe-Merchant-Key": "", }, body: JSON.stringify({}), }); console.log(await response.text()); ``` ### Python ```python import requests response = requests.patch( "https://sandbox.payme.io/api/subscriptions//resume", headers={ "PayMe-Merchant-Key": "", }, json={}, ) print(response.text) ``` ### PHP ```php /resume'); curl_setopt_array($ch, [ CURLOPT_CUSTOMREQUEST => 'PATCH', CURLOPT_RETURNTRANSFER => true, CURLOPT_HTTPHEADER => [ 'Content-Type: application/json', 'PayMe-Merchant-Key: ', ], CURLOPT_POSTFIELDS => $body, ]); $response = curl_exec($ch); curl_close($ch); echo $response; ``` ## Responses ### 200 — The subscription is active again. (success) | Field | Type | Description | | --- | --- | --- | | `status_code` | integer | `0` on success. | | `payme_status` | string | `success`. | | `status_error_code` | integer | `0` on success. | | `seller_payme_id` | string | The seller's MPL. | | `seller_id` | string | The partner's own reference for the seller, if the partner set one. Otherwise `null`. | | `sub_payme_id` | string | PayMe's subscription ID (`SUB…`). Use it in every other subscription call. | | `sub_payme_code` | integer | PayMe's numeric subscription ID. | | `subscription_id` | string | Your own reference, as sent when the subscription was created. `null` if you didn't send one. | | `sub_created` | string | When the subscription was created, `YYYY-MM-DD HH:MM:SS`. | | `sub_start_date` | string | Date of the first charge, `YYYY-MM-DD HH:MM:SS`. | | `sub_prev_date` | string | When the last successful charge ran. `null` until the first charge. | | `sub_next_date` | string | When the next charge is due. Ignore it on a canceled or completed subscription. | | `sub_status` | integer | Current status. See [Subscription statuses](/payments/codes-statuses/subscription-statuses). | | `sub_iteration_type` | integer | Billing interval. See [Subscription iteration types](/payments/codes-statuses/subscription-iteration-types). | | `sub_currency` | string | ISO 4217 currency code, e.g. `ILS`. | | `sub_price` | integer | Price of one iteration, in minor units (`5000` = 50.00). | | `sub_description` | string | What the buyer is paying for. | | `sub_iterations` | integer | Total number of iterations. `-1` means unlimited. | | `sub_iterations_completed` | integer | Iterations charged successfully. | | `sub_iterations_skipped` | integer | Iterations skipped while the subscription was paused. They are never charged. | | `sub_iterations_left` | integer | `sub_iterations` minus completed and skipped iterations. `-1` when unlimited. | | `sub_paid` | boolean | `true` once a card (buyer token) is attached to the subscription. It does not mean the current iteration was charged. | | `sub_error_text` | string | The last failure, pause or cancel reason. `null` if there is none. Reasons that PayMe writes are in Hebrew. | | `sub_payment_date` | string | Returned only when a card is attached: when the card was attached. | | `buyer_card_mask` | string | Returned only when a card is attached: the masked card number. | | `buyer_card_exp` | string | Returned only when a card is attached: card expiry, `MMYY`. | | `buyer_name` | string | Returned only when a card is attached: the card holder's name. | | `buyer_email` | string | Returned only when a card is attached: the card holder's email. | | `buyer_phone` | string | Returned only when a card is attached: the card holder's phone, or `null`. | | `buyer_social_id` | string | Returned only when a card is attached: the card holder's national ID, or `null`. | ```json { "status_code": 0, "payme_status": "success", "status_error_code": 0, "seller_payme_id": "MPLDEMO-MPLDEMO-MPLDEMO-1234567", "seller_id": null, "sub_payme_id": "SUB16885-68336QPL-UQSSS1CC-SYKXI53N", "sub_payme_code": 477004, "subscription_id": "order-1001", "sub_created": "2026-11-09 10:15:00", "sub_start_date": "2026-12-01 00:00:00", "sub_prev_date": null, "sub_next_date": "2026-12-01 00:00:00", "sub_status": 2, "sub_iteration_type": 3, "sub_currency": "ILS", "sub_price": 5000, "sub_description": "Monthly plan", "sub_iterations": 12, "sub_iterations_completed": 0, "sub_iterations_skipped": 0, "sub_iterations_left": 12, "sub_paid": true, "sub_error_text": "הושהה על ידי המשתמש בתאריך 09/11/2026 10:30:00", "sub_payment_date": "2026-11-09 10:20:00", "buyer_card_mask": "532610******5846", "buyer_card_exp": "1230", "buyer_name": "Israel Israeli", "buyer_email": "buyer@example.com", "buyer_phone": null, "buyer_social_id": null } ``` ### 400 — The subscription isn't paused (`305`). (error) | Field | Type | Description | | --- | --- | --- | | `status_code` | integer | `1` on failure. | | `status_error_details` | string | What went wrong, in the language you asked for (Hebrew by default). | | `status_additional_info` | string | The field or value concerned. Can be `null`. | | `status_error_code` | integer | PayMe error code. See the error table above and [Errors](/payments/getting-started/errors). | | `session` | string | PayMe session ID. Quote it when you contact support. | ```json { "status_code": 1, "status_error_details": "Cannot perform action due to an incorrect status", "status_additional_info": "Subscription status: active", "status_error_code": 305, "session": "FhT3aXe7" } ``` ### 500 — The request was refused. See the error table. (error) | Field | Type | Description | | --- | --- | --- | | `status_code` | integer | `1` on failure. | | `status_error_details` | string | What went wrong, in the language you asked for (Hebrew by default). | | `status_additional_info` | string | The field or value concerned. Can be `null`. | | `status_error_code` | integer | PayMe error code. See the error table above and [Errors](/payments/getting-started/errors). | | `session` | string | PayMe session ID. Quote it when you contact support. | ```json { "status_code": 1, "status_error_details": "Subscription was not found", "status_additional_info": null, "status_error_code": 371, "session": "FhT3aXe7" } ``` - [Update a subscription's price](https://docs.payme.io/payments/subscriptions/patch-subscriptions-sub-id-set-price): PATCH /subscriptions/{sub_payme_id}/set-price — Update a subscription's price # Update a subscription's price - Sandbox: `PATCH https://sandbox.payme.io/api/subscriptions/{sub_payme_id}/set-price` - Production: `PATCH https://live.payme.io/api/subscriptions/{sub_payme_id}/set-price` ## Credentials - Request body field `seller_payme_id` (required): The seller's MPL. You can send it in the `PayMe-Merchant-Key` header instead. - Request body field `payme_client_key` (optional): Partners only: your partner key. You can send it in the `PayMe-Partner-Key` header instead. A seller authenticates with `seller_payme_id` alone. ## Overview Changes the price of future iterations. The call charges nothing and doesn't change `sub_next_date`, `sub_start_date`, `sub_prev_date`, the iteration counters or the status. The billing day stays anchored to `sub_start_date`. You can update: - an active subscription (status `2`); - a template (`sub_type` `10`) in status `1`: buyers who pay the link after the change get the new price, and subscriptions already created from it keep theirs; - a subscription in status `1` whose `sub_start_date` is still in the future. Any other subscription returns error `377` (HTTP 400). If the price changed and the subscription has a buyer email, PayMe emails the buyer about the new price, subject to the seller's email settings. There is no proration: for a mid-cycle upgrade, charge the difference once with `generate-sale` and the subscription's `buyer_key`, then call this endpoint. Don't cancel and re-create the subscription: that resets `sub_start_date` and the counters. Example: `PATCH https://sandbox.payme.io/api/subscriptions/SUB16885-68336QPL-UQSSS1CC-SYKXI53N/set-price`. More: [Saved cards & recurring](/payments/saved-cards-recurring). ## Authentication Send `seller_payme_id` (the seller's MPL) in the JSON body or the `PayMe-Merchant-Key` header. Partners also send `payme_client_key`, in the body or the `PayMe-Partner-Key` header. The subscription must belong to the seller (error `370`). ## Errors Errors return `status_code` `1` with HTTP 500 unless the table says otherwise. | HTTP | Code | When | |---|---|---| | 500 | `1` | A required field is missing, or no credential was sent. `status_additional_info` names the field. | | 500 | `251` | The `seller_payme_id` matches no seller. | | 500 | `370` | The subscription belongs to another seller. | | 500 | `371` | No subscription has this `sub_payme_id`. | | 500 | `352` | `sub_price` is outside your account's range. | | 400 | `377` | This subscription's price can't be updated in its current status or type. | ## Parameters | Name | In | Type | Required | Description | | --- | --- | --- | --- | --- | | `sub_payme_id` | path | string | yes | The subscription to update: its `sub_payme_id`, returned by [Create a subscription](/payments/subscriptions/post-generate-subscription). Your own `subscription_id` doesn't work here (error `371`). | ## Request body Content type: `application/json` | Field | Type | Required | Description | | --- | --- | --- | --- | | `seller_payme_id` | string | yes | The seller's MPL. You can send it in the `PayMe-Merchant-Key` header instead. | | `payme_client_key` | string | no | Partners only: your partner key. You can send it in the `PayMe-Partner-Key` header instead. A seller authenticates with `seller_payme_id` alone. | | `sub_price` | integer | yes | New price of one iteration, in minor units (`5075` = 50.75). Default range 500–4,000,000; your account may have different limits (error `352`). | ### Request example ```json { "seller_payme_id": "MPLDEMO-MPLDEMO-MPLDEMO-1234567", "sub_price": 7500 } ``` ## Code samples ### curl ```bash curl -X PATCH 'https://sandbox.payme.io/api/subscriptions//set-price' \ -H 'Content-Type: application/json' \ --data-raw '{ "seller_payme_id": "MPLDEMO-MPLDEMO-MPLDEMO-1234567", "sub_price": 7500 }' ``` ### Node.js ```javascript const response = await fetch("https://sandbox.payme.io/api/subscriptions//set-price", { method: "PATCH", headers: { "Content-Type": "application/json", }, body: JSON.stringify({ "seller_payme_id": "MPLDEMO-MPLDEMO-MPLDEMO-1234567", "sub_price": 7500 }), }); console.log(await response.text()); ``` ### Python ```python import requests response = requests.patch( "https://sandbox.payme.io/api/subscriptions//set-price", json={ "seller_payme_id": "MPLDEMO-MPLDEMO-MPLDEMO-1234567", "sub_price": 7500, }, ) print(response.text) ``` ### PHP ```php /set-price'); curl_setopt_array($ch, [ CURLOPT_CUSTOMREQUEST => 'PATCH', CURLOPT_RETURNTRANSFER => true, CURLOPT_HTTPHEADER => [ 'Content-Type: application/json', ], CURLOPT_POSTFIELDS => $body, ]); $response = curl_exec($ch); curl_close($ch); echo $response; ``` ## Responses ### 200 — The price was updated, or was already this value. (success) | Field | Type | Description | | --- | --- | --- | | `status_code` | integer | `0` on success. | | `payme_status` | string | `success`. | | `status_error_code` | integer | `0` on success. | | `seller_payme_id` | string | The seller's MPL. | | `seller_id` | string | The partner's own reference for the seller, if the partner set one. Otherwise `null`. | | `sub_payme_id` | string | PayMe's subscription ID (`SUB…`). Use it in every other subscription call. | | `sub_payme_code` | integer | PayMe's numeric subscription ID. | | `subscription_id` | string | Your own reference, as sent when the subscription was created. `null` if you didn't send one. | | `sub_created` | string | When the subscription was created, `YYYY-MM-DD HH:MM:SS`. | | `sub_start_date` | string | Date of the first charge, `YYYY-MM-DD HH:MM:SS`. | | `sub_prev_date` | string | When the last successful charge ran. `null` until the first charge. | | `sub_next_date` | string | When the next charge is due. Ignore it on a canceled or completed subscription. | | `sub_status` | integer | Current status. See [Subscription statuses](/payments/codes-statuses/subscription-statuses). | | `sub_iteration_type` | integer | Billing interval. See [Subscription iteration types](/payments/codes-statuses/subscription-iteration-types). | | `sub_currency` | string | ISO 4217 currency code, e.g. `ILS`. | | `sub_price` | integer | Price of one iteration, in minor units (`5000` = 50.00). | | `sub_description` | string | What the buyer is paying for. | | `sub_iterations` | integer | Total number of iterations. `-1` means unlimited. | | `sub_iterations_completed` | integer | Iterations charged successfully. | | `sub_iterations_skipped` | integer | Iterations skipped while the subscription was paused. They are never charged. | | `sub_iterations_left` | integer | `sub_iterations` minus completed and skipped iterations. `-1` when unlimited. | | `sub_paid` | boolean | `true` once a card (buyer token) is attached to the subscription. It does not mean the current iteration was charged. | | `sub_error_text` | string | The last failure, pause or cancel reason. `null` if there is none. Reasons that PayMe writes are in Hebrew. | | `sub_payment_date` | string | Returned only when a card is attached: when the card was attached. | | `buyer_card_mask` | string | Returned only when a card is attached: the masked card number. | | `buyer_card_exp` | string | Returned only when a card is attached: card expiry, `MMYY`. | | `buyer_name` | string | Returned only when a card is attached: the card holder's name. | | `buyer_email` | string | Returned only when a card is attached: the card holder's email. | | `buyer_phone` | string | Returned only when a card is attached: the card holder's phone, or `null`. | | `buyer_social_id` | string | Returned only when a card is attached: the card holder's national ID, or `null`. | ```json { "status_code": 0, "payme_status": "success", "status_error_code": 0, "seller_payme_id": "MPLDEMO-MPLDEMO-MPLDEMO-1234567", "seller_id": null, "sub_payme_id": "SUB16885-68336QPL-UQSSS1CC-SYKXI53N", "sub_payme_code": 477004, "subscription_id": "order-1001", "sub_created": "2026-11-09 10:15:00", "sub_start_date": "2026-12-01 00:00:00", "sub_prev_date": null, "sub_next_date": "2026-12-01 00:00:00", "sub_status": 2, "sub_iteration_type": 3, "sub_currency": "ILS", "sub_price": 7500, "sub_description": "Monthly plan", "sub_iterations": 12, "sub_iterations_completed": 0, "sub_iterations_skipped": 0, "sub_iterations_left": 12, "sub_paid": true, "sub_error_text": null, "sub_payment_date": "2026-11-09 10:20:00", "buyer_card_mask": "532610******5846", "buyer_card_exp": "1230", "buyer_name": "Israel Israeli", "buyer_email": "buyer@example.com", "buyer_phone": null, "buyer_social_id": null } ``` ### 400 — The price can't be updated (`377`). (error) | Field | Type | Description | | --- | --- | --- | | `status_code` | integer | `1` on failure. | | `status_error_details` | string | What went wrong, in the language you asked for (Hebrew by default). | | `status_additional_info` | string | The field or value concerned. Can be `null`. | | `status_error_code` | integer | PayMe error code. See the error table above and [Errors](/payments/getting-started/errors). | | `session` | string | PayMe session ID. Quote it when you contact support. | ```json { "status_code": 1, "status_error_details": "Subscription update failed", "status_additional_info": "Subscription price can not be updated", "status_error_code": 377, "session": "FhT3aXe7" } ``` ### 500 — The request was refused. See the error table. (error) | Field | Type | Description | | --- | --- | --- | | `status_code` | integer | `1` on failure. | | `status_error_details` | string | What went wrong, in the language you asked for (Hebrew by default). | | `status_additional_info` | string | The field or value concerned. Can be `null`. | | `status_error_code` | integer | PayMe error code. See the error table above and [Errors](/payments/getting-started/errors). | | `session` | string | PayMe session ID. Quote it when you contact support. | ```json { "status_code": 1, "status_error_details": "Invalid price, out of min-max bounds", "status_additional_info": "100", "status_error_code": 352, "session": "FhT3aXe7" } ``` ## Invoices - [Create a document](https://docs.payme.io/payments/invoices/post-create-invoice): POST /documents — Create a document # Create a document - Sandbox: `POST https://sandbox.payme.io/api/documents` - Production: `POST https://live.payme.io/api/documents` ## Credentials - Header `PayMe-Merchant-Key` (optional): The seller's MPL, instead of `seller_payme_id` in the body. - Request body field `seller_payme_id` (required): The seller's MPL. You can send it in the `PayMe-Merchant-Key` header instead. - Request body field `payme_client_key` (optional): Partners only: your partner key, in the body or the `PayMe-Partner-Key` header. > ⚠️ **This API is deprecated** and is no longer recommended for use. For questions, contact partners@payme.io. ## Overview Creates an invoice, receipt or other tax document for the seller through PayMe's invoicing service. The seller's invoicing service must be active; otherwise every documents call returns error `703` (HTTP 403). Documents are created asynchronously: the response returns `doc_id` and `doc_url` at once, but the document may not be ready yet. While the document job is still running (its status is `waiting`, `active`, `delayed`, `paused` or `stuck`), [Get a document](/payments/invoices/show-generated-document-by-id) returns error `1005` with HTTP 400 and the status in `status_additional_info`, for example `status:waiting`. Wait a few seconds and call it again. If the seller still has to approve the connection to the Israel Tax Authority, the response holds only `authority_redirect_url` and no document is created. Send the seller to that URL to approve it, then call again. PayMe passes amounts, totals and `vat_rate` to the invoicing service as you send them. Don't send card numbers or CVVs: a document needs no card data. #### Document types The types you can create are listed on [Document types](/payments/codes-statuses/document-types). #### Documents issued automatically With the invoicing service active on the account, a paid sale issues a document and a refund (including a refund of a subscription charge) automatically issues a credit document. A refund never un-issues the original document; canceling a document takes a separate counter-document. To skip the automatic document for one API sale, send `"services": [{"name": "invoice", "settings": {"active": false}}]` on `generate-sale`. ## Authentication Name the seller with `seller_payme_id` in the body or the `PayMe-Merchant-Key` header. A partner may instead send `payme_client_key` (body or `PayMe-Partner-Key` header) with its own `seller_id`. With no credential at all, the call returns error `1` with `status_additional_info` `payme_client_key`. ### Errors | HTTP | Code | When | |---|---|---| | `400` | `20` | Validation failed. `status_additional_info` lists the messages per field. | | `400` | `1` | A partner key was sent, but no seller. `status_additional_info` is `seller_payme_id`. | | `400` | `20` | The seller doesn't belong to this partner. `status_additional_info` is `Merchant-Seller inconsistency`. | | `403` | `703` | The invoicing service isn't active for this seller. | | `500` | `1` | No credential was sent at all. `status_additional_info` is `payme_client_key`. | | `500` | `251` | The seller key is unknown. | | `500` | `163` | The seller isn't active. | | `500` | `200` | The partner key is unknown. | | `500` | `201` | The partner isn't active. | | `500` | `1001` | The invoicing service returned an error. `status_additional_info` carries its code and details. | | `503` | `1001` | The invoicing service didn't answer in time. | | `500` | `1004` | The invoicing service didn't create the document. | ## Parameters | Name | In | Type | Required | Description | | --- | --- | --- | --- | --- | | `PayMe-Merchant-Key` | header | string | no | The seller's MPL, instead of `seller_payme_id` in the body. | ## Request body Content type: `application/json` | Field | Type | Required | Description | | --- | --- | --- | --- | | `seller_payme_id` | string | yes | The seller's MPL. You can send it in the `PayMe-Merchant-Key` header instead. | | `payme_client_key` | string | no | Partners only: your partner key, in the body or the `PayMe-Partner-Key` header. | | `seller_id` | string | no | Partners only: your own reference for the seller, instead of `seller_payme_id`. Needs `payme_client_key`. | | `doc_type` | integer | yes | Document type: `100`, `200`, `300`, `305`, `320`, `330`, `400`, `405` or `600`. See [Document types](/payments/codes-statuses/document-types). | | `buyer_name` | string | yes | Buyer name printed on the document. | | `buyer_address` | string | no | Buyer address printed on the document. | | `buyer_social_id` | string | no | Buyer national ID or company number, printed as the buyer's tax ID. Default: `credit_card.buyer_social_id`. | | `currency` | string | no | ISO 4217 currency code of the document. | | `language` | string | no | Document language: `he` (default) or `en`. | | `doc_date` | string | no | Document date, for example `2026-11-09`. | | `due_date` | string | no | Payment due date. | | `pay_date` | string | no | Date the payment was made. | | `doc_title` | string | no | Title printed at the top of the document. | | `doc_comments` | string | no | Comments printed on the document. | | `exchange_rate` | number | no | Exchange rate used on the document. | | `vat_rate` | number | no | VAT rate applied to the document. | | `discount` | number | no | Discount applied to the document. | | `total_excluding_vat` | number | no | Total before VAT. | | `total_sum_after_discount` | number | no | Total after the discount. | | `total_sum_including_vat` | number | no | Total including VAT. | | `total_vat` | number | no | Total VAT. | | `total_paid` | number | no | Total paid on this document. | | `total_paid_including_vat` | number | no | Total paid, including VAT. | | `items` | array | yes | Document lines. At least one. | | `items[].description` | string | yes | Line description, at least 3 characters. | | `items[].unit_price` | number | no | Unit price before VAT. Send `unit_price` or `unit_price_with_vat`. | | `items[].unit_price_with_vat` | number | no | Unit price including VAT. | | `items[].quantity` | integer | no | Quantity. | | `items[].vat_exempt` | boolean | no | `true` if the line is exempt from VAT. | | `items[].currency` | string | no | ISO 4217 currency code of the line. | | `items[].exchange_rate` | number | no | Exchange rate of the line's currency. | | `cash` | object | no | Cash payment received. Send it only for cash that was actually paid. | | `cash.sum` | number | yes | Amount paid in cash. | | `cheques` | array | no | Cheques received. | | `cheques[].sum` | number | yes | Cheque amount. | | `cheques[].date` | string | yes | Cheque date. | | `cheques[].bank` | number | no | Bank code. See [Banks in Israel](/payments/codes-statuses/banks-in-israel). | | `cheques[].branch` | number | no | Branch number. | | `cheques[].account` | string | no | Account number, digits only. | | `cheques[].number` | string | no | Cheque number, digits only. | | `bank_transfer` | object | no | Bank transfer received. Send it only for a transfer that was actually made. | | `bank_transfer.sum` | number | yes | Amount transferred. | | `bank_transfer.date` | string | no | Date the transfer was received. | | `bank_transfer.account` | string | no | Account number, digits only. | | `paypal` | object | no | PayPal payment received. | | `paypal.sum` | number | yes | Amount paid with PayPal. | | `paypal.date` | string | yes | Payment date. | | `paypal.transaction_id` | string | yes | PayPal transaction ID. | | `paypal.buyer_name` | string | yes | Payer name. | | `credit_card` | object | no | Card payment received. Don't send the card number or CVV. | | `credit_card.sum` | number | yes | Amount paid by card. | | `credit_card.date` | string | no | Payment date. | | `credit_card.installments` | integer | no | Number of installments. | | `credit_card.first_payment` | number | no | Amount of the first installment. | | `credit_card.type` | string | no | Card brand, for example `Visa`. | | `credit_card.expiry` | string | no | Card expiry, exactly 4 characters `MMYY`. Must not be in the past. | | `credit_card.buyer_name` | string | no | Card holder's name. | | `credit_card.buyer_social_id` | string | no | Card holder's national ID, digits only. Also printed as the buyer's tax ID when `buyer_social_id` isn't sent. | | `credit_card.auth_number` | string | no | Authorization number of the card payment. | ### Request example ```json { "seller_payme_id": "MPLDEMO-MPLDEMO-MPLDEMO-1234567", "doc_type": 400, "buyer_name": "Israel Israeli", "doc_date": "2026-11-09", "currency": "ILS", "language": "he", "doc_title": "Receipt for order 1001", "total_paid": 140, "items": [ { "description": "Monthly plan", "quantity": 1, "unit_price": 140, "vat_exempt": false, "currency": "ILS" } ], "cash": { "sum": 40 }, "credit_card": { "sum": 100, "installments": 1, "type": "Visa", "expiry": "1230", "buyer_name": "Israel Israeli", "auth_number": "0123456" } } ``` ## Code samples ### curl ```bash curl -X POST 'https://sandbox.payme.io/api/documents' \ -H 'Content-Type: application/json' \ -H 'PayMe-Merchant-Key: ' \ --data-raw '{ "seller_payme_id": "MPLDEMO-MPLDEMO-MPLDEMO-1234567", "doc_type": 400, "buyer_name": "Israel Israeli", "doc_date": "2026-11-09", "currency": "ILS", "language": "he", "doc_title": "Receipt for order 1001", "total_paid": 140, "items": [ { "description": "Monthly plan", "quantity": 1, "unit_price": 140, "vat_exempt": false, "currency": "ILS" } ], "cash": { "sum": 40 }, "credit_card": { "sum": 100, "installments": 1, "type": "Visa", "expiry": "1230", "buyer_name": "Israel Israeli", "auth_number": "0123456" } }' ``` ### Node.js ```javascript const response = await fetch("https://sandbox.payme.io/api/documents", { method: "POST", headers: { "Content-Type": "application/json", "PayMe-Merchant-Key": "", }, body: JSON.stringify({ "seller_payme_id": "MPLDEMO-MPLDEMO-MPLDEMO-1234567", "doc_type": 400, "buyer_name": "Israel Israeli", "doc_date": "2026-11-09", "currency": "ILS", "language": "he", "doc_title": "Receipt for order 1001", "total_paid": 140, "items": [ { "description": "Monthly plan", "quantity": 1, "unit_price": 140, "vat_exempt": false, "currency": "ILS" } ], "cash": { "sum": 40 }, "credit_card": { "sum": 100, "installments": 1, "type": "Visa", "expiry": "1230", "buyer_name": "Israel Israeli", "auth_number": "0123456" } }), }); console.log(await response.text()); ``` ### Python ```python import requests response = requests.post( "https://sandbox.payme.io/api/documents", headers={ "PayMe-Merchant-Key": "", }, json={ "seller_payme_id": "MPLDEMO-MPLDEMO-MPLDEMO-1234567", "doc_type": 400, "buyer_name": "Israel Israeli", "doc_date": "2026-11-09", "currency": "ILS", "language": "he", "doc_title": "Receipt for order 1001", "total_paid": 140, "items": [ { "description": "Monthly plan", "quantity": 1, "unit_price": 140, "vat_exempt": False, "currency": "ILS", }, ], "cash": { "sum": 40, }, "credit_card": { "sum": 100, "installments": 1, "type": "Visa", "expiry": "1230", "buyer_name": "Israel Israeli", "auth_number": "0123456", }, }, ) print(response.text) ``` ### PHP ```php 'POST', CURLOPT_RETURNTRANSFER => true, CURLOPT_HTTPHEADER => [ 'Content-Type: application/json', 'PayMe-Merchant-Key: ', ], CURLOPT_POSTFIELDS => $body, ]); $response = curl_exec($ch); curl_close($ch); echo $response; ``` ## Responses ### 200 — The document job was created. (success) | Field | Type | Description | | --- | --- | --- | | `status_code` | integer | `0` on success. | | `doc_id` | string | The document's job ID. Use it with [Get a document](/payments/invoices/show-generated-document-by-id). | | `doc_num` | string | The document number, once the invoicing service has assigned one. | | `doc_status` | string | Status of the document job, when the invoicing service returns one. | | `doc_url` | string | Link to the document. | | `doc_type` | integer | Document type. See [Document types](/payments/codes-statuses/document-types). | | `buyer_name` | string | Buyer name on the document. | | `buyer_address` | string | Buyer address on the document, if sent. | | `doc_date` | string | Document date. | | `due_date` | string | Payment due date, if sent. | | `pay_date` | string | Payment date, if sent. | | `currency` | string | ISO 4217 currency code of the document. | | `language` | string | Document language. | | `doc_title` | string | Title printed at the top of the document. | | `doc_comments` | string | Comments printed on the document. | | `exchange_rate` | number | Exchange rate used on the document. | | `vat_rate` | number | VAT rate applied to the document. | | `discount` | number | Discount applied to the document. | | `total_excluding_vat` | number | Total before VAT. | | `total_sum_after_discount` | number | Total after the discount. | | `total_sum_including_vat` | number | Total including VAT. | | `total_vat` | number | Total VAT. | | `total_paid` | number | Total paid on this document. | | `total_paid_including_vat` | number | Total paid, including VAT. | | `items` | array | Document lines. | | `items[].description` | string | Line description. | | `items[].quantity` | integer | Quantity. | | `items[].unit_price` | number | Unit price before VAT. | | `items[].unit_price_with_vat` | number | Unit price including VAT. | | `items[].vat_exempt` | boolean | `true` if the line is exempt from VAT. | | `items[].currency` | string | ISO 4217 currency code of the line. | | `items[].exchange_rate` | number | Exchange rate of the line's currency. | | `cash` | object | Cash payment recorded on the document. | | `cash.sum` | number | Amount paid in cash. | | `cheques` | array | Cheques recorded on the document. | | `cheques[].sum` | number | Cheque amount. | | `cheques[].date` | string | Cheque date. | | `cheques[].bank` | number | Bank code. | | `cheques[].branch` | number | Branch number. | | `cheques[].account` | string | Account number. | | `cheques[].number` | string | Cheque number. | | `bank_transfer` | object | Bank transfer recorded on the document. | | `bank_transfer.sum` | number | Amount transferred. | | `bank_transfer.date` | string | Transfer date. | | `bank_transfer.account` | string | Account number. | | `paypal` | object | PayPal payment recorded on the document. | | `paypal.sum` | number | Amount paid with PayPal. | | `paypal.date` | string | Payment date. | | `paypal.transaction_id` | string | PayPal transaction ID. | | `paypal.buyer_name` | string | Payer name. | | `credit_card` | object | Card payment recorded on the document. It holds no card number or CVV. | | `credit_card.sum` | number | Amount paid by card. | | `credit_card.installments` | integer | Number of installments. | | `credit_card.first_payment` | number | Amount of the first installment. | | `credit_card.type` | string | Card brand. | | `credit_card.expiry` | string | Card expiry, `MMYY`. | | `credit_card.buyer_name` | string | Card holder's name. | | `credit_card.buyer_social_id` | string | Card holder's national ID. | | `credit_card.auth_number` | string | Authorization number of the card payment. | | `authority_redirect_url` | string | Returned instead of the other fields when the seller must first approve the connection to the Israel Tax Authority. No document was created. | ```json { "status_code": 0, "doc_id": "fa397fce-aee6-4c6d-ae9c-273ae1e3a317", "doc_type": 400, "buyer_name": "Israel Israeli", "doc_date": "2026-11-09", "currency": "ILS", "language": "he", "doc_title": "Receipt for order 1001", "total_paid": 140, "items": [ { "description": "Monthly plan", "quantity": 1, "unit_price": 140, "vat_exempt": false, "currency": "ILS" } ], "cash": { "sum": 40 }, "credit_card": { "sum": 100, "installments": 1, "type": "Visa", "expiry": "1230", "buyer_name": "Israel Israeli", "auth_number": "0123456" }, "doc_url": "https://invoice-staging.paymeservice.com/documents/fa397fce-aee6-4c6d-ae9c-273ae1e3a317" } ``` ### 400 — Validation failed (`20`), or a partner key came without a seller (`1`). (error) | Field | Type | Description | | --- | --- | --- | | `status_code` | integer | `1` on failure. | | `status_error_details` | string | What went wrong. | | `status_additional_info` | object | For a validation error, the messages per field, each an array of strings. Otherwise the field concerned, as a string. | | `status_error_code` | integer | PayMe error code: `20` for a validation error. | | `session` | string | PayMe session ID. Quote it when you contact support. | ```json { "status_code": 1, "status_error_details": "The given data was invalid.", "status_additional_info": { "doc_type": [ "The doc type field is required." ], "items": [ "The items field is required." ], "buyer_name": [ "The buyer name field is required." ] }, "status_error_code": 20, "session": "FhT3aXe7" } ``` ### 403 — The invoicing service isn't active for this seller (`703`). (error) | Field | Type | Description | | --- | --- | --- | | `status_code` | integer | `1` on failure. | | `status_error_details` | string | What went wrong, in the language you asked for (Hebrew by default). | | `status_additional_info` | string | The field or value concerned. Can be `null`. | | `status_error_code` | integer | PayMe error code. See the error table above and [Errors](/payments/getting-started/errors). | | `session` | string | PayMe session ID. Quote it when you contact support. | ```json { "status_code": 1, "status_error_details": "Action is not permitted", "status_additional_info": "Invoicing Service was not properly activated. Operation not permitted", "status_error_code": 703, "session": "FhT3aXe7" } ``` ### 500 — Credentials or the invoicing service failed. See the error table. (error) | Field | Type | Description | | --- | --- | --- | | `status_code` | integer | `1` on failure. | | `status_error_details` | string | What went wrong, in the language you asked for (Hebrew by default). | | `status_additional_info` | string | The field or value concerned. Can be `null`. | | `status_error_code` | integer | PayMe error code. See the error table above and [Errors](/payments/getting-started/errors). | | `session` | string | PayMe session ID. Quote it when you contact support. | ```json { "status_code": 1, "status_error_details": "Required parameter is missing", "status_additional_info": "payme_client_key", "status_error_code": 1, "session": "FhT3aXe7" } ``` - [Get a document](https://docs.payme.io/payments/invoices/show-generated-document-by-id): GET /documents/{document_id} — Get a document # Get a document - Sandbox: `GET https://sandbox.payme.io/api/documents/{document_id}` - Production: `GET https://live.payme.io/api/documents/{document_id}` ## Credentials - Header `PayMe-Merchant-Key` (API key) - Header `PayMe-Partner-Key` (optional): Partners only: your partner key. The seller must belong to you (error `20`). > ⚠️ **This API is deprecated** and is no longer recommended for use. For questions, contact partners@payme.io. ## Overview Returns a document created with [Create a document](/payments/invoices/post-create-invoice). `document_id` is the `doc_id` that call returned. The seller's invoicing service must be active; otherwise every documents call returns error `703` (HTTP 403). Documents are created asynchronously. While the document job is still running (its status is `waiting`, `active`, `delayed`, `paused` or `stuck`), this call returns error `1005` with HTTP 400 and the status in `status_additional_info`, for example `status:waiting`. Wait a few seconds and call it again. If the job failed, the call returns error `1003`. If the invoicing service reports an unknown job status, the response is HTTP 200 with `status_code` `0` and no document fields: call again later. Example: `GET https://sandbox.payme.io/api/documents/fa397fce-aee6-4c6d-ae9c-273ae1e3a317` with the header `PayMe-Merchant-Key: MPLDEMO-MPLDEMO-MPLDEMO-1234567`. ### Errors | HTTP | Code | When | |---|---|---| | `400` | `1005` | The document is still being created. `status_additional_info` is its status, such as `status:waiting`. | | `500` | `1003` | The document failed to generate. | | `400` | `1` | A partner key was sent, but no seller. `status_additional_info` is `seller_payme_id`. | | `400` | `20` | The seller doesn't belong to this partner. `status_additional_info` is `Merchant-Seller inconsistency`. | | `403` | `703` | The invoicing service isn't active for this seller. | | `500` | `1` | No credential was sent at all. `status_additional_info` is `payme_client_key`. | | `500` | `251` | The seller key is unknown. | | `500` | `163` | The seller isn't active. | | `500` | `200` | The partner key is unknown. | | `500` | `201` | The partner isn't active. | | `500` | `1001` | The invoicing service returned an error. `status_additional_info` carries its code and details. | | `503` | `1001` | The invoicing service didn't answer in time. | ## Parameters | Name | In | Type | Required | Description | | --- | --- | --- | --- | --- | | `document_id` | path | string | yes | The document's `doc_id`, returned by [Create a document](/payments/invoices/post-create-invoice). | | `PayMe-Merchant-Key` | header | string | yes | The seller's MPL. On a GET request this header is the only way to name the seller. | | `PayMe-Partner-Key` | header | string | no | Partners only: your partner key. The seller must belong to you (error `20`). | ## Code samples ### curl ```bash curl -X GET 'https://sandbox.payme.io/api/documents/' \ -H 'PayMe-Merchant-Key: ' \ -H 'PayMe-Partner-Key: ' ``` ### Node.js ```javascript const response = await fetch("https://sandbox.payme.io/api/documents/", { method: "GET", headers: { "PayMe-Merchant-Key": "", "PayMe-Partner-Key": "", }, }); console.log(await response.text()); ``` ### Python ```python import requests response = requests.get( "https://sandbox.payme.io/api/documents/", headers={ "PayMe-Merchant-Key": "", "PayMe-Partner-Key": "", }, ) print(response.text) ``` ### PHP ```php '); curl_setopt_array($ch, [ CURLOPT_CUSTOMREQUEST => 'GET', CURLOPT_RETURNTRANSFER => true, CURLOPT_HTTPHEADER => [ 'PayMe-Merchant-Key: ', 'PayMe-Partner-Key: ', ], ]); $response = curl_exec($ch); curl_close($ch); echo $response; ``` ## Responses ### 200 — The document is ready. (success) | Field | Type | Description | | --- | --- | --- | | `status_code` | integer | `0` on success. | | `doc_id` | string | The document's job ID. Use it with [Get a document](/payments/invoices/show-generated-document-by-id). | | `doc_num` | string | The document number, once the invoicing service has assigned one. | | `doc_status` | string | Status of the document job, when the invoicing service returns one. | | `doc_url` | string | Link to the document. | | `doc_type` | integer | Document type. See [Document types](/payments/codes-statuses/document-types). | | `buyer_name` | string | Buyer name on the document. | | `buyer_address` | string | Buyer address on the document, if sent. | | `doc_date` | string | Document date. | | `due_date` | string | Payment due date, if sent. | | `pay_date` | string | Payment date, if sent. | | `currency` | string | ISO 4217 currency code of the document. | | `language` | string | Document language. | | `doc_title` | string | Title printed at the top of the document. | | `doc_comments` | string | Comments printed on the document. | | `exchange_rate` | number | Exchange rate used on the document. | | `vat_rate` | number | VAT rate applied to the document. | | `discount` | number | Discount applied to the document. | | `total_excluding_vat` | number | Total before VAT. | | `total_sum_after_discount` | number | Total after the discount. | | `total_sum_including_vat` | number | Total including VAT. | | `total_vat` | number | Total VAT. | | `total_paid` | number | Total paid on this document. | | `total_paid_including_vat` | number | Total paid, including VAT. | | `items` | array | Document lines. | | `items[].description` | string | Line description. | | `items[].quantity` | integer | Quantity. | | `items[].unit_price` | number | Unit price before VAT. | | `items[].unit_price_with_vat` | number | Unit price including VAT. | | `items[].vat_exempt` | boolean | `true` if the line is exempt from VAT. | | `items[].currency` | string | ISO 4217 currency code of the line. | | `items[].exchange_rate` | number | Exchange rate of the line's currency. | | `cash` | object | Cash payment recorded on the document. | | `cash.sum` | number | Amount paid in cash. | | `cheques` | array | Cheques recorded on the document. | | `cheques[].sum` | number | Cheque amount. | | `cheques[].date` | string | Cheque date. | | `cheques[].bank` | number | Bank code. | | `cheques[].branch` | number | Branch number. | | `cheques[].account` | string | Account number. | | `cheques[].number` | string | Cheque number. | | `bank_transfer` | object | Bank transfer recorded on the document. | | `bank_transfer.sum` | number | Amount transferred. | | `bank_transfer.date` | string | Transfer date. | | `bank_transfer.account` | string | Account number. | | `paypal` | object | PayPal payment recorded on the document. | | `paypal.sum` | number | Amount paid with PayPal. | | `paypal.date` | string | Payment date. | | `paypal.transaction_id` | string | PayPal transaction ID. | | `paypal.buyer_name` | string | Payer name. | | `credit_card` | object | Card payment recorded on the document. It holds no card number or CVV. | | `credit_card.sum` | number | Amount paid by card. | | `credit_card.installments` | integer | Number of installments. | | `credit_card.first_payment` | number | Amount of the first installment. | | `credit_card.type` | string | Card brand. | | `credit_card.expiry` | string | Card expiry, `MMYY`. | | `credit_card.buyer_name` | string | Card holder's name. | | `credit_card.buyer_social_id` | string | Card holder's national ID. | | `credit_card.auth_number` | string | Authorization number of the card payment. | ```json { "status_code": 0, "doc_type": 400, "buyer_name": "Israel Israeli", "doc_date": "2026-11-09", "currency": "ILS", "language": "he", "doc_title": "Receipt for order 1001", "total_paid": 140, "items": [ { "description": "Monthly plan", "quantity": 1, "unit_price": 140, "vat_exempt": false, "currency": "ILS" } ], "cash": { "sum": 40 }, "credit_card": { "sum": 100, "installments": 1, "type": "Visa", "expiry": "1230", "buyer_name": "Israel Israeli", "auth_number": "0123456" }, "doc_id": "fa397fce-aee6-4c6d-ae9c-273ae1e3a317", "doc_num": "10023", "doc_status": "completed", "doc_url": "https://invoice-staging.paymeservice.com/documents/fa397fce-aee6-4c6d-ae9c-273ae1e3a317" } ``` ### 400 — Bad request. See the error table. (error) | Field | Type | Description | | --- | --- | --- | | `status_code` | integer | `1` on failure. | | `status_error_details` | string | What went wrong, in the language you asked for (Hebrew by default). | | `status_additional_info` | string | The field or value concerned. Can be `null`. | | `status_error_code` | integer | PayMe error code. See the error table above and [Errors](/payments/getting-started/errors). | | `session` | string | PayMe session ID. Quote it when you contact support. | ```json { "status_code": 1, "status_error_details": "Document you're requested not ready yet", "status_additional_info": "status:waiting", "status_error_code": 1005, "session": "FhT3aXe7" } ``` ### 403 — The invoicing service isn't active for this seller (`703`). (error) | Field | Type | Description | | --- | --- | --- | | `status_code` | integer | `1` on failure. | | `status_error_details` | string | What went wrong, in the language you asked for (Hebrew by default). | | `status_additional_info` | string | The field or value concerned. Can be `null`. | | `status_error_code` | integer | PayMe error code. See the error table above and [Errors](/payments/getting-started/errors). | | `session` | string | PayMe session ID. Quote it when you contact support. | ```json { "status_code": 1, "status_error_details": "Action is not permitted", "status_additional_info": "Invoicing Service was not properly activated. Operation not permitted", "status_error_code": 703, "session": "FhT3aXe7" } ``` ### 500 — Credentials or the invoicing service failed. See the error table. (error) | Field | Type | Description | | --- | --- | --- | | `status_code` | integer | `1` on failure. | | `status_error_details` | string | What went wrong, in the language you asked for (Hebrew by default). | | `status_additional_info` | string | The field or value concerned. Can be `null`. | | `status_error_code` | integer | PayMe error code. See the error table above and [Errors](/payments/getting-started/errors). | | `session` | string | PayMe session ID. Quote it when you contact support. | ```json { "status_code": 1, "status_error_details": "Document not found", "status_additional_info": null, "status_error_code": 1003, "session": "FhT3aXe7" } ``` - [List documents](https://docs.payme.io/payments/invoices/get-documents): GET /documents — List documents # List documents - Sandbox: `GET https://sandbox.payme.io/api/documents` - Production: `GET https://live.payme.io/api/documents` ## Credentials - Header `PayMe-Merchant-Key` (API key) - Header `PayMe-Partner-Key` (optional): Partners only: your partner key. The seller must belong to you (error `20`). > ⚠️ **This API is deprecated** and is no longer recommended for use. For questions, contact partners@payme.io. ## Overview Lists the seller's documents, a page at a time. Send the seller's MPL in the `PayMe-Merchant-Key` header. The seller's invoicing service must be active; otherwise every documents call returns error `703` (HTTP 403). Environment | Example ---|--- `Sandbox` | `https://sandbox.payme.io/api/documents?limit=5&field=createdAt&sort=desc` `Production` | `https://live.payme.io/api/documents?limit=5&field=createdAt&sort=desc` Each item has the fields of [Get a document](/payments/invoices/show-generated-document-by-id), except `doc_url`. To open a document, call [Get a document](/payments/invoices/show-generated-document-by-id) with its `doc_id`. Other top-level fields, such as paging details, come from the invoicing service as they are. ### Errors | HTTP | Code | When | |---|---|---| | `400` | `1` | A partner key was sent, but no seller. `status_additional_info` is `seller_payme_id`. | | `400` | `20` | The seller doesn't belong to this partner. `status_additional_info` is `Merchant-Seller inconsistency`. | | `403` | `703` | The invoicing service isn't active for this seller. | | `500` | `1` | No credential was sent at all. `status_additional_info` is `payme_client_key`. | | `500` | `251` | The seller key is unknown. | | `500` | `163` | The seller isn't active. | | `500` | `200` | The partner key is unknown. | | `500` | `201` | The partner isn't active. | | `500` | `1001` | The invoicing service returned an error. `status_additional_info` carries its code and details. | | `503` | `1001` | The invoicing service didn't answer in time. | ## Parameters | Name | In | Type | Required | Description | | --- | --- | --- | --- | --- | | `page` | query | integer | no | Page number. Omit it for the first page. | | `limit` | query | integer | no | Documents per page. | | `field` | query | string | no | Field to sort by, for example `createdAt`. | | `sort` | query | string | no | Sort order: `asc` or `desc`. | | `from` | query | string | no | Return documents from this date. | | `to` | query | string | no | Return documents up to this date. | | `PayMe-Merchant-Key` | header | string | yes | The seller's MPL. On a GET request this header is the only way to name the seller. | | `PayMe-Partner-Key` | header | string | no | Partners only: your partner key. The seller must belong to you (error `20`). | ## Code samples ### curl ```bash curl -X GET 'https://sandbox.payme.io/api/documents' \ -H 'PayMe-Merchant-Key: ' \ -H 'PayMe-Partner-Key: ' ``` ### Node.js ```javascript const response = await fetch("https://sandbox.payme.io/api/documents", { method: "GET", headers: { "PayMe-Merchant-Key": "", "PayMe-Partner-Key": "", }, }); console.log(await response.text()); ``` ### Python ```python import requests response = requests.get( "https://sandbox.payme.io/api/documents", headers={ "PayMe-Merchant-Key": "", "PayMe-Partner-Key": "", }, ) print(response.text) ``` ### PHP ```php 'GET', CURLOPT_RETURNTRANSFER => true, CURLOPT_HTTPHEADER => [ 'PayMe-Merchant-Key: ', 'PayMe-Partner-Key: ', ], ]); $response = curl_exec($ch); curl_close($ch); echo $response; ``` ## Responses ### 200 — A page of documents. (success) | Field | Type | Description | | --- | --- | --- | | `status_code` | integer | `0` on success. | | `items` | array | The documents on this page. | | `items[].doc_id` | string | The document's job ID. Use it with [Get a document](/payments/invoices/show-generated-document-by-id). | | `items[].doc_num` | string | The document number, once the invoicing service has assigned one. | | `items[].doc_status` | string | Status of the document job, when the invoicing service returns one. | | `items[].doc_type` | integer | Document type. See [Document types](/payments/codes-statuses/document-types). | | `items[].buyer_name` | string | Buyer name on the document. | | `items[].buyer_address` | string | Buyer address on the document, if sent. | | `items[].doc_date` | string | Document date. | | `items[].due_date` | string | Payment due date, if sent. | | `items[].pay_date` | string | Payment date, if sent. | | `items[].currency` | string | ISO 4217 currency code of the document. | | `items[].language` | string | Document language. | | `items[].doc_title` | string | Title printed at the top of the document. | | `items[].doc_comments` | string | Comments printed on the document. | | `items[].exchange_rate` | number | Exchange rate used on the document. | | `items[].vat_rate` | number | VAT rate applied to the document. | | `items[].discount` | number | Discount applied to the document. | | `items[].total_excluding_vat` | number | Total before VAT. | | `items[].total_sum_after_discount` | number | Total after the discount. | | `items[].total_sum_including_vat` | number | Total including VAT. | | `items[].total_vat` | number | Total VAT. | | `items[].total_paid` | number | Total paid on this document. | | `items[].total_paid_including_vat` | number | Total paid, including VAT. | | `items[].items` | array | Document lines. | | `items[].items[].description` | string | Line description. | | `items[].items[].quantity` | integer | Quantity. | | `items[].items[].unit_price` | number | Unit price before VAT. | | `items[].items[].unit_price_with_vat` | number | Unit price including VAT. | | `items[].items[].vat_exempt` | boolean | `true` if the line is exempt from VAT. | | `items[].items[].currency` | string | ISO 4217 currency code of the line. | | `items[].items[].exchange_rate` | number | Exchange rate of the line's currency. | | `items[].cash` | object | Cash payment recorded on the document. | | `items[].cash.sum` | number | Amount paid in cash. | | `items[].cheques` | array | Cheques recorded on the document. | | `items[].cheques[].sum` | number | Cheque amount. | | `items[].cheques[].date` | string | Cheque date. | | `items[].cheques[].bank` | number | Bank code. | | `items[].cheques[].branch` | number | Branch number. | | `items[].cheques[].account` | string | Account number. | | `items[].cheques[].number` | string | Cheque number. | | `items[].bank_transfer` | object | Bank transfer recorded on the document. | | `items[].bank_transfer.sum` | number | Amount transferred. | | `items[].bank_transfer.date` | string | Transfer date. | | `items[].bank_transfer.account` | string | Account number. | | `items[].paypal` | object | PayPal payment recorded on the document. | | `items[].paypal.sum` | number | Amount paid with PayPal. | | `items[].paypal.date` | string | Payment date. | | `items[].paypal.transaction_id` | string | PayPal transaction ID. | | `items[].paypal.buyer_name` | string | Payer name. | | `items[].credit_card` | object | Card payment recorded on the document. It holds no card number or CVV. | | `items[].credit_card.sum` | number | Amount paid by card. | | `items[].credit_card.installments` | integer | Number of installments. | | `items[].credit_card.first_payment` | number | Amount of the first installment. | | `items[].credit_card.type` | string | Card brand. | | `items[].credit_card.expiry` | string | Card expiry, `MMYY`. | | `items[].credit_card.buyer_name` | string | Card holder's name. | | `items[].credit_card.buyer_social_id` | string | Card holder's national ID. | | `items[].credit_card.auth_number` | string | Authorization number of the card payment. | ```json { "status_code": 0, "items": [ { "doc_id": "fa397fce-aee6-4c6d-ae9c-273ae1e3a317", "doc_type": 400, "buyer_name": "Israel Israeli", "doc_date": "2026-11-09", "currency": "ILS", "language": "he", "doc_title": "Receipt for order 1001", "total_paid": 140, "items": [ { "description": "Monthly plan", "quantity": 1, "unit_price": 140, "vat_exempt": false, "currency": "ILS" } ], "cash": { "sum": 40 }, "credit_card": { "sum": 100, "installments": 1, "type": "Visa", "expiry": "1230", "buyer_name": "Israel Israeli", "auth_number": "0123456" }, "doc_num": "10023", "doc_status": "completed" } ] } ``` ### 400 — Bad request. See the error table. (error) | Field | Type | Description | | --- | --- | --- | | `status_code` | integer | `1` on failure. | | `status_error_details` | string | What went wrong, in the language you asked for (Hebrew by default). | | `status_additional_info` | string | The field or value concerned. Can be `null`. | | `status_error_code` | integer | PayMe error code. See the error table above and [Errors](/payments/getting-started/errors). | | `session` | string | PayMe session ID. Quote it when you contact support. | ```json { "status_code": 1, "status_error_details": "Required parameter is missing", "status_additional_info": "seller_payme_id", "status_error_code": 1, "session": "FhT3aXe7" } ``` ### 403 — The invoicing service isn't active for this seller (`703`). (error) | Field | Type | Description | | --- | --- | --- | | `status_code` | integer | `1` on failure. | | `status_error_details` | string | What went wrong, in the language you asked for (Hebrew by default). | | `status_additional_info` | string | The field or value concerned. Can be `null`. | | `status_error_code` | integer | PayMe error code. See the error table above and [Errors](/payments/getting-started/errors). | | `session` | string | PayMe session ID. Quote it when you contact support. | ```json { "status_code": 1, "status_error_details": "Action is not permitted", "status_additional_info": "Invoicing Service was not properly activated. Operation not permitted", "status_error_code": 703, "session": "FhT3aXe7" } ``` ### 500 — Credentials or the invoicing service failed. See the error table. (error) | Field | Type | Description | | --- | --- | --- | | `status_code` | integer | `1` on failure. | | `status_error_details` | string | What went wrong, in the language you asked for (Hebrew by default). | | `status_additional_info` | string | The field or value concerned. Can be `null`. | | `status_error_code` | integer | PayMe error code. See the error table above and [Errors](/payments/getting-started/errors). | | `session` | string | PayMe session ID. Quote it when you contact support. | ```json { "status_code": 1, "status_error_details": "Required parameter is missing", "status_additional_info": "payme_client_key", "status_error_code": 1, "session": "FhT3aXe7" } ``` ## Generate a Sale with 3D Secure - [Generate a Sale with 3D Secure](https://docs.payme.io/payments/generate-a-sale-with-3d-secure): 3D Secure on hosted-payment-page sales: when PayMe applies it (foreign cards, 3 or more installments, amounts from the account's threshold) and how to force it on or off per sale with services. # Generate a Sale with 3D Secure 3D Secure (version 2.2.0) runs inside the hosted payment page on sales that match your account's 3D Secure rules. By default PayMe applies it to foreign cards, to sales with 3 or more installments, and to sales of at least the account's 3D Secure threshold. You can force it on or off for one sale with `services`: see [Create a sale with 3D Secure](https://docs.payme.io/payments/generate-a-sale-with-3d-secure/post-generate-sale-generate-a-sale-with-3d-secure). For 3D Secure outside PayMe's payment page, see the [Standalone 3D Secure service](https://docs.payme.io/payments/standalone-3d-secure-service). - [Create a sale with 3D Secure](https://docs.payme.io/payments/generate-a-sale-with-3d-secure/post-generate-sale-generate-a-sale-with-3d-secure): POST /generate-sale — Create a sale with 3D Secure # Create a sale with 3D Secure - 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-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. - Request body field `payme_client_key` (optional): 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`. ## Overview Creates a sale on the hosted payment page with 3D Secure. The call is an ordinary [`generate-sale`](/payments/hosted-payment-page/post-generate-sale) that returns `sale_url`; 3D Secure runs inside PayMe's payment page. `POST https://sandbox.payme.io/api/generate-sale` (production: `https://live.payme.io/api/generate-sale`), with a JSON body (`Content-Type: application/json`). ### 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](/payments/getting-started/authentication). ### When 3D Secure runs 3D Secure must be enabled on the account by PayMe. PayMe's system rules then apply it to card payments that match any of them: a card issued in a country other than the seller's registered country, 3 or more installments, or an amount of at least the account's 3D Secure threshold. The amount rule compares `sale_price` in minor units with the threshold, without converting currencies. To add rules of your own, ask your onboarding manager before you go live. ### Force it on or off for one sale Send `services` with the `3DSecure` service. This needs the 3D Secure service on the account. ```json { "services": [{"name": "3DSecure", "settings": {"active": true}}] } ``` - `"active": true` forces 3D Secure on this sale. - `"active": false` turns off your account's own 3D Secure rules for this sale. PayMe's system rules (foreign card, 3 or more installments, the amount threshold) still apply; only PayMe can switch those off for the account. - A setting for a service the account doesn't have is ignored, without an error. Each entry needs `settings`: an entry without it returns error `1` after the sale has already been created. ### When authentication fails When the buyer fails the 3D Secure challenge, the sale becomes `failed` and PayMe sends the buyer to the first of these that is set: your `sale_return_url` (with `payme_status=error`), then `cancel_url`, then PayMe's payment page to try another card. ### Check the result Query the sale with [`get-transactions`](/payments/query-apis/post-get-transactions) or [`get-sales`](/payments/query-apis/post-get-sales) and read `sale_is_3ds`. The sale callback carries `sale_3ds` (`1` when 3D Secure was used). Sandbox test cards for the challenge are on [Test Cards and Payment Methods](/payments/getting-started/test-cards-and-payment-methods). ### Rules for every request - Amounts are in minor units (`1000` = 10.00). - Never put card numbers in any field. A value (other than `transaction_id` and `order_number`) that contains a 14–19-digit number passing the card checksum is refused with error `20` (HTTP 400), " contains invalid data". - Don't send the legacy `price` field: it is in major units and, when numeric, overrides `sale_price`. - PayMe doesn't de-duplicate `transaction_id`: every call creates a new sale. See [Idempotency and Retries](/payments/getting-started/idempotency-and-retries). - Errors return `status_code: 1` with `status_error_code`, most with HTTP 500. See [Errors](/payments/getting-started/errors). ### 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](/payments/getting-started/callbacks). ## 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`. | | `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](https://en.wikipedia.org/wiki/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) or `0`: one payment. `2`–`12`: that fixed number. `102`–`112`: the buyer chooses on the page, up to the last two digits (`106` = up to 6). More than one installment is ILS only (`312`) and works only with `credit-card` or `multi` (other methods return `351`). On a `multi` page that lets the buyer choose, a buyer who pays with Apple Pay or Google Pay pays in one payment. Fixed values above 12 are accepted when the sale is created, but the payment fails unless PayMe has enabled more installments on your account. A non-numeric value returns `10`, any other unaccepted value `351`, and an ILS price lower than the number of installments `358`. | | `sale_payment_method` | string | no | Payment method. 3D Secure applies to card payments: `credit-card`, or a card chosen on a `multi` page. Default `credit-card`. | | `services` | array | no | Per-sale service settings. For 3D Secure: `[{"name": "3DSecure", "settings": {"active": true}}]` forces it, `"active": false` turns off your own rules for this sale. Each object needs `settings` (error `1`). Unknown or inactive services are ignored. | | `cancel_url` | string | no | Where to send the buyer when 3D Secure authentication fails and no `sale_return_url` is set. Without either, the buyer goes back to the payment page. Also the PayPal cancel address. Must be a public URL (error `21`). | | `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](/payments/getting-started/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. | | `sale_return_url` | string | no | Where PayMe redirects the buyer (the iframe or the full page) after a successful payment, with the sale details as query parameters; see [Hosted Payment Page options](/accepting-payments/checkout-and-in-person/hosted-payment-page-options). If omitted, your partner's default return URL is used, if one is set. Same address rules as `sale_callback_url` (error `21`). | | `sale_send_notification` | boolean | no | `true`: PayMe sends the buyer a payment request with the payment link, by email to `sale_email` and by SMS to `sale_mobile`. Default `false`. | | `sale_email` | string | no | Buyer's email. Pre-fills the payment page and receives the payment request when `sale_send_notification` is `true`. | | `sale_mobile` | string | no | Buyer's mobile number. Pre-fills the payment page and receives the SMS payment request when `sale_send_notification` is `true` and the SMS service is active on the account. | | `sale_name` | string | no | Buyer's full name. Pre-fills the payment page (split at the first space into first and last name) and is used in notifications. | | `capture_buyer` | string | no | `1` or `true` to save the buyer's card as a token after the payment; the token arrives as `buyer_key` in the callback. Omit it, or send `0`, to skip. Works with `credit-card`, `apple-pay`, `il-direct-debit` and `multi` (other methods return `4`). Can't be combined with `buyer_key` (`601`). | | `buyer_is_private` | boolean | no | With `capture_buyer` or a token sale: `true` ties the token to this seller, so `get-buyer-key` works with the seller's MPL. Without it the token is account-level: any seller of the same partner can charge it, and a `get-buyer-key` call that sends `seller_payme_id` fails with error `603`. | | `buyer_perform_validation` | boolean | no | With `capture_buyer` or a token sale: whether PayMe validates the card with the issuer before saving the token. Default `true`. Sending `true` without `capture_buyer` or a token sale returns `608`. | | `buyer_key` | string | no | Charges a saved token at once: no payment page and no `sale_url` (see the "Token charged" response). The token comes from a callback, [`get-buyer-key`](/payments/tokenization/post-get-buyer-key) or Hosted Fields `tokenize()`. Can't be combined with `capture_buyer` (`601`), `sale_type` `token`/`seller-token` (`602`) or `template` (`606`). | | `layout` | string | no | Payment page layout: `dynamic` (default), `dynamic-loose` (no social ID or CVV validation), `qr-sms` (Bit: QR code or SMS), `token-capture` (save a card without a charge; requires `sale_type: token`). Other values fall back to `dynamic`. | | `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`. | ### Request example ```json { "seller_payme_id": "MPLDEMO-MPLDEMO-MPLDEMO-1234567", "sale_price": 60000, "currency": "ILS", "product_name": "Laptop", "transaction_id": "order-1002", "installments": "1", "sale_callback_url": "https://your-server.example.com/payme/callback", "sale_return_url": "https://your-site.example.com/payment/success", "cancel_url": "https://your-site.example.com/checkout", "language": "en", "services": [ { "name": "3DSecure", "settings": { "active": true } } ] } ``` ## Code samples ### curl ```bash curl -X POST 'https://sandbox.payme.io/api/generate-sale' \ -H 'Content-Type: application/json' \ --data-raw '{ "seller_payme_id": "MPLDEMO-MPLDEMO-MPLDEMO-1234567", "sale_price": 60000, "currency": "ILS", "product_name": "Laptop", "transaction_id": "order-1002", "installments": "1", "sale_callback_url": "https://your-server.example.com/payme/callback", "sale_return_url": "https://your-site.example.com/payment/success", "cancel_url": "https://your-site.example.com/checkout", "language": "en", "services": [ { "name": "3DSecure", "settings": { "active": true } } ] }' ``` ### Node.js ```javascript 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", "sale_price": 60000, "currency": "ILS", "product_name": "Laptop", "transaction_id": "order-1002", "installments": "1", "sale_callback_url": "https://your-server.example.com/payme/callback", "sale_return_url": "https://your-site.example.com/payment/success", "cancel_url": "https://your-site.example.com/checkout", "language": "en", "services": [ { "name": "3DSecure", "settings": { "active": true } } ] }), }); console.log(await response.text()); ``` ### Python ```python import requests response = requests.post( "https://sandbox.payme.io/api/generate-sale", json={ "seller_payme_id": "MPLDEMO-MPLDEMO-MPLDEMO-1234567", "sale_price": 60000, "currency": "ILS", "product_name": "Laptop", "transaction_id": "order-1002", "installments": "1", "sale_callback_url": "https://your-server.example.com/payme/callback", "sale_return_url": "https://your-site.example.com/payment/success", "cancel_url": "https://your-site.example.com/checkout", "language": "en", "services": [ { "name": "3DSecure", "settings": { "active": True, }, }, ], }, ) print(response.text) ``` ### PHP ```php 'POST', CURLOPT_RETURNTRANSFER => true, CURLOPT_HTTPHEADER => [ 'Content-Type: application/json', ], CURLOPT_POSTFIELDS => $body, ]); $response = curl_exec($ch); curl_close($ch); echo $response; ``` ## Responses ### 200 — Sale created (success) | Field | Type | Description | | --- | --- | --- | | `status_code` | integer | `0` success, `1` error. | | `sale_url` | string | PayMe's payment page for this sale. Show it to the buyer in an iframe or a redirect, exactly as returned. It stays payable while the sale is `initial` or `failed`, until `sale_expiry_seconds` passes if you sent it. | | `payme_sale_id` | string | PayMe's sale ID. Store it: refunds, captures and queries use it. | | `payme_sale_code` | integer | Short numeric sale code, for display only. | | `price` | integer | Sale amount in minor units (`100` for a token sale). | | `transaction_id` | string | Your order reference, as sent. | | `currency` | string | Sale currency (ISO 4217). | | `sale_payment_method` | string | Payment method of the sale, for example `credit-card` or `multi`. | | `session` | string | Request ID. Quote it when you contact PayMe. | ```json { "status_code": 0, "session": "AtsJ0as5", "sale_url": "https://sandbox.payme.io/sale/generate/SALE1700-000000AA-EXAMPLE1-SALE0001", "payme_sale_id": "SALE1700-000000AA-EXAMPLE1-SALE0001", "payme_sale_code": 12345678, "price": 60000, "transaction_id": "order-1002", "currency": "ILS", "sale_payment_method": "credit-card" } ``` ### 500 — Request refused. Most request errors return HTTP 500 with `status_code: 1`; some return 400, 403, 422 or 429. See [Errors](/payments/getting-started/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. | ```json { "status_code": 1, "status_error_details": "Seller was not found", "status_additional_info": "seller_payme_id", "status_error_code": 251, "session": "AtsJ0as5" } ``` ## Standalone 3D Secure service - [Standalone 3D Secure service](https://docs.payme.io/payments/standalone-3d-secure-service): Run 3D Secure 2 authentication as a separate step, without charging the card: the flow from browser data to the resolved 3DS values. # Standalone 3D Secure service Run 3D Secure 2 authentication as a separate step, without charging the card. Use it when another gateway processes the payment but you want PayMe to authenticate the card, or when you authenticate a card now and charge it later. Background: [3D Secure as a service](https://docs.payme.io/accepting-payments/3d-secure/3d-secure-as-a-service). The seller must have the 3D Secure service active; otherwise the call returns error `720`. ## Process flow 1. Add PayMe's JS library to your checkout page and collect the buyer's browser data, as described in [3DS integration using JS API](https://docs.payme.io/accepting-payments/3d-secure/3ds-with-hosted-fields). The library returns `meta_data_jwt`. 2. Create a card sale to get a `payme_sale_id`, for example with [Generate a sale with 3D Secure](https://docs.payme.io/payments/generate-a-sale-with-3d-secure/post-generate-sale-generate-a-sale-with-3d-secure). 3. Call [Start 3D Secure authentication](https://docs.payme.io/payments/standalone-3d-secure-service/post-initialize-3dsecure-request) (`POST /sales/{payme_sale_id}/3ds`) from the browser with the seller's public key, the card (or a `buyer_key`) and `meta_data_jwt`. 4. The issuer either approves without asking the buyer anything (frictionless), or asks for a challenge: - **Frictionless:** the response has `status_code` `0` and `hash_3dsecure`. - **Challenge:** the response has `status_code` `5` and a `redirect_url` to the issuer's challenge page. Send the buyer there. When the challenge ends, PayMe's page passes `hash_3dsecure` back to the page that opened the challenge. 5. From your server, call [Resolve a 3D Secure hash](https://docs.payme.io/payments/standalone-3d-secure-service/get-sales-payme-sale-id-3ds-hash) (`GET /sales/{payme_sale_id}/3ds/{hash_3dsecure}`) with the seller's MPL to get `eci`, `cavv` and `xid` for your gateway. If authentication failed, the result has a non-null `status` and no `cavv`. - [Start 3D Secure authentication](https://docs.payme.io/payments/standalone-3d-secure-service/post-initialize-3dsecure-request): POST /sales/{payme_sale_id}/3ds — Start 3D Secure authentication # Start 3D Secure authentication - Sandbox: `POST https://sandbox.payme.io/api/sales/{payme_sale_id}/3ds` - Production: `POST https://live.payme.io/api/sales/{payme_sale_id}/3ds` ## Credentials - Header `PayMe-Public-Key` (API key) ## Overview Starts 3D Secure 2 authentication for a card on an existing sale, without charging it. Use it when another gateway processes the payment and you need the 3DS values (`eci`, `cavv`, `xid`) from PayMe's MPI. The whole flow: [Standalone 3D Secure: process flow](/payments/standalone-3d-secure-service). Call it from the buyer's browser with the seller's public key in the `PayMe-Public-Key` header. The sale must belong to that seller. Send the browser data that PayMe's JS library collected (`meta_data_jwt`); see [3DS integration using JS API](/accepting-payments/3d-secure/3ds-with-hosted-fields). The response has one of two outcomes: - `status_code` `0`: frictionless approval. Pass `hash_3dsecure` to your server and resolve it with [Resolve a 3D Secure hash](/payments/standalone-3d-secure-service/get-sales-payme-sale-id-3ds-hash). - `status_code` `5`: the issuer wants a challenge. Send the buyer to `redirect_url` (a GET request). After the challenge, the hash comes back to the page that opened it. The seller must have the 3D Secure service active. ## Errors | HTTP | Code | When | |---|---|---| | 400 | `670` | `meta_data_jwt` (or `meta_data`) is missing or can't be read. | | 400 | `4` | The sale uses another payment method. | | 400 | `720` | 3D Secure was blocked for this card. | | 500 | `720` | 3D Secure isn't available for this card, or the seller has no 3D Secure service. | | 500 | `350` | No sale has this ID. | | 500 | Card error code | The card number or expiry is invalid, for example `356` for the expiry. | | 401 | — | The `PayMe-Public-Key` header is missing or unknown. | | 403 | `163` | The seller isn't active. | ## Parameters | Name | In | Type | Required | Description | | --- | --- | --- | --- | --- | | `payme_sale_id` | path | string | yes | The sale to authenticate (`payme_sale_id`). It must belong to the seller of the public key. | | `PayMe-Public-Key` | header | string | yes | The seller's public key. Safe to use in the browser. | ## Request body Content type: `application/json` | Field | Type | Required | Description | | --- | --- | --- | --- | | `payment` | object | yes | The card to authenticate. | | `payment.method` | string | yes | `credit-card`. | | `payment.card_number` | string | no | Card number. Required unless you send `buyer_key`. | | `payment.card_expiry` | string | no | Card expiry, `MMYY`. Required unless you send `buyer_key`. | | `payment.buyer_key` | string | no | A saved buyer token of this seller, instead of `card_number` and `card_expiry`. | | `customer` | object | no | Card holder details. Ignored when you send `payment.buyer_key`. | | `customer.name` | string | no | Card holder's name. | | `customer.email` | string | no | Card holder's email. | | `customer.phone` | string | no | Card holder's mobile number. | | `customer.social_id` | string | no | Card holder's national ID. | | `customer.zip_code` | string | no | Zip code. | | `customer.country` | string | no | Two-letter ISO country code. | | `customer.state` | string | no | State or region. | | `customer.city` | string | no | City. | | `customer.line1` | string | no | Address line 1. | | `customer.line2` | string | no | Address line 2. | | `meta_data_jwt` | string | no | The browser data from PayMe's JS library. Send this or `meta_data`; without either, the call fails with error `670`. | | `meta_data` | object | no | The browser data as a plain object, instead of `meta_data_jwt`. PayMe adds the buyer's IP and `Accept` header from the request, so send it from the buyer's browser. | | `meta_data.browser` | object | yes | Browser details: `userAgent`, `language`, `colorDepth`, `screen` (`height`, `width`), `timezone`, `javaEnabled` and `javaScriptEnabled`. | | `language` | string | no | Language of error messages: `he` (default), `en`, `es`, `ru` or `ar`. | ### Request example ```json { "payment": { "method": "credit-card", "card_number": "4111111111111111", "card_expiry": "1230" }, "customer": { "name": "Israel Israeli", "email": "buyer@example.com", "phone": "0500000000" }, "meta_data_jwt": "META_DATA_JWT_FROM_THE_LIBRARY" } ``` ## Code samples ### curl ```bash curl -X POST 'https://sandbox.payme.io/api/sales//3ds' \ -H 'Content-Type: application/json' \ -H 'PayMe-Public-Key: ' \ --data-raw '{ "payment": { "method": "credit-card", "card_number": "4111111111111111", "card_expiry": "1230" }, "customer": { "name": "Israel Israeli", "email": "buyer@example.com", "phone": "0500000000" }, "meta_data_jwt": "META_DATA_JWT_FROM_THE_LIBRARY" }' ``` ### Node.js ```javascript const response = await fetch("https://sandbox.payme.io/api/sales//3ds", { method: "POST", headers: { "Content-Type": "application/json", "PayMe-Public-Key": "", }, body: JSON.stringify({ "payment": { "method": "credit-card", "card_number": "4111111111111111", "card_expiry": "1230" }, "customer": { "name": "Israel Israeli", "email": "buyer@example.com", "phone": "0500000000" }, "meta_data_jwt": "META_DATA_JWT_FROM_THE_LIBRARY" }), }); console.log(await response.text()); ``` ### Python ```python import requests response = requests.post( "https://sandbox.payme.io/api/sales//3ds", headers={ "PayMe-Public-Key": "", }, json={ "payment": { "method": "credit-card", "card_number": "4111111111111111", "card_expiry": "1230", }, "customer": { "name": "Israel Israeli", "email": "buyer@example.com", "phone": "0500000000", }, "meta_data_jwt": "META_DATA_JWT_FROM_THE_LIBRARY", }, ) print(response.text) ``` ### PHP ```php /3ds'); curl_setopt_array($ch, [ CURLOPT_CUSTOMREQUEST => 'POST', CURLOPT_RETURNTRANSFER => true, CURLOPT_HTTPHEADER => [ 'Content-Type: application/json', 'PayMe-Public-Key: ', ], CURLOPT_POSTFIELDS => $body, ]); $response = curl_exec($ch); curl_close($ch); echo $response; ``` ## Responses ### 200 — Frictionless approval (`0`) or a challenge (`5`). (success) | Field | Type | Description | | --- | --- | --- | | `status_code` | integer | `0` frictionless approval: `hash_3dsecure` is returned. `5` challenge: send the buyer to `redirect_url`. | | `hash_3dsecure` | string | The encrypted 3DS result, when `status_code` is `0`. Resolve it with [Resolve a 3D Secure hash](/payments/standalone-3d-secure-service/get-sales-payme-sale-id-3ds-hash). | | `status_message` | string | A message you can show the buyer while redirecting, when `status_code` is `5`. | | `redirect_url` | string | The issuer's challenge page, when `status_code` is `5`. Open it with GET in the buyer's browser. | ```json { "status_code": 5, "status_message": "Generating validation page, please wait", "redirect_url": "https://sandbox.payme.io/3ds/redirect/SALE1700-000000AA-EXAMPLE1-SALE0001?pa=REDACTED" } ``` ### 400 — Browser data is missing, the sale uses another payment method, or 3D Secure was blocked. Codes: `4`, `670`, `720`. (error) | Field | Type | Description | | --- | --- | --- | | `status_code` | integer | `1` on failure. | | `status_error_details` | string | What went wrong, in the language you asked for (Hebrew by default). | | `status_additional_info` | string | The field or value concerned. Can be `null`. | | `status_error_code` | integer | PayMe error code. See the error table above and [Errors](/payments/getting-started/errors). | | `session` | string | PayMe session ID. Quote it when you contact support. | ```json { "status_code": 1, "status_error_details": "Meta data details are missing", "status_additional_info": null, "status_error_code": 670, "session": "a1B2c3D4" } ``` ### 500 — 3D Secure isn't available, the sale wasn't found, or the card data is invalid. See the error table. (error) | Field | Type | Description | | --- | --- | --- | | `status_code` | integer | `1` on failure. | | `status_error_details` | string | What went wrong, in the language you asked for (Hebrew by default). | | `status_additional_info` | string | The field or value concerned. Can be `null`. | | `status_error_code` | integer | PayMe error code. See the error table above and [Errors](/payments/getting-started/errors). | | `session` | string | PayMe session ID. Quote it when you contact support. | ```json { "status_code": 1, "status_error_details": "Invalid credit card expiry", "status_additional_info": "1221f", "status_error_code": 356, "session": "a1B2c3D4" } ``` - [Resolve a 3D Secure hash](https://docs.payme.io/payments/standalone-3d-secure-service/get-sales-payme-sale-id-3ds-hash): GET /sales/{payme_sale_id}/3ds/{hash_3dsecure} — Resolve a 3D Secure hash # Resolve a 3D Secure hash - Sandbox: `GET https://sandbox.payme.io/api/sales/{payme_sale_id}/3ds/{hash_3dsecure}` - Production: `GET https://live.payme.io/api/sales/{payme_sale_id}/3ds/{hash_3dsecure}` ## Credentials - Header `PayMe-Merchant-Key` (API key) ## Overview Decodes the `hash_3dsecure` from [Start 3D Secure authentication](/payments/standalone-3d-secure-service/post-initialize-3dsecure-request), or from the challenge page, into the 3DS values to send to your gateway: `eci`, `cavv` and `xid`. Call it from your server: the `PayMe-Merchant-Key` header carries the seller's MPL, which must stay secret. The whole flow: [Standalone 3D Secure: process flow](/payments/standalone-3d-secure-service). If authentication failed, the result has a non-null `status`, no `cavv`, and `status_code` `1`. ## Parameters | Name | In | Type | Required | Description | | --- | --- | --- | --- | --- | | `payme_sale_id` | path | string | yes | Our unique sale ID. | | `hash_3dsecure` | path | string | yes | The secured hash sent from PayMe (`hash_3dsecure`). | | `PayMe-Merchant-Key` | header | string | yes | The MPL of the seller. | ## Code samples ### curl ```bash curl -X GET 'https://sandbox.payme.io/api/sales//3ds/' \ -H 'PayMe-Merchant-Key: ' ``` ### Node.js ```javascript const response = await fetch("https://sandbox.payme.io/api/sales//3ds/", { method: "GET", headers: { "PayMe-Merchant-Key": "", }, }); console.log(await response.text()); ``` ### Python ```python import requests response = requests.get( "https://sandbox.payme.io/api/sales//3ds/", headers={ "PayMe-Merchant-Key": "", }, ) print(response.text) ``` ### PHP ```php /3ds/'); curl_setopt_array($ch, [ CURLOPT_CUSTOMREQUEST => 'GET', CURLOPT_RETURNTRANSFER => true, CURLOPT_HTTPHEADER => [ 'PayMe-Merchant-Key: ', ], ]); $response = curl_exec($ch); curl_close($ch); echo $response; ``` ## Responses ### 200 — OK (success) | Field | Type | Description | | --- | --- | --- | | `xid` | string | The XID generated by the credit card issuer. | | `eci` | string | The ECI generated by the credit card issuer. | | `cavv` | string | The CAVV generated by the credit card issuer. | | `version` | string | The 3D Secure version used. | | `mid` | string | The MID, when there is one. | | `status` | string | `null` when authentication succeeded. Otherwise the failure status. | | `payParameters` | object | Payment parameters stored with the authentication, such as `installments`. An empty array (`[]`) when there are none. | | `status_code` | integer | `0` when `status` is `null`, otherwise `1`. | ```json { "xid": "XXXXXXXXXXXXXXXXXXXXXXXXXXXX", "eci": "05", "cavv": "XXXXXXXXXXXXXXXXXXXXXXXXXXXX", "version": "2.2.0", "mid": null, "status": null, "payParameters": [], "status_code": 0 } ``` ### 400 — The hash could not be read. Codes: 1, 20. (error) | Field | Type | Description | | --- | --- | --- | | `status_code` | integer | `1` on failure. | | `status_error_details` | string | What went wrong. | | `status_additional_info` | string | The field or value concerned; can be `null`. | | `status_error_code` | integer | PayMe error code. | | `session` | string | PayMe session ID. | ```json { "status_code": 1, "status_error_details": "Validation error", "status_additional_info": "eyJpdiI6Ilp...", "status_error_code": 20, "session": "a1B2c3D4" } ``` ### 401 — The `PayMe-Merchant-Key` header is missing (the body is then only `{"error": "Unauthenticated."}`), or the seller or its partner is unknown or inactive. Codes: 163, 200, 201, 251. (error) | Field | Type | Description | | --- | --- | --- | | `status_code` | integer | `1` on failure. | | `status_error_details` | string | What went wrong. | | `status_additional_info` | string | The field or value concerned; can be `null`. | | `status_error_code` | integer | PayMe error code. | | `session` | string | PayMe session ID. | ```json { "status_code": 1, "status_error_details": "Seller was not found", "status_additional_info": "seller_payme_id", "status_error_code": 251, "session": "a1B2c3D4" } ``` ### 403 — The sale does not belong to this seller, or the hash belongs to another sale. Code: 303. (error) | Field | Type | Description | | --- | --- | --- | | `status_code` | integer | `1` on failure. | | `status_error_details` | string | What went wrong. | | `status_additional_info` | string | The field or value concerned; can be `null`. | | `status_error_code` | integer | PayMe error code. | | `session` | string | PayMe session ID. | ```json { "status_code": 1, "status_error_details": "Could not access sale", "status_additional_info": null, "status_error_code": 303, "session": "a1B2c3D4" } ``` ### 404 — No sale has this ID. Code: 350. (error) | Field | Type | Description | | --- | --- | --- | | `status_code` | integer | `1` on failure. | | `status_error_details` | string | What went wrong. | | `status_additional_info` | string | The field or value concerned; can be `null`. | | `status_error_code` | integer | PayMe error code. | | `session` | string | PayMe session ID. | ```json { "status_code": 1, "status_error_details": "Sale was not found", "status_additional_info": "SALEDEMO-SALEDEMO-SALEDEMO-1234567", "status_error_code": 350, "session": "a1B2c3D4" } ``` ## Merchants Management - [Create a seller](https://docs.payme.io/payments/merchants-management/post-create-seller): POST /create-seller — Create a seller # Create a seller - Sandbox: `POST https://sandbox.payme.io/api/create-seller` - Production: `POST https://live.payme.io/api/create-seller` ## Credentials - Request body field `payme_client_key` (required): Your partner key. Partners only. Creates a seller under your partner account and returns its `seller_payme_id` (MPL), its public key, and a link where the seller finishes onboarding. Partners only: send your `payme_client_key`. A seller's MPL can't be used to create sellers. For the whole onboarding flow, see [Create sellers](/marketplaces-and-platforms/seller-onboarding/create-seller). PayMe sets which fields are required for your account. A missing required field returns error `19`, with the field name in `status_additional_info`. The **Required** column below shows the usual setup. `seller_email` is always required and must be unique among your sellers (error `150`). `seller_id`, if you send it, must also be unique among your sellers (error `108`). Other fields can be enabled for your account by PayMe. The call is limited to 5 requests per minute per IP. Over the limit, or while a call for the same `seller_email` is still running, you get HTTP 429 with error `998`. Wait and retry. ### Testing in the sandbox Field | Test value ---|--- `seller_social_id` | `9999999999`. PayMe replaces it with a random valid ID. `seller_email` | `random@paymeservice.com`. PayMe replaces it with a unique address and sends no emails. `seller_bank_code` | `54` `seller_bank_branch` | Any 3 digits, for example `123` `seller_bank_account_number` | Any 6 digits, for example `123456` ### Callback When the seller is created or updated, PayMe sends a seller callback (`POST`, `x-www-form-urlencoded`) to your default callback URL. The fields are listed on [Callbacks → Sellers](/payments/getting-started/callbacks#sellers-partners). ### Errors Every error returns `status_code` `1` with the code in `status_error_code`. The common ones: Code | Meaning ---|--- `1` | A required parameter is missing, for example `payme_client_key`. `5` | `seller_description` is longer than 255 characters. `13` | `seller_email` is missing or invalid. `19` | A field your account requires is missing. `status_additional_info` names it. `25` | Invalid phone number. `57` | `seller_merchant_name_en` or `seller_dba_en` isn't in Latin characters. `101` | Invalid national ID number. `106` | Unknown `seller_bank_code`. `108` | `seller_id` is already used by another of your sellers. `110` | Unknown or inactive business field in `seller_person_business_type`. `114` | Unknown incorporation type, a type from another country than `seller_address_country`, or a `seller_inc_code` that doesn't fit the type. `116` / `117` / `118` | Invalid birth date / registration date / ID issue date. `119` | Invalid `seller_retail_type`. `120` | Invalid characters in `seller_merchant_name`. `121` | `seller_inc_code` isn't a number. `131` | Invalid `seller_gender`. `150` | `seller_email` is already used by another of your sellers. `160` | An item in `seller_additional_details` has no `type`, or one of its files isn't an individual file type. `165` | Invalid bank branch or account number. `304` | `market_fee` is outside 0–60. `912` | Unknown `seller_address_country`. `998` | HTTP 429: over the rate limit, or a call for the same `seller_email` is still running. The full list is on [Errors](/payments/getting-started/errors). ## Parameters This endpoint takes no path, query or header parameters. ## Request body Content type: `application/json` | Field | Type | Required | Description | | --- | --- | --- | --- | | `payme_client_key` | string | yes | Your partner key. Partners only. | | `seller_id` | string | no | Your own ID for the seller. Must be unique among your sellers (error `108`). | | `seller_first_name` | string | yes | First name of the seller's owner (the seller's primary individual). | | `seller_last_name` | string | yes | Last name of the seller's owner. | | `seller_social_id` | string | yes | National ID number of the seller's owner. An invalid number returns error `101`. In the sandbox, `9999999999` is replaced with a random valid ID. | | `seller_birthdate` | string | yes | Seller's personal birth date. Required by default; PayMe can change this per partner. Format `dd/mm/yyyy` with leading zeros only: `06/05/1989` is accepted, `6/5/1989` and `06-05-1989` are rejected. The person must be at least 16. Responses return `yyyy-mm-dd`. | | `seller_social_id_issued` | string | yes | Seller's personal social ID issuing day. Required by default; PayMe can change this per partner. Format `dd/mm/yyyy` with leading zeros only. Responses return `yyyy-mm-dd`. | | `seller_gender` | integer | yes | `0` – male, `1` – female, `2` – other. Another value returns error `131`. | | `seller_email` | string | yes | The seller's email address. Always required. It must be unique among your sellers (error `150`), and an invalid address returns error `13`. In the sandbox, `random@paymeservice.com` is replaced with a unique address. | | `seller_phone` | string | yes | Seller phone number, supplied as a string. Mobile and landline formats are supported; international format with country code is recommended. Local numbers are interpreted using the seller's country, Israel by default. Phone validation or normalization failures return error `25`. | | `seller_contact_email` | string | no | Seller's contact email, shown to buyers. If not sent, it is copied from `seller_email`. | | `seller_contact_phone` | string | no | Phone number shown to buyers. If you don't send it, it is copied from `seller_phone`. | | `seller_bank_code` | integer | yes | Bank code. See [Banks in Israel](/payments/codes-statuses/banks-in-israel). An unknown code returns error `106`. | | `seller_bank_branch` | integer | yes | Bank branch number, up to 3 digits. An invalid branch returns error `165`. | | `seller_bank_account_number` | string | yes | Bank account number, digits only. An invalid number returns error `165`. | | `seller_description` | string | no | Seller’s description, including offered product line and services. Limited to 255 characters (error `5`). | | `seller_site_url` | string | yes | The seller's website URL. | | `seller_person_business_type` | integer | yes | Business field code (the seller's line of business). See [Business field codes](/marketplaces-and-platforms/seller-reference/mcc-list), or get the live list from [List business fields](/payments/merchants-management/get-business-fields). An unknown or inactive code returns error `110`. | | `seller_inc` | integer | yes | Incorporation type, see [Seller incorporation types](/marketplaces-and-platforms/seller-reference/seller-incorporation-types-il). Required by default; PayMe can change this per partner. The type must belong to the seller's country (`seller_address_country`, default Israel), otherwise error `114`. If you send `seller_inc` without `seller_person_business_type`, the business field defaults to `205`. | | `seller_inc_code` | string | no | Seller's business ID (ח.פ, ע.מ). May be required for your account (PayMe configures this per partner). When sent, it must be a number, 0 or above, otherwise the request fails with error `121`. For Israeli sellers, Individual, Sole Proprietorship and Exempt Sole Proprietorship must use the owner's national ID; other types must not equal the national ID and must start with that type's 2-digit company-registry prefix. Otherwise the request fails with error `114`. | | `seller_registration_date` | string | no | Seller's business registration date. May be required for your account (PayMe configures this per partner). Format `dd/mm/yyyy` with leading zeros only: `01/02/2020` is accepted, `1/2/2020` and `01-02-2020` are rejected. Responses return `yyyy-mm-dd`. | | `seller_retail_type` | integer | no | `1` – card not present (online), `2` – card present, `4` – MOTO (phone or mail order). Another value returns error `119`. | | `seller_merchant_name` | string | no | The business's name. Invalid characters return error `120`. May be required for your account (PayMe configures this per partner). | | `seller_merchant_name_en` | string | no | The business's name in English. Latin characters only (error `57`). | | `seller_dba` | string | no | The seller's legal (registered) name in Hebrew. | | `seller_dba_en` | string | no | The seller's legal (registered) name in English. Latin characters only (error `57`). | | `seller_address_city` | string | yes | Business address: city. | | `seller_address_street` | string | yes | Business address: street. | | `seller_address_street_number` | string | yes | Business address: street number. | | `seller_address_country` | string | no | Business address: country, as an ISO 3166-1 alpha-2 code such as `IL`. Default Israel. An unknown code returns error `912`. | | `seller_first_name_en` | string | no | The seller's first name in English. | | `seller_last_name_en` | string | no | The seller's last name in English. | | `seller_address_state` | string | no | State or region of the business address, for sellers outside Israel. | | `seller_address_zip` | string | no | Postal code of the business address. | | `seller_file_social_id` | string | no | Public URL of the owner's ID card (file type `1`). PayMe downloads it in the background. To upload other documents, use [Upload seller files](/payments/merchants-management/post-upload-seller-files). | | `seller_file_cheque` | string | no | Public URL of a bank account confirmation or a cancelled cheque (file type `2`). PayMe downloads it in the background. | | `seller_file_corporate` | string | no | Public URL of the incorporation certificate (file type `3`). PayMe downloads it in the background. | | `market_fee` | number | no | The seller's default platform fee: the percent of the sale price collected for you, from `0` to `60` (for example `2.5`). It includes VAT and is added on top of PayMe's fees. Default `0`. Out of range returns error `304`. A sale can override it with its own `market_fee`. It can't be changed later with Update a seller; see [Platform fees](/marketplaces-and-platforms/fees-and-payouts/platform-fees). | | `seller_plan` | string | no | A predefined set of settings for the seller. If required, this value will be provided by your Account Manager. Required unless your account has a default plan. | | `seller_additional_details` | array | no | More people in the business, such as owners, signatories and directors. One object per person. | | `seller_additional_details[].first_name` | string | no | First name. | | `seller_additional_details[].last_name` | string | no | Last name. | | `seller_additional_details[].national_id` | string | no | National ID number. | | `seller_additional_details[].social_id_issued` | string | no | ID issue date, `dd/mm/yyyy`. | | `seller_additional_details[].date_of_birth` | string | no | Date of birth, `dd/mm/yyyy`. | | `seller_additional_details[].email` | string | no | Email address. | | `seller_additional_details[].phone` | string | no | Phone number. | | `seller_additional_details[].type` | array | yes | The person's roles, as an array of [individual role](/marketplaces-and-platforms/seller-reference/individual-seller-types) codes, for example `[1, 2]` for an owner who is also a signatory. Missing returns error `160`. | | `seller_additional_details[].business_title` | string | no | Job title in the business. | | `seller_additional_details[].ownership_percent` | number | no | Ownership share, percent. | | `seller_additional_details[].address_country` | string | no | Address: country. | | `seller_additional_details[].address_state` | string | no | Address: state or region. | | `seller_additional_details[].address_city` | string | no | Address: city. | | `seller_additional_details[].address_street` | string | no | Address: street. | | `seller_additional_details[].address_building_number` | string | no | Address: building number. | | `seller_additional_details[].address_zip` | string | no | Address: postal code. | | `seller_additional_details[].files` | array | no | The person's documents. Only individual file types `90`–`97` are accepted (see [File types](/marketplaces-and-platforms/seller-reference/file-types)); another type returns error `160`. | | `seller_additional_details[].files[].type` | integer | yes | File type code, `90`–`97`. See [File types](/marketplaces-and-platforms/seller-reference/file-types). | | `seller_additional_details[].files[].url` | string | no | Public URL of the file. Send `url` or `base64`. | | `seller_additional_details[].files[].base64` | string | no | The file content, base64-encoded. Send `url` or `base64`. | | `seller_additional_details[].files[].name` | string | no | File name with extension, for example `id-front.jpg`. | | `seller_additional_details[].files[].mime_type` | string | no | MIME type of the file, for example `image/jpeg` or `application/pdf`. | | `language` | string | no | Language of error messages: `he` (default) or `en`. | ### Request example ```json { "payme_client_key": "XXXXXXXX", "seller_id": "store-1001", "seller_first_name": "Dana", "seller_last_name": "Levi", "seller_social_id": "9999999999", "seller_birthdate": "06/05/1989", "seller_social_id_issued": "01/02/2015", "seller_gender": 1, "seller_email": "random@paymeservice.com", "seller_phone": "+972501234567", "seller_bank_code": 54, "seller_bank_branch": 123, "seller_bank_account_number": "123456", "seller_description": "Handmade ceramics", "seller_site_url": "https://www.example.com", "seller_person_business_type": 205, "seller_inc": 1, "seller_merchant_name": "Dana Ceramics", "seller_address_city": "Tel Aviv", "seller_address_street": "Herzl", "seller_address_street_number": "10", "seller_address_country": "IL", "market_fee": 2.5, "language": "en" } ``` ## Code samples ### curl ```bash curl -X POST 'https://sandbox.payme.io/api/create-seller' \ -H 'Content-Type: application/json' \ --data-raw '{ "payme_client_key": "XXXXXXXX", "seller_id": "store-1001", "seller_first_name": "Dana", "seller_last_name": "Levi", "seller_social_id": "9999999999", "seller_birthdate": "06/05/1989", "seller_social_id_issued": "01/02/2015", "seller_gender": 1, "seller_email": "random@paymeservice.com", "seller_phone": "+972501234567", "seller_bank_code": 54, "seller_bank_branch": 123, "seller_bank_account_number": "123456", "seller_description": "Handmade ceramics", "seller_site_url": "https://www.example.com", "seller_person_business_type": 205, "seller_inc": 1, "seller_merchant_name": "Dana Ceramics", "seller_address_city": "Tel Aviv", "seller_address_street": "Herzl", "seller_address_street_number": "10", "seller_address_country": "IL", "market_fee": 2.5, "language": "en" }' ``` ### Node.js ```javascript const response = await fetch("https://sandbox.payme.io/api/create-seller", { method: "POST", headers: { "Content-Type": "application/json", }, body: JSON.stringify({ "payme_client_key": "XXXXXXXX", "seller_id": "store-1001", "seller_first_name": "Dana", "seller_last_name": "Levi", "seller_social_id": "9999999999", "seller_birthdate": "06/05/1989", "seller_social_id_issued": "01/02/2015", "seller_gender": 1, "seller_email": "random@paymeservice.com", "seller_phone": "+972501234567", "seller_bank_code": 54, "seller_bank_branch": 123, "seller_bank_account_number": "123456", "seller_description": "Handmade ceramics", "seller_site_url": "https://www.example.com", "seller_person_business_type": 205, "seller_inc": 1, "seller_merchant_name": "Dana Ceramics", "seller_address_city": "Tel Aviv", "seller_address_street": "Herzl", "seller_address_street_number": "10", "seller_address_country": "IL", "market_fee": 2.5, "language": "en" }), }); console.log(await response.text()); ``` ### Python ```python import requests response = requests.post( "https://sandbox.payme.io/api/create-seller", json={ "payme_client_key": "XXXXXXXX", "seller_id": "store-1001", "seller_first_name": "Dana", "seller_last_name": "Levi", "seller_social_id": "9999999999", "seller_birthdate": "06/05/1989", "seller_social_id_issued": "01/02/2015", "seller_gender": 1, "seller_email": "random@paymeservice.com", "seller_phone": "+972501234567", "seller_bank_code": 54, "seller_bank_branch": 123, "seller_bank_account_number": "123456", "seller_description": "Handmade ceramics", "seller_site_url": "https://www.example.com", "seller_person_business_type": 205, "seller_inc": 1, "seller_merchant_name": "Dana Ceramics", "seller_address_city": "Tel Aviv", "seller_address_street": "Herzl", "seller_address_street_number": "10", "seller_address_country": "IL", "market_fee": 2.5, "language": "en", }, ) print(response.text) ``` ### PHP ```php 'POST', CURLOPT_RETURNTRANSFER => true, CURLOPT_HTTPHEADER => [ 'Content-Type: application/json', ], CURLOPT_POSTFIELDS => $body, ]); $response = curl_exec($ch); curl_close($ch); echo $response; ``` ## Responses ### 200 — OK (success) | Field | Type | Description | | --- | --- | --- | | `status_code` | integer | `0` on success. | | `session` | string | PayMe session ID. | | `seller_payme_id` | string | The new seller's MPL. Use it on every call for this seller and keep it on your server. | | `seller_payme_secret` | string | Not a credential: a random value that PayMe does not store or check. Ignore it (see [Authentication](/payments/getting-started/authentication)). | | `seller_public_key` | object | The seller's public key, for browser code such as Hosted Fields. | | `seller_public_key.uuid` | string | The public key. | | `seller_public_key.description` | string | Name of the key. | | `seller_public_key.is_active` | boolean | `true` when the key is active. | | `seller_id` | string | Your own ID for the seller, as you sent it. | | `seller_dashboard_signup_link` | string | Link where the seller sets a password and finishes onboarding. Send it to the seller. Its host depends on your partner account and may differ from the API host, so use it as returned and don't build it yourself. | ```json { "status_code": 0, "session": "a1B2c3D4", "seller_payme_id": "MPLDEMO-MPLDEMO-MPLDEMO-1234567", "seller_payme_secret": "Qw3rTy7uI9oP1aS5dF8gH2jK4lZ6xC", "seller_public_key": { "uuid": "12345678-1234-4abc-9def-123456789012", "description": "PayMe-Public-Key", "is_active": true }, "seller_id": "store-1001", "seller_dashboard_signup_link": "https:///" } ``` ### 500 — Error, for example error `150`: the email address is already used by another of your sellers (error) | Field | Type | Description | | --- | --- | --- | | `status_code` | integer | `1` on failure. | | `status_error_code` | integer | PayMe error code. See [Errors](/payments/getting-started/errors). | | `status_error_details` | string | Error message, in the request's `language`. | | `status_additional_info` | string | Extra detail, such as the name of the missing or invalid field. Can be `null`. | | `session` | string | PayMe session ID. Quote it when you contact support. | ```json { "status_code": 1, "status_error_details": "Email is already in use", "status_additional_info": null, "status_error_code": 150, "session": "a1B2c3D4" } ``` ### 429 — Too many requests (error `998`) (error) | Field | Type | Description | | --- | --- | --- | | `status_code` | integer | `1` on failure. | | `status_error_code` | integer | PayMe error code. See [Errors](/payments/getting-started/errors). | | `status_error_details` | string | Error message, in the request's `language`. | | `status_additional_info` | string | Extra detail, such as the name of the missing or invalid field. Can be `null`. | | `session` | string | PayMe session ID. Quote it when you contact support. | ```json { "status_code": 1, "status_error_details": "Operation is not permitted", "status_additional_info": "Too Many Attempts.", "status_error_code": 998, "session": "a1B2c3D4" } ``` - [Update a seller](https://docs.payme.io/payments/merchants-management/post-update-seller): POST /update-seller — Update a seller # Update a seller - Sandbox: `POST https://sandbox.payme.io/api/update-seller` - Production: `POST https://live.payme.io/api/update-seller` ## Credentials - Request body field `payme_client_key` (required): Your partner key. - Request body field `seller_payme_id` (optional): The seller's MPL. Required unless you send `seller_id`. Changes the details of one of your sellers. Partners only: send your `payme_client_key`, the seller's `seller_payme_id` (or your own `seller_id` for the seller), and only the fields you want to change. Every other field is optional. PayMe sets, per partner, which fields can still be changed once they have a value. Changing a locked field that already has a value returns error `33`. A request with no updatable field returns error `19`. The response returns the seller's details after the update. The seller's default `market_fee` can't be changed with this call. To change it, contact PayMe Partners (partners@payme.io). The per-sale `market_fee` on generate-sale is not affected. `seller_additional_details` adds people to the seller. It doesn't change or remove the people already on file. In the sandbox, the test values listed on [Create a seller](/payments/merchants-management/post-create-seller) work here too. ### Callback After the update, PayMe sends a seller callback (`POST`, `x-www-form-urlencoded`) to your default callback URL. The fields are listed on [Callbacks → Sellers](/payments/getting-started/callbacks#sellers-partners). ### Errors Every error returns `status_code` `1` with the code in `status_error_code`. Besides the field validation errors listed on [Create a seller](/payments/merchants-management/post-create-seller): Code | Meaning ---|--- `1` | A required parameter is missing. `19` | No updatable field was sent. `33` | A locked field that already has a value was changed. `251` | No seller has this `seller_payme_id`. `163` | The seller is inactive. `20` | The seller belongs to another partner. The full list is on [Errors](/payments/getting-started/errors). ## Parameters This endpoint takes no path, query or header parameters. ## Request body Content type: `application/json` | Field | Type | Required | Description | | --- | --- | --- | --- | | `payme_client_key` | string | yes | Your partner key. | | `seller_payme_id` | string | no | The seller's MPL. Required unless you send `seller_id`. | | `seller_id` | string | no | Your own ID for the seller, as sent on Create a seller. Use it with `payme_client_key` instead of `seller_payme_id` to identify the seller. It can't be changed. | | `seller_first_name` | string | no | First name of the seller's owner. | | `seller_last_name` | string | no | Last name of the seller's owner. | | `seller_social_id` | string | no | National ID number of the seller's owner. An invalid number returns error `101`. | | `seller_birthdate` | string | no | Seller's personal birth date. Format `dd/mm/yyyy` with leading zeros only: `06/05/1989` is accepted, `6/5/1989` and `06-05-1989` are rejected. The person must be at least 16. Responses return `yyyy-mm-dd`. | | `seller_social_id_issued` | string | no | Seller's personal social ID issuing day. Format `dd/mm/yyyy` with leading zeros only. Responses return `yyyy-mm-dd`. | | `seller_gender` | integer | no | `0` – male, `1` – female, `2` – other. Another value returns error `131`. | | `seller_email` | string | no | The seller's email address. It must be unique among your sellers (error `150`). | | `seller_phone` | string | no | Seller's phone number. | | `seller_contact_email` | string | no | Seller's contact email, shown to buyers. If the seller has no contact email, it is copied from `seller_email`. | | `seller_contact_phone` | string | no | Phone number shown to buyers. | | `seller_bank_code` | integer | no | Bank code. See [Banks in Israel](/payments/codes-statuses/banks-in-israel). An unknown code returns error `106`. | | `seller_bank_branch` | integer | no | Bank branch number, up to 3 digits. An invalid branch returns error `165`. | | `seller_bank_account_number` | string | no | Bank account number, digits only. An invalid number returns error `165`. | | `seller_description` | string | no | Seller’s description, including offered product line and services. Limited to 255 characters (error `5`). | | `seller_site_url` | string | no | The seller's website URL. | | `seller_person_business_type` | integer | no | Business field code (the seller's line of business). See [Business field codes](/marketplaces-and-platforms/seller-reference/mcc-list). An unknown or inactive code returns error `110`. | | `seller_inc` | integer | no | Incorporation type, see [Seller incorporation types](/marketplaces-and-platforms/seller-reference/seller-incorporation-types-il). The type must belong to the seller's country (`seller_address_country`, default Israel), otherwise error `114`. | | `seller_inc_code` | string | no | Seller's business ID (ח.פ, ע.מ). When sent, it must be a number, 0 or above, otherwise the request fails with error `121`. For Israeli sellers, Individual, Sole Proprietorship and Exempt Sole Proprietorship must use the owner's national ID; other types must not equal the national ID and must start with that type's 2-digit company-registry prefix. Otherwise the request fails with error `114`. | | `seller_registration_date` | string | no | Seller's business registration date. Format `dd/mm/yyyy` with leading zeros only: `01/02/2020` is accepted, `1/2/2020` and `01-02-2020` are rejected. Responses return `yyyy-mm-dd`. | | `seller_retail_type` | integer | no | `1` – card not present (online), `2` – card present, `4` – MOTO (phone or mail order). Another value returns error `119`. | | `seller_merchant_name` | string | no | The business's name. Invalid characters return error `120`. | | `seller_merchant_name_en` | string | no | The business's name in English. Latin characters only (error `57`). | | `seller_dba` | string | no | The seller's legal (registered) name in Hebrew. | | `seller_dba_en` | string | no | The seller's legal (registered) name in English. Latin characters only (error `57`). | | `seller_address_city` | string | no | Business address: city. | | `seller_address_street` | string | no | Business address: street. | | `seller_address_street_number` | string | no | Business address: street number. | | `seller_address_country` | string | no | Business address: country, as an ISO 3166-1 alpha-2 code such as `IL`. An unknown code returns error `912`. | | `seller_first_name_en` | string | no | The seller's first name in English. | | `seller_last_name_en` | string | no | The seller's last name in English. | | `seller_address_state` | string | no | State or region of the business address, for sellers outside Israel. | | `seller_address_zip` | string | no | Postal code of the business address. | | `seller_file_social_id` | string | no | Public URL of the owner's ID card (file type `1`). PayMe downloads it in the background. To upload other documents, use [Upload seller files](/payments/merchants-management/post-upload-seller-files). | | `seller_file_cheque` | string | no | Public URL of a bank account confirmation or a cancelled cheque (file type `2`). PayMe downloads it in the background. | | `seller_file_corporate` | string | no | Public URL of the incorporation certificate (file type `3`). PayMe downloads it in the background. | | `seller_plan` | string | no | A predefined set of settings for the seller. If required, this value will be provided by your Account Manager. | | `seller_additional_details` | array | no | Adds people to the seller, one object per person. People already on file are not changed. Each item has the same fields as on [Create a seller](/payments/merchants-management/post-create-seller). | | `seller_additional_details[].first_name` | string | no | First name. | | `seller_additional_details[].last_name` | string | no | Last name. | | `seller_additional_details[].national_id` | string | no | National ID number. | | `seller_additional_details[].social_id_issued` | string | no | ID issue date, `dd/mm/yyyy`. | | `seller_additional_details[].date_of_birth` | string | no | Date of birth, `dd/mm/yyyy`. | | `seller_additional_details[].email` | string | no | Email address. | | `seller_additional_details[].phone` | string | no | Phone number. | | `seller_additional_details[].type` | array | yes | The person's roles, as an array of [individual role](/marketplaces-and-platforms/seller-reference/individual-seller-types) codes, for example `[1, 2]` for an owner who is also a signatory. Missing returns error `160`. | | `seller_additional_details[].business_title` | string | no | Job title in the business. | | `seller_additional_details[].ownership_percent` | number | no | Ownership share, percent. | | `seller_additional_details[].address_country` | string | no | Address: country. | | `seller_additional_details[].address_state` | string | no | Address: state or region. | | `seller_additional_details[].address_city` | string | no | Address: city. | | `seller_additional_details[].address_street` | string | no | Address: street. | | `seller_additional_details[].address_building_number` | string | no | Address: building number. | | `seller_additional_details[].address_zip` | string | no | Address: postal code. | | `seller_additional_details[].files` | array | no | The person's documents. Only individual file types `90`–`97` are accepted (see [File types](/marketplaces-and-platforms/seller-reference/file-types)); another type returns error `160`. | | `seller_additional_details[].files[].type` | integer | yes | File type code, `90`–`97`. See [File types](/marketplaces-and-platforms/seller-reference/file-types). | | `seller_additional_details[].files[].url` | string | no | Public URL of the file. Send `url` or `base64`. | | `seller_additional_details[].files[].base64` | string | no | The file content, base64-encoded. Send `url` or `base64`. | | `seller_additional_details[].files[].name` | string | no | File name with extension, for example `id-front.jpg`. | | `seller_additional_details[].files[].mime_type` | string | no | MIME type of the file, for example `image/jpeg` or `application/pdf`. | | `language` | string | no | Language of error messages: `he` (default) or `en`. | ### Request example ```json { "payme_client_key": "XXXXXXXX", "seller_payme_id": "MPLDEMO-MPLDEMO-MPLDEMO-1234567", "seller_site_url": "https://www.example.com", "seller_contact_phone": "+972501234567", "language": "en" } ``` ## Code samples ### curl ```bash curl -X POST 'https://sandbox.payme.io/api/update-seller' \ -H 'Content-Type: application/json' \ --data-raw '{ "payme_client_key": "XXXXXXXX", "seller_payme_id": "MPLDEMO-MPLDEMO-MPLDEMO-1234567", "seller_site_url": "https://www.example.com", "seller_contact_phone": "+972501234567", "language": "en" }' ``` ### Node.js ```javascript const response = await fetch("https://sandbox.payme.io/api/update-seller", { method: "POST", headers: { "Content-Type": "application/json", }, body: JSON.stringify({ "payme_client_key": "XXXXXXXX", "seller_payme_id": "MPLDEMO-MPLDEMO-MPLDEMO-1234567", "seller_site_url": "https://www.example.com", "seller_contact_phone": "+972501234567", "language": "en" }), }); console.log(await response.text()); ``` ### Python ```python import requests response = requests.post( "https://sandbox.payme.io/api/update-seller", json={ "payme_client_key": "XXXXXXXX", "seller_payme_id": "MPLDEMO-MPLDEMO-MPLDEMO-1234567", "seller_site_url": "https://www.example.com", "seller_contact_phone": "+972501234567", "language": "en", }, ) print(response.text) ``` ### PHP ```php 'POST', CURLOPT_RETURNTRANSFER => true, CURLOPT_HTTPHEADER => [ 'Content-Type: application/json', ], CURLOPT_POSTFIELDS => $body, ]); $response = curl_exec($ch); curl_close($ch); echo $response; ``` ## Responses ### 200 — OK (success) | Field | Type | Description | | --- | --- | --- | | `status_code` | integer | `0` on success. | | `session` | string | PayMe session ID. | | `seller_payme_id` | string | The seller's MPL. | | `seller_id` | string | Your own ID for the seller, or `null`. | | `seller_created` | string | When the seller was created, `yyyy-mm-dd hh:mm:ss`. | | `seller_active` | boolean | `true` when the seller is active. | | `seller_approved` | boolean | `true` when PayMe has approved the seller. Payouts need approval. | | `seller_is_deferred` | boolean | `true` when the seller has a deferred account. | | `seller_approved_date` | string | When PayMe approved the seller, or `null`. | | `seller_withdrawal_plan` | integer | `1` – manual, `2` – daily, `3` – monthly. | | `seller_withdrawal_date` | integer | Day of the month of the payout when `seller_withdrawal_plan` is `3`, otherwise `null`. | | `seller_allow_foreign_cards` | boolean | `true` when the seller accepts foreign cards. | | `seller_personal_details` | object | The seller's owner (primary individual). | | `seller_personal_details.seller_first_name` | string | First name. | | `seller_personal_details.seller_last_name` | string | Last name. | | `seller_personal_details.seller_social_id` | string | National ID number. | | `seller_personal_details.seller_social_id_issued` | string | ID issue date, `yyyy-mm-dd`. | | `seller_personal_details.seller_birthdate` | string | Date of birth, `yyyy-mm-dd`. | | `seller_personal_details.seller_date_of_birth` | string | Legacy copy of `seller_birthdate`. | | `seller_personal_details.seller_gender` | integer | `0` – male, `1` – female, `2` – other. | | `seller_personal_details.seller_email` | string | The seller's email address. | | `seller_personal_details.seller_phone` | string | The seller's phone number. | | `seller_personal_details.seller_first_name_en` | string | First name in English. | | `seller_personal_details.seller_last_name_en` | string | Last name in English. | | `seller_personal_details.seller_social_id_country` | string | Country that issued the ID, ISO 3166-1 alpha-2. | | `seller_personal_details.seller_has_criminal_record` | boolean | As declared during onboarding, or `null`. | | `seller_business_details` | object | The business. | | `seller_business_details.seller_inc` | integer | Incorporation type. `0` for a private individual. | | `seller_business_details.seller_inc_code` | string | Business registration number. | | `seller_business_details.seller_registration_date` | string | Business registration date, `yyyy-mm-dd`. | | `seller_business_details.seller_merchant_name` | string | The business's name. | | `seller_business_details.seller_merchant_name_en` | string | The business's name in English. | | `seller_business_details.seller_dba` | string | Legal (registered) name in Hebrew. | | `seller_business_details.seller_dba_en` | string | Legal (registered) name in English. | | `seller_business_details.seller_business_type` | integer | Business field code, as sent in `seller_person_business_type`. | | `seller_business_details.seller_site_url` | string | Website URL. | | `seller_business_details.seller_description` | string | Description of the business. | | `seller_business_details.seller_retail_type` | integer | `1` – card not present, `2` – card present, `4` – MOTO. | | `seller_business_details.seller_contact_email` | string | Contact email shown to buyers. | | `seller_business_details.seller_contact_phone` | string | Contact phone shown to buyers. | | `seller_business_details.seller_bank_account_code` | integer | Bank code (sent as `seller_bank_code`). | | `seller_business_details.seller_bank_account_branch` | integer | Bank branch (sent as `seller_bank_branch`). | | `seller_business_details.seller_bank_account_number` | string | Bank account number. | | `seller_business_details.seller_need_foreign_currency` | boolean | Whether the seller asked to work in foreign currencies, or `null`. | | `seller_business_details.seller_was_rejected_by_bank` | boolean | Whether a bank rejected the seller before, as declared, or `null`. | | `seller_business_details.seller_bank_rejection_reason` | string | The declared reason for the bank rejection, or `null`. | | `seller_business_details.seller_source_of_finance` | string | Declared source of finance, as an enum name, or `null`. | | `seller_business_details.seller_required_service_type` | string | Declared required service type, as an enum name, or `null`. | | `seller_business_details.seller_account_type` | string | Account type, as an enum name. | | `seller_address` | object | The business address. | | `seller_address.seller_address_city` | string | City. | | `seller_address.seller_address_street` | string | Street. | | `seller_address.seller_address_street_number` | string | Street number. | | `seller_address.seller_address_country` | string | Country, ISO 3166-1 alpha-2. | | `seller_processing_percent` | number | How much of the seller's processing limit is used, percent. | | `seller_processing_limit` | number | The seller's processing limit. | | `seller_timezone` | string | The seller's time zone, for example `Asia/Jerusalem`. | | `seller_display_language` | string | The seller's language, for example `he` or `en`. | ```json { "status_code": 0, "session": "a1B2c3D4", "seller_payme_id": "MPLDEMO-MPLDEMO-MPLDEMO-1234567", "seller_id": "store-1001", "seller_created": "2026-01-15 10:30:00", "seller_active": true, "seller_approved": true, "seller_withdrawal_plan": 1, "seller_withdrawal_date": null, "seller_personal_details": { "seller_first_name": "Dana", "seller_last_name": "Levi", "seller_gender": 1, "seller_email": "dana@example.com" }, "seller_business_details": { "seller_inc": 0, "seller_merchant_name": "Dana Ceramics", "seller_site_url": "https://www.example.com", "seller_contact_phone": "+972501234567" }, "seller_address": { "seller_address_city": "Tel Aviv", "seller_address_country": "IL" }, "seller_display_language": "he" } ``` ### 500 — Error, for example error `33`: a locked field already has a value (error) | Field | Type | Description | | --- | --- | --- | | `status_code` | integer | `1` on failure. | | `status_error_code` | integer | PayMe error code. See [Errors](/payments/getting-started/errors). | | `status_error_details` | string | Error message, in the request's `language`. | | `status_additional_info` | string | Extra detail, such as the name of the missing or invalid field. Can be `null`. | | `session` | string | PayMe session ID. Quote it when you contact support. | ```json { "status_code": 1, "status_error_details": "Cannot update as field is already set", "status_additional_info": "seller_bank_account_number", "status_error_code": 33, "session": "a1B2c3D4" } ``` - [Upload seller files](https://docs.payme.io/payments/merchants-management/post-upload-seller-files): POST /upload-seller-files — Upload seller files # Upload seller files - Sandbox: `POST https://sandbox.payme.io/api/upload-seller-files` - Production: `POST https://live.payme.io/api/upload-seller-files` ## Credentials - Request body field `payme_client_key` (required): Your partner key. - Request body field `seller_payme_id` (optional): The seller's MPL. Required unless you send `seller_id`. Uploads KYC documents for one of your sellers, such as an ID card or a bank account confirmation. Partners only: send your `payme_client_key` and the seller's `seller_payme_id` (or your own `seller_id` for the seller). Send one file or several in `seller_files`. Each file is either a public `url` that PayMe downloads, or the file content in `base64`. Set each file's `type` from [File types](/marketplaces-and-platforms/seller-reference/file-types). Types `90`–`97` are personal documents. They are attached to the seller's primary individual, and the call fails with error `184` if the seller has more than one individual. All other types are attached to the seller. Allowed extensions: `pdf`, `jpg`, `jpeg`, `jfif`, `png`, `bmp`, `tif`, `tiff`, `doc`, `docx`, and `mp4`, `avi`, `mov`, `webm` for video (used for the face-to-face video, type `97`). Allowed MIME types include `application/pdf`, `image/jpeg`, `image/png`, `image/heic`, `image/tiff`, `application/msword`, `video/mp4` and `video/quicktime`. ### Errors Every error returns `status_code` `1` with the code in `status_error_code`. Code | When ---|--- `1` | `seller_files` is missing or empty (HTTP 400), or a file has neither `url` nor `base64`. `20` | A file's `type` is missing or not an integer (HTTP 400), or isn't a known file type. `184` | A personal document (types `90`–`97`) was sent for a seller with more than one individual. `904` | The file extension isn't allowed. `905` | The `mime_type` isn't allowed. `909` | PayMe can't read the file. The full list is on [Errors](/payments/getting-started/errors). ## Parameters This endpoint takes no path, query or header parameters. ## Request body Content type: `application/json` | Field | Type | Required | Description | | --- | --- | --- | --- | | `payme_client_key` | string | yes | Your partner key. | | `seller_payme_id` | string | no | The seller's MPL. Required unless you send `seller_id`. | | `seller_id` | string | no | Your own ID for the seller, as sent on Create a seller. Use it instead of `seller_payme_id`. | | `seller_files` | array | yes | The files to upload, at least one. | | `seller_files[].type` | integer | yes | Document type code, see [File types](/marketplaces-and-platforms/seller-reference/file-types). Missing or not an integer returns error `20`. | | `seller_files[].url` | string | no | Public URL of the file. Send `url` or `base64`. | | `seller_files[].base64` | string | no | The file content, base64-encoded. A `data:;base64,` prefix is allowed and sets the MIME type. Send `url` or `base64`. | | `seller_files[].name` | string | no | File name with extension, for example `id.pdf`. If you omit it, PayMe names the file from its MIME type. | | `seller_files[].mime_type` | string | no | MIME type of the file, for example `application/pdf` or `image/jpeg`. | | `language` | string | no | Language of error messages: `he` (default) or `en`. | ### Request example ```json { "payme_client_key": "XXXXXXXX", "seller_payme_id": "MPLDEMO-MPLDEMO-MPLDEMO-1234567", "seller_files": [ { "name": "social_id.pdf", "type": 1, "url": "https://www.example.com/files/social_id.pdf", "mime_type": "application/pdf" }, { "name": "cheque.png", "type": 2, "base64": "iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNkYPhfDwAChwGA60e6kgAAAABJRU5ErkJggg==", "mime_type": "image/png" } ], "language": "en" } ``` ## Code samples ### curl ```bash curl -X POST 'https://sandbox.payme.io/api/upload-seller-files' \ -H 'Content-Type: application/json' \ --data-raw '{ "payme_client_key": "XXXXXXXX", "seller_payme_id": "MPLDEMO-MPLDEMO-MPLDEMO-1234567", "seller_files": [ { "name": "social_id.pdf", "type": 1, "url": "https://www.example.com/files/social_id.pdf", "mime_type": "application/pdf" }, { "name": "cheque.png", "type": 2, "base64": "iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNkYPhfDwAChwGA60e6kgAAAABJRU5ErkJggg==", "mime_type": "image/png" } ], "language": "en" }' ``` ### Node.js ```javascript const response = await fetch("https://sandbox.payme.io/api/upload-seller-files", { method: "POST", headers: { "Content-Type": "application/json", }, body: JSON.stringify({ "payme_client_key": "XXXXXXXX", "seller_payme_id": "MPLDEMO-MPLDEMO-MPLDEMO-1234567", "seller_files": [ { "name": "social_id.pdf", "type": 1, "url": "https://www.example.com/files/social_id.pdf", "mime_type": "application/pdf" }, { "name": "cheque.png", "type": 2, "base64": "iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNkYPhfDwAChwGA60e6kgAAAABJRU5ErkJggg==", "mime_type": "image/png" } ], "language": "en" }), }); console.log(await response.text()); ``` ### Python ```python import requests response = requests.post( "https://sandbox.payme.io/api/upload-seller-files", json={ "payme_client_key": "XXXXXXXX", "seller_payme_id": "MPLDEMO-MPLDEMO-MPLDEMO-1234567", "seller_files": [ { "name": "social_id.pdf", "type": 1, "url": "https://www.example.com/files/social_id.pdf", "mime_type": "application/pdf", }, { "name": "cheque.png", "type": 2, "base64": "iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNkYPhfDwAChwGA60e6kgAAAABJRU5ErkJggg==", "mime_type": "image/png", }, ], "language": "en", }, ) print(response.text) ``` ### PHP ```php 'POST', CURLOPT_RETURNTRANSFER => true, CURLOPT_HTTPHEADER => [ 'Content-Type: application/json', ], CURLOPT_POSTFIELDS => $body, ]); $response = curl_exec($ch); curl_close($ch); echo $response; ``` ## Responses ### 200 — OK (success) | Field | Type | Description | | --- | --- | --- | | `status_code` | integer | `0` when the files were accepted. | | `session` | string | PayMe session ID. | ```json { "status_code": 0, "session": "a1B2c3D4" } ``` ### 400 — Bad request, for example error `20`: a file's `type` is missing or invalid (error) | Field | Type | Description | | --- | --- | --- | | `status_code` | integer | `1` on failure. | | `status_error_code` | integer | PayMe error code. See [Errors](/payments/getting-started/errors). | | `status_error_details` | string | Error message, in the request's `language`. | | `status_additional_info` | string | Extra detail, such as the name of the missing or invalid field. Can be `null`. | | `session` | string | PayMe session ID. Quote it when you contact support. | ```json { "status_code": 1, "status_error_details": "Validation error", "status_additional_info": "type", "status_error_code": 20, "session": "a1B2c3D4" } ``` ### 500 — Error, for example error `904`: the file extension isn't allowed (error) | Field | Type | Description | | --- | --- | --- | | `status_code` | integer | `1` on failure. | | `status_error_code` | integer | PayMe error code. See [Errors](/payments/getting-started/errors). | | `status_error_details` | string | Error message, in the request's `language`. | | `status_additional_info` | string | Extra detail, such as the name of the missing or invalid field. Can be `null`. | | `session` | string | PayMe session ID. Quote it when you contact support. | ```json { "status_code": 1, "status_error_details": "Invalid file extension", "status_additional_info": null, "status_error_code": 904, "session": "a1B2c3D4" } ``` - [List a seller's services](https://docs.payme.io/payments/merchants-management/post-get-vas-seller): POST /get-vas-seller — List a seller's services # List a seller's services - Sandbox: `POST https://sandbox.payme.io/api/get-vas-seller` - Production: `POST https://live.payme.io/api/get-vas-seller` ## Credentials - Request body field `payme_client_key` (required): Your partner key. - Request body field `seller_payme_id` (required): The seller's MPL. - Request body field `vas_api_key` (optional): A service's public ID, or an array of them. Returns the value-added services (VAS) installed on one of your sellers, with each service's prices, payer and status. Partners only: send your `payme_client_key` and the seller's `seller_payme_id`. Inactive sellers can be queried too. To narrow the list, filter by `vas_type`, `vas_api_key` or `vas_payme_id`. Service types are on [VAS types](/marketplaces-and-platforms/seller-reference/vas-types). Prices ending in `_fixed` are in minor units of `vas_price_currency`. Prices ending in `_variable` are percentages. ## Parameters This endpoint takes no path, query or header parameters. ## Request body Content type: `application/json` | Field | Type | Required | Description | | --- | --- | --- | --- | | `payme_client_key` | string | yes | Your partner key. | | `seller_payme_id` | string | yes | The seller's MPL. | | `vas_type` | string | no | A service type name from [VAS types](/marketplaces-and-platforms/seller-reference/vas-types), for example `Settlements`. Unknown names return error `24`. | | `vas_api_key` | string | no | A service's public ID, or an array of them. | | `vas_payme_id` | string | no | The `vas_guid` of one of the seller's services. Returns that service. | | `language` | string | no | Language of error messages: `he` (default) or `en`. | ### Request example ```json { "payme_client_key": "XXXXXXXX", "seller_payme_id": "MPLDEMO-MPLDEMO-MPLDEMO-1234567", "vas_type": "Settlements", "language": "en" } ``` ## Code samples ### curl ```bash curl -X POST 'https://sandbox.payme.io/api/get-vas-seller' \ -H 'Content-Type: application/json' \ --data-raw '{ "payme_client_key": "XXXXXXXX", "seller_payme_id": "MPLDEMO-MPLDEMO-MPLDEMO-1234567", "vas_type": "Settlements", "language": "en" }' ``` ### Node.js ```javascript const response = await fetch("https://sandbox.payme.io/api/get-vas-seller", { method: "POST", headers: { "Content-Type": "application/json", }, body: JSON.stringify({ "payme_client_key": "XXXXXXXX", "seller_payme_id": "MPLDEMO-MPLDEMO-MPLDEMO-1234567", "vas_type": "Settlements", "language": "en" }), }); console.log(await response.text()); ``` ### Python ```python import requests response = requests.post( "https://sandbox.payme.io/api/get-vas-seller", json={ "payme_client_key": "XXXXXXXX", "seller_payme_id": "MPLDEMO-MPLDEMO-MPLDEMO-1234567", "vas_type": "Settlements", "language": "en", }, ) print(response.text) ``` ### PHP ```php 'POST', CURLOPT_RETURNTRANSFER => true, CURLOPT_HTTPHEADER => [ 'Content-Type: application/json', ], CURLOPT_POSTFIELDS => $body, ]); $response = curl_exec($ch); curl_close($ch); echo $response; ``` ## Responses ### 200 — OK (success) | Field | Type | Description | | --- | --- | --- | | `status_code` | integer | `0` on success. | | `session` | string | PayMe session ID. | | `seller_payme_id` | string | The seller's MPL. | | `vas_payme_id` | string | The `vas_payme_id` filter from the request, or `null`. | | `items_count` | integer | Number of services in `items`. | | `items` | array | The seller's services. | | `items[].vas_description` | string | Name of the service. | | `items[].vas_type` | string | Service type name, see [VAS types](/marketplaces-and-platforms/seller-reference/vas-types). | | `items[].vas_name` | string | Plan name, for creation plans only. Otherwise `null`. | | `items[].vas_api_key` | string | The service's public ID, or `null`. | | `items[].vas_guid` | string | This seller's instance of the service. | | `items[].vas_is_active` | boolean | `true` when the service is active for this seller. | | `items[].vas_payer_type` | integer | Who pays for the service: `1` – partner, `2` – seller, `3` – reseller. | | `items[].vas_price_currency` | string | Currency of the prices, ISO 4217, for example `ILS`. | | `items[].vas_price_setup_fixed` | integer | One-time setup price, in minor units. | | `items[].vas_price_periodic_fixed` | integer | Fixed periodic price, in minor units. | | `items[].vas_price_periodic_variable` | string | Variable periodic price, percent. | | `items[].vas_price_usage_fixed` | integer | Fixed price per use, in minor units. | | `items[].vas_price_usage_variable` | string | Variable price per use, percent. | | `items[].vas_market_fee` | string | Market fee set on this service, or `null`. | | `items[].vas_period` | integer | Billing period: `1` – instant, `2` – daily, `3` – monthly, `4` – yearly. | | `items[].vas_data` | array | Settings stored on the service. Their content depends on the service type. | ```json { "status_code": 0, "session": "a1B2c3D4", "seller_payme_id": "MPLDEMO-MPLDEMO-MPLDEMO-1234567", "vas_payme_id": null, "items_count": 1, "items": [ { "vas_description": "עמלת סליקה", "vas_type": "Settlements", "vas_name": null, "vas_api_key": null, "vas_guid": "VASL1234-ABCD1234-EFGH5678-IJKL9012", "vas_is_active": true, "vas_payer_type": 2, "vas_price_currency": "ILS", "vas_price_setup_fixed": 0, "vas_price_periodic_fixed": 0, "vas_price_periodic_variable": "0.00", "vas_price_usage_fixed": 0, "vas_price_usage_variable": "0.00", "vas_market_fee": null, "vas_period": 1, "vas_data": [] } ] } ``` ### 500 — Error, for example error `24`: unknown `vas_type` (error) | Field | Type | Description | | --- | --- | --- | | `status_code` | integer | `1` on failure. | | `status_error_code` | integer | PayMe error code. See [Errors](/payments/getting-started/errors). | | `status_error_details` | string | Error message, in the request's `language`. | | `status_additional_info` | string | Extra detail, such as the name of the missing or invalid field. Can be `null`. | | `session` | string | PayMe session ID. Quote it when you contact support. | ```json { "status_code": 1, "status_error_details": "Invalid enum value", "status_additional_info": null, "status_error_code": 24, "session": "a1B2c3D4" } ``` - [Withdraw a seller's balance](https://docs.payme.io/payments/merchants-management/post-withdraw-balance): POST /withdraw-balance — Withdraw a seller's balance # Withdraw a seller's balance - Sandbox: `POST https://sandbox.payme.io/api/withdraw-balance` - Production: `POST https://live.payme.io/api/withdraw-balance` ## Credentials - Request body field `payme_client_key` (optional): Your partner key. A seller calling for itself doesn't send it. - Request body field `seller_payme_id` (required): The seller's MPL. Requests a payout of a seller's released balance in one currency to the seller's bank account. By default it withdraws the whole released balance. To withdraw a set amount, send `withdrawal_amount`. To withdraw specific transactions, send `transaction_ids`. A partner sends `payme_client_key` and the seller's `seller_payme_id`. A seller sends its own `seller_payme_id`. The seller must be on the manual withdrawal plan (`seller_withdrawal_plan` `1` on [List sellers](/payments/query-apis/post-get-sellers)), approved by PayMe (`seller_approved`), and have bank details on file. Approval needs the seller's documents: see [File types](/marketplaces-and-platforms/seller-reference/file-types). The amount must be at least the minimum: 100.00 per currency (`10000` in minor units), unless PayMe set another value for your account. PayMe records the withdrawal, sends a `withdrawal-complete` callback, and transfers the money later. If the response has no `items`, no withdrawal was created. If the call times out, check [List withdrawals](/payments/query-apis/post-get-withdrawals) before you retry. For plans, timing and reconciliation, see [Withdrawals](/marketplaces-and-platforms/fees-and-payouts/withdrawals). ### Errors Every error returns `status_code` `1` with the code in `status_error_code`. Code | Meaning ---|--- `1` | `withdrawal_currency` is missing. `2` | A previous withdrawal is stuck on a funds mismatch. Contact PayMe support. `17` | `withdrawal_currency` holds more than one currency. Send one currency per request. `42` | `withdrawal_amount` isn't an integer. `109` | The seller isn't approved yet. `165` | The seller's bank details are missing. `171` | No released balance to withdraw, or `withdrawal_amount` is above it. `252` | Unknown `withdrawal_currency`. `907` | The seller is on an automatic (daily or monthly) withdrawal plan. `908` | The seller, or a listed transaction, is paid directly by the card companies. `913` | The amount is below the minimum, or `withdrawal_amount` isn't a positive integer. `998` | HTTP 429: another withdrawal for this seller is running. Wait and retry. `507` / `523` / `525` / `526` | A listed transaction is in another currency / not released yet / already withdrawn / not found for this seller. The full list is on [Errors](/payments/getting-started/errors). ### Callback When the withdrawal is recorded, before the bank transfer, PayMe sends a `withdrawal-complete` callback (`POST`, `x-www-form-urlencoded`) to your default callback URL. See [Callbacks](/payments/getting-started/callbacks). Field | Description ---|--- `notify_type` | `withdrawal-complete` `payme_status` | `success` `status_code` | `0` `status_error_code` | `0` `seller_payme_id` | The seller's MPL, for example `MPLDEMO-MPLDEMO-MPLDEMO-1234567`. `seller_id` | Your own ID for the seller. Omitted when the seller has none. `sale_payme_code` | Always `0`. `tran_payme_code` | The withdrawal's ID: `withdrawal_id` in this response, `withdrawal_payme_code` on List withdrawals. `tran_created` | When the withdrawal was created, `yyyy-mm-dd hh:mm:ss`. `tran_type` | `40` (bank withdrawal). `tran_currency` | Currency, for example `ILS`. `tran_total` | Amount, in minor units (`10000` = 100.00). `tran_description` | A Hebrew label. Don't parse it. ## 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 | Your partner key. A seller calling for itself doesn't send it. | | `seller_payme_id` | string | yes | The seller's MPL. | | `withdrawal_currency` | string | yes | Currency to withdraw, a 3-letter [ISO 4217](https://en.wikipedia.org/wiki/ISO_4217) code such as `ILS`. One currency per request. | | `withdrawal_amount` | integer | no | Withdraw this amount of the released balance instead of all of it, in minor units (`50000` = 500.00). It must be at least the minimum and no more than the released balance. Ignored when you send `transaction_ids`. | | `transaction_ids` | array | no | Withdraw only these transactions: `payme_transaction_id` values from [List transactions](/payments/query-apis/post-get-transactions), for example `TRAN1499-869602B9-7QIUNKHI-F0SL1AOV`. Each must belong to the seller, be in `withdrawal_currency`, be released and not withdrawn already. PayMe also includes the other released transactions of the same sales, such as refunds, and lists them all in the response's `transaction_ids`. | | `language` | string | no | Language of error messages: `he` (default) or `en`. | ### Request example ```json { "payme_client_key": "XXXXXXXX", "seller_payme_id": "MPLDEMO-MPLDEMO-MPLDEMO-1234567", "withdrawal_currency": "ILS", "language": "en" } ``` ## Code samples ### curl ```bash curl -X POST 'https://sandbox.payme.io/api/withdraw-balance' \ -H 'Content-Type: application/json' \ --data-raw '{ "payme_client_key": "XXXXXXXX", "seller_payme_id": "MPLDEMO-MPLDEMO-MPLDEMO-1234567", "withdrawal_currency": "ILS", "language": "en" }' ``` ### Node.js ```javascript const response = await fetch("https://sandbox.payme.io/api/withdraw-balance", { method: "POST", headers: { "Content-Type": "application/json", }, body: JSON.stringify({ "payme_client_key": "XXXXXXXX", "seller_payme_id": "MPLDEMO-MPLDEMO-MPLDEMO-1234567", "withdrawal_currency": "ILS", "language": "en" }), }); console.log(await response.text()); ``` ### Python ```python import requests response = requests.post( "https://sandbox.payme.io/api/withdraw-balance", json={ "payme_client_key": "XXXXXXXX", "seller_payme_id": "MPLDEMO-MPLDEMO-MPLDEMO-1234567", "withdrawal_currency": "ILS", "language": "en", }, ) print(response.text) ``` ### PHP ```php 'POST', CURLOPT_RETURNTRANSFER => true, CURLOPT_HTTPHEADER => [ 'Content-Type: application/json', ], CURLOPT_POSTFIELDS => $body, ]); $response = curl_exec($ch); curl_close($ch); echo $response; ``` ## Responses ### 200 — OK (success) | Field | Type | Description | | --- | --- | --- | | `status_code` | integer | `0` on success. | | `session` | string | PayMe session ID. | | `page` | integer | Always `1`. | | `items_per_page` | integer | Number of withdrawals in `items`. | | `items_total` | integer | Number of withdrawals in `items`. | | `items` | array | The withdrawals created. Missing when no withdrawal was created. | | `items[].withdrawal_id` | integer | The withdrawal's ID. The same number is `withdrawal_payme_code` on List withdrawals and `tran_payme_code` in the callback. | | `items[].withdrawal_currency` | string | Withdrawal currency. | | `items[].withdrawal_total` | integer | Withdrawal amount, in minor units. | | `transaction_ids` | array | Partial withdrawals only: every transaction included, which can be more than you sent. | ```json { "status_code": 0, "session": "a1B2c3D4", "page": 1, "items_per_page": 1, "items_total": 1, "items": [ { "withdrawal_id": 10001, "withdrawal_currency": "ILS", "withdrawal_total": 600000 } ] } ``` ### 500 — Error, for example error `171`: no released balance to withdraw (error) | Field | Type | Description | | --- | --- | --- | | `status_code` | integer | `1` on failure. | | `status_error_code` | integer | PayMe error code. See [Errors](/payments/getting-started/errors). | | `status_error_details` | string | Error message, in the request's `language`. | | `status_additional_info` | string | Extra detail, such as the name of the missing or invalid field. Can be `null`. | | `session` | string | PayMe session ID. Quote it when you contact support. | ```json { "status_code": 1, "status_error_details": "No available funds for withdrawal", "status_additional_info": null, "status_error_code": 171, "session": "a1B2c3D4" } ``` - [List a seller's public keys](https://docs.payme.io/payments/merchants-management/get-sellers-mpl-public-keys): GET /sellers/{seller_payme_id}/public-keys — List a seller's public keys # List a seller's public keys - Sandbox: `GET https://sandbox.payme.io/api/sellers/{seller_payme_id}/public-keys` - Production: `GET https://live.payme.io/api/sellers/{seller_payme_id}/public-keys` ## Credentials - Header `PayMe-Partner-Key` (API key) Returns the public keys of one of your sellers, including deactivated ones. Use a public key in browser code, for example to create Hosted Fields with `PayMe.create`. Never put the seller's MPL in browser code. Partners only: send your partner key in the `PayMe-Partner-Key` header. `create-seller` also returns the new seller's key as `seller_public_key`. See [Authentication](/payments/getting-started/authentication#the-public-key). ### Errors HTTP status | Code | When ---|---|--- `500` | `1` | The `PayMe-Partner-Key` header is missing. `500` | `200` | The partner key matches no partner. `400` | `20` | The seller belongs to another partner ("Partner-Seller inconsistency"). `404` | – | No seller has this MPL. The body is `{"message": "…"}`, not the PayMe error fields. ## Parameters | Name | In | Type | Required | Description | | --- | --- | --- | --- | --- | | `PayMe-Partner-Key` | header | string | yes | Your partner key (`payme_client_key`). | | `seller_payme_id` | path | string | yes | The seller's MPL (`seller_payme_id`). An unknown MPL returns HTTP 404. | ## Code samples ### curl ```bash curl -X GET 'https://sandbox.payme.io/api/sellers//public-keys' \ -H 'PayMe-Partner-Key: ' ``` ### Node.js ```javascript const response = await fetch("https://sandbox.payme.io/api/sellers//public-keys", { method: "GET", headers: { "PayMe-Partner-Key": "", }, }); console.log(await response.text()); ``` ### Python ```python import requests response = requests.get( "https://sandbox.payme.io/api/sellers//public-keys", headers={ "PayMe-Partner-Key": "", }, ) print(response.text) ``` ### PHP ```php /public-keys'); curl_setopt_array($ch, [ CURLOPT_CUSTOMREQUEST => 'GET', CURLOPT_RETURNTRANSFER => true, CURLOPT_HTTPHEADER => [ 'PayMe-Partner-Key: ', ], ]); $response = curl_exec($ch); curl_close($ch); echo $response; ``` ## Responses ### 200 — OK (success) | Field | Type | Description | | --- | --- | --- | | `status_code` | integer | `0` on success. | | `session` | string | PayMe session ID. | | `page` | integer | Always `1`. The list isn't paginated. | | `items_total` | integer | Number of keys. | | `items_per_page` | integer | Number of keys (same as `items_total`). | | `seller_payme_id` | string | The seller's MPL. | | `items` | array | The seller's public keys, active and deactivated. | | `items[].uuid` | string | The public key. | | `items[].description` | string | Name of the key. | ```json { "status_code": 0, "session": "a1B2c3D4", "page": 1, "items_total": 1, "items_per_page": 1, "seller_payme_id": "MPLDEMO-MPLDEMO-MPLDEMO-1234567", "items": [ { "uuid": "12345678-1234-4abc-9def-123456789012", "description": "PayMe-Public-Key" } ] } ``` ### 400 — Bad request: the seller belongs to another partner (error `20`) (error) | Field | Type | Description | | --- | --- | --- | | `status_code` | integer | `1` on failure. | | `status_error_code` | integer | PayMe error code. See [Errors](/payments/getting-started/errors). | | `status_error_details` | string | Error message, in the request's `language`. | | `status_additional_info` | string | Extra detail, such as the name of the missing or invalid field. Can be `null`. | | `session` | string | PayMe session ID. Quote it when you contact support. | ```json { "status_code": 1, "status_error_details": "Validation error", "status_additional_info": "Partner-Seller inconsistency", "status_error_code": 20, "session": "a1B2c3D4" } ``` ### 500 — Error, for example error `1`: the `PayMe-Partner-Key` header is missing (error) | Field | Type | Description | | --- | --- | --- | | `status_code` | integer | `1` on failure. | | `status_error_code` | integer | PayMe error code. See [Errors](/payments/getting-started/errors). | | `status_error_details` | string | Error message, in the request's `language`. | | `status_additional_info` | string | Extra detail, such as the name of the missing or invalid field. Can be `null`. | | `session` | string | PayMe session ID. Quote it when you contact support. | ```json { "status_code": 1, "status_error_details": "Required parameter is missing", "status_additional_info": "PayMe-Partner-Key", "status_error_code": 1, "session": "a1B2c3D4" } ``` - [List business fields](https://docs.payme.io/payments/merchants-management/get-business-fields): GET /business-fields — List business fields # List business fields - Sandbox: `GET https://sandbox.payme.io/api/business-fields` - Production: `GET https://live.payme.io/api/business-fields` ## Credentials - Header `PayMe-Partner-Key` (API key) - Header `PayMe-Merchant-Key` (optional): The seller's MPL (`seller_payme_id`), instead of `PayMe-Partner-Key`. ## Overview Returns PayMe's business fields (the seller's line of business). Send a field's `code` as `seller_person_business_type` when you [create](/payments/merchants-management/post-create-seller) or [update](/payments/merchants-management/post-update-seller) a seller. The full list with Hebrew and English names is on [Business field codes](/marketplaces-and-platforms/seller-reference/mcc-list). Without a code in the path, only top-level fields (codes 10000 and above) are returned. Add `allow_children=true` to include their child fields. To get one field, add its code to the path: `GET /business-fields/{code}`. This also returns child fields and older codes below 10000. A code that doesn't exist returns `status_code` `0` with an empty `items`. A non-numeric code fails with error `10`. A code that is inactive is rejected by Create a seller with error `110`. ## Authentication Send your partner key in the `PayMe-Partner-Key` header, or, as a seller, your MPL in the `PayMe-Merchant-Key` header. Keys in the query string are not read. Without either, the call fails with error `1` (`status_additional_info`: `payme_client_key`). ## Parameters | Name | In | Type | Required | Description | | --- | --- | --- | --- | --- | | `PayMe-Partner-Key` | header | string | no | Your partner key (`payme_client_key`). Required unless you send `PayMe-Merchant-Key`. | | `PayMe-Merchant-Key` | header | string | no | The seller's MPL (`seller_payme_id`), instead of `PayMe-Partner-Key`. | | `sort_by` | query | string | no | Response field to sort by: `code`, `name_intl` or `name_local`. Default `code`. | | `sort_direction` | query | string | no | `desc` sorts descending. Any other value sorts ascending. | | `language` | query | string | no | Language of `name_local`: `he` (default) or `en`. `es`, `ru` and `ar` are accepted but return the English name. Any other value falls back to `he` without an error. | | `allow_children` | query | boolean | no | `true` also returns child business fields. Default `false`. | ## Code samples ### curl ```bash curl -X GET 'https://sandbox.payme.io/api/business-fields' \ -H 'PayMe-Partner-Key: ' \ -H 'PayMe-Merchant-Key: ' ``` ### Node.js ```javascript const response = await fetch("https://sandbox.payme.io/api/business-fields", { method: "GET", headers: { "PayMe-Partner-Key": "", "PayMe-Merchant-Key": "", }, }); console.log(await response.text()); ``` ### Python ```python import requests response = requests.get( "https://sandbox.payme.io/api/business-fields", headers={ "PayMe-Partner-Key": "", "PayMe-Merchant-Key": "", }, ) print(response.text) ``` ### PHP ```php 'GET', CURLOPT_RETURNTRANSFER => true, CURLOPT_HTTPHEADER => [ 'PayMe-Partner-Key: ', 'PayMe-Merchant-Key: ', ], ]); $response = curl_exec($ch); curl_close($ch); echo $response; ``` ## Responses ### 200 — OK (success) | Field | Type | Description | | --- | --- | --- | | `status_code` | integer | `0` on success. | | `page` | integer | Always `1`. The list isn't paginated. | | `items_per_page` | integer | Number of items returned (same as `items_total`). | | `items_total` | integer | Number of items returned. | | `language` | string | Language used for `name_local`. | | `items` | array | Business fields, sorted by `sort_by`. | | `items[].code` | integer | Business field code. Send it as `seller_person_business_type`. | | `items[].name_intl` | string | English name. | | `items[].name_local` | string | Name in the requested `language`. | ```json { "status_code": 0, "page": 1, "items_per_page": 2, "items_total": 2, "language": "he", "items": [ { "code": 10000, "name_intl": "Nurseries", "name_local": "משתלות" }, { "code": 10004, "name_intl": "Confectionery", "name_local": "קונדיטוריה" } ] } ``` ### 500 — Error, for example error `1`: no key was sent (error) | Field | Type | Description | | --- | --- | --- | | `status_code` | integer | `1` on failure. | | `status_error_code` | integer | PayMe error code. See [Errors](/payments/getting-started/errors). | | `status_error_details` | string | Error message, in the request's `language`. | | `status_additional_info` | string | Extra detail, such as the name of the missing or invalid field. Can be `null`. | | `session` | string | PayMe session ID. Quote it when you contact support. | ```json { "status_code": 1, "status_error_details": "Required parameter is missing", "status_additional_info": "payme_client_key", "status_error_code": 1, "session": "a1B2c3D4" } ``` - [Attach a saved card to a seller](https://docs.payme.io/payments/merchants-management/post-add-card-to-seller): POST /add-card-to-seller — Attach a saved card to a seller # Attach a saved card to a seller - Sandbox: `POST https://sandbox.payme.io/api/add-card-to-seller` - Production: `POST https://live.payme.io/api/add-card-to-seller` ## Credentials - Request body field `seller_payme_id` (required): The seller's MPL: the seller the card is attached to. Attaches a saved card, identified by its `buyer_key`, to a seller. A contract paid by credit card uses a card attached this way; see the [contracts overview](/b2b-payments/contracts). If the card was saved by PayMe for a contract, it is assigned to this seller. Calling again for the same card isn't needed. This endpoint sends no callback. The result, including the buyer token fields, is in the HTTP response: `status_code` `0` means success and `1` means failure. The response holds the buyer's details, so handle it securely. ### Errors HTTP status | Error code | Message | When ---|---|---|--- `500` | `900` | Please provide all required information in JSON format. Make sure to include 'Content-Type: application/json' header | The request is not JSON. `500` | `901` | Please verify that the JSON provided is valid | The JSON body is empty or invalid. `500` | `1` | Required parameter is missing | One of these is missing: `seller_payme_id`, `buyer_key`. `status_additional_info` names it. `500` | `251` | Seller was not found | The seller key is unknown. `500` | `163` | Account settings problem - please contact Customer Support | The seller is not active. `500` | `600` | Buyer not found | No buyer has this `buyer_key`. `500` | `604` | Buyer inactive | The buyer is inactive. `500` | `605` | The buyer was not captured using the provided seller | This seller may not use this buyer. ## 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: the seller the card is attached to. | | `buyer_key` | string | yes | The saved card to attach, from [Capture a buyer token](/payments/tokenization/post-capture-buyer-token) or a sale callback. | ### Request example ```json { "seller_payme_id": "MPLDEMO-MPLDEMO-MPLDEMO-1234567", "buyer_key": "BUYERDEMO-BUYERDEMO-BUYERDEMO-1234567" } ``` ## Code samples ### curl ```bash curl -X POST 'https://sandbox.payme.io/api/add-card-to-seller' \ -H 'Content-Type: application/json' \ --data-raw '{ "seller_payme_id": "MPLDEMO-MPLDEMO-MPLDEMO-1234567", "buyer_key": "BUYERDEMO-BUYERDEMO-BUYERDEMO-1234567" }' ``` ### Node.js ```javascript const response = await fetch("https://sandbox.payme.io/api/add-card-to-seller", { method: "POST", headers: { "Content-Type": "application/json", }, body: JSON.stringify({ "seller_payme_id": "MPLDEMO-MPLDEMO-MPLDEMO-1234567", "buyer_key": "BUYERDEMO-BUYERDEMO-BUYERDEMO-1234567" }), }); console.log(await response.text()); ``` ### Python ```python import requests response = requests.post( "https://sandbox.payme.io/api/add-card-to-seller", json={ "seller_payme_id": "MPLDEMO-MPLDEMO-MPLDEMO-1234567", "buyer_key": "BUYERDEMO-BUYERDEMO-BUYERDEMO-1234567", }, ) print(response.text) ``` ### PHP ```php 'POST', CURLOPT_RETURNTRANSFER => true, CURLOPT_HTTPHEADER => [ 'Content-Type: application/json', ], CURLOPT_POSTFIELDS => $body, ]); $response = curl_exec($ch); curl_close($ch); echo $response; ``` ## Responses ### 200 — OK (success) | Field | Type | Description | | --- | --- | --- | | `status_code` | integer | `0` on success. | | `session` | string | PayMe session ID. | | `buyer_key` | string | The buyer token (`buyer_key`) you sent. | | `buyer_name` | string | The buyer's name. | | `buyer_email` | string | The buyer's email address. | | `buyer_phone` | string | The buyer's phone number. | | `buyer_card_mask` | string | The masked card number. | | `buyer_card_exp` | string | The card expiry date, `MMYY`. | | `buyer_social_id` | string | The buyer's national ID number. | | `buyer_is_permanent` | boolean | Whether the buyer token is permanent. | | `buyer_status` | string | Always `null`; ignore it. | ```json { "status_code": 0, "session": "a1B2c3D4", "buyer_key": "BUYERDEMO-BUYERDEMO-BUYERDEMO-1234567", "buyer_name": "Example Buyer", "buyer_email": "buyer@example.com", "buyer_phone": "0500000001", "buyer_card_mask": "458045******4580", "buyer_card_exp": "1228", "buyer_social_id": "123456782", "buyer_is_permanent": false, "buyer_status": null } ``` ### 500 — Error, for example error `600`: no buyer has this `buyer_key` (error) | Field | Type | Description | | --- | --- | --- | | `status_code` | integer | `1` on failure. | | `status_error_code` | integer | PayMe error code. See [Errors](/payments/getting-started/errors). | | `status_error_details` | string | Error message, in the request's `language`. | | `status_additional_info` | string | Extra detail, such as the name of the missing or invalid field. Can be `null`. | | `session` | string | PayMe session ID. Quote it when you contact support. | ```json { "status_code": 1, "status_error_details": "Buyer not found", "status_additional_info": null, "status_error_code": 600, "session": "XXXXXXXX" } ``` ## Buyers Management - [Get a buyer](https://docs.payme.io/payments/buyers-management/get-buyers-guid): GET /buyers/{buyer_guid} — Get a buyer # Get a buyer - Sandbox: `GET https://sandbox.payme.io/api/buyers/{buyer_guid}` - Production: `GET https://live.payme.io/api/buyers/{buyer_guid}` ## Credentials - Header `PayMe-Merchant-Key` (API key) Returns the saved details of a buyer: name, contact details and the masked card. Send the seller's MPL (`seller_payme_id`) in the `PayMe-Merchant-Key` header. The buyer must belong to that seller (error `605`). In the path, send a buyer key (`BUYER…`) from [Capture a buyer token](/payments/tokenization/post-capture-buyer-token) or a sale callback, or a token UUID from `POST /tokens`. With a UUID, the response has no `buyer_key`. The success body is the buyer object only, with no `status_code` or `session`. The card fields `club`, `type`, `organization` and `origin_country` come from the card's BIN and can be empty when PayMe doesn't recognize it. ### Errors HTTP status | Error code | Message | When ---|---|---|--- `400` | `1` | Required parameter is missing | No seller was named. `status_additional_info` is `seller_payme_id`. `500` | `251` | Seller was not found | The seller key is unknown. `500` | `163` | Account settings problem - please contact Customer Support | The seller is not active. `500` | `600` | Buyer not found | No buyer has this ID. `status_additional_info` is the ID you sent. `500` | `604` | Buyer inactive | The buyer is inactive. `500` | `605` | The buyer was not captured using the provided seller | This seller may not read this buyer. ## Parameters | Name | In | Type | Required | Description | | --- | --- | --- | --- | --- | | `PayMe-Merchant-Key` | header | string | yes | The seller's MPL (`seller_payme_id`), for example `MPLDEMO-MPLDEMO-MPLDEMO-1234567`. Not the seller's public key. | | `buyer_guid` | path | string | yes | A buyer key (`BUYER…`) or a token UUID. With a UUID, the response has no `buyer_key`. | ## Code samples ### curl ```bash curl -X GET 'https://sandbox.payme.io/api/buyers/' \ -H 'PayMe-Merchant-Key: ' ``` ### Node.js ```javascript const response = await fetch("https://sandbox.payme.io/api/buyers/", { method: "GET", headers: { "PayMe-Merchant-Key": "", }, }); console.log(await response.text()); ``` ### Python ```python import requests response = requests.get( "https://sandbox.payme.io/api/buyers/", headers={ "PayMe-Merchant-Key": "", }, ) print(response.text) ``` ### PHP ```php '); curl_setopt_array($ch, [ CURLOPT_CUSTOMREQUEST => 'GET', CURLOPT_RETURNTRANSFER => true, CURLOPT_HTTPHEADER => [ 'PayMe-Merchant-Key: ', ], ]); $response = curl_exec($ch); curl_close($ch); echo $response; ``` ## Responses ### 200 — OK (success) | Field | Type | Description | | --- | --- | --- | | `uuid` | string | The buyer's token UUID. | | `customer` | object | The buyer's details. | | `customer.name` | string | The buyer's name. | | `customer.email` | string | The buyer's email address. | | `customer.phone` | string | The buyer's phone number. | | `customer.social_id` | string | The buyer's national ID number. | | `payment` | object | The saved card. | | `payment.display` | string | The masked card number. | | `payment.expiry` | string | Card expiry date, `MMYY`. | | `payment.brand` | string | Card brand, for example `Visa`. | | `payment.club` | string | Card club, from the BIN. Can be empty. | | `payment.type` | string | Card type, for example `Credit`, from the BIN. | | `payment.organization` | string | Card organization, from the BIN. Can be empty. | | `payment.origin_country` | string | Country that issued the card, ISO 3166-1 alpha-2, from the BIN. | | `buyer_key` | string | The buyer key. Returned only when the path holds a buyer key. | ```json { "uuid": "6ac45306-1755-45e4-8b74-f6de3ea2239b", "customer": { "name": "Example Buyer", "email": "buyer@example.com", "phone": "0500000001", "social_id": "123456782" }, "payment": { "display": "411111******1111", "expiry": "1228", "brand": "Visa", "club": "", "type": "Credit", "organization": "", "origin_country": "US" }, "buyer_key": "BUYERDEMO-BUYERDEMO-BUYERDEMO-1234567" } ``` ### 400 — Bad Request (error) | Field | Type | Description | | --- | --- | --- | | `status_code` | number | Status code 1 (for failure) | | `status_error_details` | string | What caused the error | | `status_additional_info` | string | The parameters related to the error | | `status_error_code` | number | Status error code | | `session` | string | PayMe session ID. | ```json { "status_code": 1, "status_error_details": "Required parameter is missing", "status_additional_info": "seller_payme_id", "status_error_code": 1, "session": "FhT3aXe7" } ``` ### 500 — Internal Server Error (error) | Field | Type | Description | | --- | --- | --- | | `status_code` | number | Status code 1 (for failure) | | `status_error_details` | string | What caused the error | | `status_additional_info` | string | The parameters related to the error | | `status_error_code` | number | Status error code | | `session` | string | PayMe session ID. | ```json { "status_code": 1, "status_error_details": "Seller was not found", "status_additional_info": "seller_payme_id", "status_error_code": 251, "session": "FhT3aXe7" } ``` ## Query APIs - [Query APIs](https://docs.payme.io/payments/query-apis): The query APIs list sales, transactions, subscriptions, sellers and withdrawals. A partner sends payme_client_key and sees its sellers; a seller sends its own seller_payme_id (body or PayMe-Merchant-Key header) and sees only its own data. Results page at 500 by default (page 1-1000, page_size 1-500); filters are exact matches except *_min/*_max; times are Asia/Jerusalem. # Query APIs Use the query APIs to read your data: sales, transactions, subscriptions, sellers and withdrawals, and the bank codes you need when you create a seller. Every call is a `POST` with a JSON body, except `GET /banks/{country_iso_code}`. | Call | Returns | |---|---| | [List sales](https://docs.payme.io/payments/query-apis/post-get-sales) (`POST /get-sales`) | One row per sale (order), with its status, amounts, fees and buyer details | | [List transactions](https://docs.payme.io/payments/query-apis/post-get-transactions) (`POST /get-transactions`) | One row per money movement: payment, capture, refund, void, chargeback | | [List subscriptions](https://docs.payme.io/payments/query-apis/post-get-subscriptions) (`POST /get-subscriptions`) | Subscriptions, their status and schedule | | [List sellers](https://docs.payme.io/payments/query-apis/post-get-sellers) (`POST /get-sellers`) | Your sellers' details, fee settings and balances | | [List withdrawals](https://docs.payme.io/payments/query-apis/post-get-withdrawals) (`POST /get-withdrawals`) | Past withdrawals (payouts to the seller's bank account) | | [List future withdrawals](https://docs.payme.io/payments/query-apis/get-future-withdrawals) (`POST /get-future-withdrawals`) | A seller's expected payouts in one currency | | [List banks](https://docs.payme.io/payments/query-apis/get-banks-country-iso-code) (`GET /banks/{country_iso_code}`) | Bank codes for a country | To choose the right call for a question (sales in a period, refunds, balances), see [Find the right data](https://docs.payme.io/accepting-payments/reporting/find-the-right-data). ## Credentials - A **partner** sends `payme_client_key` in the body, or the `PayMe-Partner-Key` header. Without `seller_payme_id`, the query covers all your sellers. To narrow it, send `seller_payme_id` as one MPL or as an array of up to 100 MPLs of your own sellers. - A **seller** sends its own MPL as `seller_payme_id` in the JSON body, or in the `PayMe-Merchant-Key` header. The results cover that seller only. See [Authentication](https://docs.payme.io/payments/getting-started/authentication). ## Filters Every filter is an exact match, except fields that end in `_min` (from, inclusive) and `_max` (to, inclusive). Most filters also take an array of up to 100 values, meaning "any of". Date filters take a single value in `yyyy-mm-dd hh:mm:ss`. Status, currency and payment-method filters take the same values the responses show, for example `completed`, `ILS` or `credit-card`. | Error | Cause | |---|---| | `15` | A date filter isn't in `yyyy-mm-dd hh:mm:ss` | | `6` | An array has more than 100 values | ## Paging Results come in pages. `page` starts at `1` (default) and goes up to `1000`. `page_size` is `1`–`500`, default `500`. A call without these fields returns only the first 500 items. There's no total count: `items_count` is the number of items on this page. Request the next page until `items_count` is lower than `page_size`. An invalid `page` returns error `52`, and an invalid `page_size` returns error `27`, both with HTTP 400. `get-future-withdrawals` and `GET /banks/{country_iso_code}` don't page. ```json { "payme_client_key": "XXXXXXXX", "seller_payme_id": "MPLDEMO-MPLDEMO-MPLDEMO-1234567", "sale_created_min": "2026-10-01 00:00:00", "sale_created_max": "2026-10-31 23:59:59", "page_size": 500, "page": 2 } ``` ## Sorting `get-sales`, `get-transactions`, `get-subscriptions`, `get-sellers` and `get-withdrawals` accept `items_order_by_column` (a field to sort by, for example `sale_created` on `get-sales`) and `items_order_by_direction` (`asc`, the default, or `desc`). Any other direction returns error `28`. Without a sort column, the order isn't guaranteed, so set one when you page through results. ## Rate limits `get-transactions` is rate limited per partner, or per seller when the call has no partner key. `get-future-withdrawals` is rate limited per seller. Over the limit, the call returns HTTP 429 with error `998` and a `Retry-After` header. Wait and retry. ## Timezone All timestamps returned by the query APIs (`sale_created`, `sale_paid_date`, `sub_next_date` and the others), and the `*_min` / `*_max` filter values you send, are Asia/Jerusalem local time, not UTC. A 2–3 hour offset against a UTC clock is the timezone, not a bug. - [List sales](https://docs.payme.io/payments/query-apis/post-get-sales): POST /get-sales — List sales # List sales - Sandbox: `POST https://sandbox.payme.io/api/get-sales` - Production: `POST https://live.payme.io/api/get-sales` ## Credentials - Header `PayMe-Partner-Key` (optional): Partner key, instead of `payme_client_key` in the body. Partners only. - Header `PayMe-Merchant-Key` (optional): A seller's own MPL, instead of `seller_payme_id` in the body. - Request body field `payme_client_key` (optional): Partner key. Partners only. Can also be sent in the `PayMe-Partner-Key` header. Without `seller_payme_id`, the query covers all your sellers. - Request body field `seller_payme_id` (optional): The seller's MPL. A partner can send one MPL or an array of up to 100 MPLs of its own sellers to narrow the query. A seller sends its own MPL, here or in the `PayMe-Merchant-Key` header, and gets only its own data. Returns the sales (orders) of one seller or of all your sellers, with their status, amounts, fees and buyer details. Use it to check where an order stands. For amounts in a period, use [List transactions](/payments/query-apis/post-get-transactions): a refund or chargeback is its own transaction row. A partner sends `payme_client_key` (or the `PayMe-Partner-Key` header) and, optionally, `seller_payme_id`: one MPL or an array of up to 100 MPLs of its own sellers. Without it, the query covers all your sellers. A seller sends its own MPL as `seller_payme_id` in the body, or in the `PayMe-Merchant-Key` header, and gets only its own data. Defaults: without `sale_status`, sales in status `initial` (not paid yet) are left out; send `"sale_status": ["initial"]` to see them. Without `sale_type`, tokens (`2`, `12`) and deposits (`6`) are left out. An unknown `sale_status` value is ignored. Filters are exact matches, except `sale_created_min` / `sale_created_max`. Most filters take a single value or an array of up to 100 values. Dates are `yyyy-mm-dd hh:mm:ss`. Timestamps in the response, and the date filters you send, are Asia/Jerusalem local time, not UTC. A 2–3 hour offset against a UTC clock is the timezone, not a bug. Results come in pages of up to 500 items (default 500). A call without `page` and `page_size` returns only the first 500. Paging, sorting and filter rules are on [Query APIs](/payments/query-apis). ## Parameters | Name | In | Type | Required | Description | | --- | --- | --- | --- | --- | | `PayMe-Partner-Key` | header | string | no | Partner key, instead of `payme_client_key` in the body. Partners only. | | `PayMe-Merchant-Key` | header | string | no | A seller's own MPL, instead of `seller_payme_id` in the body. | ## Request body Content type: `application/json` Every field is optional. Send at least your credentials. | Field | Type | Required | Description | | --- | --- | --- | --- | | `payme_client_key` | string | no | Partner key. Partners only. Can also be sent in the `PayMe-Partner-Key` header. Without `seller_payme_id`, the query covers all your sellers. | | `seller_payme_id` | string | no | The seller's MPL. A partner can send one MPL or an array of up to 100 MPLs of its own sellers to narrow the query. A seller sends its own MPL, here or in the `PayMe-Merchant-Key` header, and gets only its own data. | | `seller_id` | string | no | Your own ID for the seller, as sent to create-seller. Partners only. | | `sale_payme_code` | integer | no | PayMe's numeric sale code. | | `sale_payme_id` | string | no | PayMe's sale ID, as returned by generate-sale. | | `transaction_id` | string | no | Your own order ID, as sent to generate-sale. It is not unique, so the call can return several sales. | | `sale_type` | integer | no | Numeric sale type, see [Sale Types](/payments/codes-statuses/sale-types). Default `[1, 3, 4, 5, 7, 10, 11]`. | | `sale_parent_code` | integer | no | Code of the parent the sale was created from, for example the template's `sale_payme_code`. | | `sale_created` | string | no | Exact creation date and time, `yyyy-mm-dd hh:mm:ss`. | | `sale_created_min` | string | no | Created at or after this time, `yyyy-mm-dd hh:mm:ss`. | | `sale_created_max` | string | no | Created at or before this time, `yyyy-mm-dd hh:mm:ss`. | | `sale_status` | string | no | Sale status name, or an array of them, for example `["completed", "refunded"]`. See [Sale Statuses](/payments/codes-statuses/sale-statuses). Default: every status except `initial`. | | `sale_price` | integer | no | Exact amount, in minor units (`5075` = 50.75). | | `sale_currency` | string | no | Currency, 3-letter [ISO 4217](https://en.wikipedia.org/wiki/ISO_4217) code, for example `ILS`. | | `sale_payment_method` | string | no | Payment method, for example `credit-card`, `bit`, `apple-pay` or `google-pay`. See [Wallets & APMs](/payments/wallets-apms). | | `sale_auth_number` | string | no | Authorization number from the card company. | | `sale_is_3ds` | boolean | no | `true` returns only sales paid with 3D Secure, `false` only sales paid without it. | | `sale_send_notification` | boolean | no | `true` returns only `initial` or `failed` sales that have a buyer email or phone, for example to send a payment reminder. | | `buyer_card_mask` | string | no | Masked card number, first 6 and last 4 digits, for example `458045******4580`. | | `buyer_card_last_four_digits` | string | no | Last four digits of the card. | | `buyer_card_is_foreign` | boolean | no | `true` returns only sales paid with a foreign card, `false` only local cards. | | `buyer_email` | string | no | Buyer's email. | | `buyer_name` | string | no | Buyer's full name. | | `buyer_phone` | string | no | Buyer's phone number. | | `buyer_social_id` | string | no | Buyer's national ID number (Israeli sellers). | | `page` | integer | no | Page number, `1`–`1000`. Default `1`. Out of range returns error `52`. | | `page_size` | integer | no | Items per page, `1`–`500`. Default `500`. Out of range returns error `27`. | | `items_order_by_column` | string | no | Field to sort by, for example `sale_created`. Without it, the order isn't guaranteed. A field that doesn't exist fails the call. | | `items_order_by_direction` | string | no | `asc` (default) or `desc`, in upper or lower case. Used only with `items_order_by_column`. Any other value returns error `28`. | ### Request example ```json { "payme_client_key": "XXXXXXXX", "seller_payme_id": "MPLDEMO-MPLDEMO-MPLDEMO-1234567", "sale_created_min": "2026-10-01 00:00:00", "sale_created_max": "2026-10-31 23:59:59", "sale_status": [ "completed", "refunded" ], "items_order_by_column": "sale_created", "page": 1, "page_size": 500 } ``` ## Code samples ### curl ```bash curl -X POST 'https://sandbox.payme.io/api/get-sales' \ -H 'Content-Type: application/json' \ -H 'PayMe-Partner-Key: ' \ -H 'PayMe-Merchant-Key: ' \ --data-raw '{ "payme_client_key": "XXXXXXXX", "seller_payme_id": "MPLDEMO-MPLDEMO-MPLDEMO-1234567", "sale_created_min": "2026-10-01 00:00:00", "sale_created_max": "2026-10-31 23:59:59", "sale_status": [ "completed", "refunded" ], "items_order_by_column": "sale_created", "page": 1, "page_size": 500 }' ``` ### Node.js ```javascript const response = await fetch("https://sandbox.payme.io/api/get-sales", { method: "POST", headers: { "Content-Type": "application/json", "PayMe-Partner-Key": "", "PayMe-Merchant-Key": "", }, body: JSON.stringify({ "payme_client_key": "XXXXXXXX", "seller_payme_id": "MPLDEMO-MPLDEMO-MPLDEMO-1234567", "sale_created_min": "2026-10-01 00:00:00", "sale_created_max": "2026-10-31 23:59:59", "sale_status": [ "completed", "refunded" ], "items_order_by_column": "sale_created", "page": 1, "page_size": 500 }), }); console.log(await response.text()); ``` ### Python ```python import requests response = requests.post( "https://sandbox.payme.io/api/get-sales", headers={ "PayMe-Partner-Key": "", "PayMe-Merchant-Key": "", }, json={ "payme_client_key": "XXXXXXXX", "seller_payme_id": "MPLDEMO-MPLDEMO-MPLDEMO-1234567", "sale_created_min": "2026-10-01 00:00:00", "sale_created_max": "2026-10-31 23:59:59", "sale_status": [ "completed", "refunded", ], "items_order_by_column": "sale_created", "page": 1, "page_size": 500, }, ) print(response.text) ``` ### PHP ```php 'POST', CURLOPT_RETURNTRANSFER => true, CURLOPT_HTTPHEADER => [ 'Content-Type: application/json', 'PayMe-Partner-Key: ', 'PayMe-Merchant-Key: ', ], CURLOPT_POSTFIELDS => $body, ]); $response = curl_exec($ch); curl_close($ch); echo $response; ``` ## Responses ### 200 — OK (success) | Field | Type | Description | | --- | --- | --- | | `status_code` | integer | `0` on success. | | `items_count` | integer | Number of items on this page. There is no total count. | | `items` | array | The sales. | | `items[].seller_payme_id` | string | The seller's MPL. | | `items[].seller_id` | string | Your own ID for the seller, or `null`. | | `items[].sale_payme_id` | string | PayMe's sale ID. | | `items[].sale_payme_code` | integer | PayMe's numeric sale code. | | `items[].transaction_id` | string | Your own order ID, as you sent it to generate-sale. It is not unique: several sales can share it. | | `items[].sale_type` | integer | Numeric sale type, see [Sale Types](/payments/codes-statuses/sale-types). | | `items[].sale_payment_method` | string | Payment method of the sale, for example `credit-card`. | | `items[].sale_created` | string | Creation time, `yyyy-mm-dd hh:mm:ss`. | | `items[].sale_status` | string | Sale status, see [Sale Statuses](/payments/codes-statuses/sale-statuses). | | `items[].sale_currency` | string | Currency, 3-letter ISO 4217 code. | | `items[].sale_price` | integer | Amount charged, in minor units (`5075` = 50.75). The sale price when there is no payment yet. | | `items[].sale_price_after_fees` | string | Net amount after PayMe fees, in minor units, as a numeric string. Final once the transaction is settled. `null` without a payment. | | `items[].sale_description` | string | What the buyer paid for. | | `items[].sale_installments` | integer | Number of installments. `null` if the sale has no payment yet. | | `items[].transaction_first_payment` | string | First installment, in minor units, or the full amount when there are no installments. | | `items[].transaction_periodical_payment` | string | Each later installment, in minor units. `0` when there are no installments. | | `items[].transaction_risk_score` | integer | Fraud risk score of the payment, or `null` without a payment. | | `items[].sale_vat` | string | VAT rate at the time of the sale, as a fraction (`"0.18"` = 18%). | | `items[].sale_paid_date` | string | When the payment was made, `yyyy-mm-dd hh:mm:ss`. `null` if not paid. | | `items[].sale_auth_number` | string | Authorization number from the card company. | | `items[].sale_release_date` | string | When the funds are expected in the seller's balance, `yyyy-mm-dd hh:mm:ss`, or `null`. | | `items[].sale_error_code` | string | Error code of a failed payment, otherwise `null`. | | `items[].sale_error_text` | string | Gateway message for the payment. On a failed payment, the error message. | | `items[].sale_url` | string | Link to the sale's payment page. | | `items[].sale_is_3ds` | boolean | `true` if the payment used 3D Secure. | | `items[].sale_fees` | object | Fees on this sale. Rates are percent strings. `*_total` fields are in minor units, without VAT, computed on `sale_price`. | | `items[].sale_fees.sale_processing_fee` | string | Processing rate, percent of the amount (`"2.50"` = 2.5%). | | `items[].sale_fees.sale_processing_fee_total` | integer | Processing fee, in minor units. | | `items[].sale_fees.sale_processing_charge` | string | Fixed processing charge per sale, in major units (`"1.20"` = 1.20). | | `items[].sale_fees.sale_discount_fee` | string | Discount rate (early settlement of installments) per installment, percent. | | `items[].sale_fees.sale_discount_fee_total` | integer | Discount fee, in minor units. | | `items[].sale_fees.sale_rapid_settlement_fee` | string | Rapid settlement rate, percent. | | `items[].sale_fees.sale_rapid_settlement_fee_total` | integer | Rapid settlement fee, in minor units. | | `items[].sale_fees.sale_annual_interest_rate` | string | Annual interest rate (percent) behind the discount and rapid settlement fees, or `null`. | | `items[].sale_fees.sale_market_fee` | string | Platform (market) fee rate, percent of the amount. | | `items[].sale_fees.sale_market_fee_fixed` | number | Fixed platform fee per sale, in major units. | | `items[].sale_fees.sale_market_fee_total` | integer | Platform fee, in minor units: the percent part plus the fixed part. | | `items[].sale_buyer_details` | object | The buyer and the card used. | | `items[].sale_buyer_details.buyer_card_mask` | string | Masked card number: first 6 and last 4 digits. | | `items[].sale_buyer_details.buyer_card_expiry` | string | Card expiry, `MMYY`. | | `items[].sale_buyer_details.buyer_card_brand` | string | Card brand, for example `Visa`. | | `items[].sale_buyer_details.buyer_card_is_foreign` | boolean | `true` for a card issued outside the seller's country, `false` for a local card. | | `items[].sale_buyer_details.buyer_name` | string | Buyer's full name. | | `items[].sale_buyer_details.buyer_email` | string | Buyer's email. | | `items[].sale_buyer_details.buyer_phone` | string | Buyer's phone number. | | `items[].sale_buyer_details.buyer_social_id` | string | Buyer's national ID number. | | `items[].sale_invoices` | object | Invoices for the sale, keyed by invoice document number. Each value has `invoice_doc_number` and `invoice_url`. `{}` when there are none. | ```json { "status_code": 0, "items_count": 1, "items": [ { "seller_payme_id": "MPLDEMO-MPLDEMO-MPLDEMO-1234567", "seller_id": "store-1001", "sale_payme_id": "SALE1767-704312AB-CD3FGH12-JKLM4567", "sale_payme_code": 98765432, "transaction_id": "order-12345", "sale_type": 1, "sale_payment_method": "credit-card", "sale_created": "2026-10-12 15:15:15", "sale_status": "completed", "sale_currency": "ILS", "sale_price": 10000, "sale_price_after_fees": "9610", "sale_description": "Handmade ceramic bowl", "sale_installments": 1, "transaction_first_payment": "10000", "transaction_periodical_payment": "0", "transaction_risk_score": 0, "sale_vat": "0.18", "sale_paid_date": "2026-10-12 15:16:02", "sale_auth_number": "0123456", "sale_release_date": "2026-10-19 06:00:00", "sale_error_code": null, "sale_error_text": "Permitted transaction", "sale_url": "https://sandbox.payme.io/sale/generate/SALE1767-704312AB-CD3FGH12-JKLM4567", "sale_is_3ds": false, "sale_fees": { "sale_processing_fee": "2.50", "sale_processing_fee_total": 250, "sale_processing_charge": "1.20", "sale_discount_fee": "0.00", "sale_discount_fee_total": 0, "sale_rapid_settlement_fee": "0.00", "sale_rapid_settlement_fee_total": 0, "sale_annual_interest_rate": null, "sale_market_fee": "1.50", "sale_market_fee_fixed": 0, "sale_market_fee_total": 150 }, "sale_buyer_details": { "buyer_card_mask": "458045******4580", "buyer_card_expiry": "1228", "buyer_card_brand": "Visa", "buyer_card_is_foreign": false, "buyer_name": "Israel Israeli", "buyer_email": "buyer@example.com", "buyer_phone": "0500000001", "buyer_social_id": "000000018" }, "sale_invoices": {} } ] } ``` ### 500 — Error. Most errors return HTTP 500. Paging errors (`52`, `27`) return HTTP 400. The body is the same. See [Errors](/payments/getting-started/errors). (error) | Field | Type | Description | | --- | --- | --- | | `status_code` | integer | `1` on failure. | | `status_error_code` | integer | PayMe error code. | | `status_error_details` | string | Error message. | | `status_additional_info` | string | The field the error refers to, when there is one. | ```json { "status_code": 1, "status_error_details": "Required parameter is missing", "status_additional_info": "payme_client_key", "status_error_code": 1 } ``` - [List transactions](https://docs.payme.io/payments/query-apis/post-get-transactions): POST /get-transactions — List transactions # List transactions - Sandbox: `POST https://sandbox.payme.io/api/get-transactions` - Production: `POST https://live.payme.io/api/get-transactions` ## Credentials - Header `PayMe-Partner-Key` (optional): Partner key, instead of `payme_client_key` in the body. Partners only. - Header `PayMe-Merchant-Key` (optional): A seller's own MPL, instead of `seller_payme_id` in the body. - Request body field `payme_client_key` (optional): Partner key. Partners only. Can also be sent in the `PayMe-Partner-Key` header. Without `seller_payme_id`, the query covers all your sellers. - Request body field `seller_payme_id` (optional): The seller's MPL. A partner can send one MPL or an array of up to 100 MPLs of its own sellers to narrow the query. A seller sends its own MPL, here or in the `PayMe-Merchant-Key` header, and gets only its own data. Returns money movements (payments, captures, refunds, voids and chargebacks) for one seller or all your sellers. Use it for amounts in a period: a refund or chargeback is its own row, with its own date and a positive `transaction_price`. A partner sends `payme_client_key` (or the `PayMe-Partner-Key` header) and, optionally, `seller_payme_id`: one MPL or an array of up to 100 MPLs of its own sellers. Without it, the query covers all your sellers. A seller sends its own MPL as `seller_payme_id` in the body, or in the `PayMe-Merchant-Key` header, and gets only its own data. #### Defaults - `transaction_type` is `1` (sale transactions). A sale that is authorized and not yet captured is type `40`, so send `transaction_type: 40` to see it. Types are listed on [Transaction Types](/payments/codes-statuses/transaction-types). - The default statuses are `validated`, `failed`, `refunded`, `p-refund`, `chargeback`, `partial-chargeback`, `chargeback-refund` and `partial-chargeback-refund`. `pending`, `voided` and `partial-void` rows are left out. Send `transaction_status: "validated"` when you add up volume. Statuses are listed on [Transaction Statuses](/payments/codes-statuses/transaction-statuses). - A voided authorization returns no rows from a default query: with `transaction_type: 40` you get its authorization row, whose `sale_status` is `voided`, and adding `transaction_status: ["validated", "voided"]` also returns the `Void` row. #### Telling rows apart `transaction_action` says what each row is: `Debit`, `Authorize`, `Capture`, `Refund`, `Partial Refund`, `Void`, `Partial Void`, `Chargeback`, `Partial Chargeback`, `Chargeback Refund`, `Partial Chargeback Refund`, `Tokenize` or `Detokenize`. A refund is its own row, with a positive `transaction_price`, the action `Refund` or `Partial Refund`, and the status `refunded` or `p-refund`. A void adds no refund row. See [Reading the rows](/agents/steps/capture-refund-void#reading-the-rows). For a sale opened with `sale_payment_method` `multi`, `transaction_payment_method` shows the method the buyer actually used; the sale keeps `multi`. `transaction_error_code` is `null` on a successful transaction. This call is rate limited per partner, or per seller when there's no partner key. On HTTP 429 (error `998`), wait for the `Retry-After` time and retry. Timestamps in the response, and the date filters you send, are Asia/Jerusalem local time, not UTC. A 2–3 hour offset against a UTC clock is the timezone, not a bug. Results come in pages of up to 500 items (default 500). A call without `page` and `page_size` returns only the first 500. Paging, sorting and filter rules are on [Query APIs](/payments/query-apis). ## Parameters | Name | In | Type | Required | Description | | --- | --- | --- | --- | --- | | `PayMe-Partner-Key` | header | string | no | Partner key, instead of `payme_client_key` in the body. Partners only. | | `PayMe-Merchant-Key` | header | string | no | A seller's own MPL, instead of `seller_payme_id` in the body. | ## Request body Content type: `application/json` Every field is optional. Send at least your credentials. | Field | Type | Required | Description | | --- | --- | --- | --- | | `payme_client_key` | string | no | Partner key. Partners only. Can also be sent in the `PayMe-Partner-Key` header. Without `seller_payme_id`, the query covers all your sellers. | | `seller_payme_id` | string | no | The seller's MPL. A partner can send one MPL or an array of up to 100 MPLs of its own sellers to narrow the query. A seller sends its own MPL, here or in the `PayMe-Merchant-Key` header, and gets only its own data. | | `seller_id` | string | no | Your own ID for the seller, as sent to create-seller. Partners only. | | `sale_payme_id` | string | no | PayMe's sale ID. | | `sale_payme_code` | integer | no | PayMe's numeric sale code. | | `transaction_id` | string | no | Your own order ID, as sent to generate-sale. It is not unique. | | `payme_transaction_id` | string | no | PayMe's transaction ID. | | `transaction_type` | integer | no | Transaction type, or an array of them. See [Transaction Types](/payments/codes-statuses/transaction-types). Default `1`. | | `transaction_status` | string | no | Transaction status name, or an array of up to 100. See [Transaction Statuses](/payments/codes-statuses/transaction-statuses). The default set is in the description above. | | `sale_status` | string | no | Status of the transaction's sale, for example `completed`, or an array of up to 100. See [Sale Statuses](/payments/codes-statuses/sale-statuses). | | `sale_currency` | string | no | Currency, 3-letter [ISO 4217](https://en.wikipedia.org/wiki/ISO_4217) code, for example `ILS`, or an array of up to 100. | | `sale_payment_method` | string | no | Payment method of the sale, for example `credit-card`, or an array of up to 100. See [Wallets & APMs](/payments/wallets-apms). | | `transaction_payment_method` | string | no | Payment method actually used on the transaction, for example `bit` on a `multi` sale. | | `transaction_created` | string | no | Exact creation date and time, `yyyy-mm-dd hh:mm:ss`. | | `transaction_created_min` | string | no | Created at or after this time, `yyyy-mm-dd hh:mm:ss`. | | `transaction_created_max` | string | no | Created at or before this time, `yyyy-mm-dd hh:mm:ss`. | | `transaction_price` | integer | no | Exact transaction amount, in minor units (`5075` = 50.75). | | `sale_price` | integer | no | Exact sale amount, in minor units. | | `sale_auth_number` | string | no | Authorization number from the card company. | | `buyer_card_mask` | string | no | Masked card number, first 6 and last 4 digits. | | `buyer_card_last_four_digits` | string | no | Last four digits of the card. | | `buyer_card_is_foreign` | boolean | no | `true` returns only foreign cards, `false` only local cards. | | `buyer_name` | string | no | Buyer's full name. | | `buyer_email` | string | no | Buyer's email. | | `buyer_phone` | string | no | Buyer's phone number. | | `buyer_social_id` | string | no | Buyer's national ID number. | | `sale_is_3ds` | boolean | no | `true` returns only transactions paid with 3D Secure, `false` only those without it. | | `transaction_is_matched` | boolean | no | `true` returns only transactions that PayMe has matched (correlated) in its reconciliation, `false` only the others. | | `page` | integer | no | Page number, `1`–`1000`. Default `1`. Out of range returns error `52`. | | `page_size` | integer | no | Items per page, `1`–`500`. Default `500`. Out of range returns error `27`. | | `items_order_by_column` | string | no | Field to sort by, for example `transaction_created_at`. Without it, the order isn't guaranteed. A field that doesn't exist fails the call. | | `items_order_by_direction` | string | no | `asc` (default) or `desc`, in upper or lower case. Used only with `items_order_by_column`. Any other value returns error `28`. | ### Request example ```json { "payme_client_key": "XXXXXXXX", "seller_payme_id": "MPLDEMO-MPLDEMO-MPLDEMO-1234567", "transaction_status": "validated", "transaction_created_min": "2026-10-01 00:00:00", "transaction_created_max": "2026-10-31 23:59:59", "sale_currency": "ILS", "items_order_by_column": "transaction_created_at", "page": 1, "page_size": 500 } ``` ## Code samples ### curl ```bash curl -X POST 'https://sandbox.payme.io/api/get-transactions' \ -H 'Content-Type: application/json' \ -H 'PayMe-Partner-Key: ' \ -H 'PayMe-Merchant-Key: ' \ --data-raw '{ "payme_client_key": "XXXXXXXX", "seller_payme_id": "MPLDEMO-MPLDEMO-MPLDEMO-1234567", "transaction_status": "validated", "transaction_created_min": "2026-10-01 00:00:00", "transaction_created_max": "2026-10-31 23:59:59", "sale_currency": "ILS", "items_order_by_column": "transaction_created_at", "page": 1, "page_size": 500 }' ``` ### Node.js ```javascript const response = await fetch("https://sandbox.payme.io/api/get-transactions", { method: "POST", headers: { "Content-Type": "application/json", "PayMe-Partner-Key": "", "PayMe-Merchant-Key": "", }, body: JSON.stringify({ "payme_client_key": "XXXXXXXX", "seller_payme_id": "MPLDEMO-MPLDEMO-MPLDEMO-1234567", "transaction_status": "validated", "transaction_created_min": "2026-10-01 00:00:00", "transaction_created_max": "2026-10-31 23:59:59", "sale_currency": "ILS", "items_order_by_column": "transaction_created_at", "page": 1, "page_size": 500 }), }); console.log(await response.text()); ``` ### Python ```python import requests response = requests.post( "https://sandbox.payme.io/api/get-transactions", headers={ "PayMe-Partner-Key": "", "PayMe-Merchant-Key": "", }, json={ "payme_client_key": "XXXXXXXX", "seller_payme_id": "MPLDEMO-MPLDEMO-MPLDEMO-1234567", "transaction_status": "validated", "transaction_created_min": "2026-10-01 00:00:00", "transaction_created_max": "2026-10-31 23:59:59", "sale_currency": "ILS", "items_order_by_column": "transaction_created_at", "page": 1, "page_size": 500, }, ) print(response.text) ``` ### PHP ```php 'POST', CURLOPT_RETURNTRANSFER => true, CURLOPT_HTTPHEADER => [ 'Content-Type: application/json', 'PayMe-Partner-Key: ', 'PayMe-Merchant-Key: ', ], CURLOPT_POSTFIELDS => $body, ]); $response = curl_exec($ch); curl_close($ch); echo $response; ``` ## Responses ### 200 — OK (success) | Field | Type | Description | | --- | --- | --- | | `status_code` | integer | `0` on success. | | `items_count` | integer | Number of items on this page. There is no total count. | | `items` | array | The transactions. | | `items[].seller_payme_id` | string | The seller's MPL. | | `items[].seller_id` | string | Your own ID for the seller, or `null`. | | `items[].sale_payme_id` | string | PayMe's sale ID. | | `items[].sale_payme_code` | integer | PayMe's numeric sale code. | | `items[].transaction_id` | string | Your own order ID, as you sent it to generate-sale. Not a PayMe ID, and not unique. | | `items[].payme_transaction_id` | string | PayMe's transaction ID. Use it in `transaction_ids` on withdraw-balance. | | `items[].transaction_created_at` | string | Creation time, `yyyy-mm-dd hh:mm:ss`, Asia/Jerusalem. | | `items[].sale_type` | integer | Numeric sale type, see [Sale Types](/payments/codes-statuses/sale-types). | | `items[].sale_status` | string | Status of the sale, see [Sale Statuses](/payments/codes-statuses/sale-statuses). | | `items[].transaction_status` | string | Status of this row, see [Transaction Statuses](/payments/codes-statuses/transaction-statuses). | | `items[].transaction_type` | integer | Transaction type, see [Transaction Types](/payments/codes-statuses/transaction-types). | | `items[].transaction_action` | string | What this row is: `Authorize`, `Tokenize`, `Detokenize`, `Debit`, `Capture`, `Refund`, `Partial Refund`, `Void`, `Partial Void`, `Chargeback`, `Partial Chargeback`, `Chargeback Refund` or `Partial Chargeback Refund`. | | `items[].sale_currency` | string | Currency, 3-letter ISO 4217 code. | | `items[].sale_description` | string | What the buyer paid for. | | `items[].sale_installments` | integer | Number of installments. | | `items[].sale_payment_method` | string | Payment method of the sale, see [Wallets & APMs](/payments/wallets-apms). | | `items[].transaction_payment_method` | string | Payment method used on this transaction. For a `multi` sale, the method the buyer chose. | | `items[].transaction_price` | integer | Amount of this row, in minor units. Positive for refunds and chargebacks too. | | `items[].transaction_price_after_fees` | string | Net amount after PayMe fees, in minor units, as a numeric string. Final once settled. | | `items[].sale_vat` | string | VAT rate at the time of the sale, as a fraction (`"0.18"` = 18%). | | `items[].sale_auth_number` | string | Authorization number from the card company. | | `items[].sale_is_3ds` | boolean | `true` if the payment used 3D Secure. | | `items[].transaction_release_date` | string | When the funds are expected in the seller's balance, `yyyy-mm-dd hh:mm:ss`, or `null`. | | `items[].transaction_voucher` | string | Voucher number of the transaction. | | `items[].transaction_reference_number` | string | Reference number from the gateway, or `null`. | | `items[].transaction_first_payment` | string | First installment, in minor units, or the full amount when there are no installments. | | `items[].transaction_periodical_payment` | string | Each later installment, in minor units. `0` when there are no installments. | | `items[].transaction_arn` | string | Acquirer reference number (ARN), or `null`. | | `items[].transaction_acquirer` | string | Acquirer that processed the transaction, or `null`. | | `items[].transaction_discounter` | string | Company that settles the transaction, or `null`. | | `items[].transaction_credit_type` | string | Credit type of the card transaction, as reported by the acquirer. | | `items[].transaction_error_code` | string | Error code on failure. `null` on success. | | `items[].transaction_error_text` | string | Gateway message for the transaction. | | `items[].transaction_comment` | string | Chargeback reason. `null` except on chargeback rows. | | `items[].transaction_is_matched` | boolean | `true` when PayMe has matched (correlated) the transaction in its reconciliation. | | `items[].transaction_match_statuses` | array | The reconciliation statuses set on the transaction. Empty when it isn't matched. | | `items[].transaction_is_canceled` | boolean | `true` if the transaction was canceled before it was transmitted. | | `items[].transaction_is_eligible_for_manual_auth` | boolean | `true` when the transaction was processed by an Israeli acquirer. | | `items[].sale_fees` | object | Fees on this row. Rates are percent strings. `*_total` fields are in minor units, without VAT, computed on `transaction_price`. | | `items[].sale_fees.sale_processing_fee` | string | Processing rate, percent of the amount (`"2.50"` = 2.5%). | | `items[].sale_fees.sale_processing_fee_total` | integer | Processing fee, in minor units. | | `items[].sale_fees.sale_processing_charge` | string | Fixed processing charge per sale, in major units (`"1.20"` = 1.20). | | `items[].sale_fees.sale_discount_fee` | string | Discount rate (early settlement of installments) per installment, percent. | | `items[].sale_fees.sale_discount_fee_total` | integer | Discount fee, in minor units. | | `items[].sale_fees.sale_rapid_settlement_fee` | string | Rapid settlement rate, percent. | | `items[].sale_fees.sale_rapid_settlement_fee_total` | integer | Rapid settlement fee, in minor units. | | `items[].sale_fees.sale_annual_interest_rate` | string | Annual interest rate (percent) behind the discount and rapid settlement fees, or `null`. | | `items[].sale_fees.sale_market_fee` | string | Platform (market) fee rate, percent of the amount. | | `items[].sale_fees.sale_market_fee_fixed` | number | Fixed platform fee per sale, in major units. | | `items[].sale_fees.sale_market_fee_total` | integer | Platform fee, in minor units: the percent part plus the fixed part. | | `items[].sale_business_data` | object | Only on `transaction_type` `50` rows: business details of the paying seller. On these rows `sale_fees` is `{}`. | | `items[].sale_buyer_details` | object | The buyer and the card used. | | `items[].sale_buyer_details.buyer_card_mask` | string | Masked card number: first 6 and last 4 digits. | | `items[].sale_buyer_details.buyer_card_expiry` | string | Card expiry, `MMYY`. | | `items[].sale_buyer_details.buyer_card_brand` | string | Card brand, for example `Visa`. | | `items[].sale_buyer_details.buyer_card_is_foreign` | boolean | `true` for a card issued outside the seller's country, `false` for a local card. | | `items[].sale_buyer_details.buyer_name` | string | Buyer's full name. | | `items[].sale_buyer_details.buyer_email` | string | Buyer's email. | | `items[].sale_buyer_details.buyer_phone` | string | Buyer's phone number. | | `items[].sale_buyer_details.buyer_social_id` | string | Buyer's national ID number. | | `items[].transaction_invoice_url` | string | Link to the transaction's invoice, or `null`. | | `items[].transaction_invoice_doc_number` | string | Invoice document number, or `null`. | ```json { "status_code": 0, "items_count": 1, "items": [ { "seller_payme_id": "MPLDEMO-MPLDEMO-MPLDEMO-1234567", "seller_id": null, "sale_payme_id": "SALE1499-869577YG-Y2QXJ6PK-INXR2FAE", "sale_payme_code": 115498, "transaction_id": "order-12345", "payme_transaction_id": "TRAN1499-869602B9-7QIUNKHI-F0SL1AOV", "transaction_created_at": "2026-10-12 17:26:42", "sale_type": 1, "sale_status": "completed", "transaction_status": "validated", "transaction_type": 1, "transaction_action": "Debit", "sale_currency": "ILS", "sale_description": "Handmade ceramic bowl", "sale_installments": 1, "sale_payment_method": "credit-card", "transaction_payment_method": "credit-card", "transaction_price": 9000, "transaction_price_after_fees": "8617", "sale_vat": "0.18", "sale_auth_number": "2154577", "sale_is_3ds": false, "transaction_release_date": "2026-10-19 06:00:00", "transaction_voucher": "10784", "transaction_reference_number": null, "transaction_first_payment": "9000", "transaction_periodical_payment": "0", "transaction_arn": null, "transaction_acquirer": null, "transaction_discounter": null, "transaction_credit_type": "1", "transaction_error_code": null, "transaction_error_text": "Permitted transaction", "transaction_comment": null, "transaction_is_matched": false, "transaction_match_statuses": [], "transaction_is_canceled": false, "transaction_is_eligible_for_manual_auth": false, "sale_fees": { "sale_processing_fee": "2.50", "sale_processing_fee_total": 225, "sale_processing_charge": "1.20", "sale_discount_fee": "0.00", "sale_discount_fee_total": 0, "sale_rapid_settlement_fee": "0.00", "sale_rapid_settlement_fee_total": 0, "sale_annual_interest_rate": null, "sale_market_fee": "0.00", "sale_market_fee_fixed": 0, "sale_market_fee_total": 0 }, "sale_buyer_details": { "buyer_card_mask": "458045******4580", "buyer_card_expiry": "1228", "buyer_card_brand": "Visa", "buyer_card_is_foreign": false, "buyer_name": "Israel Israeli", "buyer_email": "buyer@example.com", "buyer_phone": "0500000001", "buyer_social_id": "000000018" }, "transaction_invoice_url": null, "transaction_invoice_doc_number": null } ] } ``` ### 500 — Error. Most errors return HTTP 500. Paging errors (`52`, `27`) return HTTP 400, and the rate limit (`998`) returns HTTP 429. The body is the same. See [Errors](/payments/getting-started/errors). (error) | Field | Type | Description | | --- | --- | --- | | `status_code` | integer | `1` on failure. | | `status_error_code` | integer | PayMe error code. | | `status_error_details` | string | Error message. | | `status_additional_info` | string | The field the error refers to, when there is one. | ```json { "status_code": 1, "status_error_details": "Required parameter is missing", "status_additional_info": "payme_client_key", "status_error_code": 1 } ``` - [List subscriptions](https://docs.payme.io/payments/query-apis/post-get-subscriptions): POST /get-subscriptions — List subscriptions # List subscriptions - Sandbox: `POST https://sandbox.payme.io/api/get-subscriptions` - Production: `POST https://live.payme.io/api/get-subscriptions` ## Credentials - Header `PayMe-Partner-Key` (optional): Partner key, instead of `payme_client_key` in the body. Partners only. - Header `PayMe-Merchant-Key` (optional): A seller's own MPL, instead of `seller_payme_id` in the body. - Request body field `payme_client_key` (optional): Partner key. Partners only. Can also be sent in the `PayMe-Partner-Key` header. Without `seller_payme_id`, the query covers all your sellers. - Request body field `seller_payme_id` (optional): The seller's MPL. A partner can send one MPL or an array of up to 100 MPLs of its own sellers to narrow the query. A seller sends its own MPL, here or in the `PayMe-Merchant-Key` header, and gets only its own data. Returns subscriptions for one seller or all your sellers, with their status, schedule and buyer. Use `sub_status` to find active (`2`) or failing (`4`, `7`) subscriptions. The response never contains the `buyer_key`. See [Recurring Payments](/payments/saved-cards-recurring) for how subscriptions are charged and retried. A partner sends `payme_client_key` (or the `PayMe-Partner-Key` header) and, optionally, `seller_payme_id`: one MPL or an array of up to 100 MPLs of its own sellers. Without it, the query covers all your sellers. A seller sends its own MPL as `seller_payme_id` in the body, or in the `PayMe-Merchant-Key` header, and gets only its own data. Status values are numbers, see [Subscription Statuses](/payments/codes-statuses/subscription-statuses). Iteration types are on [Subscription Iteration Types](/payments/codes-statuses/subscription-iteration-types). Without `sub_type`, all four subscription types are returned. Filters are exact matches, except `sub_created_min` / `sub_created_max`. Most filters take a single value or an array of up to 100 values. Dates are `yyyy-mm-dd hh:mm:ss`. Timestamps and the `*_min` / `*_max` filters are Asia/Jerusalem local time, not UTC. Results come in pages of up to 500 items (default 500). A call without `page` and `page_size` returns only the first 500. Paging, sorting and filter rules are on [Query APIs](/payments/query-apis). ## Parameters | Name | In | Type | Required | Description | | --- | --- | --- | --- | --- | | `PayMe-Partner-Key` | header | string | no | Partner key, instead of `payme_client_key` in the body. Partners only. | | `PayMe-Merchant-Key` | header | string | no | A seller's own MPL, instead of `seller_payme_id` in the body. | ## Request body Content type: `application/json` Every field is optional. Send at least your credentials. | Field | Type | Required | Description | | --- | --- | --- | --- | | `payme_client_key` | string | no | Partner key. Partners only. Can also be sent in the `PayMe-Partner-Key` header. Without `seller_payme_id`, the query covers all your sellers. | | `seller_payme_id` | string | no | The seller's MPL. A partner can send one MPL or an array of up to 100 MPLs of its own sellers to narrow the query. A seller sends its own MPL, here or in the `PayMe-Merchant-Key` header, and gets only its own data. | | `seller_id` | string | no | Your own ID for the seller, as sent to create-seller. Partners only. | | `sub_payme_code` | integer | no | PayMe's numeric subscription code. | | `sub_payme_id` | string | no | PayMe's subscription ID. | | `subscription_id` | string | no | Your own reference set on generate-subscription. Not unique: several subscriptions can match. | | `sub_parent_code` | integer | no | Code of the parent the subscription was created from, such as its template. | | `sub_type` | integer | no | Subscription type, or an array of them: `1` regular, `2` created from a template, `10` template, `20` payment contract. Default: all four. | | `sub_created` | string | no | Exact creation date and time, `yyyy-mm-dd hh:mm:ss`. | | `sub_created_min` | string | no | Created at or after this time, `yyyy-mm-dd hh:mm:ss`. | | `sub_created_max` | string | no | Created at or before this time, `yyyy-mm-dd hh:mm:ss`. | | `sub_status` | integer | no | Subscription status, or an array of them: `1` initial, `2` active, `3` paused, `4` failed, `5` canceled, `6` completed, `7` failed, pending an automatic retry. See [Subscription Statuses](/payments/codes-statuses/subscription-statuses). | | `sub_iteration_type` | integer | no | Iteration type, see [Subscription Iteration Types](/payments/codes-statuses/subscription-iteration-types). | | `sub_price` | integer | no | Exact price, in minor units (`5075` = 50.75). | | `sub_currency` | string | no | Subscription currency, 3-letter [ISO 4217](https://en.wikipedia.org/wiki/ISO_4217) code. | | `sub_iterations` | integer | no | Total number of charges. `-1` for a subscription with no end. | | `sub_paid` | boolean | no | `true` returns only subscriptions the buyer has paid (a payment method is saved), `false` only unpaid ones. | | `sub_send_notification` | boolean | no | `true` returns only `initial` subscriptions that have a buyer email or phone, for example to send a payment reminder. | | `buyer_card_mask` | string | no | Masked card number, first 6 and last 4 digits. | | `buyer_name` | string | no | Buyer's full name. | | `buyer_email` | string | no | Buyer's email. | | `buyer_phone` | string | no | Buyer's phone number. | | `buyer_social_id` | string | no | Buyer's national ID number. | | `page` | integer | no | Page number, `1`–`1000`. Default `1`. Out of range returns error `52`. | | `page_size` | integer | no | Items per page, `1`–`500`. Default `500`. Out of range returns error `27`. | | `items_order_by_column` | string | no | Field to sort by, for example `sub_created`. Without it, the order isn't guaranteed. A field that doesn't exist fails the call. | | `items_order_by_direction` | string | no | `asc` (default) or `desc`, in upper or lower case. Used only with `items_order_by_column`. Any other value returns error `28`. | ### Request example ```json { "payme_client_key": "XXXXXXXX", "seller_payme_id": "MPLDEMO-MPLDEMO-MPLDEMO-1234567", "sub_status": [ 4, 7 ] } ``` ## Code samples ### curl ```bash curl -X POST 'https://sandbox.payme.io/api/get-subscriptions' \ -H 'Content-Type: application/json' \ -H 'PayMe-Partner-Key: ' \ -H 'PayMe-Merchant-Key: ' \ --data-raw '{ "payme_client_key": "XXXXXXXX", "seller_payme_id": "MPLDEMO-MPLDEMO-MPLDEMO-1234567", "sub_status": [ 4, 7 ] }' ``` ### Node.js ```javascript const response = await fetch("https://sandbox.payme.io/api/get-subscriptions", { method: "POST", headers: { "Content-Type": "application/json", "PayMe-Partner-Key": "", "PayMe-Merchant-Key": "", }, body: JSON.stringify({ "payme_client_key": "XXXXXXXX", "seller_payme_id": "MPLDEMO-MPLDEMO-MPLDEMO-1234567", "sub_status": [ 4, 7 ] }), }); console.log(await response.text()); ``` ### Python ```python import requests response = requests.post( "https://sandbox.payme.io/api/get-subscriptions", headers={ "PayMe-Partner-Key": "", "PayMe-Merchant-Key": "", }, json={ "payme_client_key": "XXXXXXXX", "seller_payme_id": "MPLDEMO-MPLDEMO-MPLDEMO-1234567", "sub_status": [ 4, 7, ], }, ) print(response.text) ``` ### PHP ```php 'POST', CURLOPT_RETURNTRANSFER => true, CURLOPT_HTTPHEADER => [ 'Content-Type: application/json', 'PayMe-Partner-Key: ', 'PayMe-Merchant-Key: ', ], CURLOPT_POSTFIELDS => $body, ]); $response = curl_exec($ch); curl_close($ch); echo $response; ``` ## Responses ### 200 — OK (success) | Field | Type | Description | | --- | --- | --- | | `status_code` | integer | `0` on success. | | `items_count` | integer | Number of items on this page. There is no total count. | | `items` | array | The subscriptions. | | `items[].seller_payme_id` | string | The seller's MPL. | | `items[].seller_id` | string | Your own ID for the seller, or `null`. | | `items[].sub_payme_id` | string | PayMe's subscription ID. | | `items[].sub_payme_code` | integer | PayMe's numeric subscription code. | | `items[].sub_parent_code` | integer | Code of the parent the subscription was created from, or `null`. | | `items[].subscription_id` | string | Your own reference, as sent to generate-subscription. | | `items[].sub_type` | integer | Subscription type: `1` regular, `2` created from a template, `10` template, `20` payment contract. | | `items[].sub_created` | string | Creation time, `yyyy-mm-dd hh:mm:ss`. | | `items[].sub_start_date` | string | Start date of the subscription, `yyyy-mm-dd hh:mm:ss`. | | `items[].sub_prev_date` | string | Date of the previous charge, `yyyy-mm-dd hh:mm:ss`, or `null`. | | `items[].sub_next_date` | string | Date of the next charge, `yyyy-mm-dd hh:mm:ss`, or `null`. | | `items[].sub_status` | integer | Subscription status: `1` initial, `2` active, `3` paused, `4` failed, `5` canceled, `6` completed, `7` failed, pending an automatic retry. See [Subscription Statuses](/payments/codes-statuses/subscription-statuses). | | `items[].sub_iteration_type` | integer | Iteration type, see [Subscription Iteration Types](/payments/codes-statuses/subscription-iteration-types). | | `items[].sub_currency` | string | Subscription currency, 3-letter ISO 4217 code. | | `items[].sub_price` | integer | Price of each charge, in minor units (`5075` = 50.75). | | `items[].sub_description` | string | Description of the subscription. | | `items[].sub_iterations` | integer | Total number of charges. `-1` when the subscription has no end. | | `items[].sub_iterations_completed` | integer | Charges completed so far. | | `items[].sub_iterations_skipped` | integer | Charges skipped. | | `items[].sub_iterations_left` | integer | Charges left. | | `items[].sub_payment_date` | string | When the buyer's payment method was saved (the first successful payment), `yyyy-mm-dd hh:mm:ss`, or `null`. | | `items[].sub_error_text` | string | Reason for the last failure, if any. | | `items[].sub_url` | string | Link to the subscription's payment page. | | `items[].sub_paid` | boolean | `true` once the buyer has paid and a payment method is saved. | | `items[].sub_buyer_details` | object | The buyer. | | `items[].sub_buyer_details.buyer_card_mask` | string | Masked card number: first 6 and last 4 digits. | | `items[].sub_buyer_details.buyer_name` | string | Buyer's full name. | | `items[].sub_buyer_details.buyer_email` | string | Buyer's email. | | `items[].sub_buyer_details.buyer_phone` | string | Buyer's phone number. | | `items[].sub_buyer_details.buyer_social_id` | string | Buyer's national ID number. | ```json { "status_code": 0, "items_count": 1, "items": [ { "seller_payme_id": "MPLDEMO-MPLDEMO-MPLDEMO-1234567", "seller_id": "store-1001", "sub_payme_id": "XXXXXXXX-XXXXXXXX-XXXXXXXX-XXXXXXXX", "sub_payme_code": 1234, "sub_parent_code": null, "subscription_id": "member-778", "sub_type": 1, "sub_created": "2026-01-01 15:15:15", "sub_start_date": "2026-01-10 08:00:00", "sub_prev_date": "2026-10-10 08:00:00", "sub_next_date": "2026-11-10 08:00:00", "sub_status": 7, "sub_iteration_type": 3, "sub_currency": "ILS", "sub_price": 10000, "sub_description": "Monthly membership", "sub_iterations": 12, "sub_iterations_completed": 9, "sub_iterations_skipped": 0, "sub_iterations_left": 3, "sub_payment_date": "2026-01-10 08:00:05", "sub_error_text": "Card declined", "sub_url": "https://sandbox.payme.io/subscription/generate/XXXXXXXX-XXXXXXXX-XXXXXXXX-XXXXXXXX", "sub_paid": true, "sub_buyer_details": { "buyer_card_mask": "458045******4580", "buyer_name": "Israel Israeli", "buyer_email": "buyer@example.com", "buyer_phone": "0500000001", "buyer_social_id": "000000018" } } ] } ``` ### 500 — Error. Most errors return HTTP 500. Paging errors (`52`, `27`) return HTTP 400. The body is the same. See [Errors](/payments/getting-started/errors). (error) | Field | Type | Description | | --- | --- | --- | | `status_code` | integer | `1` on failure. | | `status_error_code` | integer | PayMe error code. | | `status_error_details` | string | Error message. | | `status_additional_info` | string | The field the error refers to, when there is one. | ```json { "status_code": 1, "status_error_details": "Required parameter is missing", "status_additional_info": "payme_client_key", "status_error_code": 1 } ``` - [List sellers](https://docs.payme.io/payments/query-apis/post-get-sellers): POST /get-sellers — List sellers # List sellers - Sandbox: `POST https://sandbox.payme.io/api/get-sellers` - Production: `POST https://live.payme.io/api/get-sellers` ## Credentials - Header `PayMe-Partner-Key` (optional): Partner key, instead of `payme_client_key` in the body. Partners only. - Header `PayMe-Merchant-Key` (optional): A seller's own MPL, instead of `seller_payme_id` in the body. - Request body field `payme_client_key` (optional): Partner key. Partners only. Can also be sent in the `PayMe-Partner-Key` header. Without `seller_payme_id`, the query covers all your sellers. - Request body field `seller_payme_id` (optional): The seller's MPL. A partner can send one MPL or an array of up to 100 MPLs of its own sellers to narrow the query. A seller sends its own MPL, here or in the `PayMe-Merchant-Key` header, and gets only its own data. Returns your sellers with their personal, business and bank details, fee settings and wallet balances. Use it to check a seller's balance or approval, or to list the sellers created in a period. Only seller accounts are returned, not partner or system accounts. A partner sends `payme_client_key` (or the `PayMe-Partner-Key` header) and, optionally, `seller_payme_id`: one MPL or an array of up to 100 MPLs of its own sellers. Without it, the query covers all your sellers. A seller sends its own MPL as `seller_payme_id` in the body, or in the `PayMe-Merchant-Key` header, and gets only its own data. The response contains ID numbers and bank details: keep it on your server. Set `api_mode` to `slim` for a faster call on long lists. It leaves out `seller_wallets`, `seller_monthly_invoices` and `seller_monthly_balance_authorizations`. Omit `api_mode` for the default, which includes them. Filters are exact matches, except `seller_created_min` / `seller_created_max`. Most filters take a single value or an array of up to 100 values. Dates are `yyyy-mm-dd hh:mm:ss`, Asia/Jerusalem time. Results come in pages of up to 500 items (default 500). A call without `page` and `page_size` returns only the first 500. Paging, sorting and filter rules are on [Query APIs](/payments/query-apis). ## Parameters | Name | In | Type | Required | Description | | --- | --- | --- | --- | --- | | `PayMe-Partner-Key` | header | string | no | Partner key, instead of `payme_client_key` in the body. Partners only. | | `PayMe-Merchant-Key` | header | string | no | A seller's own MPL, instead of `seller_payme_id` in the body. | ## Request body Content type: `application/json` Every field is optional. Send at least your credentials. | Field | Type | Required | Description | | --- | --- | --- | --- | | `payme_client_key` | string | no | Partner key. Partners only. Can also be sent in the `PayMe-Partner-Key` header. Without `seller_payme_id`, the query covers all your sellers. | | `seller_payme_id` | string | no | The seller's MPL. A partner can send one MPL or an array of up to 100 MPLs of its own sellers to narrow the query. A seller sends its own MPL, here or in the `PayMe-Merchant-Key` header, and gets only its own data. | | `seller_id` | string | no | Your own ID for the seller, as sent to create-seller. Partners only. | | `api_mode` | string | no | `slim` returns seller details only, without `seller_wallets`, `seller_monthly_invoices` and `seller_monthly_balance_authorizations`. Omit it for the default, which includes them. | | `seller_created` | string | no | Exact creation date and time, `yyyy-mm-dd hh:mm:ss`. | | `seller_created_min` | string | no | Created at or after this time, `yyyy-mm-dd hh:mm:ss`. | | `seller_created_max` | string | no | Created at or before this time, `yyyy-mm-dd hh:mm:ss`. | | `seller_first_name` | string | no | First name of the seller's owner. | | `seller_last_name` | string | no | Last name of the seller's owner. | | `seller_social_id` | string | no | National ID number of the seller's owner. | | `seller_email` | string | no | Seller's email. | | `seller_phone` | string | no | Seller's phone number. | | `seller_contact_email` | string | no | Contact email shown to buyers. | | `seller_contact_phone` | string | no | Contact phone shown to buyers. | | `seller_inc` | integer | no | Incorporation type, see [Seller Incorporation Types (IL)](/marketplaces-and-platforms/seller-reference/seller-incorporation-types-il). `0` and `1` both mean Individual. | | `seller_inc_code` | string | no | Business registration number (ח.פ or ע.מ). | | `seller_merchant_name` | string | no | Seller's business name. | | `fee_market_fee` | number | no | The seller's default platform (market) fee, percent of the sale price. | | `seller_active` | boolean | no | `true` returns only active sellers, `false` only inactive ones. | | `seller_approved` | boolean | no | `true` returns only sellers approved by PayMe, `false` only sellers not approved yet. | | `page` | integer | no | Page number, `1`–`1000`. Default `1`. Out of range returns error `52`. | | `page_size` | integer | no | Items per page, `1`–`500`. Default `500`. Out of range returns error `27`. | | `items_order_by_column` | string | no | Field to sort by. Without it, the order isn't guaranteed. A field that doesn't exist fails the call. | | `items_order_by_direction` | string | no | `asc` (default) or `desc`, in upper or lower case. Used only with `items_order_by_column`. Any other value returns error `28`. | ### Request example ```json { "payme_client_key": "XXXXXXXX", "seller_created_min": "2026-10-01 00:00:00", "seller_created_max": "2026-10-31 23:59:59", "seller_approved": true, "api_mode": "slim" } ``` ## Code samples ### curl ```bash curl -X POST 'https://sandbox.payme.io/api/get-sellers' \ -H 'Content-Type: application/json' \ -H 'PayMe-Partner-Key: ' \ -H 'PayMe-Merchant-Key: ' \ --data-raw '{ "payme_client_key": "XXXXXXXX", "seller_created_min": "2026-10-01 00:00:00", "seller_created_max": "2026-10-31 23:59:59", "seller_approved": true, "api_mode": "slim" }' ``` ### Node.js ```javascript const response = await fetch("https://sandbox.payme.io/api/get-sellers", { method: "POST", headers: { "Content-Type": "application/json", "PayMe-Partner-Key": "", "PayMe-Merchant-Key": "", }, body: JSON.stringify({ "payme_client_key": "XXXXXXXX", "seller_created_min": "2026-10-01 00:00:00", "seller_created_max": "2026-10-31 23:59:59", "seller_approved": true, "api_mode": "slim" }), }); console.log(await response.text()); ``` ### Python ```python import requests response = requests.post( "https://sandbox.payme.io/api/get-sellers", headers={ "PayMe-Partner-Key": "", "PayMe-Merchant-Key": "", }, json={ "payme_client_key": "XXXXXXXX", "seller_created_min": "2026-10-01 00:00:00", "seller_created_max": "2026-10-31 23:59:59", "seller_approved": True, "api_mode": "slim", }, ) print(response.text) ``` ### PHP ```php 'POST', CURLOPT_RETURNTRANSFER => true, CURLOPT_HTTPHEADER => [ 'Content-Type: application/json', 'PayMe-Partner-Key: ', 'PayMe-Merchant-Key: ', ], CURLOPT_POSTFIELDS => $body, ]); $response = curl_exec($ch); curl_close($ch); echo $response; ``` ## Responses ### 200 — OK (success) | Field | Type | Description | | --- | --- | --- | | `status_code` | integer | `0` on success. | | `items_count` | integer | Number of items on this page. There is no total count. | | `items` | array | The sellers. | | `items[].seller_payme_id` | string | The seller's MPL. | | `items[].seller_id` | string | Your own ID for the seller, or `null`. | | `items[].seller_created` | string | Creation time, `yyyy-mm-dd hh:mm:ss`. | | `items[].seller_active` | boolean | `true` if the seller is active. | | `items[].seller_approved` | boolean | `true` once PayMe has approved the seller. Withdrawals need approval. | | `items[].seller_approved_date` | string | When PayMe approved the seller, or `null`. | | `items[].seller_is_deferred` | boolean | `true` if the seller's account type is Deferred. | | `items[].seller_withdrawal_plan` | integer | Withdrawal plan: `1` manual, `2` daily, `3` monthly. | | `items[].seller_withdrawal_date` | integer | Day of the month of the payout when the plan is `3`, otherwise `null`. | | `items[].seller_allow_foreign_cards` | boolean | `true` if the seller accepts foreign cards. | | `items[].seller_personal_details` | object | The seller's owner (primary individual). | | `items[].seller_personal_details.seller_first_name` | string | First name. | | `items[].seller_personal_details.seller_last_name` | string | Last name. | | `items[].seller_personal_details.seller_first_name_en` | string | First name in English. | | `items[].seller_personal_details.seller_last_name_en` | string | Last name in English. | | `items[].seller_personal_details.seller_social_id` | string | National ID number. | | `items[].seller_personal_details.seller_social_id_country` | string | Country that issued the ID, ISO 3166-1 alpha-2 code. | | `items[].seller_personal_details.seller_social_id_issued` | string | ID issue date, `yyyy-mm-dd`. | | `items[].seller_personal_details.seller_birthdate` | string | Date of birth, `yyyy-mm-dd`. | | `items[].seller_personal_details.seller_date_of_birth` | string | Same as `seller_birthdate`. Kept for older integrations. | | `items[].seller_personal_details.seller_gender` | integer | `0` male, `1` female, `2` other. | | `items[].seller_personal_details.seller_email` | string | Seller's email. | | `items[].seller_personal_details.seller_phone` | string | Seller's phone number. | | `items[].seller_personal_details.seller_has_criminal_record` | boolean | The owner's answer to the criminal record question, or `null`. | | `items[].seller_business_details` | object | The business and its bank account. | | `items[].seller_business_details.seller_inc` | integer | Incorporation type, see [Seller Incorporation Types (IL)](/marketplaces-and-platforms/seller-reference/seller-incorporation-types-il). `0` for Individual. | | `items[].seller_business_details.seller_inc_code` | string | Business registration number (ח.פ or ע.מ). | | `items[].seller_business_details.seller_registration_date` | string | Business registration date, `yyyy-mm-dd`, or `null`. | | `items[].seller_business_details.seller_merchant_name` | string | Business name. | | `items[].seller_business_details.seller_merchant_name_en` | string | Business name in English. | | `items[].seller_business_details.seller_dba` | string | Trading name (doing business as). | | `items[].seller_business_details.seller_dba_en` | string | Trading name in English. | | `items[].seller_business_details.seller_business_type` | integer | Business field code (`seller_person_business_type` on create-seller). See [MCC List](/marketplaces-and-platforms/seller-reference/mcc-list). | | `items[].seller_business_details.seller_site_url` | string | Seller's website. | | `items[].seller_business_details.seller_description` | string | Description of the business. | | `items[].seller_business_details.seller_retail_type` | integer | `1` card not present (online), `2` card present, `4` phone or mail order (MOTO). | | `items[].seller_business_details.seller_contact_email` | string | Contact email shown to buyers. | | `items[].seller_business_details.seller_contact_phone` | string | Contact phone shown to buyers. | | `items[].seller_business_details.seller_bank_account_code` | string | Bank code (`seller_bank_code` on create-seller). See [Banks in Israel](/payments/codes-statuses/banks-in-israel). | | `items[].seller_business_details.seller_bank_account_branch` | string | Bank branch (`seller_bank_branch` on create-seller). | | `items[].seller_business_details.seller_bank_account_number` | string | Bank account number. | | `items[].seller_business_details.seller_bank_routing_number_foreign` | string | Routing number of a bank account abroad, or `null`. | | `items[].seller_business_details.seller_bank_account_number_foreign` | string | Number of a bank account abroad, or `null`. | | `items[].seller_business_details.seller_need_foreign_currency` | boolean | The seller's answer: needs to process foreign currencies. `null` if not answered. | | `items[].seller_business_details.seller_was_rejected_by_bank` | boolean | The seller's answer: was rejected by a bank before. `null` if not answered. | | `items[].seller_business_details.seller_bank_rejection_reason` | string | The reason the seller gave for the bank rejection, or `null`. | | `items[].seller_business_details.seller_source_of_finance` | string | Source of the business's funds, as a name, or `null`. | | `items[].seller_business_details.seller_required_service_type` | string | Service type the seller asked for, as a name, or `null`. | | `items[].seller_business_details.seller_account_type` | string | Account type: `Deferred`, `Restricted`, `Unrestricted`, `Accounting` or `POS`. | | `items[].seller_address` | object | The business address. | | `items[].seller_address.seller_address_city` | string | City. | | `items[].seller_address.seller_address_street` | string | Street. | | `items[].seller_address.seller_address_street_number` | string | Street number. | | `items[].seller_address.seller_address_country` | string | Country, ISO 3166-1 alpha-2 code. | | `items[].seller_fees` | object | This seller's fee settings. Rates are percent strings (`"2.50"` = 2.5%), and `*_processing_charge` is a fixed charge in major units. `foreign` is for foreign cards, `forcurr` for sales in a foreign currency. | | `items[].seller_fees.fee_market_fee` | string | Default platform (market) fee you take on this seller's sales, percent. | | `items[].seller_fees.fee_default_processing_fee` | string | Processing rate, percent. | | `items[].seller_fees.fee_default_processing_charge` | string | Fixed charge per transaction, in major units. | | `items[].seller_fees.fee_default_rapid_settlement_fee` | string | Rapid settlement rate, percent. | | `items[].seller_fees.fee_default_discount_fee` | string | Discount rate (early settlement of installments) per installment, percent. | | `items[].seller_fees.fee_default_premium_processing_fee` | string | Processing rate for premium cards, percent. | | `items[].seller_fees.fee_corporate_processing_fee` | string | Processing rate for corporate cards, percent. | | `items[].seller_fees.fee_foreign_processing_fee` | string | Processing rate for foreign cards, percent. | | `items[].seller_fees.fee_foreign_processing_charge` | string | Fixed charge per transaction on foreign cards, in major units. | | `items[].seller_fees.fee_foreign_rapid_settlement_fee` | string | Rapid settlement rate for foreign cards, percent. | | `items[].seller_fees.fee_foreign_discount_fee` | string | Discount rate for foreign cards, percent. | | `items[].seller_fees.fee_foreign_premium_processing_fee` | string | Processing rate for foreign premium cards, percent. | | `items[].seller_fees.fee_foreign_corporate_processing_fee` | string | Processing rate for foreign corporate cards, percent. | | `items[].seller_fees.fee_forcurr_processing_fee` | string | Processing rate for sales in a foreign currency, percent. | | `items[].seller_fees.fee_forcurr_processing_charge` | string | Fixed charge per transaction in a foreign currency, in major units. | | `items[].seller_fees.fee_forcurr_rapid_settlement_fee` | string | Rapid settlement rate for sales in a foreign currency, percent. | | `items[].seller_fees.fee_forcurr_discount_fee` | string | Discount rate for sales in a foreign currency, percent. | | `items[].seller_fees.fee_forcurr_premium_processing_fee` | string | Processing rate for premium cards in a foreign currency, percent. | | `items[].seller_fees.fee_forcurr_corporate_processing_fee` | string | Processing rate for corporate cards in a foreign currency, percent. | | `items[].seller_currencies` | array | Currencies the seller can sell in, as ISO 4217 codes. | | `items[].seller_processing_percent` | number | Share of the seller's processing limit used, percent. | | `items[].seller_processing_limit` | integer | The seller's processing limit. | | `items[].seller_timezone` | string | The seller's timezone. | | `items[].seller_display_language` | string | The seller's language, for example `he` or `en`. | | `items[].seller_wallets` | object | Balances, one entry per currency, keyed by the currency code. Not returned with `api_mode` `slim`. | | `items[].seller_wallets.ILS` | object | The wallet in this currency. | | `items[].seller_wallets.ILS.wallet_currency` | string | Currency of the wallet. | | `items[].seller_wallets.ILS.wallet_total` | integer | Everything PayMe holds for the seller in this currency, in minor units. | | `items[].seller_wallets.ILS.wallet_releasable` | integer | The part past its release date, available to withdraw, in minor units. | | `items[].seller_monthly_invoices` | object | PayMe's monthly invoices to the seller, keyed by invoice document number. Not returned with `api_mode` `slim`. | | `items[].seller_monthly_invoices.1234` | object | One invoice. | | `items[].seller_monthly_invoices.1234.invoice_reference` | string | Month the invoice covers, `yyyy-mm`. | | `items[].seller_monthly_invoices.1234.invoice_created` | string | Invoice date, `yyyy-mm-dd`. | | `items[].seller_monthly_invoices.1234.invoice_doc_number` | string | Invoice document number. | | `items[].seller_monthly_invoices.1234.invoice_currency` | string | Invoice currency. | | `items[].seller_monthly_invoices.1234.invoice_url` | string | Link to the invoice PDF. | | `items[].seller_monthly_invoices.1234.invoice_details_url` | string | Link to the invoice details page. | | `items[].seller_monthly_balance_authorizations` | object | Links to the seller's monthly balance statements, keyed by year and then by month (`1`–`12`). A month appears from the 10th of the following month. Not returned with `api_mode` `slim`. | ```json { "status_code": 0, "items_count": 1, "items": [ { "seller_payme_id": "MPLDEMO-MPLDEMO-MPLDEMO-1234567", "seller_id": "store-1001", "seller_created": "2026-01-01 15:15:15", "seller_active": true, "seller_approved": true, "seller_approved_date": "2026-01-05 10:00:00", "seller_is_deferred": false, "seller_withdrawal_plan": 1, "seller_withdrawal_date": null, "seller_allow_foreign_cards": true, "seller_personal_details": { "seller_first_name": "Dana", "seller_last_name": "Levi", "seller_first_name_en": "Dana", "seller_last_name_en": "Levi", "seller_social_id": "000000018", "seller_social_id_country": "IL", "seller_social_id_issued": "2015-02-01", "seller_birthdate": "1989-05-06", "seller_date_of_birth": "1989-05-06", "seller_gender": 1, "seller_email": "dana@example.com", "seller_phone": "0500000005", "seller_has_criminal_record": false }, "seller_business_details": { "seller_inc": 2, "seller_inc_code": "000000018", "seller_registration_date": null, "seller_merchant_name": "Dana Ceramics", "seller_merchant_name_en": "Dana Ceramics", "seller_dba": "Dana Ceramics", "seller_dba_en": "Dana Ceramics", "seller_business_type": 10004, "seller_site_url": "https://www.example.com", "seller_description": "Handmade ceramics", "seller_retail_type": 1, "seller_contact_email": "contact@example.com", "seller_contact_phone": "031234567", "seller_bank_account_code": "12", "seller_bank_account_branch": "123", "seller_bank_account_number": "123456", "seller_bank_routing_number_foreign": null, "seller_bank_account_number_foreign": null, "seller_need_foreign_currency": null, "seller_was_rejected_by_bank": null, "seller_bank_rejection_reason": null, "seller_source_of_finance": null, "seller_required_service_type": null, "seller_account_type": "Unrestricted" }, "seller_address": { "seller_address_city": "Tel Aviv", "seller_address_street": "Herzl", "seller_address_street_number": "10", "seller_address_country": "IL" }, "seller_fees": { "fee_market_fee": "1.50", "fee_default_processing_fee": "2.50", "fee_default_processing_charge": "1.20", "fee_default_rapid_settlement_fee": "0.00", "fee_default_discount_fee": "0.50", "fee_default_premium_processing_fee": "2.50", "fee_corporate_processing_fee": "2.50", "fee_foreign_processing_fee": "3.50", "fee_foreign_processing_charge": "1.20", "fee_foreign_rapid_settlement_fee": "0.00", "fee_foreign_discount_fee": "0.50", "fee_foreign_premium_processing_fee": "3.50", "fee_foreign_corporate_processing_fee": "3.50", "fee_forcurr_processing_fee": "3.50", "fee_forcurr_processing_charge": "0.30", "fee_forcurr_rapid_settlement_fee": "0.00", "fee_forcurr_discount_fee": "0.50", "fee_forcurr_premium_processing_fee": "3.50", "fee_forcurr_corporate_processing_fee": "3.50" }, "seller_currencies": [ "ILS", "USD" ], "seller_processing_percent": 12, "seller_processing_limit": 100000, "seller_timezone": "Asia/Jerusalem", "seller_display_language": "he", "seller_wallets": { "ILS": { "wallet_currency": "ILS", "wallet_total": 10000, "wallet_releasable": 2500 }, "USD": { "wallet_currency": "USD", "wallet_total": 0, "wallet_releasable": 0 } }, "seller_monthly_invoices": { "1234": { "invoice_reference": "2026-09", "invoice_created": "2026-10-01", "invoice_doc_number": "1234", "invoice_currency": "ILS", "invoice_url": "https://example.com/invoices/1234.pdf", "invoice_details_url": "https://example.com/invoice-details/1234" } }, "seller_monthly_balance_authorizations": { "2026": { "9": "https://example.com/balance/2026-09" } } } ] } ``` ### 500 — Error. Most errors return HTTP 500. Paging errors (`52`, `27`) return HTTP 400. The body is the same. See [Errors](/payments/getting-started/errors). (error) | Field | Type | Description | | --- | --- | --- | | `status_code` | integer | `1` on failure. | | `status_error_code` | integer | PayMe error code. | | `status_error_details` | string | Error message. | | `status_additional_info` | string | The field the error refers to, when there is one. | ```json { "status_code": 1, "status_error_details": "Required parameter is missing", "status_additional_info": "payme_client_key", "status_error_code": 1 } ``` - [List withdrawals](https://docs.payme.io/payments/query-apis/post-get-withdrawals): POST /get-withdrawals — List withdrawals # List withdrawals - Sandbox: `POST https://sandbox.payme.io/api/get-withdrawals` - Production: `POST https://live.payme.io/api/get-withdrawals` ## Credentials - Header `PayMe-Partner-Key` (optional): Partner key, instead of `payme_client_key` in the body. Partners only. - Header `PayMe-Merchant-Key` (optional): A seller's own MPL, instead of `seller_payme_id` in the body. - Request body field `payme_client_key` (optional): Partner key. Partners only. Can also be sent in the `PayMe-Partner-Key` header. Without `seller_payme_id`, the query covers all your sellers. - Request body field `seller_payme_id` (optional): The seller's MPL. A partner can send one MPL or an array of up to 100 MPLs of its own sellers to narrow the query. A seller sends its own MPL, here or in the `PayMe-Merchant-Key` header, and gets only its own data. Returns past withdrawals (payouts to the seller's bank account) for one seller or all your sellers. Canceled withdrawals are not returned. Use `withdrawal_payme_code` to match a withdrawal to the `withdrawal_id` from withdraw-balance and to the `tran_payme_code` of the `withdrawal-complete` callback. To match a withdrawal to its sales, see [Reconcile sales and withdrawals](/accepting-payments/reporting/reconcile-sales-and-withdrawals). A partner sends `payme_client_key` (or the `PayMe-Partner-Key` header) and, optionally, `seller_payme_id`: one MPL or an array of up to 100 MPLs of its own sellers. Without it, the query covers all your sellers. A seller sends its own MPL as `seller_payme_id` in the body, or in the `PayMe-Merchant-Key` header, and gets only its own data. When you send exactly one `seller_payme_id`, the response also returns it at the top level, with `seller_id`. An inactive seller then returns error `163`, and a seller that isn't yours returns error `20`. Filters are exact matches, except `withdrawal_created_min` / `withdrawal_created_max`. Most filters take a single value or an array of up to 100 values. Dates are `yyyy-mm-dd hh:mm:ss`, Asia/Jerusalem time. Results come in pages of up to 500 items (default 500). A call without `page` and `page_size` returns only the first 500. Paging, sorting and filter rules are on [Query APIs](/payments/query-apis). ## Parameters | Name | In | Type | Required | Description | | --- | --- | --- | --- | --- | | `PayMe-Partner-Key` | header | string | no | Partner key, instead of `payme_client_key` in the body. Partners only. | | `PayMe-Merchant-Key` | header | string | no | A seller's own MPL, instead of `seller_payme_id` in the body. | ## Request body Content type: `application/json` Every field is optional. Send at least your credentials. | Field | Type | Required | Description | | --- | --- | --- | --- | | `payme_client_key` | string | no | Partner key. Partners only. Can also be sent in the `PayMe-Partner-Key` header. Without `seller_payme_id`, the query covers all your sellers. | | `seller_payme_id` | string | no | The seller's MPL. A partner can send one MPL or an array of up to 100 MPLs of its own sellers to narrow the query. A seller sends its own MPL, here or in the `PayMe-Merchant-Key` header, and gets only its own data. | | `withdrawal_payme_code` | integer | no | PayMe's withdrawal code (the `withdrawal_id` from withdraw-balance). | | `withdrawal_created` | string | no | Exact creation date and time, `yyyy-mm-dd hh:mm:ss`. | | `withdrawal_created_min` | string | no | Created at or after this time, `yyyy-mm-dd hh:mm:ss`. | | `withdrawal_created_max` | string | no | Created at or before this time, `yyyy-mm-dd hh:mm:ss`. | | `withdrawal_total` | integer | no | Exact amount, in minor units (`5075` = 50.75). | | `withdrawal_currency` | string | no | Withdrawal currency, 3-letter [ISO 4217](https://en.wikipedia.org/wiki/ISO_4217) code. | | `page` | integer | no | Page number, `1`–`1000`. Default `1`. Out of range returns error `52`. | | `page_size` | integer | no | Items per page, `1`–`500`. Default `500`. Out of range returns error `27`. | | `items_order_by_column` | string | no | Field to sort by, for example `withdrawal_created`. Without it, the order isn't guaranteed and `items_order_by_direction` is ignored. | | `items_order_by_direction` | string | no | `asc` (default) or `desc`, in upper or lower case. Used only with `items_order_by_column`. Any other value returns error `28`. | ### Request example ```json { "payme_client_key": "XXXXXXXX", "seller_payme_id": "MPLDEMO-MPLDEMO-MPLDEMO-1234567", "withdrawal_created_min": "2026-10-01 00:00:00", "items_order_by_column": "withdrawal_created", "items_order_by_direction": "desc" } ``` ## Code samples ### curl ```bash curl -X POST 'https://sandbox.payme.io/api/get-withdrawals' \ -H 'Content-Type: application/json' \ -H 'PayMe-Partner-Key: ' \ -H 'PayMe-Merchant-Key: ' \ --data-raw '{ "payme_client_key": "XXXXXXXX", "seller_payme_id": "MPLDEMO-MPLDEMO-MPLDEMO-1234567", "withdrawal_created_min": "2026-10-01 00:00:00", "items_order_by_column": "withdrawal_created", "items_order_by_direction": "desc" }' ``` ### Node.js ```javascript const response = await fetch("https://sandbox.payme.io/api/get-withdrawals", { method: "POST", headers: { "Content-Type": "application/json", "PayMe-Partner-Key": "", "PayMe-Merchant-Key": "", }, body: JSON.stringify({ "payme_client_key": "XXXXXXXX", "seller_payme_id": "MPLDEMO-MPLDEMO-MPLDEMO-1234567", "withdrawal_created_min": "2026-10-01 00:00:00", "items_order_by_column": "withdrawal_created", "items_order_by_direction": "desc" }), }); console.log(await response.text()); ``` ### Python ```python import requests response = requests.post( "https://sandbox.payme.io/api/get-withdrawals", headers={ "PayMe-Partner-Key": "", "PayMe-Merchant-Key": "", }, json={ "payme_client_key": "XXXXXXXX", "seller_payme_id": "MPLDEMO-MPLDEMO-MPLDEMO-1234567", "withdrawal_created_min": "2026-10-01 00:00:00", "items_order_by_column": "withdrawal_created", "items_order_by_direction": "desc", }, ) print(response.text) ``` ### PHP ```php 'POST', CURLOPT_RETURNTRANSFER => true, CURLOPT_HTTPHEADER => [ 'Content-Type: application/json', 'PayMe-Partner-Key: ', 'PayMe-Merchant-Key: ', ], CURLOPT_POSTFIELDS => $body, ]); $response = curl_exec($ch); curl_close($ch); echo $response; ``` ## Responses ### 200 — OK (success) | Field | Type | Description | | --- | --- | --- | | `status_code` | integer | `0` on success. | | `seller_payme_id` | string | The seller, when exactly one `seller_payme_id` was sent; otherwise `null`. | | `seller_id` | string | Your own ID for that seller, or `null`. | | `items_count` | integer | Number of items on this page. There is no total count. | | `items` | array | The withdrawals. | | `items[].seller_payme_id` | string | The seller's MPL. | | `items[].withdrawal_payme_code` | integer | PayMe's withdrawal code. | | `items[].withdrawal_created` | string | When the withdrawal was created, `yyyy-mm-dd hh:mm:ss`, Asia/Jerusalem. | | `items[].withdrawal_currency` | string | Currency, 3-letter ISO 4217 code. | | `items[].withdrawal_total` | integer | Amount paid out, in minor units. | | `items[].withdrawal_source` | integer | Who pays it out: `1` PayMe; another value is a card company that pays the seller directly. | | `items[].withdrawal_card_brand` | integer | Card brand the withdrawal covers, when a card company pays the seller directly. | | `items[].withdrawal_is_reconciled` | boolean | `true` when PayMe has matched the payout with its records. | | `items[].withdrawal_description` | string | Always empty. Kept for older integrations. | ```json { "status_code": 0, "seller_payme_id": "MPLDEMO-MPLDEMO-MPLDEMO-1234567", "seller_id": "store-1001", "items_count": 1, "items": [ { "seller_payme_id": "MPLDEMO-MPLDEMO-MPLDEMO-1234567", "withdrawal_payme_code": 10001, "withdrawal_created": "2026-10-15 15:15:15", "withdrawal_currency": "ILS", "withdrawal_total": 600000, "withdrawal_source": 1, "withdrawal_card_brand": 1, "withdrawal_is_reconciled": true, "withdrawal_description": "" } ] } ``` ### 500 — Error. Most errors return HTTP 500. Paging errors (`52`, `27`) return HTTP 400. The body is the same. See [Errors](/payments/getting-started/errors). (error) | Field | Type | Description | | --- | --- | --- | | `status_code` | integer | `1` on failure. | | `status_error_code` | integer | PayMe error code. | | `status_error_details` | string | Error message. | | `status_additional_info` | string | The field the error refers to, when there is one. | ```json { "status_code": 1, "status_error_details": "Required parameter is missing", "status_additional_info": "payme_client_key", "status_error_code": 1 } ``` - [List future withdrawals](https://docs.payme.io/payments/query-apis/get-future-withdrawals): POST /get-future-withdrawals — List future withdrawals # List future withdrawals - Sandbox: `POST https://sandbox.payme.io/api/get-future-withdrawals` - Production: `POST https://live.payme.io/api/get-future-withdrawals` ## Credentials - Header `PayMe-Partner-Key` (optional): Partner key, instead of `payme_client_key` in the body. Partners only. - Header `PayMe-Merchant-Key` (optional): A seller's own MPL, instead of `seller_payme_id` in the body. - Request body field `seller_payme_id` (optional): The seller's MPL. Required unless a partner sends `seller_id`. Can also be sent in the `PayMe-Merchant-Key` header. - Request body field `payme_client_key` (optional): Partner key. Required with `seller_id`. Can also be sent in the `PayMe-Partner-Key` header. Projects a seller's upcoming withdrawals in one currency, from the funds waiting for release and the seller's withdrawal plan. Use it to show the next payout dates and amounts. A seller sends its own `seller_payme_id` (in the body or the `PayMe-Merchant-Key` header). A partner sends `payme_client_key` with the seller's `seller_payme_id` or your own `seller_id`. Send `currency` too. One seller and one currency per call. You get `limit` items: `limit − 1` scheduled payouts, then one summary item with `end_time` `-1` that holds everything due later. Amounts are in minor units. When card companies pay the seller directly, the items are split by release date, `source` and `card_brand`, with `withdrawable` `0`. The call doesn't page. It is rate limited per seller: on HTTP 429 (error `998`), wait for the `Retry-After` time and retry. A missing `currency` returns error `1`, and an unknown one returns error `24`. ## Parameters | Name | In | Type | Required | Description | | --- | --- | --- | --- | --- | | `PayMe-Partner-Key` | header | string | no | Partner key, instead of `payme_client_key` in the body. Partners only. | | `PayMe-Merchant-Key` | header | string | no | A seller's own MPL, instead of `seller_payme_id` in the body. | ## Request body Content type: `application/json` Send `currency` and identify one seller. | Field | Type | Required | Description | | --- | --- | --- | --- | | `seller_payme_id` | string | no | The seller's MPL. Required unless a partner sends `seller_id`. Can also be sent in the `PayMe-Merchant-Key` header. | | `payme_client_key` | string | no | Partner key. Required with `seller_id`. Can also be sent in the `PayMe-Partner-Key` header. | | `seller_id` | string | no | Your own ID for the seller, as sent to create-seller. Partners only, with `payme_client_key`. | | `currency` | string | yes | Wallet currency, 3-letter [ISO 4217](https://en.wikipedia.org/wiki/ISO_4217) code, for example `ILS`. | | `limit` | integer | no | Number of items to return, including the final summary item. Default `7`. | | `language` | string | no | Language of `source_text` and `card_brand_text`: `he` (default) or `en`. | ### Request example ```json { "seller_payme_id": "MPLDEMO-MPLDEMO-MPLDEMO-1234567", "currency": "ILS", "limit": 3, "language": "en" } ``` ## Code samples ### curl ```bash curl -X POST 'https://sandbox.payme.io/api/get-future-withdrawals' \ -H 'Content-Type: application/json' \ -H 'PayMe-Partner-Key: ' \ -H 'PayMe-Merchant-Key: ' \ --data-raw '{ "seller_payme_id": "MPLDEMO-MPLDEMO-MPLDEMO-1234567", "currency": "ILS", "limit": 3, "language": "en" }' ``` ### Node.js ```javascript const response = await fetch("https://sandbox.payme.io/api/get-future-withdrawals", { method: "POST", headers: { "Content-Type": "application/json", "PayMe-Partner-Key": "", "PayMe-Merchant-Key": "", }, body: JSON.stringify({ "seller_payme_id": "MPLDEMO-MPLDEMO-MPLDEMO-1234567", "currency": "ILS", "limit": 3, "language": "en" }), }); console.log(await response.text()); ``` ### Python ```python import requests response = requests.post( "https://sandbox.payme.io/api/get-future-withdrawals", headers={ "PayMe-Partner-Key": "", "PayMe-Merchant-Key": "", }, json={ "seller_payme_id": "MPLDEMO-MPLDEMO-MPLDEMO-1234567", "currency": "ILS", "limit": 3, "language": "en", }, ) print(response.text) ``` ### PHP ```php 'POST', CURLOPT_RETURNTRANSFER => true, CURLOPT_HTTPHEADER => [ 'Content-Type: application/json', 'PayMe-Partner-Key: ', 'PayMe-Merchant-Key: ', ], CURLOPT_POSTFIELDS => $body, ]); $response = curl_exec($ch); curl_close($ch); echo $response; ``` ## Responses ### 200 — OK (success) | Field | Type | Description | | --- | --- | --- | | `status_code` | integer | `0` on success. | | `withdrawal_plan` | integer | The seller's withdrawal plan: `1` manual, `2` daily, `3` monthly. | | `currency` | string | The currency you asked for. | | `items_count` | integer | Number of items. | | `items` | array | Expected payouts, then one summary item. | | `items[].start_time` | integer | Start of the period the payout covers, Unix epoch. | | `items[].end_time` | integer | Expected payout time, Unix epoch. `-1` on the summary item. | | `items[].created_at` | string | Expected payout date and time, `yyyy-mm-dd hh:mm:ss`. On the summary item, the current time. | | `items[].withdrawable` | integer | `1` paid out by PayMe; `0` paid directly by a card company. | | `items[].source` | integer | Who pays it out: `1` PayMe, other values a card company. | | `items[].source_text` | string | Name of `source`, in the requested `language`. | | `items[].card_brand` | integer | Card brand code. | | `items[].card_brand_text` | string | Name of `card_brand`, in the requested `language`. | | `items[].total` | string | Expected amount, in minor units. | | `items[].withdrawal_payme_code` | string | Opaque token for this expected payout. It's not a withdrawal code from get-withdrawals. | ```json { "status_code": 0, "withdrawal_plan": 2, "currency": "ILS", "items_count": 3, "items": [ { "start_time": 1793836800, "end_time": 1793923200, "created_at": "2026-11-06 02:00:00", "withdrawable": 1, "source": 1, "source_text": "PayMe", "card_brand": 1, "card_brand_text": "Other", "total": "48250", "withdrawal_payme_code": "" }, { "start_time": 1793923200, "end_time": 1794009600, "created_at": "2026-11-07 02:00:00", "withdrawable": 1, "source": 1, "source_text": "PayMe", "card_brand": 1, "card_brand_text": "Other", "total": "0", "withdrawal_payme_code": "" }, { "start_time": 1794009600, "end_time": -1, "created_at": "2026-11-05 14:00:20", "withdrawable": 1, "source": 1, "source_text": "PayMe", "card_brand": 1, "card_brand_text": "Other", "total": "156390", "withdrawal_payme_code": "" } ] } ``` ### 500 — Error. Most errors return HTTP 500; the rate limit (`998`) returns HTTP 429. The body is the same. See [Errors](/payments/getting-started/errors). (error) | Field | Type | Description | | --- | --- | --- | | `status_code` | integer | `1` on failure. | | `status_error_code` | integer | PayMe error code. | | `status_error_details` | string | Error message. | | `status_additional_info` | string | The field the error refers to, when there is one. | ```json { "status_code": 1, "status_error_details": "Required parameter is missing", "status_additional_info": "currency", "status_error_code": 1 } ``` - [List banks](https://docs.payme.io/payments/query-apis/get-banks-country-iso-code): GET /banks/{country_iso_code} — List banks # List banks - Sandbox: `GET https://sandbox.payme.io/api/banks/{country_iso_code}` - Production: `GET https://live.payme.io/api/banks/{country_iso_code}` ## Credentials - Header `PayMe-Partner-Key` (API key) - Header `PayMe-Merchant-Key` (optional): A seller's MPL. Send this or `PayMe-Partner-Key`. Returns the bank codes for a country. Use them as `seller_bank_code` when you create or update a seller. Only Israel (`IL`) has banks today; other countries return an empty list. The same list is on [Banks in Israel](/payments/codes-statuses/banks-in-israel). Send your partner key in the `PayMe-Partner-Key` header, or a seller's MPL in the `PayMe-Merchant-Key` header. One of them is required: without either, the call fails with error `1`. The list isn't paged. ## Parameters | Name | In | Type | Required | Description | | --- | --- | --- | --- | --- | | `PayMe-Partner-Key` | header | string | no | Partner key. Send this or `PayMe-Merchant-Key`. | | `PayMe-Merchant-Key` | header | string | no | A seller's MPL. Send this or `PayMe-Partner-Key`. | | `country_iso_code` | path | string | yes | ISO 3166-1 alpha-2 country code, case-insensitive, for example `IL`. An unknown code returns HTTP 422 with error `912`. | ## Code samples ### curl ```bash curl -X GET 'https://sandbox.payme.io/api/banks/' \ -H 'PayMe-Partner-Key: ' \ -H 'PayMe-Merchant-Key: ' ``` ### Node.js ```javascript const response = await fetch("https://sandbox.payme.io/api/banks/", { method: "GET", headers: { "PayMe-Partner-Key": "", "PayMe-Merchant-Key": "", }, }); console.log(await response.text()); ``` ### Python ```python import requests response = requests.get( "https://sandbox.payme.io/api/banks/", headers={ "PayMe-Partner-Key": "", "PayMe-Merchant-Key": "", }, ) print(response.text) ``` ### PHP ```php '); curl_setopt_array($ch, [ CURLOPT_CUSTOMREQUEST => 'GET', CURLOPT_RETURNTRANSFER => true, CURLOPT_HTTPHEADER => [ 'PayMe-Partner-Key: ', 'PayMe-Merchant-Key: ', ], ]); $response = curl_exec($ch); curl_close($ch); echo $response; ``` ## Responses ### 200 — OK (success) | Field | Type | Description | | --- | --- | --- | | `status_code` | integer | `0` on success. | | `page` | integer | Always `1`. | | `items_per_page` | integer | Number of banks returned. | | `items_total` | integer | Number of banks returned. | | `country_iso_code` | string | The country code you sent. | | `items` | array | The banks. | | `items[].code` | string | Bank code. Send it as `seller_bank_code`. | | `items[].local_name` | string | Bank name in the local language. | | `items[].international_name` | string | Bank name in English. | ```json { "status_code": 0, "page": 1, "items_per_page": 1, "items_total": 1, "country_iso_code": "IL", "items": [ { "code": "12", "local_name": "בנק הפועלים", "international_name": "Bank Hapoalim" } ] } ``` ### 500 — Error. A missing key returns HTTP 500 with error `1`. An unknown country code returns HTTP 422 with error `912`. See [Errors](/payments/getting-started/errors). (error) | Field | Type | Description | | --- | --- | --- | | `status_code` | integer | `1` on failure. | | `status_error_code` | integer | PayMe error code. | | `status_error_details` | string | Error message. | | `status_additional_info` | string | The field the error refers to, when there is one. | ```json { "status_code": 1, "status_error_details": "Required parameter is missing", "status_additional_info": "payme_client_key", "status_error_code": 1 } ``` ## Codes & Statuses - [Sale Types](https://docs.payme.io/payments/codes-statuses/sale-types): PayMe sale types: the number returned by queries, the name sent in callbacks, and the sale_type value to send in requests (sale, authorize, token, seller-token, credit, template, multi-capture). # Sale Types | Number | Name in callbacks | Request value (`sale_type`) | |---|---|---| | `1` | `Sale` | `sale` (J4), `authorize` (J5) | | `2` | `Token` | `token` | | `3` | `SaleFromSubscription` | – | | `4` | `SaleFromTemplate` | – | | `5` | `MultiCapture` | `multi-capture` | | `6` | `CustomerDeposit` | – | | `7` | `Credit` | `credit` | | `10` | `Template` | `template` | | `11` | `SaleFromPaymentContract` | – | | `12` | `SellerToken` | `seller-token` | Query responses return the number, and callbacks return the name. A row without a request value is created by PayMe, for example a sale paid on a template link (`4`) or charged by a subscription (`3`). An authorization is type `1` (`Sale`): check `sale_status` `authorized` to tell it from a charge. - [Sale Statuses](https://docs.payme.io/payments/codes-statuses/sale-statuses): Reference list of sale statuses, from `initial` and `completed` to `refunded`, `chargeback` and `voided`, with what each means. ## Related - [Understand the sale lifecycle](https://docs.payme.io/payments/codes-statuses/sale-lifecycle) # Sale Statuses ID | Sale Status | Description ---- | ---- | ---- 1 | initial | Creation status, a payment was not attempted 2 | completed | The sale was paid successfully 3 | refunded |The sale was fully refunded 4 | partial-refund|The sale was partially refunded 5 | authorized | The sale was authorized successfully 6 | failed | The sale failed 7 | chargeback|The sale was charged back 8 | canceled|The template sale was canceled with `cancel-template` 9 | voided|The authorization was fully voided 10| partial-void|The authorization was partially voided 11| partial-chargeback|The sale was partially charged back For how a sale moves between these statuses, and which callback PayMe sends at each step, see [Understand the sale lifecycle](https://docs.payme.io/payments/codes-statuses/sale-lifecycle). - [Understand the sale lifecycle](https://docs.payme.io/payments/codes-statuses/sale-lifecycle): A sale starts initial. Payment moves it to completed (sale-complete), or authorized for sale_type authorize (sale-authorized). A failed attempt moves it to failed (sale-failure per attempt), but failed isn't final: sale_url stays payable while initial or failed, until sale_expiry_seconds passes (then HTTP 403 and error 367; the status doesn't change). Capture: completed. Void: voided or partial-void. Refund: refunded, or partial-refund (it stays so). Chargeback: chargeback or partial-chargeback; reversal: completed. Confirm with get-sales and send sale_status: initial is hidden by default. ## Related - [Sale Statuses](https://docs.payme.io/payments/codes-statuses/sale-statuses) - [Sale Types](https://docs.payme.io/payments/codes-statuses/sale-types) - [Callback types reference](https://docs.payme.io/payments/getting-started/callback-types) - [Callbacks](https://docs.payme.io/payments/getting-started/callbacks) - [List sales](https://docs.payme.io/payments/query-apis/post-get-sales) - [List transactions](https://docs.payme.io/payments/query-apis/post-get-transactions) - [Capture an authorized sale](https://docs.payme.io/payments/post-sale-actions/post-capture-sale) - [Refund a sale](https://docs.payme.io/payments/post-sale-actions/post-refund-sale) - [Void an authorization](https://docs.payme.io/payments/post-sale-actions/void-sale) - [Idempotency and Retries](https://docs.payme.io/payments/getting-started/idempotency-and-retries) # Understand the sale lifecycle A sale is PayMe's record of one order. It starts as `initial` when you create it, and its `sale_status` changes as the buyer pays and as you capture, refund or void it. This page shows every transition, what causes it, the callback PayMe sends for it, how long the payment link stays open, and how to read a sale's current state. The status values are listed on [Sale Statuses](https://docs.payme.io/payments/codes-statuses/sale-statuses). The callbacks are described on [Callback types reference](https://docs.payme.io/payments/getting-started/callback-types). ## The states at a glance ```text Charge now (sale_type: sale) initial ──► completed ──► refunded │ ▲ ├───────► partial-refund │ │ └───────► chargeback / partial-chargeback ──► completed (reversed) ▼ │ failed (the buyer can pay again on the same sale) Authorize now, capture later (sale_type: authorize) initial or failed ──► authorized ──► completed (captured) ├────────► failed (capture declined; capture again) ├────────► voided └────────► partial-void ``` ## Transitions | From | To | What causes it | Callback (`notify_type`) | |---|---|---|---| | — | `initial` | You create the sale with `generate-sale` | `sale-create`, only if you sent `sale_send_creation_callback: true` | | `initial`, `failed` | `completed` | The buyer pays | `sale-complete` | | `initial`, `failed` | `authorized` | The buyer pays a sale created with `sale_type: authorize` | `sale-authorized` | | `initial`, `failed` | `failed` | A payment attempt fails: a decline, or a failed 3D Secure check | `sale-failure`, once per failed attempt | | `authorized`, or `failed` after a declined capture | `completed` | [`capture-sale`](https://docs.payme.io/payments/post-sale-actions/post-capture-sale) succeeds. A capture for less than the authorized amount sets the sale price to the captured amount | `sale-complete` | | `authorized` | `failed` | `capture-sale` is declined. You can capture again while the authorization is still valid | `sale-failure` | | `authorized` | `voided` | [`refund-sale`](https://docs.payme.io/payments/post-sale-actions/void-sale) releases the whole hold | `refund` | | `authorized`, `partial-void` | `partial-void` | `refund-sale` releases part of the hold. A `partial-void` sale can't be captured, and further voids keep it `partial-void` | `refund` | | `completed` | `refunded` | [`refund-sale`](https://docs.payme.io/payments/post-sale-actions/post-refund-sale) refunds the full amount at once | `refund` | | `completed`, `partial-refund` | `partial-refund` | `refund-sale` refunds part of the amount. The sale stays `partial-refund` even after the parts add up to the full amount | `refund` | | A paid sale | `chargeback` or `partial-chargeback` | The card issuer charges the payment back, in full or in part | `sale-chargeback` | | `chargeback`, `partial-chargeback` | `completed` | Every chargeback on the sale is reversed in the seller's favor | `sale-chargeback-refund` | | `initial` (template sales only) | `canceled` | [`cancel-template`](https://docs.payme.io/payments/post-sale-actions/post-cancel-template) closes the template's link | None | Some sales are created by PayMe rather than by your `generate-sale` call, and then follow the same statuses: - Each payment on a [template sale](https://docs.payme.io/accepting-payments/checkout-and-in-person/multi-payment-page) (one link that many buyers pay) creates its own sale, `sale_type` `4`. The template itself only moves from `initial` to `canceled`. - Each subscription charge creates a sale, `sale_type` `3`, which sends its own `sale-complete` or `sale-failure`. - An Israeli direct-debit payment sends `sale-paid` when the debit is submitted to the bank, then `sale-complete`, or `sale-failure` if the bank returns it. See [Israeli Direct Debit](https://docs.payme.io/accepting-payments/payment-methods/israeli-direct-debit). Capturing in several parts creates child sales; see [multi-capture](https://docs.payme.io/accepting-payments/capture-and-saved-cards/multi-capture). ## Failures aren't final `failed` means the last attempt failed, not that the sale is closed. The buyer can try again on the same payment page, and you can call [`pay-sale`](https://docs.payme.io/payments/direct-api/post-pay-sale) again on a `failed` sale. Each failed attempt sends another `sale-failure` with its own `payme_transaction_id`. The attempts stop when the sale completes. So: - Don't cancel the order on the first `sale-failure`. Wait for `sale-complete`, or for your own deadline. - If you create a new sale for a retry, the old `sale_url` stays payable too, and the buyer could pay twice. Reuse the same sale, or set `sale_expiry_seconds` on each sale. - Once a sale is `completed`, a late failure can't move it back to `failed`. ## How long the payment link stays open `sale_url` has no fixed expiry. The payment page opens while the sale is `initial` or `failed`; once the sale has any other status, the page no longer takes a payment. To set a deadline, send `sale_expiry_seconds` when you create the sale. The time counts from the sale's creation. After it: - the payment page answers HTTP 403; - `pay-sale` returns error `367` ("the sale has expired"); - `sale_status` doesn't change. An expired sale still reads `initial` or `failed` in `get-sales`, so track the deadline on your side too. `sale_should_be_opened_once: true` works only on a sale with `layout: token-capture`: the page then opens only once. There is no call to cancel an ordinary open sale. To stop a buyer from paying, rely on `sale_expiry_seconds`. `cancel-template` works only on template sales. ## Callbacks at each step The last column of the table above is the callback each transition sends. Three rules matter when you handle them: - `sale-create` is opt-in: PayMe sends it only when you create the sale with `sale_send_creation_callback: true`. - `sale-failure` is sent once per failed attempt, and `refund` once per refund or void. Each carries its own `payme_transaction_id`. - Callbacks can arrive more than once and out of order. Never let a later callback overwrite a final state you already recorded. The payloads, the signature and the delivery rules are on [Callbacks](https://docs.payme.io/payments/getting-started/callbacks). Who receives each type, and its key fields, is on [Callback types reference](https://docs.payme.io/payments/getting-started/callback-types). ## Read the current state Callbacks can be lost after their retries, so confirm a sale with [`get-sales`](https://docs.payme.io/payments/query-apis/post-get-sales) before you fulfil the order, and when a request timed out. `POST https://sandbox.payme.io/api/get-sales` (production: `https://live.payme.io/api/get-sales`) ```json { "seller_payme_id": "MPLDEMO-MPLDEMO-MPLDEMO-1234567", "sale_payme_id": "SALE1655-3843870J-NTPYLJNW-SOWRLK9X", "sale_status": ["initial", "completed", "failed", "authorized", "refunded", "partial-refund", "voided", "partial-void", "chargeback", "partial-chargeback"] } ``` **Send `sale_status`.** Without it, `get-sales` leaves out `initial` sales, so an unpaid sale comes back as an empty `items` list, as if it didn't exist. The response (other fields omitted): ```json { "status_code": 0, "items_count": 1, "items": [ { "seller_payme_id": "MPLDEMO-MPLDEMO-MPLDEMO-1234567", "sale_payme_id": "SALE1655-3843870J-NTPYLJNW-SOWRLK9X", "transaction_id": "order-1002", "sale_type": 1, "sale_status": "completed", "sale_currency": "ILS", "sale_price": 1000, "sale_paid_date": "2026-11-09 12:30:05", "sale_error_code": null, "sale_is_3ds": false } ] } ``` Before you fulfil the order, check that: 1. `sale_status` is `completed` (or `authorized`, if you capture later); 2. `sale_price` and `sale_currency` match your order. `sale_price` is the amount charged, in minor units; 3. `transaction_id` is your own order ID for this order. On a `failed` sale, `sale_error_code` and `sale_error_text` give the reason of the failed payment. `sale_type` tells you where the sale came from, for example `3` for a subscription charge and `4` for a payment on a template sale's link; see [Sale Types](https://docs.payme.io/payments/codes-statuses/sale-types). To see each money movement on its own row (the payment, the capture, every refund and chargeback), use [`get-transactions`](https://docs.payme.io/payments/query-apis/post-get-transactions). There, `transaction_error_code` is `null` on a successful transaction. A sale that is authorized and not yet captured appears only when you send `transaction_type: 40`. If a request timed out and you don't know whether it ran, read the sale before you retry. See [Idempotency and Retries](https://docs.payme.io/payments/getting-started/idempotency-and-retries). - [Transaction Types](https://docs.payme.io/payments/codes-statuses/transaction-types): Reference list of transaction type numbers, such as Sale, Token, Authorization/Void and Balance. # Transaction Types Transaction Types | Description ----|---- 1 | Sale 2 | Setup 10 | SubscriptionToken 20 | Token 30 | CustomerDeposit 40 | Authorization (J5). A void shows as status `8` or `9` on it; see [Transaction Statuses](https://docs.payme.io/payments/codes-statuses/transaction-statuses) 50 | CustomerSale 60 | Balance - [Transaction Statuses](https://docs.payme.io/payments/codes-statuses/transaction-statuses): Reference list of transaction statuses, from `pending` and `validated` to refunds, chargebacks and voids. # Transaction Statuses Transaction Status | Status Description ----|---- 1|pending 2|validated 3 |refunded 4 |p-refund 5 |failed 6 |chargeback 7 |chargeback-refund 8 |voided 9 |partial-void 10|partial-chargeback 11|partial-chargeback-refund - [Subscription statuses](https://docs.payme.io/payments/codes-statuses/subscription-statuses): Reference list of subscription statuses (sub_status): initial, active, paused, failed, canceled, completed, and failed with a retry pending. # Subscription statuses Values of `sub_status` in subscription responses and callbacks. How a subscription moves between them: [Subscriptions overview](https://docs.payme.io/payments/subscriptions). | ID | Status | Meaning | |---|---|---| | `1` | Initial | Waiting for the buyer to pay. Nothing has been charged. | | `2` | Active | A card is attached and charges run on schedule. With a `buyer_key` or a future `sub_start_date`, nothing may have been charged yet. | | `3` | Paused | No charges. Iterations whose date passes are skipped and never charged. | | `4` | Failed | The card check failed when the buyer paid. The subscription isn't canceled and isn't retried; the buyer can pay again with [Pay a subscription](https://docs.payme.io/payments/subscriptions/post-generate-subscription-2). | | `5` | Canceled | Canceled by the seller, or automatically after the last failed charge attempt. | | `6` | Completed | All iterations were charged or skipped. | | `7` | Failed, retry pending | A scheduled charge failed. PayMe retries it the next day, up to 7 attempts in total. | - [Subscription iteration types](https://docs.payme.io/payments/codes-statuses/subscription-iteration-types): Reference list of subscription billing intervals (sub_iteration_type): daily, weekly, monthly, yearly and quarterly. # Subscription iteration types Values of `sub_iteration_type` in [Create a subscription](https://docs.payme.io/payments/subscriptions/post-generate-subscription) and in subscription responses. | ID | Interval | Notes | |---|---|---| | `1` | Daily | A failed charge isn't retried: the subscription is canceled. | | `2` | Weekly | | | `3` | Monthly | The start day must be between 1 and 28 (error `375`). | | `4` | Yearly | | | `5` | Quarterly | | - [Bank authorization statuses](https://docs.payme.io/payments/codes-statuses/bank-authorization-statuses): Values of authorization_status in the Israeli direct-debit callback, and what each does to the buyer: opened, failed, canceled, moved, reactivated and more. # Bank authorization statuses Values of `authorization_status` (sent with `authorization_error_code`) in the `sale-il-direct-debit-update` sale callback for [Israeli direct debit](https://docs.payme.io/payments/il-direct-debit/post-generate-sale-il-direct-debit) sales. | Status | Meaning | Effect | |---|---|---| | `1` | Bank authorization opened successfully | The buyer becomes active and can be charged. | | `2` | Bank authorization failed | The buyer becomes inactive. If the authorization is already active, PayMe ignores this status and sends no callback. | | `3` | Canceled by the account owner, in the bank app | The buyer becomes inactive. | | `4` | Unknown | The buyer becomes inactive. | | `5` | Authorization moved from a previous account | The buyer becomes inactive and charges are rejected until PayMe receives status `1`, `13` or `18` for the same authorization. The buyer key stays the same. If that status doesn't arrive, ask the payer to sign a new authorization. | | `6` | Account changed | The buyer becomes inactive and charges are rejected until PayMe receives status `1`, `13` or `18` for the same authorization. The buyer key stays the same. If that status doesn't arrive, ask the payer to sign a new authorization. | | `13` | Frozen authorization reactivated: the buyer had frozen it in the bank app | The buyer becomes active and can be charged. | | `14` | Sent to the bank | No change: the authorization stays pending. | | `15` | Sent to the bank again | No change: the authorization stays pending. | | `16` | Details missing | The buyer becomes inactive. | | `17` | Details incorrect | The buyer becomes inactive. | | `18` | Already processed (success) | The buyer becomes active and can be charged. | - [Banks in Israel](https://docs.payme.io/payments/codes-statuses/banks-in-israel): Israeli bank codes and names, used as seller_bank_code on create-seller and update-seller (unknown code: error 106), with the branch and account-number validation rules (error 165) and the sandbox test bank 54. # Banks in Israel Use these codes as `seller_bank_code` on [Create a seller](https://docs.payme.io/payments/merchants-management/post-create-seller) and [Update a seller](https://docs.payme.io/payments/merchants-management/post-update-seller). The same list is returned by [`GET /banks/IL`](https://docs.payme.io/payments/query-apis/get-banks-country-iso-code) as `code`, `local_name` and `international_name`. A code that isn't in the list returns error `106`. ## Validation PayMe checks the branch (`seller_bank_branch`) and account number (`seller_bank_account_number`) before it saves them. A value that fails returns error `165`. - The branch has at most 3 digits and can't be `0`. - The account number has digits only and can't be `0`. - Maximum account number length: 6 digits for banks `4`, `12`, `20` and `46`; 8 digits for `10`, `13` and `34`; 9 digits for `1`, `9`, `11`, `14`, `17`, `22`, `31` and `52`. - For banks `4`, `9`, `10`, `11`, `12`, `13`, `14`, `17`, `20`, `22`, `31`, `34`, `46` and `52`, the branch and account number must also pass the bank's check-digit rule. In the sandbox, use bank `54` (Bank of Jerusalem) with any 3-digit branch and any 6-digit account number. Bank `54` has no check-digit rule. ## Bank codes | Code | Bank (Hebrew) | Bank (English) | | --- | --- | --- | | `1` | ישראכרט | Isracard | | `4` | בנק יהב לעובדי המדינה | Bank Yahav for Government Employees | | `9` | בנק הדואר | Israel Postal Bank | | `10` | בנק לאומי | Bank Leumi Le-Israel | | `11` | בנק דיסקונט | Israel Discount Bank | | `12` | בנק הפועלים | Bank Hapoalim | | `13` | בנק אגוד לישראל | Union Bank of Israel | | `14` | בנק אוצר החייל | Bank Otsar Ha-hayal | | `17` | בנק מרכנתיל דיסקונט | Mercantile Discount Bank | | `18` | בנק One Zero | One Zero Digital Bank | | `20` | בנק מזרחי-טפחות | Mizrahi Tefahot Bank Ltd | | `22` | סיטיבנק | Citibank | | `23` | HSBC | HSBC Bank | | `26` | UBANK | UBank | | `31` | הבין לאומי הראשון | The First International Bank of Israel | | `34` | בנק ערבי ישראלי | Arab Israel Bank | | `39` | בנק אוף אינדיה | State Bank Of India | | `46` | בנק מסד | Bank Massad | | `52` | בנק פאגי | Poaley Agudat Israel Bank | | `54` | בנק ירושלים | Bank of Jerusalem | | `68` | דקסיה ישראל | Dexia Israel Bank | | `77` | בנק לאומי למשכנתאות | Leumi Mortgage Bank | | `90` | בנק דיסקונט למשכנתאות | Discount Mortgage Bank | | `91` | משכן בנהפ למשכנתאות | Bank Mishkan - Hapoalim Mortgage Bank | | `92` | הבינלאומי למשכנתאות | First International Mortgage Bank | - [Document types](https://docs.payme.io/payments/codes-statuses/document-types): Values of doc_type for Create a document: work order, delivery note, invoices, invoice receipt, credit invoice, receipts and price offer. # Document types Values of `doc_type` in [Create a document](https://docs.payme.io/payments/invoices/post-create-invoice). Documents are returned with the same value. | `doc_type` | Document | Invoicing-service name | |---|---|---| | `100` | Work order | `order` | | `200` | Delivery note | `delcert` | | `300` | Transaction invoice | `deal` | | `305` | Tax invoice | `invoice` | | `320` | Invoice receipt | `invrec` | | `330` | Credit invoice (refund) | `refund` | | `400` | Receipt | `receipt` | | `405` | Donation receipt | `trec` | | `600` | Price offer | `offer` |