Rules for Agents

Cite these by ID in plans, reviews and reports. The IDs don't change. P means partners only, S means direct sellers only, and no mark means both.

Working

ID Rule
WRK-01 Look up every field name in these docs before writing it. PayMe's names are not guessable: amount or merchant_id compile and then fail.
WRK-02 Work in the sandbox with your dedicated test account. Never point an integration at production yourself.
WRK-03 Never say a flow works unless you ran it against PayMe and checked the final state with a query.
WRK-04 If the docs don't answer something, say so and ask. Never invent a field or a behaviour.
WRK-05 Keep PayMe's field names as they are in your transport layer. Rename only in your own domain code.
WRK-06 Anything you add that moves money or shows payment or seller data needs your app's own login and permission check. If the app has none, stop and ask. If you're working unattended, implement named authentication and explicit roles before exposing these routes, and record your assumptions.

Secrets

ID Rule
SEC-01 The MPL, the partner key and the partner secret stay on the server. They never reach a browser, a mobile app, a log, a URL, a commit or a chat message.
SEC-02 Only the seller's public key goes to the browser.
SEC-03 Load credentials from the environment or a secrets manager, and fail at startup when one is missing, without printing it.
SEC-04 P Never send the partner secret to PayMe on any request.
SEC-05 Redact from logs: payme_client_key, seller_payme_id, buyer_key, sub_payme_id, sub_url, meta_data_jwt, card fields and personal data. IDs also appear in URL paths, so log a masked path.
SEC-06 Ignore seller_payme_secret from create-seller. It is a random value that nothing checks. Don't store it.

Money

ID Rule
MON-01 Amounts are integers in minor units everywhere: 5075 means 50.75. Convert only for display.
MON-02 Compute every amount on your server, from your own order. Never take a price from the browser.
MON-03 Reject a decimal or out-of-range amount before calling PayMe. generate-sale rounds a decimal instead of refusing it.

Transport

ID Rule
TRN-01 Success is status_code 0 in a 2xx response. Compare the numeric value, because it can arrive as a string. Nothing else counts as success.
TRN-02 Branch on status_error_code, never on the message.
TRN-03 Log status_error_code, status_error_details, status_additional_info and session on every error, after redacting.
TRN-04 Judge a failure by its body, not its HTTP status. status_code 1 with a non-zero status_error_code means PayMe refused, even at HTTP 500. The outcome is unknown after a timeout, a dropped connection, a body that isn't PayMe's JSON, codes 991, 20002 and 999, or HTTP 429. Then don't repeat a call that moves money until a query has shown the state. See Reading a failure.
TRN-05 Always send seller_payme_id in the JSON body of a query. Don't rely on a header for it. A direct seller sends a single value. A partner may send an array to read several sellers.
TRN-06 Send language: "en", or messages come back in Hebrew.
TRN-07 If a money call succeeded and your read-back query then failed, answer success with a "check this" flag, and let reconciliation clear it. Never answer an error: that invites a repeat of a call that worked.

Callbacks

ID Rule
CB-01 Never apply a callback body. Status, amounts and tokens come from PayMe's answer to your own query.
CB-02 A valid sale signature means only "worth checking". It proves neither the status nor the amount. Confirm by query and match it to your own order.
CB-03 P Check the signature before anything else on a sale callback. A wrong one, or one you could not check, changes nothing.
CB-04 Subscription, seller and withdrawal-complete callbacks carry no signature. Don't reject them for that, and don't believe them for that either: re-read from PayMe.
CB-05 Find the order by the payme_sale_id you stored, and query by your own order ID. A callback naming an unknown ID changes nothing.
CB-06 Answer below 400 for every decision you recorded, including rejections. Use 400 or above only when your own system failed before it could record the callback.
CB-07 Every value in a callback is a string, and a missing field means "no information", never zero. Update only what is present, and never use a strict schema that rejects unknown fields.
CB-08 Callbacks repeat, arrive out of order, and can be skipped. Make side effects happen once, never move a status backwards, and reconcile on a schedule.
CB-09 Never fulfil from the return URL. The buyer controls that browser.
CB-10 Record every callback with its outcome, including rejected ones, and alert on runs of failures.

Tokens

ID Rule
TOK-01 A saved-card token is a bearer credential. Encrypt it at rest, never send it to a browser, never log it.
TOK-02 S Never store a token taken from a callback body. Fetch it with get-buyer-key after the sale is confirmed.
TOK-03 Never send raw card data unless you are PCI DSS certified and a person has confirmed it.

Sales

ID Rule
SAL-01 Keep one open sale per order. A hosted sale stays payable while it is initial or failed: after a decline, the same sale_url still opens and a good card completes it. Reuse that sale rather than creating another: two payable sales is how a buyer pays twice.
SAL-02 Send your order ID as transaction_id, and store payme_sale_id before anything else can fail.
SAL-03 Don't build a scheduler that charges subscriptions. PayMe runs the schedule.

The steps that apply to your integration are in plan order under Steps, and the checks that prove them are under Verify.