Config and Transport
Reference pages: Authentication, Environments, Errors, Idempotency and Retries. This page holds only the order and the traps.
Configuration
- Choose the environment from one setting, such as
PAYME_ENV. The base URL and the Hosted FieldstestModeboth follow it, because a sandbox token can't pay a live sale. - Load credentials by name from the environment or a secrets manager, and refuse to start without them (SEC-03).
- Keep two public addresses: one PayMe's servers can reach for callbacks, and one the buyer's browser reaches for return pages. In development these are usually different.
| Role | Values to configure |
|---|---|
| Direct seller | MPL, public key if using Hosted Fields, the two public addresses |
| Partner | Partner key, partner secret, the two public addresses. Each seller's MPL and public key belong with that seller's record |
The client
Write one client for every call, with these behaviours:
POSTwith a JSON body andContent-Type: application/json, except the few endpoints that use another method or headers (their reference pages say so).- Success per TRN-01. A non-2xx is a failure even if its body says
status_code: 0. pay-salecan answerstatus_code: 5with aredirect_url. That is a 3D Secure challenge, not a failure.- One error type that carries the code, details, additional information and
session. Support asks forsessionfirst. - A request timeout, and a distinct "outcome unknown" result, decided as in Reading a failure (TRN-04).
- Redaction per SEC-05. PayMe sometimes echoes a value inside an error message, so scrub what you sent from what it returns before logging.
reference/payme-client.ts and reference/payme-error.ts in the integration kit implement this.
Reading a failure
The HTTP status doesn't decide this. PayMe sends ordinary refusals as HTTP 500 with a full error body, and a declined card as HTTP 200. Go down the table and stop at the first row that matches.
| What came back | What it means | What to do |
|---|---|---|
status_code 0 in a 2xx |
Success (TRN-01) | Carry on |
HTTP 429, usually with code 998 |
This call was turned away, but a matching call may still be running: a retried pay-sale can be |
Wait for Retry-After if it was sent, re-read the state, and repeat only if the read shows it didn't happen. See error 998 |
Code 991, 20002 or 999, at any HTTP status |
Unknown. 991 and 20002 mean contact was lost part-way, and the sale can show failed even so. 999 gives no information |
Re-read, block repeats, and have a person check with PayMe, quoting session |
status_code 1 and any other non-zero status_error_code, at any HTTP status, or any other 4xx |
Refused | Show it, fix the request or offer another try. Don't freeze the order |
Anything else: a timeout, a dropped connection, a body that isn't JSON, a gateway error page, JSON with no error code, or code 0 with status_code 1 |
Unknown. PayMe may have acted | Re-read, and don't repeat a money call until the read settles it. Only a connection that was refused or never resolved is known to be unsent |
Before offering a refused money call again, re-read the sale once. It costs nothing, and PayMe publishes no promise that a code means no money moved: work continues after the card company answers. If the read disagrees with the refusal, trust the read.
URLs PayMe checks
PayMe validates sale_callback_url and sale_return_url when it receives the request, so a bad value fails the whole generate-sale with error 21. In the sandbox this happened for localhost in either field and for a private address.
- When an address is local, leave the field out and log that you did. PayMe then falls back to a URL held on its side for the account. A partner asks PayMe to set it. A direct seller has no call to read or set it, and whether its account has one is unconfirmed, so expect no callback and rely on the scheduled re-check.
- To receive real callbacks in development, run a tunnel and use its public address.
- Put your order ID in the path of a return URL. PayMe appends its own query parameters.
A tunnel for callbacks in development
PayMe hasn't run this recipe end to end. It follows Cloudflare's documentation, so if a step looks different, follow theirs. An agent's permissions may block the download or the tunnel. If so, give a person these commands and ask them to paste back only the public address, which isn't a secret.
Download
cloudflaredfrom Cloudflare's downloads page. On 64-bit Windows, the file iscloudflared-windows-amd64.exe.Start your server. Then, in a terminal of its own, start the tunnel with your server's port:
# Windows, in the folder holding the download .\cloudflared-windows-amd64.exe tunnel --url http://localhost:<port># macOS or Linux, once installed cloudflared tunnel --url http://localhost:<port>Read the public address it prints, an
https://address ending intrycloudflare.com, and leave the process running.Send that address plus your callback path as
sale_callback_url, and restart your server if it loads settings at startup.Call your health route through the public address, so the request comes in from outside. On Windows, type
curl.exe:curl -i <public address>/healthResult Meaning 200 Good 502 The tunnel is up and your server is down Cloudflare error 1033 The tunnel process has gone
A quick tunnel's address stops working when the process stops, and the next run gets a new one, so update sale_callback_url each time. Anyone with the address can reach your server, so use it for development only.
A per-sale sale_callback_url needs nothing from PayMe. The Default Callback URL, where seller callbacks arrive, does: only PayMe can set it.
Dates
| Where | Format |
|---|---|
seller_birthdate, seller_social_id_issued, sub_start_date |
dd/mm/yyyy |
| Query date filters | yyyy-mm-dd hh:mm:ss, Asia/Jerusalem local time, not UTC |
| Dates in responses | yyyy-mm-dd hh:mm:ss, with a space and no T |