Skip to main content

Funnel Navigation

tagada.funnel.navigate() takes the cart from the loaded checkout session, bootstraps an anonymous CMS session, and returns a redirect URL into a specific funnel step. It’s the JS equivalent of the WooCommerce / Shopify checkout plugins — one call from your own site, one URL to redirect to.
When to use it:
  • The cart lives in your store (Shopify, WooCommerce, PrestaShop, custom) and you want to route the shopper into a TagadaPay marketing funnel.
  • You want the shopper to enter at a specific funnel step (step_xxx) rather than the funnel default.
When NOT to use it:
  • You’re building a fully self-hosted checkout page — use Checkout Flow directly.
  • You only need a one-shot Tagada-hosted checkout link without a funnel — use tagada.checkout.createSession() and follow its checkoutUrl.

Prerequisites

accountId is required on createHeadlessClient()funnel.navigate() will throw TagadaError('missing_account_id') without it. A checkout session must be loaded first (tagada.checkout.loadSession(...)). The SDK sources the cart, currency, customer email, and promotion code from that session.
React provider: TagadaHeadlessProvider only forwards accountId through the full config prop, not the individual named props. Pass config={{ storeId, accountId, environment }} if you need funnel navigation in React.

Quick Start

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

const tagada = createHeadlessClient({
  storeId: 'store_abc123',
  accountId: 'acc_abc123',
  environment: 'production',
});

// 1. Load (or create) a checkout session — populates the cart.
await tagada.checkout.loadSession(checkoutToken, sessionToken);

// 2. Get a redirect URL into the funnel.
const { url } = await tagada.funnel.navigate({
  funnelId: 'fnlv2_abc123',
  stepId:   'step_abc123',
  returnUrl: 'https://merchant.com/thank-you',
});

// 3. Send the shopper there.
window.location.assign(url);

What Happens Under the Hood

navigate() runs the same sequence the WooCommerce plugin does, with caching so repeat calls in the same page are cheap:
  1. POST /api/v1/cms/session/anonymous — creates an anonymous CMS session, returns a token.
  2. POST /api/v1/cms/session/v2/init — initializes the CMS session and binds a CMS customer id.
  3. POST /api/v1/funnel/initialize — creates the funnel session for funnelId + stepId.
  4. POST /api/v1/funnel/navigate — fires an INIT_CHECKOUT event with the cart and returns { url }.
The CMS token, session id, and customer id are cached on the module instance. Calling navigate() again in the same page skips steps 1–3.
FieldTypeRequiredNotes
funnelIdstringyesFunnel to enter (e.g. fnlv2_xxx).
stepIdstringyesFunnel step to land on. Used for both entryStepId and funnelStepId.
returnUrlstringnoWhere the funnel should send the shopper back to after checkout.
customer{ email?, currency?, locale? }noOverrides. Defaults to session.customer.email / session.currency.
discountCodesstring[]noDefaults to [session.promotionCode] if a promo is applied, otherwise none.
metadataRecord<string, unknown>noArbitrary metadata forwarded to the funnel-navigate event.
currentUrlstringnoPage URL recorded by the funnel. Defaults to globalThis.location?.href in browsers.
accountIdstringnoPer-call override. Falls back to HeadlessConfig.accountId.

Return Value

{
  url: string;             // Redirect destination.
  funnelSessionId: string; // From /funnel/initialize, useful for logging/debugging.
}
The SDK does not perform the redirect — call window.location.assign(url), router.push(url), or whatever your framework uses.

Errors

funnel.navigate() throws typed TagadaErrors:
  • no_cart_loadedsdk.checkout.loadSession(...) was not called first. The SDK has no cart to send.
  • missing_account_idaccountId was not provided on createHeadlessClient() and not passed per call.
Network and validation failures throw the standard TagadaNetworkError / TagadaValidationError.

SSR & Non-Browser Environments

The SDK reads globalThis.location?.href for currentUrl when running in a browser. In SSR / Node contexts, pass currentUrl explicitly:
await sdk.funnel.navigate({
  funnelId,
  stepId,
  currentUrl: 'https://merchant.com/products/foo',
  returnUrl: 'https://merchant.com/thank-you',
});
Because navigate() returns { url } rather than redirecting, it composes cleanly with SPA routers (react-router, next/router) and server-side handoffs.
Funnel navigation vs. checkout.createSessionUrl(): Use funnel.navigate() to enter a marketing funnel (pre-checkout steps, upsell sequencing). Use checkout.createSessionUrl() when you just need a self-hosted checkout URL with no funnel logic in front of it.