The safest and fastest way to add payment integration to your website is to use a payment provider’s ready infrastructure (such as iyzico or Stripe) instead of processing payments on your own server. These providers handle card data inside their own PCI-DSS certified systems; you simply send a request with your API keys and listen for the result via webhook. For Turkey, iyzico is the most common option, Stripe is best for international sales, and bank virtual POS suits high-volume businesses. Getting this right is a frequently requested part of our custom software development services.
Which Payment Provider Should You Choose?
The right provider depends on your target market, transaction volume and technical resources. Let’s compare the three main options:
- iyzico / PayTR: Focused on the Turkish market, fully compatible with Turkish Lira and local cards, with strong installment support. Quick to integrate, documentation in Turkish.
- Stripe: The most mature infrastructure for international sales and subscription models. 135+ currencies; however, setting up a legal entity in Turkey requires extra steps.
- Bank Virtual POS (Garanti, İş Bankası, Akbank): The lowest commission rate, advantageous at high volume; but integration is more complex and requires separate development per bank.
Commission rates per transaction typically range between 1.5% and 3.5%. At low volume the provider commission is negligible; at high monthly turnover, even a 0.5-point difference adds up to a significant annual amount.
Security: PCI-DSS and Card Data
The most critical rule in online payments is that card data must never touch your own server. Modern providers solve this with "hosted checkout" or "tokenization": the user enters their card details into the provider’s iframe or page, and you only receive a single-use token. This keeps your PCI-DSS obligations at the lowest level and shifts data-breach risk to the provider. We cover the personal-data side in our GDPR-compliant website guide.
- Never store the card number, CVC or expiry date in your own database
- Carry all payment traffic over HTTPS (TLS)
- Keep API keys in environment variables (env), never embed them on the client side
- Enforce 3D Secure on every transaction to reduce chargeback risk
How Does the Technical Flow Work?
The core of payment integration is three steps: create a checkout session on the server, redirect the user to the provider’s secure payment screen, and verify the result via webhook. The Stripe example below shows how to create a checkout session on the server side:
// app/api/checkout/route.ts (Next.js — server side)
import Stripe from 'stripe';
const stripe = new Stripe(process.env.STRIPE_SECRET_KEY!);
export async function POST(req: Request) {
const { priceId } = await req.json();
const session = await stripe.checkout.sessions.create({
mode: 'payment',
line_items: [{ price: priceId, quantity: 1 }],
success_url: `${process.env.SITE_URL}/payment/success?session_id={CHECKOUT_SESSION_ID}`,
cancel_url: `${process.env.SITE_URL}/payment/cancel`,
});
// Redirect the user to Stripe's secure payment screen
return Response.json({ url: session.url });
}When the payment completes, the provider sends a webhook request to your server. Mark the order as "paid" only after this webhook is verified — never trust the client-side "success" page, because it can be manipulated.
// Webhook: verify the payment on the server (source: the real event)
export async function POST(req: Request) {
const sig = req.headers.get('stripe-signature')!;
const body = await req.text();
const event = stripe.webhooks.constructEvent(
body, sig, process.env.STRIPE_WEBHOOK_SECRET!
);
if (event.type === 'checkout.session.completed') {
const session = event.data.object;
await markOrderAsPaid(session.id); // confirm the order here
}
return new Response(null, { status: 200 });
}One-Time Payment or Subscription?
Your business model determines the shape of the integration. While a one-time payment is enough for e-commerce, SaaS and membership models need recurring subscription infrastructure: automatic renewals, failed-payment retries, cancellation and refund flows. The subscription side is markedly more complex than one-time payments and must be set up correctly from the start. If you’re building an e-commerce platform, our article on how to set up an e-commerce site offers a holistic roadmap.
How Long Does Integration Take?
- Ready provider (iyzico/Stripe) one-time payment: typically 3-5 business days
- Subscription + billing management: 1-2 weeks
- Bank virtual POS (including 3D Secure): 2-4 weeks depending on the bank approval process
Conclusion
Adding payment integration to a website is a predictable process when you pick the right provider and follow the security rules: leave card data to the provider, verify the result via webhook, and build a one-time or subscription flow based on your business model. If you’re unsure which provider fits your project, explore our web development services or request a quote directly.