Payment Gateway Integration: The Complete Developer Guide (2026)
Everything developers need to know about payment gateway integration in 2026 — Stripe, Adyen, Braintree, subscription billing, webhooks, and production-ready implementation.

Payment Gateway Integration: The Complete Developer Guide (2026)
Payment gateway integration is one of those areas where the basics look deceptively simple but production-grade implementation has dozens of edge cases. This is a practical guide covering everything from choosing the right gateway to handling failed payments, refunds, and reconciliation.
Choosing the Right Payment Gateway
| Gateway | Best For | Processing Fee | Notes |
|---|---|---|---|
| Stripe | Startups, SaaS, global | 2.9% + $0.30 | Best developer experience, most features |
| Adyen | Enterprise, marketplace | Interchange++ | Lower cost at scale, complex setup |
| Braintree (PayPal) | Marketplaces, PayPal users | 2.59% + $0.49 | Good if PayPal is required |
| Square | In-person + online | 2.6% + $0.10 | Strong POS integration |
| Razorpay | India | 2% | Best for India market |
For most new applications: start with Stripe. The developer experience, documentation, test mode, and webhook tooling are best in class.
Core Integration: Charge a Customer
// Stripe server-side: Create payment intent
import Stripe from 'stripe'
const stripe = new Stripe(process.env.STRIPE_SECRET_KEY!, {
apiVersion: '2024-04-10',
})
export async function createPaymentIntent(
amountCents: number,
currency: string,
customerId?: string,
metadata?: Record<string, string>
) {
const paymentIntent = await stripe.paymentIntents.create({
amount: amountCents, // Always in minor units (cents)
currency: currency.toLowerCase(),
customer: customerId,
automatic_payment_methods: { enabled: true },
metadata: metadata ?? {},
})
return {
clientSecret: paymentIntent.client_secret,
paymentIntentId: paymentIntent.id,
}
}
// Frontend: Confirm payment using Stripe.js
const { error, paymentIntent } = await stripe.confirmPayment({
elements,
confirmParams: {
return_url: 'https://yourapp.com/payment/complete',
},
})
💳 Fintech That Passes Compliance — Not Just Demos
Payment integrations, KYC/AML flows, trading APIs, and regulatory compliance — we build fintech that survives real audits, not just product demos.
- PCI DSS, PSD2, FCA, GDPR-aware architecture
- Stripe, Plaid, Rapyd, OpenBanking integrations
- Real-time transaction monitoring and fraud flags
- UK/EU/US compliance requirements mapped from day one
Subscription Billing Implementation
Subscription billing with trials, upgrades, downgrades, and proration is the most complex part of payment integration. Stripe Billing handles most of this.
// Create a subscription with 14-day trial
export async function createSubscription(
customerId: string,
priceId: string,
trialDays: number = 14
) {
const subscription = await stripe.subscriptions.create({
customer: customerId,
items: [{ price: priceId }],
trial_period_days: trialDays,
payment_settings: {
save_default_payment_method: 'on_subscription',
},
expand: ['latest_invoice.payment_intent'],
})
return subscription
}
// Handle plan upgrade (prorate immediately)
export async function upgradePlan(
subscriptionId: string,
currentItemId: string,
newPriceId: string
) {
return stripe.subscriptions.update(subscriptionId, {
items: [{ id: currentItemId, price: newPriceId }],
proration_behavior: 'create_prorations', // Charge difference immediately
billing_cycle_anchor: 'unchanged',
})
}
Webhook Handling (Critical)
Webhooks are how Stripe notifies you of asynchronous events: payment succeeded, subscription renewed, invoice failed. Handle them wrong and your database gets out of sync with Stripe.
// Webhook endpoint — verify signature first
import { NextRequest, NextResponse } from 'next/server'
import Stripe from 'stripe'
export async function POST(req: NextRequest) {
const body = await req.text()
const sig = req.headers.get('stripe-signature')!
let event: Stripe.Event
try {
event = stripe.webhooks.constructEvent(
body,
sig,
process.env.STRIPE_WEBHOOK_SECRET!
)
} catch (err) {
return NextResponse.json({ error: 'Invalid signature' }, { status: 400 })
}
// Idempotency: check if we already processed this event
const processed = await db.webhookEvents.findUnique({ where: { eventId: event.id } })
if (processed) return NextResponse.json({ received: true })
switch (event.type) {
case 'payment_intent.succeeded':
await handlePaymentSuccess(event.data.object as Stripe.PaymentIntent)
break
case 'customer.subscription.deleted':
await handleSubscriptionCancelled(event.data.object as Stripe.Subscription)
break
case 'invoice.payment_failed':
await handlePaymentFailed(event.data.object as Stripe.Invoice)
break
}
// Mark as processed (idempotency)
await db.webhookEvents.create({ data: { eventId: event.id, type: event.type } })
return NextResponse.json({ received: true })
}
🏦 Trading Systems, Payment Rails, and Financial APIs
From algorithmic trading platforms to neobank backends — Viprasol has built the full spectrum of fintech. Senior engineers, no junior handoffs, verified track record.
- MT4/MT5 EA development for prop firms and hedge funds
- Custom payment gateway and wallet systems
- Regulatory reporting automation (MiFID, EMIR)
- Free fintech architecture consultation
Failed Payment Handling and Dunning
Subscription payments fail 5-15% of the time. Without a dunning strategy, you lose revenue silently.
Stripe Smart Retries — Stripe automatically retries failed payments at optimal times using ML. Enable in dashboard.
Custom dunning flow:
- Day 0: Payment fails → send "payment failed" email
- Day 3: Smart retry + reminder email
- Day 7: Final retry + urgent notice
- Day 10: Subscription paused, access restricted
- Day 30: Subscription cancelled, send win-back offer
Refund and Dispute Handling
// Process refund
export async function refundPayment(
paymentIntentId: string,
amountCents?: number, // Partial refund if specified
reason?: 'duplicate' | 'fraudulent' | 'requested_by_customer'
) {
return stripe.refunds.create({
payment_intent: paymentIntentId,
amount: amountCents, // Omit for full refund
reason,
})
}
For disputes (chargebacks): respond within 7 days with evidence. Maintain records of: delivery confirmation, customer communication, terms acceptance, and fraud checks performed.
Need payment integration built correctly the first time? Viprasol implements production-grade payment systems. Contact us.
See also: Fintech App Development Guide · SaaS Development Services
About the Author
Viprasol Tech Team
Custom Software Development Specialists
The Viprasol Tech team specialises in algorithmic trading software, AI agent systems, and SaaS development. With 100+ projects delivered across MT4/MT5 EAs, fintech platforms, and production AI systems, the team brings deep technical experience to every engagement. Based in India, serving clients globally.
Building Fintech Solutions?
Payment integrations, trading systems, compliance — we build fintech that passes audits.
Free consultation • No commitment • Response within 24 hours
Building fintech or trading infrastructure?
Viprasol delivers custom trading software — MT4/MT5 EAs, TradingView indicators, backtesting frameworks, and real-time execution systems. Trusted by traders and prop firms worldwide.