LabHub

Blog

Payment APIs & Developer Fintech 2026 — Stripe / Adyen / Toss Payments / PortOne / Square / Mollie / Lago Deep Dive

한국어English日本語

"Payments is not a solution, it is infrastructure. Infrastructure changes once every nine years." — Patrick Collison, Stripe Co-founder, Sessions 2024 keynote

As of May 2026, the payment API ecosystem has solidified into four camps rather than a single global standard: Global (Stripe) + Regional leaders (Adyen, Toss Payments, Razorpay, GMO PG) + Billing-only (Lago, Orb, Metronome) + Builder tooling (Bolt, Tier). A SaaS that wants to serve the United States, Korea, and Japan at the same time has to run at least three payment gateways, and once consumption pricing enters the picture a billing engine joins as a separate layer.

This post covers the positioning, API surface, pricing, limits, and "who should pick what" for 18 payment products in one place — useful for Korean developers going global, Japanese developers entering Korea, and B2B SaaS teams adopting usage-based pricing. Real code patterns included throughout.

1. The 2026 Payment API Map — Stripe / Regional / Billing / Builder

Payments is no longer "swipe a card once." A modern payment product spans:

LayerRoleRepresentative products
Acquirer / PSPDirect connection to card networks and banks, transaction processingStripe, Adyen, Worldpay, Fiserv
AggregatorBundles multiple PSPs behind one APIToss Payments, PortOne, Razorpay, KOMOJU
OrchestrationRouting, retries, failover across PSPsSpreedly, Primer, Gr4vy
Billing / InvoicingSubscriptions, metering, invoice generationStripe Billing, Lago, Orb, Metronome, Maxio
Tax / ComplianceTax calculation and filing, KYCStripe Tax, Avalara, TaxJar, Sovos
Identity / KYCIdentity verification, business onboardingStripe Identity, Persona, Onfido, Sumsub
IssuingCard and account issuanceStripe Issuing, Marqeta, Adyen Issuing

The 2026 market sits in four camps:

The first decision point is always "which market are you targeting?" A global English-speaking SaaS picks Stripe almost automatically. If more than 30% of revenue is Korea, you must add Toss Payments or PortOne. Japan needs its own dedicated gateway.

2. Stripe — Atlas + Tax + Identity + Issuing Expansion

Stripe started in 2010 with a famous "seven lines of code" payment API. By 2026 it has grown into a platform that handles much more than payments — it runs significant parts of company operations. The 2024 IPO rumors fizzled out (Stripe stayed private), and the 2025 valuation recovered to roughly $95B.

Core product lineup:

Basic payment flow with the PaymentIntents API (2026 standard):

import Stripe from 'stripe'

const stripe = new Stripe(process.env.STRIPE_SECRET_KEY!, {
  apiVersion: '2026-01-15',
})

// 1) Create a PaymentIntent on the server
const intent = await stripe.paymentIntents.create({
  amount: 1999,           // $19.99 in cents
  currency: 'usd',
  automatic_payment_methods: { enabled: true },  // Cards + wallets shown automatically
  metadata: { order_id: 'ord_abc123' },
})

// 2) Client mounts the payment UI with client_secret
//    <Elements options={ clientSecret: intent.client_secret }>
//      <PaymentElement />
//    </Elements>

// 3) Handle webhooks after payment completes
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 === 'payment_intent.succeeded') {
    await fulfillOrder(event.data.object)
  }
  return new Response('ok')
}

Three notable 2026 changes:

  1. Stripe Tax adds Korea and Japan — As of November 2025, Korean VAT auto-filing and Japanese consumption-tax calculation are supported. Global SaaS can handle East-Asian taxes without external accountants.
  2. Stripe Issuing officially launches in EU and UK — You can now build Brex/Ramp-style expense management startups in Europe.
  3. Agent Commerce Protocol (ACP) beta — A new auth flow for AI agents transacting on a user's behalf, co-designed with Anthropic and OpenAI.

Stripe's weaknesses: Korean domestic cards are poorly supported (workaround via PayPal or run Toss alongside), Japan lacks PayPay and LINE Pay support, and pricing is expensive (Adyen is often cheaper at enterprise scale).

3. Adyen — The European Enterprise Standard

Adyen, founded in 2006 in the Netherlands, is Stripe's strongest enterprise competitor globally. Uber, Spotify, McDonald's, eBay, Microsoft, and Booking.com all process payments through Adyen.

What makes Adyen different:

The API is RESTful but has a steeper learning curve than Stripe. The standard flow is paymentMethods.jsonpayments.jsonpayments/details.json. All requests are JSON, all responses carry a pspReference transaction ID.

// Adyen Checkout API basic flow
import { Client, CheckoutAPI } from '@adyen/api-library'

const client = new Client({ apiKey: process.env.ADYEN_API_KEY!, environment: 'TEST' })
const checkout = new CheckoutAPI(client)

// 1) List available payment methods
const methods = await checkout.PaymentsApi.paymentMethods({
  merchantAccount: 'YourMerchantAccount',
  amount: { value: 1999, currency: 'USD' },
  countryCode: 'US',
  shopperLocale: 'en-US',
})

// 2) Submit a payment
const result = await checkout.PaymentsApi.payments({
  merchantAccount: 'YourMerchantAccount',
  amount: { value: 1999, currency: 'USD' },
  reference: 'order-abc-123',
  paymentMethod: { type: 'scheme', encryptedCardNumber: '...' },
  returnUrl: 'https://your-site.com/checkout/result',
})

// 3) Handle 3DS if challenged
if (result.resultCode === 'IdentifyShopper') {
  // Client performs the 3DS challenge
}

Adyen makes sense when you have more than 10,000 transactions per month, operate in multiple countries simultaneously, and need offline-online integration. For low volume or fast self-service signup, Stripe is the better choice by a wide margin.

4. Toss Payments — Korea's Standard

Toss Payments was created when Toss (Viva Republica) acquired LG U+'s payment business in 2020. By 2026 it is the default choice for Korean SaaS and e-commerce — over 80% of new Korean startups evaluate Toss Payments first.

Strengths:

Basic payment flow with the Toss Payments JavaScript SDK:

// Client side
import { loadTossPayments } from '@tosspayments/payment-sdk'

const tossPayments = await loadTossPayments(
  'live_ck_xxx' // client key
)

await tossPayments.requestPayment('Card', {
  amount: 50000,
  orderId: 'order_abc_123',
  orderName: 'Premium subscription 1 month',
  customerName: 'Hong Gildong',
  successUrl: 'https://example.com/success',
  failUrl: 'https://example.com/fail',
})

// Server side — confirm payment at successUrl
const response = await fetch('https://api.tosspayments.com/v1/payments/confirm', {
  method: 'POST',
  headers: {
    Authorization: `Basic ${btoa(process.env.TOSS_SECRET_KEY + ':')}`,
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    paymentKey,
    orderId,
    amount: 50000,
  }),
})

Webhook signature verification has been mandatory since 2024 — verify the TossPayments-Signature header with your signing_key via HMAC-SHA256. For idempotency, send an Idempotency-Key header on every payment confirmation request.

Toss Payments weaknesses: it supports global card-issued payments but FX conversion and settlement require extra steps, so a global-leaning revenue mix will still need Stripe alongside it. Certain industries (adult, gambling, parts of fintech) face strict merchant onboarding.

5. PortOne (formerly Iamport) — Korea's Aggregator

PortOne (rebranded from Iamport in 2024) is the payment aggregator that wraps every Korean PSP behind a single SDK. One integration gives you Toss, KCP, Inicis, Danal, KakaoPay, Naver Pay, PayCo, SmilePay, credit cards, virtual accounts, mobile carrier billing, and even global payments (Stripe and PayPal pass-through).

Reasons to use PortOne:

// PortOne V2 SDK example
import * as PortOne from '@portone/browser-sdk/v2'

const response = await PortOne.requestPayment({
  storeId: 'store-xxx',
  channelKey: 'channel-xxx',  // channel determines the PSP (Toss/KCP/Inicis/etc.)
  paymentId: `payment-${crypto.randomUUID()}`,
  orderName: 'Premium subscription',
  totalAmount: 50000,
  currency: 'CURRENCY_KRW',
  payMethod: 'CARD',
})

// Verify on the server
const verification = await fetch(
  `https://api.portone.io/payments/${response.paymentId}`,
  { headers: { Authorization: `PortOne ${process.env.PORTONE_API_SECRET}` } }
)

PortOne's biggest value is multi-PSP negotiation leverage. As volume grows you can negotiate a lower fee at PSP A and route part of the traffic there. Conversely, if you only ever need one PSP, the PortOne layer is just overhead cost.

In 2026 PortOne added integrations with Japan's KOMOJU and Indonesia's Xendit, making it a default for Korean SaaS expanding across Southeast Asia.

6. KCP / Inicis / Danal — Korean Classic PSPs

The three giants of the Korean payment market before Toss took the lead:

API surfaces still reflect early-2010s design — key issuance, encryption, and callback URL setup are involved. JSP/PHP examples remain canonical, and modern TypeScript SDKs are scarce.

# Conceptual flow for Inicis result-callback verification
# The merchant shares P_MID, P_OID, P_AMT, P_TID with KCP and HMAC-verifies with a shared key
# Almost every Korean legacy PSP carries EUC-KR encoding legacy — be careful when converting to UTF-8

Working directly with KCP / Inicis / Danal:

In 2026 all three are mid-renewal of their RESTful APIs, but the migration is slow — aggregators like PortOne retain a lot of value.

7. Square + Cash App — The Block Ecosystem

Square started in 2009 as Jack Dorsey's mobile card reader. After rebranding the parent to Block in 2021, it became an integrated payments + P2P (Cash App) + Bitcoin fintech group.

Square (B2B payments):

Cash App (P2P + B2C):

// Square Payments API example
import { Client, Environment } from 'square'

const client = new Client({
  accessToken: process.env.SQUARE_ACCESS_TOKEN,
  environment: Environment.Production,
})

const response = await client.paymentsApi.createPayment({
  sourceId: 'cnon:card-nonce-from-web-sdk',
  idempotencyKey: crypto.randomUUID(),
  amountMoney: { amount: 1999n, currency: 'USD' },
  locationId: 'L1234567890',
})

Square is strong for businesses with physical locations, while Stripe is strong for software companies. They rarely compete head-on, and using both (Square in-store, Stripe on the web) is common.

8. Mollie / Checkout.com / Braintree — Europe + PayPal Family

Mollie (Netherlands, founded 2004):

Checkout.com (UK, founded 2012):

Braintree (PayPal subsidiary, founded 2007, acquired in 2013):

// Mollie Payments example — the cleanest European API
import { createMollieClient } from '@mollie/api-client'

const mollie = createMollieClient({ apiKey: process.env.MOLLIE_API_KEY! })

const payment = await mollie.payments.create({
  amount: { currency: 'EUR', value: '19.99' },
  description: 'Premium subscription',
  redirectUrl: 'https://example.com/return',
  webhookUrl: 'https://example.com/webhook',
  metadata: { orderId: 'order-abc-123' },
})

// Redirect the user to payment.getCheckoutUrl()

Where they sit: Mollie for European SMB, Checkout.com for European/Middle Eastern enterprise, Braintree for the US PayPal-friendly market. Korean teams rarely use any of them as primary; usually they appear as one of several enabled global options.

9. Razorpay — India's Payment Standard

Razorpay was founded in 2014 by IIT alumni — call it India's Stripe. By 2026 it holds roughly 40% of India's payment market.

What stands out:

import Razorpay from 'razorpay'

const razorpay = new Razorpay({
  key_id: process.env.RAZORPAY_KEY_ID!,
  key_secret: process.env.RAZORPAY_KEY_SECRET!,
})

// Create order
const order = await razorpay.orders.create({
  amount: 50000,   // 500 INR in paise
  currency: 'INR',
  receipt: 'order_rcptid_11',
})

// Client invokes Razorpay Checkout
// After payment, verify razorpay_payment_id, razorpay_signature

A Korean SaaS expanding into India cannot capture UPI with Stripe alone — Razorpay integration is essentially mandatory because over 70% of Indian payments flow through UPI.

10. Japan — GMO Payment Gateway / PAY.JP / KOMOJU / PayPay / LINE Pay

Japan has a completely different payment ecosystem from Korea.

GMO Payment Gateway:

PAY.JP:

KOMOJU:

PayPay:

LINE Pay:

// KOMOJU API — the cleanest path for foreign SaaS accepting Japanese payments
import KomojuApi from 'komoju-node'

const komoju = new KomojuApi({
  secretKey: process.env.KOMOJU_SECRET_KEY!,
})

const session = await komoju.sessions.create({
  amount: 1980,           // 1,980 JPY
  currency: 'JPY',
  email: 'customer@example.jp',
  return_url: 'https://example.com/return',
  payment_types: ['credit_card', 'konbini', 'paypay', 'linepay'],
})

// Redirect user to session.session_url

Recommended Korean → Japan combo: KOMOJU (small ticket, foreigner-friendly) + GMO PG (high volume) in parallel. Japanese cards are increasingly enforcing 3DS, so 3DS2 SDK integration is becoming progressively more important.

11. Billing — Stripe Billing vs Lago vs OpenMeter vs Orb vs Metronome

For SaaS, billing (subscriptions + usage) is a domain separate from payments. The 2026 billing market has consolidated around six products.

ProductOperating modelStrengthsWeaknesses
Stripe BillingSaaS, Stripe-lockedTight payment integration, subscription standardWeak for complex usage metering
LagoOpen source + CloudSelf-hostable, free to startNewer, some features still maturing
OpenMeterOpen source, CNCFUsage metering specialist, Kafka-basedSeparate tool needed for billing itself
OrbSaaSStrong on complex usage models, AI-company favoriteExpensive
MetronomeSaaSUsed by OpenAI, Anthropic, DatabricksEnterprise only
Maxio (formerly Chargify + SaaSOptics)SaaSB2B-focused, strong MRR/ARR reportingWeaker on modern usage models

Stripe Billing — basic subscription model:

// 1) Create a Price (once)
const price = await stripe.prices.create({
  product: 'prod_premium',
  unit_amount: 1999,
  currency: 'usd',
  recurring: { interval: 'month' },
})

// 2) Create a subscription
const subscription = await stripe.subscriptions.create({
  customer: 'cus_xxx',
  items: [{ price: price.id }],
  payment_behavior: 'default_incomplete',
  expand: ['latest_invoice.payment_intent'],
})

// 3) Usage-based pricing — redesigned as Meter Events in 2025
await stripe.billing.meterEvents.create({
  event_name: 'api_request',
  payload: { stripe_customer_id: 'cus_xxx', value: '1' },
})

Lago's appeal (open source):

# Self-host with a single Docker Compose file
# https://github.com/getlago/lago
services:
  api:
    image: getlago/api:v1.x
    environment:
      DATABASE_URL: postgres://...
      REDIS_URL: redis://...

Lago delegates payment processing to Stripe / Adyen and only handles usage metering, invoice generation, and subscription management. That makes PSP swaps painless and is ideal for EU and Korean companies that need data sovereignty via self-hosting.

Where Orb and Metronome sit:

12. Consumption Pricing — Tier / Stripe Billing

The single biggest shift in SaaS pricing from 2023 to 2026 is the move from seat-based subscription to consumption-based. OpenAI (tokens), Snowflake (compute), Vercel (build minutes), and Cloudflare (requests) standardized the model, and by 2026 it has become the default for nearly all infrastructure SaaS.

Implementation challenges for consumption pricing:

  1. Accurate metering: aggregate tens of thousands of events per second without loss
  2. Deferred invoicing: aggregating a month of events at bill time loads the billing system
  3. Budget alerts: protect users from surprise bills with 80% and 100% notifications
  4. Mixing prepaid credits and postpaid billing: the canonical OpenAI model
  5. Multi-unit invoices: API calls + storage GB + egress GB on one bill

Tier (open source) lets you add consumption pricing with a single SDK call.

// Tier SDK example (conceptual)
import { Tier } from 'tier'
const tier = new Tier()

// Report usage
await tier.report('org:acme', 'feature:api-calls', 100)

// Pricing model is declared in YAML
// plans:
//   premium:
//     features:
//       api-calls:
//         tiers:
//           - upto: 10000
//             price: 0
//           - upto: 100000
//             price: 0.001
//           - upto: inf
//             price: 0.0005

Stripe Billing's Meter Events (launched in 2025) solves the same problem inside Stripe.

// Fire a meter event on each API call
await stripe.billing.meterEvents.create({
  event_name: 'api_calls',
  payload: {
    stripe_customer_id: 'cus_xxx',
    value: '1',
  },
})

// Stripe aggregates automatically and generates the end-of-month invoice

The key insight for consumption pricing is that your event-collection infrastructure should be decoupled from your billing system. The pattern that has become standard: write events first to an analytics store (OpenMeter, Tinybird, ClickHouse), then let billing (Stripe/Lago/Orb) read from there.

13. Security — Webhook Verification / Idempotency Keys / SCA / 3DS2

80% of payment integration work is "the basic transaction flow." The other 20% is security and reliability — but that 20% causes 99% of incidents.

Webhook signature verification (Stripe example):

import { headers } from 'next/headers'

export async function POST(req: Request) {
  const sig = (await headers()).get('stripe-signature')!
  const body = await req.text()       // raw body, before JSON.parse
  let event
  try {
    event = stripe.webhooks.constructEvent(
      body,
      sig,
      process.env.STRIPE_WEBHOOK_SECRET!
    )
  } catch (err) {
    return new Response('Invalid signature', { status: 400 })
  }
  // event is now verified; proceed
}

The stripe-signature header has the format t=timestamp,v1=signature, and the Stripe SDK automatically verifies:

  1. Timestamp is within 5 minutes (replay-attack protection)
  2. HMAC-SHA256(body, secret) matches the signature
  3. Comparison uses timing-safe compare

Idempotency-Key:

Guarantees the same result if the same request is sent twice. Supported by Stripe, Square, Razorpay, and Toss Payments.

const intent = await stripe.paymentIntents.create(
  { amount: 1999, currency: 'usd' },
  { idempotencyKey: `order-${orderId}-${attempt}` }
)

Key points: idempotency keys are valid for 24 hours, and sending a different payload with the same key throws an error. The standard pattern is: generate a UUID once and reuse it across retries.

SCA (Strong Customer Authentication):

EU PSD2 requirement, mandatory since 2021. Nearly every EU transaction needs two of:

In practice 3DS2 (3D Secure 2.x) is the standard implementation. The card network scores transaction risk: some are frictionless (auto-pass), some require an OTP or biometric challenge.

// Creating a PaymentIntent triggers the SCA flow automatically
const intent = await stripe.paymentIntents.create({
  amount: 1999,
  currency: 'eur',
  payment_method_types: ['card'],
  // automatic_payment_methods handles SCA automatically
})

// The PaymentElement on the client renders the 3DS challenge modal

Korea uses identity verification (phone/PKI) instead of SCA for some transactions; Toss Payments and PortOne handle it in a one-line SDK call. Japan started phased 3DS2 mandates in 2025 (large merchants first).

14. Who Should Pick What — Global / Korea / Japan / B2B SaaS / Marketplaces

Finally, scenario-based recommendations.

ScenarioFirst choiceSecondary / supplementaryBilling
Global SaaS (English-speaking)StripeAdyen (enterprise)Stripe Billing
Korea-focused SaaSToss Payments or PortOneStripe (international cards)Stripe Billing or Lago
Korea + Japan dual launchPortOne (Korea) + KOMOJU (Japan)Stripe (West)Lago (decoupled)
Japan-focusedGMO PG + KOMOJUStripe (West)Stripe Billing
India entryRazorpayStripe (international cards)Stripe Billing
European SMBMollieStripeStripe Billing
European enterpriseAdyenCheckout.comStripe Billing or Orb
AI usage billingStripe (payments)Metronome or Orb
Open source / self-host requiredStripe + LagoLago
Offline store + onlineSquare (US) / AdyenStripe (web only)Stripe Billing
Marketplace (Uber, Etsy style)Stripe ConnectAdyen for PlatformsStripe Billing
B2B invoice-heavyStripe BillingMaxioMaxio
One-click checkout focusBolt + StripePayPal + BraintreeStripe Billing

Decision heuristics:

  1. First question: Where does more than 50% of revenue come from? That country's standard PSP is your first choice.
  2. Second question: Is usage-based billing core to the business? If yes, separate billing from PSP (Lago/Orb).
  3. Third question: Volume under 10,000 transactions/month? If yes, start with self-service Stripe / Toss.
  4. Fourth question: International expansion within 12 months? If yes, design Stripe in parallel from day one.

Most common mistakes:

Payments are infrastructure, and infrastructure is expensive to migrate after a wrong choice (1–3% of revenue is typical). Picking the right scenario row above gets you halfway to success. The other half is treating webhooks, idempotency, and 3DS2 correctly from the start.

15. References

Comments

No comments yet.

Sign in to leave a comment