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 before you fulfil an order.

Format

Callback URL 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.

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.

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
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
sale_type Sale Sale type name: Sale (also for authorizations), Token, SaleFromTemplate, SaleFromSubscription, … See 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 before acting. Charge retries (once a day, up to 7 attempts) are described on Recurring Payments.

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
sub_iteration_type 1 See 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

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)
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.

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

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 (partners@payme.io). A merchant that has no payme_client_key cannot compute the signature: verify the sale instead with POST /get-sales or 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:

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 with sale_payme_id and check sale_status and sale_price against your order. POST /get-transactions works too, and shows each charge and refund as a row, which is why the AI Toolkit 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

Retries

Do not rely on callbacks alone. Reconcile with 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.