API, webhooks and backend Published June 29, 2026 9 min read

Payment API integration for a custom website: payment sessions and webhooks

A custom website gives full checkout control, but it needs a strict backend contract, statuses and repeatable event processing.

Payment API integration for a custom website: payment sessions and webhooks

Key topics

Payment API integration for a custom website: payment sessions and webhooksAPI, webhooks and backendpayment webhooksidempotency key paymentsserver-side payment verificationpayment statusespayment backend API

Related public pages

If you need the product, API or operations page rather than only the article, start with these VPOS.am sections.

Payment session should be created on backend

Frontend can start checkout, but amount, currency and final status should be controlled by server-side layer.

Backend creates payment session
Website sends order intent; backend validates amount and creates hosted checkout session.

For a custom website, Laravel/Yii2 backend, React storefront or mobile app, a safe flow starts server-side. Client UI can collect cart and send payment intent, but backend should calculate amount, currency, order id and create the payment session.

If frontend decides amount or treats redirect as paid, parameter tampering, duplicate orders and lost successful payments become likely. Payment session should store internal id, merchant order id, amount, currency, status and expiration.

  • create payment session only after backend validation;
  • lock amount and currency before checkout;
  • use hosted checkout or controlled redirect;
  • do not treat redirect as final payment status.

Idempotency prevents duplicate orders and payments

Repeated payment creation request should return the same result or a controlled new attempt.

Idempotency key -> stable payment
Repeated create request, double click or network retry does not create duplicate business objects.

In real checkout, a user clicks twice, mobile network retries, browser reloads the page and webhook can arrive several times. Without idempotency, each case can create a duplicate payment attempt or order.

It is better to bind idempotency key to operation: create payment session, process webhook, create fiscal receipt, update CRM. Then retry returns predictable result and audit trail shows what happened.

  • unique key for create payment session;
  • repeated webhook does not move final status backwards;
  • CRM/ERP update should be repeatable;
  • manual fixes should enter audit log.

Webhooks, status checks and business-system sync

Payment backend should accept the final event, verify it and then deliver normalized status to internal systems.

Webhook -> status check -> CRM/ERP
Verified event updates payment state, order, CRM, ERP, fiscal workflow and reconciliation queue.

Webhook should not be processed like a regular form. Verify signature or run provider status check, compare provider reference, amount, currency and order id, then apply an allowed status transition.

After that, normalized event can be delivered to CRM, ERP, fiscalization, notifications and reconciliation. If a downstream system is temporarily unavailable, payment status should stay persisted and integration should retry delivery.

  • verify provider reference, amount and currency;
  • use state machine for status transitions;
  • deliver events through retry queues;
  • separate payment status from fiscal and delivery status.

FAQ

Can payment session be created from frontend?

Frontend can initiate the request, but session should be created by backend after verifying order, amount, currency and access rights. Otherwise payment parameters are easy to change.

Is webhook needed if there is a success page?

Yes. Success page shows result to the customer, but final business status should be set after webhook or server-side status check.

What if CRM is unavailable after successful payment?

Store paid status in the internal payment session, put CRM update into retry and show an exception to operator only if repeated attempts fail.