A developer's guide to the PayPlus REST API - the generateLink endpoint, the api-key and secret-key header pair, the payment_page_uid you must have first, and the staging environment that makes this the least painful Israeli gateway to build against.
Key takeaways
- PayPlus documents a staging environment alongside production. For a payment integration that is worth more than any interface nicety - you can build the whole flow without moving real money.
- Authentication is a header pair - api-key and secret-key. Both are server-side secrets that authorise charging customers on behalf of the business, so neither belongs anywhere near client code.
- You need a payment_page_uid before any call works. It identifies which configured payment page to generate a link for - it is set up in the PayPlus interface, not created by the API.
- A payment link is a link, not a session. It can be sent by WhatsApp, email or SMS, which makes this a natural fit for quote-to-payment flows - and means you must decide how long it stays valid.
PayPlus is an Israeli gateway whose primary interface is built around a simple idea: you generate a payment link and the customer pays through it. There is no mandatory iframe and no page you host - the link leads to a payment page hosted by PayPlus.
That makes it a particularly good fit for scenarios that are not a classic online store: sending a payment link over WhatsApp after a sales call, attaching one to a quote, or collecting for a service ordered by phone.
The basics
Generating a payment link:
POST https://restapi.payplus.co.il/api/v1.0/PaymentPages/generateLinkAuthentication is a header pair: api-key and secret-key, both issued in the PayPlus interface.
The request also requires a payment_page_uid - and this is the first stumbling point. It identifies which configured payment page you are generating a link for, and it is not created by the API: you configure a payment page in the interface and take its identifier from there. Without it no call works, and there is no shortcut in code.
The documentation lives at docs.payplus.co.il, where every function lists both its Staging and Production URLs.
Where is the PayPlus API documentation, and which URL is staging?
The PayPlus API documentation is at docs.payplus.co.il, current version v1.0, and every endpoint is published against two servers:
| Environment | Base URL |
|---|---|
| Staging | https://restapidev.payplus.co.il/api/v1.0/ |
| Production | https://restapi.payplus.co.il/api/v1.0/ |
The docs stress sending each request to the right environment with that environment's credentials. PayPlus also asks developers who plan an integration to tell its technical support by email, so they hear about significant API changes.
What does a PayPlus payment link request need?
PayPlus's own guide to payment page requests lists six mandatory fields: payment_page_uid, charge_method, amount, currency_code, sendEmailApproval and sendEmailFailure. charge_method is the one that changes what the link does:
| charge_method | Transaction type | Used for |
|---|---|---|
| 0 | J2 - card check | Validating a card without charging it |
| 1 | J4 - regular charge | A normal payment |
| 2 | J5 - approval (deferred charge) | Holding the amount now and charging later |
| 3 | Recurring payments | Starting a recurring payment from the link |
The optional more_info field is a unique identifier of yours that comes back with the transaction. Put the order id in it - it is also a value you can search by later.
What makes this comfortable: a staging environment
This is what I put first. PayPlus documents a separate Staging environment alongside production, and every function in the docs carries both addresses.
Why that matters more than it sounds: in a payments integration, a mistake in production is not a row you delete. It is a real transaction - a refund, a bookkeeping entry, sometimes a confused customer. An environment where you can run twenty iterations without moving money is worth more than any difference in API syntax.
Practically: keep the base URL, the api-key, the secret-key and the payment_page_uid as four separate environment variables. Automated tests always point at Staging. Going live is a configuration change, not a code change.
A link is not a session - and what follows from that
The substantive difference from an iframe: a payment link is a URL that can be sent, forwarded, and opened tomorrow.
That is a real advantage for genuine business flows - sending over WhatsApp, attaching to a quote, collecting on a phone order. But it also raises three questions you must not leave open:
- How long is the link valid? A link that never expires is an exposure. A customer can open it two months later, after the offer is no longer relevant, or forward it to someone else.
- What if it is paid twice? One link, two payments. Your system must know the order is already paid and not fulfil twice.
- How will you know it was paid? The customer is not going to tell you.
Source of truth: a server notification, not the browser
As with every gateway, this is what determines how many orders quietly vanish.
The page the customer is redirected to after paying is not a reliable update mechanism. A customer who closes the tab the moment payment clears, or whose connection drops, never gets there - and the order stays "pending" while the money has been taken.
The point is sharper still with a link sent over WhatsApp: the customer pays on their phone, closes the browser and returns to the conversation. They never see a thank-you screen, and they do not care.
The rule: order state comes from a server-to-server notification. The page shows the customer a thank-you screen. Never the other way round.
And the endpoint receiving that notification must be idempotent and cross-check the amount against the order - notifications can repeat, and that must not mark two orders paid.
How do you verify a PayPlus callback?
A PayPlus callback is verified with two headers that come with every payload: hash and user-agent. The documented check is that user-agent equals PayPlus, and that hash equals a base64 HMAC-SHA256 of the JSON body, keyed with your secret-key. The published Node sample builds the message with JSON.stringify of the received body, so test the check on Staging against a real callback before you rely on it.
Two details in the callback reference change how the handler is written:
- The callback is sent for every successful transaction that is charged or refunded, when a callback URL is set on the account. A handler that marks an order paid on any callback will "pay" an order on a refund.
payment_request_uidis included only when the transaction came through a payment page, so do not make it the only key you match on.
What if the PayPlus callback never arrives?
Ask for the status yourself. POST /PaymentPages/ipn returns a transaction by payment_request_uid or transaction_uid, and can also search by the more_info you sent. A scheduled job that checks orders still pending an hour after the link went out closes the gap a lost notification leaves. The same part of the API answers the other operational questions:
- A link you no longer want paid:
POST /PaymentPages/Disable/{page_request_uid}disables the link request. This is how the validity period above is enforced in practice. - A charge to undo today:
Transactions/Cancelworks only before the transaction is deposited - the same day, and before the account's deposit time, 23:00 by default. Cancelling a J5 releases the credit-limit hold. - After that: a refund, through
Transactions/RefundByTransactionUID.
Who issues the invoice
The decision that recurs in every project connecting payments and accounting: if the gateway is configured to issue a document automatically and your system also issues one through your invoicing system, one transaction produces two tax documents.
It surfaces at month end, at the accountant's desk. Pick one side and document it before writing a line.
Security
- Both keys are server secrets. The
secret-keyauthorises charging customers on behalf of the business. Not in source control, not in logs, and not in anything running in a browser. - Do not touch card details. They are entered on PayPlus's page. Do not relay them, do not log them - doing so pulls you into PCI DSS scope.
- Authenticate the inbound notification. A public endpoint that marks orders paid is an obvious target.
- Cross-check the amount always. Even when everything looks fine. This is the check that catches what the others missed.
Pre-launch checklist
- Confirm a
payment_page_uidis configured, and that all four values are environment variables. - Build the entire flow against Staging, including failure.
- Test the case where the customer pays and immediately closes - did the order update?
- Test a double payment on the same link.
- Decide the link's validity period and confirm it is enforced.
- Confirm there is no double document issuance.
For a comparison of the gateways, see Israeli payment gateways compared.
Sources
Frequently asked questions
How do you authenticate with the PayPlus API?
With two headers, api-key and secret-key, both issued in the PayPlus interface. Requests also require a payment_page_uid identifying which configured payment page the link is for - that identifier comes from the interface and is not created through the API, so nothing works until a payment page has been set up.
Does PayPlus have a sandbox or test environment?
Yes - a documented Staging environment alongside Production, with every function in the documentation listing both URLs. In a payments integration that matters a great deal, because a mistake in production is a real transaction requiring a refund and a bookkeeping entry rather than a row you can delete.
Can a PayPlus payment link be sent over WhatsApp?
Yes, and that is one of the main reasons to choose a link-based gateway - it suits quotes, phone orders and sales conversations rather than only a classic checkout. But because a link can be forwarded and opened later, you must decide how long it stays valid and make sure paying the same link twice cannot fulfil an order twice.
Should order status be updated on the PayPlus redirect page?
No - use the server-to-server notification. The redirect depends on the customer staying in the browser, and with a link sent over WhatsApp they typically pay on their phone and return to the conversation without ever seeing a thank-you page. Marking the order paid there leaves it pending while the money has been collected.
How do I verify that a callback really came from PayPlus?
Check both headers PayPlus sends with every payload. The user-agent header must equal PayPlus, and the hash header must match a base64 HMAC-SHA256 of the JSON body computed with your secret-key. If either check fails, do not touch the order. Test the check on Staging against a real callback before going live.
Can I cancel a PayPlus transaction through the API?
Yes, but only before it is deposited. Transactions/Cancel works on the same day and before the account deposit time, which is 23:00 by default, and cancelling a J5 approval releases the credit-limit hold. After the deposit time the documentation directs you to the refund endpoints, such as Transactions/RefundByTransactionUID.
What does charge_method mean in a PayPlus payment link?
It sets the transaction type the link creates. 0 is a J2 card check with no charge, 1 is a regular J4 charge, 2 is a J5 approval that holds the amount for a later charge, and 3 starts recurring payments. It is one of the mandatory fields, together with payment_page_uid, amount and currency_code.
Keep reading
Related service
Integrations
Make the systems you already pay for talk to each other.
Have a project like this?
Tell me what you're trying to automate or build. I reply within 24 business hours with a few targeted questions, then we walk through it on a free 30-minute call, with no commitment. You come away with a scope, a timeline and a fixed price - or a straight answer that it isn't worth building.