Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.tagada.io/llms.txt

Use this file to discover all available pages before exploring further.

Payment Setup

The payment module is the core of the Headless SDK. It lets you discover which payment methods are configured for a store, tokenize cards, and process payments with automatic 3DS, redirect, and polling handling.

Discover Available Payment Methods

Every store has a payment setup config — a map of payment methods (card, Apple Pay, Google Pay, Klarna, etc.) with their enabled/disabled state, processor IDs, and flow IDs.
const setup = await tagada.payment.getPaymentSetup(checkoutSessionId);

// Example response:
// {
//   "card": { enabled: true, method: "card", paymentFlowId: "pf_xxx" },
//   "apple_pay:stripe": { enabled: true, method: "apple_pay", express: true, processorId: "proc_xxx" },
//   "google_pay:stripe": { enabled: true, method: "google_pay", express: true },
//   "klarna:stripe": { enabled: true, method: "klarna", processorId: "proc_stripe" },
// }

Just the enabled method keys

const methods = await tagada.payment.getEnabledMethods(checkoutSessionId);
// ["card", "apple_pay:stripe", "google_pay:stripe"]

Express methods with browser availability

const express = await tagada.payment.getExpressMethods(checkoutSessionId);
// {
//   applePay: { available: true, processorId: "proc_xxx" },
//   googlePay: { available: true },
//   klarna: { available: true, processorId: "proc_stripe" },
// }
The SDK automatically checks ApplePaySession.canMakePayments() in the browser to determine Apple Pay availability.

Card Payment Flow

processPayment() is the high-level orchestrator that handles the entire payment lifecycle automatically:
  1. Submits payment to the processor
  2. If 3DS / bank auth is required → redirects the user and resumes on return
  3. If the payment is async → polls until a terminal status
  4. Returns a typed ProcessPaymentResult
// 1. Tokenize
const { tagadaToken } = await tagada.payment.tokenizeCard({
  cardNumber: '4242424242424242',
  expiryDate: '12/28',
  cvc: '123',
  cardholderName: 'Jane Doe',
});

// 2. Process payment (3DS, redirects, polling all handled)
const result = await tagada.payment.processPayment({
  checkoutSessionId: session.id,
  tagadaToken,
});

// 3. Handle result
switch (result.status) {
  case 'succeeded':
    console.log('Payment confirmed!', result.order);
    break;
  case 'requires_redirect':
    // In React, usePayment() handles this automatically.
    // In vanilla JS, redirect manually:
    window.location.href = result.redirectUrl;
    break;
  case 'failed':
    console.error('Payment failed:', result.error);
    break;
  case 'pending':
    console.log('Still processing...', result.paymentId);
    break;
}
tokenizeCard() requires @tagadapay/core-js as an optional peer dependency. Install it: npm install @tagadapay/core-js.

Return type: ProcessPaymentResult

The return value is a discriminated union — check result.status for exhaustive handling:
StatusFieldsMeaning
succeededpayment, orderPayment confirmed. Show success screen.
requires_redirectredirectUrl, method?, postData?, paymentIdUser must visit a URL (3DS, bank auth, APM).
failederror, payment?Payment declined or errored.
pendingpaymentIdStill processing (rare — polling timed out).

3DS Return URL

After a 3DS redirect, the bank sends the user back to your page with query parameters. The SDK auto-detects these and resumes the payment:
  • React (usePayment): Handled automatically on mount — detects ?paymentAction=... params, polls for result, fires callbacks.
  • Vanilla JS: Call tagada.payment.resumeAfterRedirect(paymentId) manually after detecting the return.
// Vanilla JS — on page load, check for return from 3DS
const params = new URLSearchParams(window.location.search);
const paymentId = params.get('paymentId');
if (params.get('paymentAction') === 'requireAction' && paymentId) {
  const result = await tagada.payment.resumeAfterRedirect(paymentId);
  // result is a ProcessPaymentResult
}

Express Checkout

Apple Pay

const result = await tagada.payment.processApplePay({
  checkoutSessionId: session.id,
  applePayToken: applePayEvent.payment.token,
});

Google Pay

const result = await tagada.payment.processGooglePay({
  checkoutSessionId: session.id,
  googlePayToken: paymentData.paymentMethodData.tokenizationData.token,
});

Redirect APMs (Klarna, iDEAL, etc.)

const result = await tagada.payment.processApm({
  checkoutSessionId: session.id,
  paymentMethod: 'klarna',
  processorId: 'proc_stripe',
});

if (result.payment.requireAction === 'redirect') {
  window.location.href = result.payment.requireActionData.redirectUrl;
}

React Hook

import { usePayment } from '@tagadapay/headless-sdk/react';

function PaymentForm({ sessionId }) {
  const {
    processPayment,
    tokenizeCard,
    isProcessing,
    paymentSetup,
    loadPaymentSetup,
  } = usePayment({
    onPaymentSuccess: (result) => {
      router.push(`/thank-you?orderId=${result.order?.id}`);
    },
    onPaymentFailed: (result) => {
      setError(result.error);
    },
  });

  const handleSubmit = async () => {
    const { tagadaToken } = await tokenizeCard({ cardNumber, expiryDate, cvc });
    await processPayment({ checkoutSessionId: sessionId, tagadaToken });
    // 3DS redirects + return detection + polling all handled automatically
  };

  return (
    <button onClick={handleSubmit} disabled={isProcessing}>
      {isProcessing ? 'Processing...' : 'Pay Now'}
    </button>
  );
}

Full Hook API

Property / MethodDescription
processPayment(opts)High-level: tokenize → pay → 3DS → poll → callbacks. Recommended.
pay(opts)Low-level: submit payment, returns raw PayResult. No auto-redirect.
tokenizeCard(card)Tokenize card via @tagadapay/core-js
isProcessingTrue during payment processing
paymentSetupCached payment method config
loadPaymentSetup(sessionId)Fetch available payment methods
getExpressMethods(sessionId)Check Apple Pay / Google Pay availability
onPaymentSuccessCallback when payment succeeds (including after 3DS return)
onPaymentFailedCallback when payment fails or is declined

Low-Level API

For advanced use cases, you can create instruments and process payments separately:
// Create a reusable payment instrument
const { paymentInstrument } = await tagada.payment.createInstrument({
  tagadaToken,
  storeId: 'store_xxx',
  customerData: { email: 'jane@example.com' },
});

// Create 3DS session
const threeds = await tagada.payment.create3dsSession({
  paymentInstrumentId: paymentInstrument.id,
  sessionData: { sessionId: 'bt_session_xyz' },
});

// Process with instrument directly
const result = await tagada.payment.payDirect({
  checkoutSessionId: session.id,
  paymentInstrumentId: paymentInstrument.id,
  threedsSessionId: threeds.id,
});
Need even more control? For instrument-level management, MIT (merchant-initiated) charges, auth+capture flows, or mobile app integrations, see the Low-Level Payments guide which uses @tagadapay/core-js + REST directly.