How to Integrate a Payment Gateway: Types, PCI Scope and Multiple Gateways
Payment gateway integration step by step: hosted page, embedded fields or API, the PCI SAQ each puts you in, webhooks, 3DS, tests and multiple gateways.
Article summary
TL;DR
To integrate a payment gateway, open a merchant account, pick how card data is collected (hosted page, embedded fields, direct API or a store plugin), build the server call with idempotency keys, confirm payments through signed webhooks, handle 3D Secure, then test declines and duplicates in the sandbox before switching to live keys.
- The integration type decides your PCI workload: a hosted page or a provider iframe can qualify for SAQ A, your own form posting to the gateway is SAQ A-EP, and card numbers on your servers mean far more controls.
- Since March 31, 2025, an embedded payment form only qualifies for SAQ A if the page is protected against script attacks. A full redirect is not concerned.
- Never fulfill an order from the success page. Confirm it from a verified webhook, and make every handler safe to run twice.
- In the EEA, a customer-initiated card payment needs Strong Customer Authentication unless an exemption applies: build the 3D Secure step in from day one.
- Several gateways means one layer for routing, failover and reporting. Saved cards are the hard part: a token from one processor can't be charged at another.
On this page
Integrating a payment gateway takes more than adding a pay button. You choose how card details are collected, and that choice sets your PCI DSS workload. Then come the server calls, the webhooks that confirm each payment, 3D Secure and the tests. This guide covers the four integration types, what PCI asks of each since the 2025 change to SAQ A, the steps from sandbox to live, and what changes when you connect several gateways.
What payment gateway integration covers
A payment gateway takes the payment details from your checkout and passes them to the processor and the card networks for approval. The gateway and the processor are often the same company, but their roles differ: see payment gateway vs payment processor.
Whatever the provider, an integration has the same five parts:
| Part | What it does | Who builds it |
|---|---|---|
| Merchant account | The contract that lets you accept cards and get paid out | The provider, after underwriting |
| Payment form | Collects card or wallet details in the browser or app | The provider, you, or both, depending on the integration type |
| Server call | Creates the payment with your secret key and the amount you trust | You |
| Webhooks | Tell your server what happened afterwards: paid, failed, refunded, disputed | The provider sends them, you handle them |
| Reconciliation | Matches payments, fees and payouts with your orders | You, or your accounting tool |
The payment form is where the big decision sits, because it decides whether card numbers ever touch your systems.
The four ways to integrate a payment gateway
Every major gateway offers the same families of integration, under different names.
| Integration type | How it works | Examples | Control over the page | Usual PCI questionnaire |
|---|---|---|---|---|
| Hosted payment page (redirect) | The customer leaves your site to pay on the provider's page, then comes back | Stripe Checkout hosted page, Authorize.net Accept Hosted, PayPal | Low: logo and colors | SAQ A |
| Embedded fields (iframe) | The provider's fields sit inside your checkout, in iframes served by the provider | Stripe Elements, Adyen Drop-in and Components, Braintree Hosted Fields | High | SAQ A, if the 2025 script criterion is met |
| Your own form, sent to the gateway by script | Your page builds the form, a provider script sends the data straight to the gateway and returns a token | Authorize.net Accept.js with your own form | Full | SAQ A-EP |
| Direct API | Card numbers reach your server, which sends them to the gateway | Server-to-server card APIs | Full | SAQ D |
Platform plugins for Shopify, WooCommerce and others are a fifth path, covered further down: they wrap one of the first two types.
Authorize.net puts the split in plain words. With Accept.js you "host your own payment form for a PCI-DSS SAQ A-EP solution", while its hosted form collects card data "in a PCI-DSS SAQ A compliant way".13Authorize.net Developer Center, Accept.js Adyen offers a Sessions flow, where your server makes one request and the client library handles the rest, and an Advanced flow with three requests for merchants who need checks before payment or a changing amount.12Adyen Docs, Build your integration
Verdict
Start with a hosted page or the provider's embedded fields. Build your own form only when you can't get the checkout you need otherwise, and accept card numbers on your servers only with a reason worth hundreds of security controls.
Depth on the redirect option, its trade-offs and providers, is in our guide to hosted payment gateways.
PCI DSS scope: SAQ A, SAQ A-EP or SAQ D
PCI DSS applies to every merchant that accepts cards. What changes with the integration type is the self-assessment questionnaire (SAQ) you file each year, and the number of controls in it. Stripe sums up the stakes: a business that handles card data directly "might be required to meet more than 300 security controls in PCI DSS".5Stripe Docs, Integration security guide
The PCI Security Standards Council draws the line by the origin of each element of the payment page:
For SAQ A, all elements of the payment pages must only originate from PCI DSS compliant service provider(s). No single element of a payment page can originate from the merchant's website.
For SAQ A-EP, each element of the payment page comes either from the merchant's website or from a compliant provider.3PCI Security Standards Council, FAQ: If all elements of payment pages originate from a PCI DSS compliant service provider, is the merchant eligible for SAQ A or SAQ A-EP? That questionnaire covers e-commerce merchants whose website doesn't receive the card data but can affect the security of the payment page.4PCI Security Standards Council, Self-Assessment Questionnaire A-EP for PCI DSS v4.0 If card numbers pass through your servers, neither applies.
What changed for SAQ A in 2025
On January 30, 2025, the PCI SSC published a new SAQ A. It removed requirements 6.4.3 and 11.6.1, the controls on payment page scripts, and requirement 12.3.1 that supported them. In exchange, it added an eligibility criterion: merchants must "confirm their site is not susceptible to attacks from scripts that could affect the merchant's e-commerce system(s)". The new version took effect on March 31, 2025, when the October 2024 version was retired.1PCI Security Standards Council blog, Important updates announced for merchants validating to SAQ A, January 30, 2025
A month later, FAQ 1588 set the scope and the method.2PCI Security Standards Council blog, FAQ clarifies new SAQ A eligibility criteria for e-commerce merchants, February 28, 2025
Who it applies to
E-commerce merchants whose webpage includes an embedded payment page or form from a provider, for example an iframe.
Who it doesn't
Merchants that redirect customers to the provider, or fully outsource payment, for example with a payment link sent by email.
How to confirm
Use techniques such as those in requirements 6.4.3 and 11.6.1, yourself or through a third party. Or get your provider's confirmation that its form, set up as instructed, protects your page from script attacks.
Practical rule
If you embed the gateway's fields, ask your provider in writing whether its solution covers the script criterion, and keep that answer with your SAQ. Your acquirer, not the gateway, confirms which questionnaire you file.
The full PCI picture, with what each questionnaire contains and how to pick a compliant gateway, is in our guide to PCI-compliant payment gateways.
How to integrate a payment gateway, step by step
The order below works for Stripe, Adyen, Braintree or Authorize.net. Names change, the steps don't.
- Open the merchant account. The provider reviews your business, website, products and refund policy. Some businesses need more documents, and approval isn't automatic.
- Get sandbox access and API keys. A publishable key for the browser, a secret key for your server only. Keep secrets out of the code.
- Choose the integration type. Hosted page, embedded fields or your own form, based on the table above and the PCI questionnaire you can carry.
- Build the client side. Load the provider's script from its own domain, collect the details in its fields, and receive a token or payment method ID. No card number reaches your code.
- Build the server side. Create the payment from your server, with the amount from your database, never from the browser, and an idempotency key.
- Handle webhooks. Verify the signature, store the event, answer fast, process it in a queue.
- Handle 3D Secure. Let the provider's library run the authentication step, and treat "requires action" as a normal state.
- Test. Approvals, declines, 3D Secure, duplicates, timeouts, refunds.
- Go live. Swap to live keys, register live webhooks, watch the first payments.
Steps 1 and 2 can run in parallel: build in the sandbox while underwriting reviews your file.
Client side and server side: who does what
The rule fits in one line: the browser collects, the server decides. Anything the browser sends can be changed by the customer, including the amount.
Fig. 1Where the card data goes with embedded fields
approved declined or closed routing step
- Customer's browserTypes the card in the provider's fields
- card data goes straight toGatewayStores the card, returns a token
- token onlyYour serverCreates the payment with the token and the real amount
- secret keyGateway and issuerAuthorize, 3D Secure if neededApproved
your server only sees a token
Tokens have limits worth knowing. At Authorize.net, the payment nonce returned by Accept.js is single-use and "valid for 15 minutes".13Authorize.net Developer Center, Accept.js Create the payment right after the customer submits, not in a later batch.
On the server, every request that creates or changes something gets an idempotency key. If the connection drops, you send the same request again with the same key, and the gateway returns the first result instead of charging twice. At Stripe, keys are up to 255 characters, Stripe suggests random V4 UUIDs, keys can be removed once they're at least 24 hours old, and a retry with different parameters returns an error.7Stripe API reference, Idempotent requests
What you can keep is narrow. Stripe lists the card type, the last four digits and the expiry date as outside PCI scope, along with anything its API returns.5Stripe Docs, Integration security guide The full card number and the security code stay with the gateway. More on that split in tokenization vs encryption.
Webhooks: the part that decides if orders are right
The response to your server call is only the first answer. Bank debits settle days later, 3D Secure finishes in the browser, refunds and disputes arrive weeks later, and renewals run with no customer present. Webhooks carry all of that.
Don't fulfill from the success page
Stripe is explicit: you can't rely on triggering fulfillment only from your checkout landing page, because "it's not guaranteed customers visit that page". A customer can pay and lose connection before it loads. Use the landing page to show the order, and the webhook to confirm it.8Stripe Docs, Fulfill orders (Checkout)
Stripe and Adyen document the same rules, with different numbers:
| Rule | Stripe | Adyen |
|---|---|---|
| Verify the sender | Check the Stripe-Signature header against the raw request body; reject old timestamps (5 minutes by default in the libraries)6Stripe Docs, Receive Stripe events in your webhook endpoint | Verify the HMAC signature before using any data11Adyen Docs, Handle webhook events |
| Acknowledge fast | Return a 2xx before any complex logic | Return 202 for most events; no answer within 10 seconds marks the webhook as failing11Adyen Docs, Handle webhook events |
| Expect duplicates | The same event can arrive more than once: log processed event IDs | The same event can arrive twice, with the same eventCode and pspReference: use the latest |
| Don't expect order | Events aren't delivered in the order they were created | Check the timestamp, and the sequence number when present |
| Retries | Up to three days, with exponential backoff, in live mode6Stripe Docs, Receive Stripe events in your webhook endpoint | Placed in a retry queue after the first attempts fail |
The pattern that holds up: verify, store the raw event, answer 2xx, then process it from a queue. Stripe recommends the queue because renewal peaks, such as the start of the month, can overwhelm an endpoint that does everything inline.6Stripe Docs, Receive Stripe events in your webhook endpoint The fulfillment function itself must handle being called several times, even at the same moment, for the same payment.8Stripe Docs, Fulfill orders (Checkout)
Inside Tagada
See every payment's route, processor by processor
Set the order your processors are tried in, per store, per country or per product.

3D Secure and Strong Customer Authentication
In the EEA, the SCA rules make strong authentication the default for customer-initiated online card payments. An issuer can decline a payment that needed it and didn't get it, unless an exemption applies.15Commission Delegated Regulation (EU) 2018/389, RTS on strong customer authentication The UK applies equivalent rules. Outside Europe, 3D Secure is optional but useful on risky orders.
In the integration, that means three things:
- Let the provider's library run it. Hosted pages and embedded fields handle the challenge screen. With your own server flow, the payment comes back in a "requires action" state, and the browser must finish it.
- Don't treat "requires action" as a failure. Keep the order pending until the webhook confirms the final result.
- Flag saved cards correctly. The first payment authenticates the customer; later charges you start yourself go as merchant-initiated.
Exemptions, liability shift and subscriptions are covered in what payment authentication is.
Testing in the sandbox
Every gateway gives you test card numbers. Use them, never real cards: Stripe's terms forbid testing in live mode with real payment details, and Stripe warns that putting card numbers in server-side code, even in tests, can leave your code non-compliant when you go live.9Stripe Docs, Testing
- Approved card (Stripe: 4242 4242 4242 4242)The happy path, end to endOrder paid once, from the webhook
- Generic decline (4000 0000 0000 0002) and insufficient funds (4000 0000 0000 9995)Your decline messages and order statesClear message, order stays unpaid, no fulfillment
- 3D Secure every time (4000 0027 6000 3184)The challenge flow and the pending stateOrder pending until authentication succeeds
- Same request sent twiceIdempotency keysOne charge, the same response twice
- Same webhook replayed, or events out of orderDuplicate and ordering handlingOne fulfillment, final state unchanged
- Refund, then a test disputePost-payment eventsOrder, accounting and customer emails updated
Stripe's go-live checklist adds incomplete, invalid and duplicate data, and suggests having someone who isn't a developer test the checkout.10Stripe Docs, Go-live checklist
Going live
- Swap keysLive keys in, test keys out; rotate any key that left the codebase
- Live webhooksRegister the live endpoint; check it handles delays, duplicates and any order
- Recreate objectsProducts and plans from the sandbox don't exist in live mode
- First live paymentsSmall real orders, refunded, then reconcile the payout
These points come from Stripe's go-live checklist, which also asks you to pin your API version, review error handling and check that your logs hold no card details or personal data you don't need.10Stripe Docs, Go-live checklist The same list applies to any gateway.
Platform plugins: Shopify, WooCommerce and headless
On a hosted store platform, most of the work above is done by the platform or the plugin.
Shopify
You activate or change a provider from the Payments page of the admin. Direct providers keep the customer on your store; external providers redirect to their own checkout. Shopify charges third-party transaction fees on payments through other gateways, even when Shopify Payments is activated.
WooCommerce
Each gateway is an extension: Stripe, PayPal and most others have one. Several can run at once and the customer picks at checkout. You keep the plugin updated, and the webhook settings it asks for.
Headless
Your front end calls the gateway's client library and your own server. You get the full step-by-step above, with no plugin to lean on.
The Shopify points come from Shopify's help center.14Shopify Help Center, Third-party payment providers A plugin doesn't remove PCI: your SAQ still depends on whether the plugin redirects or embeds, and whether your theme loads scripts on the payment page.
Multiple payment gateway integration
Merchants add a second gateway for four reasons: a backup when the first one is down, routing by country, currency or card type, payment methods the first gateway doesn't offer, and not depending on one provider's risk review. Each brings the same three problems.
| Approach | How it works | Strength | Limit |
|---|---|---|---|
| Direct integration with each gateway | One integration per provider, your own routing code | Full control | You maintain every API, webhook format and status list |
| Platform with several methods | One provider that offers many payment methods, sometimes several acquirers | One integration | Routing and failover limited to what that provider offers |
| Store platform | Several gateways enabled side by side | NoCode | The customer picks, there's no automatic routing or failover |
| Orchestration layer | One integration to a layer that connects the processors | Routing, failover and one report | Another provider in the chain; check who holds the card vault |
The three problems to solve
1. One routing decision. Something must decide which gateway takes each payment, and what happens when it fails. A technical failure can go to the next gateway. An issuer decline is different: card networks limit what you may retry and how often. The rules are in our guide to dynamic payment routing.
2. One vocabulary. Each gateway has its own statuses, decline codes and webhook formats. Map them to one internal list of payment states before anything reaches fulfillment, support or accounting.
3. Saved cards. This is the hard part. A token created at one processor can only be charged there. A subscription saved at Stripe can't renew at Adyen with the same token.
Fig. 2Who holds the card decides where it can be charged
Stays in the processor's vaultOnly that processor can charge it
- Forwarded by the vaultStripe Vault and Forward sends card details to supported endpoints, access through Stripe support
- Exported on requestStripe can export card data to another PCI DSS compliant processor
Held by a neutral vaultAn orchestration layer stores the card and charges any connected processor
the vault is the real lock-in
Stripe's Vault and Forward keeps cards in Stripe's vault and sends them to supported endpoints, including Adyen, Braintree, Checkout.com and Worldpay.16Stripe Docs, Forward card details to third-party API endpoints (Vault and Forward) Stripe also documents card data exports to another processor, on request.17Stripe Docs, Request a payment data export Plan this before the first subscription, not after. The layer around these choices is explained in what payment orchestration is.
Common payment gateway integration mistakes
- Order marked paid from the success pageMissed orders when the customer closes the tab; fake confirmations if the URL is guessedFulfill from a verified webhook
- Webhook handler that isn't idempotentDuplicate shipments, emails or subscription startsStore event IDs, make fulfillment safe to run twice
- Amount taken from the browserCustomers can change the priceRead the amount from your database on the server
- Card data in logs or your databaseYour PCI scope grows to every system that holds itKeep tokens and last four digits only, mask logs
- No 3D Secure step for European customersIssuers decline payments that needed authenticationUse the provider's 3DS flow and handle the pending state
- Extra scripts on the payment pageScript attack risk, and SAQ A at stake with an iframeInventory scripts, remove tags from checkout pages
- Secret key in the front end or the repositoryAnyone can create refunds or read paymentsRotate the key, keep it server-side only
Stripe adds one more for any page that loads outside JavaScript: each third-party script makes your security depend on that site's, so keep them to a minimum on payment pages.5Stripe Docs, Integration security guide
Integrating several processors with Tagada
How Tagada helps
One checkout, TagadaPay, Stripe, NMI and Airwallex behind it
Tagada runs the checkout and connects the processors behind it, standalone or with Shopify, WooCommerce or a headless store. It routes payments across TagadaPay and processors such as Stripe, NMI and Airwallex, with one logic, and cascades to another processor when one is down or times out. Its card vault lets you switch processors without re-onboarding customers, so running subscriptions keep charging. 3D Secure 2 is native, with device intelligence and a rules engine. TagadaPay still underwrites each business. Details on the payments page and the pricing page.
Whatever tool you pick, the checklist stays the same: an integration type you can defend at PCI time, server-side amounts, idempotent webhooks, 3D Secure where it's required, and a plan for saved cards before you add the second gateway.
Frequently asked questions
What is payment gateway integration?
Can I integrate multiple payment gateways on one website?
Which PCI SAQ applies to my payment gateway integration?
Do I still qualify for SAQ A with an embedded iframe?
What is the difference between payment gateway integration and implementation?
Do I need webhooks if my gateway returns a response right away?
Sources
Checked October 14, 2026- PCI Security Standards Council blog, Important updates announced for merchants validating to SAQ A, January 30, 2025
- PCI Security Standards Council blog, FAQ clarifies new SAQ A eligibility criteria for e-commerce merchants, February 28, 2025
- PCI Security Standards Council, FAQ: If all elements of payment pages originate from a PCI DSS compliant service provider, is the merchant eligible for SAQ A or SAQ A-EP?
- PCI Security Standards Council, Self-Assessment Questionnaire A-EP for PCI DSS v4.0
- Stripe Docs, Integration security guide
- Stripe Docs, Receive Stripe events in your webhook endpoint
- Stripe API reference, Idempotent requests
- Stripe Docs, Fulfill orders (Checkout)
- Stripe Docs, Testing
- Stripe Docs, Go-live checklist
- Adyen Docs, Handle webhook events
- Adyen Docs, Build your integration
- Authorize.net Developer Center, Accept.js
- Shopify Help Center, Third-party payment providers
- Commission Delegated Regulation (EU) 2018/389, RTS on strong customer authentication
- Stripe Docs, Forward card details to third-party API endpoints (Vault and Forward)
- Stripe Docs, Request a payment data export
TagadaPay
One checkout, several processors behind it
Tell us what you sell and how you sell it. Each application is underwritten, and approval is not guaranteed.
- 01Tell us what you sell and how
- 02Underwriting reviews your business
- 03Process through TagadaPay alongside your other processors
