Peach Payments Integration Tips for Developers
Explore essential Peach Payments integration tips for developers, including API setup, security, testing, payment workflows, error handling, and best practices.
Payment integrations look easy on day one. You skim the docs, push a test charge through, and assume the rest is cleanup. Then a webhook arrives twice, a customer closes their browser halfway through paying, and your orders table stops agreeing with the gateway.
Most of that pain is avoidable with Peach Payments. The platform is well documented, but a few early decisions decide whether your integration stays quiet or turns into a support queue. Here's what we'd flag for any developer starting out.
Pick your integration path first
Peach Payments offers several ways in: Embedded Checkout, Hosted Checkout, Payment Links and the Payments API. The docs recommend Checkout V2, so start there unless something specific rules it out.
Embedded Checkout keeps customers on your own site, and you can theme it and reorder payment methods. Hosted Checkout sends them to a Peach page, which is less to build but gives you less control. If you want the fastest route to a working payment, Hosted gets you there sooner. If the checkout experience affects your conversion, Embedded is worth the extra effort. Building a mobile app? There are Embedded Checkout guides for React Native and Flutter.
One catch to check early: Embedded Checkout doesn't support Apple Pay or PayPal. If your customers expect either, that may settle the question. Payment Links suit cases with no storefront at all, like invoicing. Supported methods change, so read the current docs before committing.
Keep sandbox and live apart
Sandbox and live use different addresses for authentication, checkout and the JavaScript SDK. Put all three in environment config and switch them together. Hardcoded URLs are how a sandbox key ends up hitting a live server, and the auth errors that follow look like bugs in your own code.
Peach also publishes a Postman collection and sample projects in Node and Python. When a request misbehaves, replay it in Postman first. If it works there, the problem is on your side.
Wrap every Peach call in one module
Keep all calls to Peach Payments in a single service instead of scattering requests across controllers. When the API changes, or when you move from Checkout V1 to V2, you'll touch one place instead of twenty. It also gives you one spot to add logging, retries and timeouts.
Do the sensitive work on the server
Create the checkout from your backend and give the front end only what it needs to render the form. Your credentials and secret token should never sit in a JavaScript bundle or a mobile build, because anyone can pull them out. It sounds obvious, and it still slips through when a deadline is close.
Treat webhooks as the source of truth
Landing back on your thank-you page doesn't prove a customer paid. Tabs get closed and networks drop. The reliable signal is the webhook.
Peach Payments sends a webhook on every state change for debits, preauthorisations and refunds. The states are created, pending, successful, uncertain and cancelled. A few habits keep this part solid.
-
Verify the signature. Every webhook is signed with your secret token, so check it before trusting the payload. Webhooks also come from a known range of IP addresses, and allowlisting them adds a second layer.
-
Check the amount. Compare the amount and currency in the webhook against what you expect for that order before you fulfil it. Attach your own order ID when you create the checkout so matching never involves guessing.
-
Don't assume order. Peach can't guarantee webhooks arrive in sequence. If your endpoint goes down and a pending message retries after a successful one, a "last message wins" handler moves a paid order backwards. Accept only legal transitions: created to pending, pending to successful, cancelled or uncertain, and uncertain or cancelled to successful.
-
Expect repeats. Failed deliveries get retried, so the same event can show up more than once. Store the transaction reference and skip duplicates.
-
Answer fast. Return a 200 quickly and do the slow work, like emails and stock updates, in a background job. Keep the raw payloads for a few weeks too. When a customer swears they paid, you'll want the original message.
-
Handle "uncertain" carefully. It covers closed windows and timeouts, and it can still turn successful later. Don't cancel the order or release stock the moment you see it. Give it a grace period and check again.
Respect the 30-minute window
A checkout expires after 30 minutes, and Embedded Checkout doesn't extend that clock. If a customer leaves the cart open over lunch, the old session is dead. Create a fresh checkout for the retry, but check the order's current status first so you never open a second payment against an order that's already paid.
Show useful errors
Peach returns response codes for declines and failures. Map them to plain language. "Your bank declined this card, try another" beats a raw code every time. Don't retry a declined payment automatically either; let the customer choose another method. Then log the code beside your own order ID so support can trace a complaint in minutes.
Plan for tokenisation and refunds
If you offer saved cards or repeat billing, use Peach's tokenisation instead of storing card details yourself. It keeps you clear of the heaviest compliance work, and it's easier to design for early than to bolt on later. Refunds also go through the API and generate their own webhooks, so a handler that only understands debits will quietly ignore them.
Reconcile every day
Even with careful handling, something eventually gets missed. Peach Payments offers a Reconciliation API and dashboard reports, so a nightly job that compares your orders with their records will catch gaps before your finance team does. Flag anything that's paid on their side but still pending on yours.
Test the ugly paths before going live
Peach documents a test and go-live procedure, so follow it step by step. Then go beyond the happy path. In sandbox, run a cancelled payment, a failed one and a timeout. Switch your webhook endpoint off for a few minutes and confirm your system recovers when the retries land. Ask a teammate to try to break it too: double-click the pay button, hit back mid-payment, refresh on the return page. Finally, check that the environment switch really points at live before launch day.
Wrapping up
A good Peach Payments integration comes down to discipline around edge cases: verified webhooks, sensible state handling, separate environments and daily reconciliation. Get those right and the payment code itself is the easy part.


