Payment gateway integration in Azerbaijan should be designed as an operational payment lifecycle, not as a checkout widget. A customer can complete 3D Secure but never return to your site, a provider callback can arrive late or twice, and a refund can be accepted for processing but fail later. If the product has no reliable internal record of those events, support staff, finance and customers will all see conflicting answers.

For a website, customer portal or mobile-backed service, treat the payment provider as an external system of record for processing and your application as the system of record for your order and fulfilment decisions. The integration must connect the two through durable identifiers, controlled state changes, verified webhooks and a reconciliation process. That is the difference between accepting a card payment and operating payments safely after launch.

Start with orders and payment attempts—not provider statuses

Create an internal order before sending a shopper to checkout. Then create a separate payment attempt each time that order is submitted to the payment gateway. One order may have several attempts: a card may be declined, the shopper may abandon authentication, or the payment page may time out before a successful retry.

  • Give every order an immutable internal ID.
  • Give every payment attempt its own ID and merchant reference sent to the provider.
  • Store money as integer minor units plus ISO currency, never as floating-point values.
  • Record the provider transaction ID, relevant response codes, timestamps and raw event references.
  • Keep authorisation, capture/payment success, refund and settlement conceptually separate.

Use a small, documented internal state machine rather than exposing provider terminology across the whole product. For example: created → checkout_started → pending_authentication → authorised/captured → paid, with failed, cancelled, expired and unknown as controlled alternatives. Your exact names can differ, but every transition needs a defined trigger and owner. A late failure notification must not casually overwrite a payment already confirmed as paid; it should be routed to an exception review path where appropriate.

Make the webhook authoritative for final payment status

The browser return URL is a user-experience route, not reliable proof that funds were accepted. The shopper might close the page, lose connection or come back before the provider has finished processing. Mark an order paid only after your server has verified the provider’s signed server-to-server notification, or after a documented provider status query where a webhook is unavailable.

Webhook handling that survives real traffic

  1. Authenticate the event. Validate the signature or HMAC exactly as the provider specifies, typically against the unmodified request body. Reject invalid events without acting on them.
  2. Persist before processing. Store a unique event identifier, headers needed for audit, payload reference, received time and processing result. Do not write card data or secrets into application logs.
  3. Acknowledge quickly. Once verified and durably queued, return a successful HTTP response. Run fulfilment, email and heavy downstream work asynchronously.
  4. Process idempotently. The same event may be delivered again. A duplicate event must not send a second receipt, provision access twice or create another refund.
  5. Record transition evidence. Keep which event or API response moved an attempt to each state, so staff can explain the outcome later.

Idempotency also applies to outbound requests. Generate and retain a unique idempotency key for each state-changing request you make to the provider, such as creating a payment, capturing, cancelling or refunding. If your service times out after sending the request, a safe retry should resolve to the same operation rather than a second charge or duplicate refund.

Plan for pending, failed and abandoned payments

A checkout page needs useful customer messaging, but operations need more. Your staff view should show the order ID, attempt history, provider reference, amount, currency, last status, decline reason where permitted and the time of the last confirmed update. A customer should see a clear next action—try again, use another method or contact support—without exposing internal provider codes.

Run a scheduled recovery process for attempts that remain pending beyond a defined window. It should query only eligible unresolved attempts, retrieve the current provider status, apply the same guarded state transitions and log the result. Do not “fix” payment statuses with direct database edits. If a manual resolution is necessary, make it a permission-controlled admin action with a reason and immutable audit entry. This type of back-office control belongs in the scope of a properly engineered web platform or application, not in an afterthought spreadsheet.

Refunds need a workflow, permissions and asynchronous confirmation

A refund request is not necessarily a completed refund. The provider may validate it first, the payment method may process it later, or a scheme may reject it after an initial acknowledgement. Your product should therefore model a refund as its own record linked to the original paid attempt.

  • Limit refunds to captured or paid transactions according to the provider’s rules.
  • Calculate the remaining refundable amount from completed and pending refunds; never rely on a staff member’s manual arithmetic.
  • Support full and partial refunds only where your business policy and provider allow them.
  • Require the appropriate role—and, for higher-risk cases, a second approval—to initiate a refund.
  • Use an idempotency key and retain the provider refund reference.
  • Move the refund to final status from the webhook or subsequent verified status check, not solely from the initial API response.

Show customers a truthful status such as “refund requested” or “refund processed” rather than promising an arrival date your system cannot control. The admin interface should expose the reason, initiator, approver, original payment reference and all status events. For sophisticated products, these controls can be part of a tailored FinTech systems build.

Reconciliation closes the gap between successful payments and received funds

Payment approval, settlement to your account, fees, reversals and refunds happen on related but distinct timelines. Reconciliation compares your internal payment attempts and refunds with provider transaction reports, payout or settlement reports, and ultimately the accounting or bank-facing record. Without it, a “paid orders” dashboard can conceal missing callbacks, unmatched provider transactions, delayed payouts or incorrect fee assumptions.

Design a reconciliation job around stable matching fields: your merchant reference, provider transaction ID, amount, currency, transaction date and settlement/payout reference. Categorise unmatched items for action: provider transaction missing internally, internal paid attempt missing at the provider, amount mismatch, pending settlement, refund mismatch or duplicate reference. Give finance staff an exception queue with filters, ownership and notes—not a CSV that is overwritten every month. This is the practical foundation of payment reconciliation software.

Security and launch checklist

Where possible, use the provider’s hosted payment page or properly implemented embedded component so your own servers do not receive card data. That reduces exposure, but it does not eliminate responsibility for the security of the merchant site. PCI SSC guidance makes clear that redirect and embedded-payment implementations still require attention to risks on the merchant webpage, including scripts that can affect the payment flow. Confirm the compliance responsibilities applicable to your exact implementation with your acquirer and qualified advisers.

  • Test success, decline, cancelled 3D Secure, no browser return, delayed webhook, duplicate webhook and temporary webhook endpoint failure.
  • Separate sandbox and production credentials; keep secrets in a secure secret-management mechanism.
  • Monitor webhook delivery failures, queue depth, pending-payment ageing, refund failures and reconciliation exceptions.
  • Test role-based refund permissions and audit logs with real operational users.
  • Review provider documentation for settlement reports, fees, dispute handling, refund limitations and support escalation before contract sign-off.

POLADO’s Web Platforms & Applications service can scope the full payment lifecycle: checkout UX, backend state model, webhook workers, admin operations and reconciliation reporting. If your service also needs a customer-facing app, align it with the same backend through Mobile App Development. Book a technical consultation before launch to review provider documentation, failure scenarios and the operational controls your team will need on day one.