> ## 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.

# Merchant Quick Start

> Go from zero to a live checkout in 7 Node.js SDK calls

# Merchant Quick Start

**Time**: \~5 minutes | **Difficulty**: Beginner

This guide walks you through the minimal steps to set up a complete, working checkout using the **TagadaPay Node.js SDK** (`@tagadapay/node-sdk`). Every step has been tested end-to-end on a live environment.

***

## Overview

```
1. Create processor    → Connect a payment gateway
2. Create payment flow → Define routing strategy
3. Create store        → Your merchant storefront
4. Create product      → What you're selling
5. Create funnel       → Checkout + Thank You pages
6. Activate funnel     → Routes are mounted, checkout is live
7. Create session      → Generate a checkout link for your customer
```

<Info>
  **Native checkout is automatic.** When you create a funnel with `checkout` and `thankyou` steps, TagadaPay injects its built-in checkout UI automatically. No plugin deployment needed.
</Info>

***

## Prerequisites

| Requirement           | How to get it                                             |
| --------------------- | --------------------------------------------------------- |
| **Node.js 18+**       | [nodejs.org](https://nodejs.org)                          |
| **TagadaPay account** | Sign up at [app.tagadapay.com](https://app.tagadapay.com) |
| **API key**           | Dashboard → Settings → API Keys → Generate                |

```bash theme={null}
npm install @tagadapay/node-sdk
```

```ts theme={null}
import Tagada from '@tagadapay/node-sdk';
const tagada = new Tagada('your-api-key');
```

***

## Step 1: Create a Processor

A processor is your connection to a payment gateway (Stripe, NMI, Adyen, etc.). For testing, use the `sandbox` type.

```ts theme={null}
const { processor } = await tagada.processors.create({
  processor: {
    name: 'Stripe US',
    type: 'stripe',
    enabled: true,
    supportedCurrencies: ['USD', 'EUR'],
    baseCurrency: 'USD',
    options: {
      secretKey: 'sk_live_...',
      publicKey: 'pk_live_...',
      webhookSecret: 'whsec_...',
    },
  },
});
```

<Tip>
  For testing without real credentials, use `type: 'sandbox'` with `options: { testMode: true }`. See the [Sandbox Testing Guide](/developer-tools/node-sdk/sandbox-testing) for details.

  Each processor type requires different credentials. See the [Processor Credentials Reference](/developer-tools/node-sdk/processor-credentials) for the exact `options` fields for Stripe, NMI, Checkout.com, Airwallex, and all other gateways.
</Tip>

***

## Step 2: Create a Payment Flow

A payment flow defines how transactions are routed through your processors. A simple flow sends all traffic to one processor.

```ts theme={null}
const flow = await tagada.paymentFlows.create({
  data: {
    name: 'Default Flow',
    strategy: 'simple',
    fallbackMode: false,
    maxFallbackRetries: 0,
    threeDsEnabled: false,
    stickyProcessorEnabled: false,
    pickProcessorStrategy: 'weighted',
    processorConfigs: [
      { processorId: processor.id, weight: 100, disabled: false, nonStickable: false },
    ],
    fallbackProcessorConfigs: [],
    abuseDetectionConfig: null,
  },
});
```

<Info>
  For production, consider using `strategy: 'cascade'` with multiple processors and fallback configs. See [Multi-Stripe Routing](/developer-tools/node-sdk/multi-stripe-routing) for advanced setups.
</Info>

***

## Step 3: Create a Store

The store represents your merchant storefront. Pass `selectedPaymentFlowId` to assign the payment flow at creation.

```ts theme={null}
const store = await tagada.stores.create({
  name: 'My Store',
  baseCurrency: 'USD',
  presentmentCurrencies: ['USD', 'EUR'],
  chargeCurrencies: ['USD'],
  selectedPaymentFlowId: flow.id,
});
```

***

## Step 4: Create a Product

Products define what you're selling, with multi-currency pricing and optional recurring billing.

```ts theme={null}
const product = await tagada.products.create({
  storeId: store.id,
  name: 'Premium Plan',
  active: true,
  variants: [{
    name: 'Monthly',
    sku: 'premium-monthly',
    grams: 0,
    price: 2999,
    compareAtPrice: 0,
    active: true,
    default: true,
    prices: [{
      currencyOptions: {
        USD: { amount: 2999 },
        EUR: { amount: 2599 },
      },
      recurring: false,
      billingTiming: 'in_advance',
      default: true,
    }],
  }],
});

const variantId = product.variants[0].id;
console.log('Product:', product.id, '| Variant:', variantId);
```

<Tip>
  For subscriptions, set `recurring: true`, `interval: 'month'`, and `intervalCount: 1`. See [Subscriptions Guide](/developer-tools/node-sdk/subscriptions).
</Tip>

***

## Step 5: Create a Funnel

A **funnel** is the sequence of pages your customer goes through. Think of it like a slideshow:

```
Page 1: Checkout (customer pays) → Page 2: Thank You (order confirmed)
```

You just tell TagadaPay what pages you want — it gives you a live URL.

```ts theme={null}
const funnel = await tagada.funnels.create({
  storeId: store.id,
  config: {
    id: 'my-checkout',
    name: 'My Checkout',
    version: '1.0.0',
    nodes: [
      {
        id: 'step_checkout',
        name: 'Checkout',
        type: 'checkout',       // ← tells TagadaPay this is a payment page
        kind: 'step',
        isEntry: true,          // ← this is the first page
        position: { x: 0, y: 0 },
        config: { path: '/checkout' },
      },
      {
        id: 'step_thankyou',
        name: 'Thank You',
        type: 'thankyou',       // ← tells TagadaPay this is the confirmation page
        kind: 'step',
        position: { x: 300, y: 0 },
        config: { path: '/thankyou' },
      },
    ],
    edges: [
      { id: 'e1', source: 'step_checkout', target: 'step_thankyou' },
    ],
  },
  isDefault: true,
});
```

<Info>
  **You don't need to build a checkout page.** TagadaPay automatically injects its built-in checkout UI (the "native checkout") into `checkout` and `thankyou` steps. It always uses the latest version — no plugin deployment, no configuration needed.

  Want your own custom pages instead? See the [Funnel Pages](/developer-tools/node-sdk/custom-checkout) guide.
</Info>

***

## Step 6: Activate the Funnel

Creating a funnel saves it to the database, but it's not live yet. Calling `update` triggers the **routing engine** — this is the step that actually mounts your pages to a URL on TagadaPay's CDN.

```ts theme={null}
const result = await tagada.funnels.update(funnel.id, {
  storeId: store.id,
  config: funnel.config,
});

const checkoutNode = result.funnel.config.nodes
  .find(n => n.id === 'step_checkout');

console.log('Checkout live at:', checkoutNode.config.url);
```

After this call, your checkout has a real URL that customers can visit.

<Warning>
  **Don't skip this step.** Without `update`, the funnel exists in the database but has no routes — the checkout URL won't work. Think of `create` as saving a draft and `update` as publishing it.
</Warning>

***

## Step 7: Create a Checkout Session

The funnel is live, but to send a customer to checkout you need a **checkout session**. This ties a specific cart (product + quantity + currency) to a unique session token.

Use `tagada.checkout.createSession()` — it creates a session and returns the redirect URL with a checkout token:

```ts theme={null}
const funnelCheckoutUrl = result.funnel.config.nodes
  .find(n => n.id === 'step_checkout').config.url;

const session = await tagada.checkout.createSession({
  storeId: store.id,
  items: [{ variantId, quantity: 1 }],
  currency: 'USD',
  checkoutUrl: funnelCheckoutUrl,
});

console.log('Checkout token:', session.checkoutToken);
console.log('Checkout link:', session.redirectUrl);
```

<Tip>
  The `variantId` is returned by `products.create()` in step 4. If you need it later, you can also retrieve the product with `tagada.products.retrieve(productId)`.
</Tip>

The returned `redirectUrl` can be used as:

* A **direct link** in emails, ads, or landing pages — the customer clicks it and lands on checkout with their cart pre-filled
* A **redirect target** from your backend — embed it in a button or `<a>` tag

<Info>
  The `checkoutUrl` parameter is **critical** — it tells TagadaPay where to redirect the customer. Without it, the session redirects to the default CMS checkout instead of your funnel's deployed page.
</Info>

***

## Complete Script

Here's the full flow in one script:

```ts theme={null}
import Tagada from '@tagadapay/node-sdk';
const tagada = new Tagada('your-api-key');

// 1. Processor
const { processor } = await tagada.processors.create({
  processor: {
    name: 'Sandbox', type: 'sandbox', enabled: true,
    supportedCurrencies: ['USD'], baseCurrency: 'USD',
    options: { testMode: true },
  },
});

// 2. Payment flow
const flow = await tagada.paymentFlows.create({
  data: {
    name: 'Default', strategy: 'simple',
    fallbackMode: false, maxFallbackRetries: 0,
    threeDsEnabled: false, stickyProcessorEnabled: false,
    pickProcessorStrategy: 'weighted',
    processorConfigs: [{ processorId: processor.id, weight: 100, disabled: false, nonStickable: false }],
    fallbackProcessorConfigs: [], abuseDetectionConfig: null,
  },
});

// 3. Store
const store = await tagada.stores.create({
  name: 'My Store', baseCurrency: 'USD',
  presentmentCurrencies: ['USD', 'EUR'], chargeCurrencies: ['USD'],
  selectedPaymentFlowId: flow.id,
});

// 4. Product
const product = await tagada.products.create({
  storeId: store.id, name: 'Premium Plan', active: true,
  variants: [{
    name: 'Monthly', sku: 'premium-monthly', grams: 0,
    price: 2999, compareAtPrice: 0, active: true, default: true,
    prices: [{ currencyOptions: { USD: { amount: 2999 } }, recurring: false, billingTiming: 'in_advance', default: true }],
  }],
});
const variantId = product.variants[0].id;

// 5. Funnel
const funnel = await tagada.funnels.create({
  storeId: store.id,
  config: {
    id: 'my-checkout', name: 'My Checkout', version: '1.0.0',
    nodes: [
      { id: 'step_checkout', name: 'Checkout', type: 'checkout', kind: 'step', isEntry: true, position: { x: 0, y: 0 }, config: { path: '/checkout' } },
      { id: 'step_thankyou', name: 'Thank You', type: 'thankyou', kind: 'step', position: { x: 300, y: 0 }, config: { path: '/thankyou' } },
    ],
    edges: [{ id: 'e1', source: 'step_checkout', target: 'step_thankyou' }],
  },
  isDefault: true,
});

// 6. Activate
const result = await tagada.funnels.update(funnel.id, {
  storeId: store.id, config: funnel.config,
});

const funnelCheckoutUrl = result.funnel.config.nodes
  .find(n => n.id === 'step_checkout').config.url;
console.log('Funnel live at:', funnelCheckoutUrl);

// 7. Checkout session — generate a link customers can open
const session = await tagada.checkout.createSession({
  storeId: store.id,
  items: [{ variantId, quantity: 1 }],
  currency: 'USD',
  checkoutUrl: funnelCheckoutUrl,
});

console.log('Checkout link:', session.redirectUrl);
```

***

## What Happens Under the Hood

| Step                       | What it does                                                                         | Side effects                      |
| -------------------------- | ------------------------------------------------------------------------------------ | --------------------------------- |
| `processors.create()`      | Stores gateway credentials                                                           | None                              |
| `paymentFlows.create()`    | Defines routing rules                                                                | None                              |
| `stores.create()`          | Creates store, assigns flow                                                          | Seeds translations, order counter |
| `products.create()`        | Creates product + variants + prices                                                  | None                              |
| `funnels.create()`         | Saves funnel config, auto-injects native checkout                                    | Creates plugin instance if needed |
| `funnels.update()`         | **Triggers routing engine** — mounts pages, creates CDN routes, builds prebuilt HTML | Pages go live                     |
| `checkout.createSession()` | Creates a checkout session with cart items, returns redirect URL                     | Creates customer, session         |

***

## Next Steps

<CardGroup cols={2}>
  <Card title="Sandbox Testing" icon="flask-vial" href="/developer-tools/node-sdk/sandbox-testing">
    Test payments without real money using the sandbox processor
  </Card>

  <Card title="Multi-PSP Routing" icon="route" href="/developer-tools/node-sdk/multi-stripe-routing">
    Cascade across Stripe, Adyen, NMI with weighted distribution
  </Card>

  <Card title="Subscriptions" icon="repeat" href="/developer-tools/node-sdk/subscriptions">
    Set up recurring billing with subscription products
  </Card>

  <Card title="Funnel Pages" icon="paintbrush" href="/developer-tools/node-sdk/custom-checkout">
    Page types, custom pages, and deploy your own checkout, landing, or offer pages
  </Card>
</CardGroup>
