Payment gateway integration connects your application to a payment service provider so you can accept, authorize, and settle card payments. The decisions you make during integration shape your PCI scope, your ability to switch providers, and how much engineering time you'll spend on payments for years to come.
This guide covers the full integration process — from choosing an integration method through to testing and go-live. It's written for developers and technical product managers building payments into apps, SaaS platforms, and marketplaces.
What Is Payment Gateway Integration?
A payment gateway is the service that sits between your application and the acquiring bank. It encrypts card data, routes authorization requests to the card networks (Visa, Mastercard, etc.), and returns an approval or decline response — typically in under two seconds.
Integration means connecting your checkout flow, backend, or payment surface to that gateway's API. The result: your users can pay with cards, digital wallets, and local payment methods without leaving your product experience.
The scope of a gateway integration typically includes:
Client-side — collecting card details securely (via iframes, hosted fields, or redirect)
Server-side — creating payment intents, processing charges, handling 3D Secure callbacks
Webhooks — receiving asynchronous notifications for settlement, disputes, refunds
Reconciliation — matching gateway transactions to your internal records
For platforms that need to support multiple merchants or payment providers, the integration also includes merchant onboarding, payout splitting, and multi-PSP routing — which is where it gets complex fast.
Payment Gateway Integration Methods
There are three primary integration patterns. Each makes a different trade-off between control, PCI scope, and development effort.
API / Direct Integration
You call the gateway's REST API directly from your backend. Card data is collected via tokenized client-side fields (Stripe Elements, Adyen Web Components) so raw card numbers never touch your server.
A typical server-side charge request looks like this:
POST /v1/payments
Headers: Authorization: Bearer sk_live_xxx, Content-Type: application/json, Idempotency-Key: order_12345_attempt_1
Body: { "amount": 4999, "currency": "GBP", "payment_method": "tok_abc123", "capture": true, "metadata": { "order_id": "12345" } }
Best for: teams that need full control over the checkout UX and have the engineering capacity to manage PCI SAQ A-EP compliance.
PCI scope: SAQ A-EP (if using client-side tokenization) or SAQ D (if raw card data hits your server — avoid this).
Hosted Checkout / Redirect
The gateway hosts the entire payment page. You redirect the user to the gateway's URL, they enter card details there, and the gateway redirects them back with a transaction result.
The flow is: your app creates a checkout session via API → receives a redirect URL → sends the customer to that URL → gateway processes the payment → customer returns to your success/failure URL → you verify the result via webhook or API callback.
Best for: teams that want the simplest possible integration with minimal PCI scope. Trade-off: you lose control of the payment page design.
PCI scope: SAQ A — the lowest level. Card data never touches your infrastructure.
Embedded / Drop-in Components
This is the middle ground. The gateway provides pre-built UI components (iframes or web components) that you embed in your checkout page. The components handle card input, validation, and tokenization — your page never sees raw card data.
Examples include Stripe Elements, Adyen Drop-in, and Braintree Hosted Fields. You style them with CSS to match your brand, but the actual input fields are rendered inside the gateway's iframe.
Best for: most applications. You get a branded checkout experience with SAQ A PCI scope. This is the default recommendation for teams that don't have a specific reason to go fully direct.
PCI scope: SAQ A.
Requirements for Payment Gateway Integration
Before you write any integration code, you need four things in place.
1. PCI DSS compliance path
Any entity that stores, processes, or transmits cardholder data must comply with PCI DSS. Your integration method determines your SAQ level: hosted checkout or drop-in components qualify for SAQ A (22 questions). If card data touches your servers, you're looking at SAQ D (300+ questions) or a QSA audit.
2. TLS/SSL certificate
All payment pages must be served over HTTPS. Gateways reject API calls from non-TLS origins, and browsers flag insecure checkouts. Use TLS 1.2 or higher.
3. Merchant account or PSP agreement
You need a merchant account with an acquiring bank or a direct agreement with a PSP like Stripe or Adyen. For platforms with sub-merchants, you'll need either a PayFac license, a PayFac-as-a-service arrangement, or a payment layer that handles merchant onboarding for you.
4. Sandbox / test environment
Every major gateway provides a sandbox with test API keys and simulated card numbers. Set this up before touching production — you should be able to run your full checkout flow, including 3DS challenges and webhook delivery, in test mode.
Step-by-Step Payment Gateway Integration Process
Here's the integration process broken down into concrete engineering steps. Timelines assume a team of 1-2 developers working with a modern gateway API.
Step 1: Create your gateway account and get API keys (Day 1)
Sign up with your chosen PSP. You'll receive a publishable key (safe for client-side code) and a secret key (server-side only, never exposed to the browser). Store your secret key in environment variables or a secrets manager — never commit it to source control.
Step 2: Install the SDK or configure HTTP client (Day 1)
Most gateways offer server-side SDKs (Node.js, Python, Ruby, PHP, Go, Java) that wrap the REST API with authentication, retries, and serialization. If you prefer raw HTTP, use a client with retry logic and exponential backoff.
Step 3: Build the client-side payment form (Days 2-3)
Mount the gateway's drop-in component or hosted fields in your checkout page. The component collects card details and returns a token (a one-time-use reference to the card). Send this token to your backend — never the card number.
Key implementation details:
Load the gateway's JavaScript library from their CDN — never self-host it, or you'll break PCI scope
Initialize the component with your publishable key
Handle validation errors (expired card, invalid CVV) in the UI before submitting
Disable the submit button after the first click to prevent duplicate charges
Step 4: Create the server-side payment endpoint (Days 3-4)
Your backend receives the token and calls the gateway's charge or payment-intent API. Set the amount, currency, and metadata here.
Critical patterns to implement:
Idempotency keys. Every payment request should include an idempotency key (typically your order ID + attempt number). If a network timeout causes a retry, the gateway will return the original response instead of creating a duplicate charge. Example header: Idempotency-Key: order_12345_attempt_1
Amount validation. Never trust client-side amounts. Re-calculate the total from your server-side cart/order state before sending to the gateway.
Error handling. Distinguish between card-declined errors (show to user), validation errors (fix and retry), and gateway errors (retry with backoff or fail gracefully).
Authorize vs. capture. For orders that ship later, authorize the card at checkout and capture when you fulfil. Authorizations expire (typically 7 days), so capture promptly.
Step 5: Handle 3D Secure authentication (Days 4-5)
3D Secure (3DS) adds cardholder authentication — typically a bank-issued challenge. In the EU, SCA regulations make 3DS mandatory for most transactions.
The pattern: attempt payment → gateway returns "requires_action" with a redirect URL → redirect the customer or open an iframe → customer authenticates → gateway redirects back → confirm via API.
Step 6: Set up webhooks (Days 5-6)
Webhooks notify you about asynchronous events — settlements, failed captures, chargebacks, refunds. Register an HTTPS endpoint with the gateway, and it POSTs event payloads to that URL.
Webhook implementation rules:
Verify signatures. Every webhook payload should include an HMAC signature. Verify it using your webhook secret before processing. This prevents replay attacks and forged events.
Respond with 200 fast. Acknowledge the webhook immediately and process asynchronously. If your endpoint takes too long, the gateway will retry — potentially causing duplicate processing.
Make handlers idempotent. Gateways retry failed deliveries. Your handler should check whether you've already processed a given event ID before taking action.
Handle key events. At minimum, subscribe to: payment.succeeded, payment.failed, refund.created, dispute.created, and payout.paid.
Step 7: Build refund and dispute handling (Days 6-7)
Integrate the refund API for full and partial refunds. For disputes, set up webhook handlers to flag affected orders and collect evidence for representment automatically.
Step 8: Go live (Day 8-10)
Swap test keys for production keys. Run a real transaction with a small amount, verify it in the dashboard, then refund it. Monitor your first 100 transactions for elevated decline rates, webhook failures, and 3DS drop-offs.
PCI Compliance and Security
PCI DSS compliance is not optional — it's a contractual requirement from the card networks. The good news: modern integration methods dramatically reduce your scope.
Here's how your integration method maps to PCI scope:
SAQ A (hosted checkout, drop-in components): 22 questions. Card data stays entirely with the gateway. This is where you want to be.
SAQ A-EP (API integration with client-side tokenization): ~140 questions. Your website controls the payment page, but card data is tokenized before reaching your server.
SAQ D (direct server-side card handling): 300+ questions plus quarterly ASV scans. Avoid this unless you have a dedicated security team and a reason to handle raw card data.
Beyond PCI, implement these security fundamentals:
Use tokenization for stored payment methods — never store raw card numbers in your database
Enforce TLS 1.2+ on all payment endpoints
Log payment events without logging card data (mask PAN to last 4 digits)
Set Content-Security-Policy headers to restrict which domains can embed scripts on your payment pages
Rotate API keys regularly and use separate keys per environment (test, staging, production)
Testing Your Payment Gateway Integration
Payment testing should cover more than the happy path. Here's a testing checklist organized by category.
Authorization testing
Successful charge with test card (Visa: 4242 4242 4242 4242)
Declined card (use gateway-specific decline test numbers)
Insufficient funds decline
Expired card
Invalid CVV
3D Secure challenge flow (successful and failed authentication)
Post-payment testing
Full refund
Partial refund
Void (cancel an authorized but uncaptured payment)
Chargeback/dispute simulation
Edge case testing
Network timeout during payment (verify idempotency key prevents double charge)
Webhook delivery failure and retry
Currency mismatch between frontend and backend
Zero-amount or negative-amount edge cases
Concurrent payments from the same user
Browser back button during 3DS flow
Use the gateway's webhook testing tools (e.g. Stripe CLI's "stripe trigger") to simulate events locally during development.
Common Integration Challenges (and How to Solve Them)
Multi-currency support. Handle presentment currency (what the customer sees) vs. settlement currency (what you receive), and minor-unit formatting (GBP uses pence, JPY has no minor unit). Pass the correct ISO 4217 currency code and amount format for each gateway.
Webhook reliability. Webhooks can arrive out of order, be delayed, or be duplicated. Make webhook processing idempotent and always verify payment status via a synchronous API call as a fallback — never rely solely on webhooks for critical state transitions.
Gateway-specific error codes. Every gateway returns errors differently (Stripe: "card_declined"; Adyen: refusal reason codes). Build an abstraction layer that maps gateway-specific errors to your internal error taxonomy for consistent UI messages.
Mobile app integration. Native mobile apps need Apple Pay and Google Pay SDKs alongside card payments. These use device-level tokenization with their own certification requirements. Plan for this early — retrofitting mobile wallets later is expensive.
Subscription and recurring billing. Store tokenized payment methods and implement dunning logic (retry schedules for failed recurring charges). Notify customers before cards expire to reduce involuntary churn.
Migrating between gateways. Switching gateways means migrating stored tokens (via network tokenization), updating webhook endpoints, and running both gateways in parallel during transition. This is the most underestimated cost of direct integration — and a strong argument for using a payment abstraction layer from the start.
When to Use a Payment Layer Instead of Direct Integration
For a single-product app with one PSP, direct gateway integration is fine. But the calculus changes when you're building a platform.
Consider a payment layer if:
You need to support multiple PSPs — enterprise customers often mandate specific gateways. Maintaining 3-5 separate codepaths for payments, webhooks, and reconciliation is expensive.
You need payments across multiple channels — voice, chat, email, and messaging alongside web checkout need a unified payment API, not separate integrations per channel.
You don't want to become a PayFac — direct integration with sub-merchants means becoming a PayFac (6-12 months, heavy compliance) or using PayFac-as-a-service. A payment layer handles merchant onboarding for you.
Payments aren't your core product — every week your team spends maintaining payment infrastructure is a week not spent on your actual product. Embedded payment infrastructure lets you ship payment features without the ongoing maintenance burden.
Shuttle Global provides exactly this — a single integration point to accept payments across 40+ PSPs and multiple channels, with PCI Level 1 compliance and merchant onboarding included. If payments are a required step in your platform but not your core IP, explore this before committing to multi-gateway direct integration.
Learn how Shuttle works for platforms or book a technical walkthrough.
FAQ
How long does payment gateway integration take?
A basic single-gateway integration using drop-in components typically takes 1-2 weeks for an experienced developer. That covers client-side form, server-side API, webhooks, and testing. Multi-PSP or marketplace integrations can take 4-8 weeks. If you need SAQ D or a QSA audit, add 2-6 months for the compliance process.
Do I need PCI certification to integrate a gateway?
Yes, but the level varies. If you use hosted checkout or drop-in components (SAQ A), you complete a short self-assessment questionnaire — no external audit required. If raw card data touches your servers, you need SAQ D or a QSA audit, which is significantly more involved. Most applications should use tokenized client-side collection to stay at SAQ A.
Can I integrate multiple gateways?
Yes, but each gateway has its own API schema, error codes, webhook format, and reconciliation flow. You'll need an abstraction layer to normalize these differences. For platforms needing multi-PSP support, a payment layer provides this abstraction out of the box — giving you one API and one webhook format regardless of the underlying PSP.
Payment gateway integration starts simple and accumulates complexity. Get the fundamentals right — tokenization, idempotency, webhook verification, proper PCI scoping — and you'll avoid significant rework later.
If you're building payments into a platform and want to skip the multi-gateway integration work, talk to Shuttle. We handle the gateway integrations, PCI compliance, and merchant onboarding so your team can focus on the product.