Skip to main content

SaaS Billing with TagadaPay

Time: ~20 minutes | Difficulty: Intermediate Bill subscriptions from your own SaaS app — not a storefront, not a funnel. You keep your UI; TagadaPay handles vaulting, routing, and recurring charges across any processor or TPA.
This guide is for SaaS builders migrating from Stripe Billing or building subscription billing from scratch. For e-commerce storefronts, see Build a Store with AI.

Why TagadaPay for SaaS (vs Stripe)

StripeTagadaPay
Locked to Stripe as processorProcessor-agnostic — Stripe, Adyen, Checkout.com, NMI, your own TPA
One PaymentMethod per Stripe accountOne vault — card tokenized once, routed to any processor
Switching processor = re-collect cardsPayment flows — switch TPAs/processors without touching customer cards
stripe.subscriptions.createtagada.subscriptions.create — same mental model
The killer feature: payment flows. Connect as many TPAs and processors as you want. If one TPA is banned, add a fallback in the flow — cards stay vaulted, rebills keep working.
Your SaaS checkout

  Card tokenized (core-js) — once

  ┌──── Payment Flow ────┐
  │  sandbox  (dev)      │
  │  → tagadapay-router  │  ← live TPA (tpa_xxx)
  │  → Stripe (optional) │
  │  → Checkout.com      │
  └──────────────────────┘

  Subscription rebills — automatic, same vault

Architecture: frontend vs backend

Package: @tagadapay/core-js
  • Tokenize the card → tagadaToken
  • Handle 3DS if the charge asks for it (requireAction: 'redirect' → send the customer to the processor’s hosted page; standalone 3DS sessions are only for gateway-style processors like NMI — see Quick Start)
  • Never put your CRM API key in the browser
import { useCardTokenization } from '@tagadapay/core-js/react';

const { tokenizeCard } = useCardTokenization({ environment: 'production' });
const { tagadaToken } = await tokenizeCard({
  cardNumber: '4242424242424242',
  expiryDate: '12/30',
  cvc: '123',
  cardholderName: 'Alex Founder',
});

// Send tagadaToken to YOUR backend — not to TagadaPay directly
await fetch('/api/payment-instruments', {
  method: 'POST',
  body: JSON.stringify({ tagadaToken, storeId, customerData }),
});

Working example

Everything in this guide was tested against production. Clone and run:
git clone https://github.com/TagadaPay/examples.git
cd examples/mini-saas-billing   # or examples/mini-saas-billing in the monorepo
cp env.example .env             # add TAGADA_API_KEY + TAGADA_STORE_ID
npm install
npm run seed                    # product + cascade payment flow
npm run verify                  # automated end-to-end test
npm run dev                     # frontend :5173 + backend :3001
Open http://localhost:5173, click Subscribe, and watch the flow log.

Next steps

Quick Start

Step-by-step: product → checkout → subscription in 15 minutes

Payment Flows

Multi-TPA routing, cascade, failover — the Stripe killer

Migrate from Stripe

Object mapping and cutover playbook

Subscriptions API

Rebilling, trials, cancel, processor migration