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)

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

⚠ TO CONFIRM: The exact sale_status string after a partial refund — the existing docs show partial-refund, while PayMe's API code suggests partially-refunded. Which is it (and the matching void strings)? [Q37]

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

Other callbacks

Subscriptions

Sent to sub_callback_url, or to the partner's callback URL if none 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 billing iteration was paid (adds payme_sale_id and payme_sale_code)
sub-iteration-skipped A billing iteration was skipped
sub-failure The subscription failed
sub-pause The subscription was paused
sub-cancel The subscription was cancelled
sub-complete The subscription completed

The payload includes sub_payme_id, sub_status, sub_price, iteration counters and buyer fields. Each iteration also creates a sale, which sends its own sale-complete or sale-failure.

Israeli direct debit

An Israeli direct-debit payment (not authorization) sends no callback on success and can take up to 8 days.

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

Bank transfer

A bank transfer reaching PAID is reported with a callback.

⚠ TO CONFIRM: Bank transfers most likely use the normal sale-complete / sale-failure callbacks with no dedicated notify_type. Please confirm. [Q34]

B2B payment contracts

A contract's callback_url receives a callback for every change in status.

Verifying a callback (payme_signature)

How it is computed

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
  3. payme_transaction_id (from the payload)
  4. payme_sale_id (from the payload)

It is a plain MD5 hash, not an HMAC.

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", ""))

⚠ TO CONFIRM: What is the "client password" called in PayMe's onboarding material, how does a partner receive it, and how can a merchant that has no payme_client_key verify payme_signature? [Q1]

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.

⚠ TO CONFIRM: Do callbacks come from a fixed set of IP addresses that merchants can allow-list? [Q3]

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

⚠ TO CONFIRM: Callbacks are most likely not delivered 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. Please confirm, so the docs can state it as a rule. Until then: never let a later-arriving callback overwrite a final state you already recorded, and query the sale when in doubt. [Q33]

Handling checklist

  1. Parse the body as form data and reply 200 within 5 seconds.
  2. 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.