Funnel Pages
A funnel is a sequence of pages (steps). Each page has atype that determines its capabilities — whether it can accept payments, show upsells, fire conversion events, etc.
Page Types
Every node in a funnel has atype. Here are all the available types and what they unlock:
| Type | Purpose | Payment Form | Order Bumps | Upsell Offers | Can be Entry | Conversion |
|---|---|---|---|---|---|---|
checkout | Payment page | Yes | Yes | — | Yes | — |
thankyou | Order confirmation | — | — | — | — | Yes |
offer | Upsell / downsell / cross-sell | Optional | — | Yes | — | — |
landing | Landing page / hero with CTA | — | — | — | Yes | — |
custom | Any custom page | Optional | Optional | Optional | Yes | — |
error | Error state page | — | — | — | — | — |
external | Redirect to external URL | — | — | — | Yes | — |
storefront_shopify | Shopify product page | — | — | — | Yes | — |
storefront_woocommerce | WooCommerce product page | — | — | — | Yes | — |
Why types matter
The steptype controls what stepConfig options are available:
checkoutsteps can havepaymentSetupConfig(card, Apple Pay, Google Pay routing),orderBumps, andpaymentconfigoffersteps can haveupsellOffersfor post-purchase offersthankyousteps are marked as the conversion endpoint — analytics events likePurchasefire herelandingandcustomsteps are general-purpose — they have pixels and scripts but no payment-specific config
// Checkout step — full payment config
{
id: 'step_checkout',
type: 'checkout',
config: {
stepConfig: {
paymentSetupConfig: { card: { enabled: true, paymentFlowId: 'flow_xxx' } },
orderBumps: { mode: 'custom', enabledOfferIds: ['offer_1'] },
pixels: { facebook: [...] },
},
},
}
// Offer step — upsell config
{
id: 'step_upsell',
type: 'offer',
config: {
stepConfig: {
upsellOffers: [{ offerId: 'offer_2', type: 'one_click' }],
pixels: { facebook: [...] },
},
},
}
// Landing step — pixels and scripts only
{
id: 'step_landing',
type: 'landing',
isEntry: true,
config: {
stepConfig: {
pixels: { facebook: [...] },
scripts: [{ name: 'Hotjar', content: '...', position: 'head-end', enabled: true }],
},
},
}
Common funnel patterns
Landing → Checkout → Thank You (simple)
Landing → Checkout → Offer → Thank You (with upsell)
Storefront (Shopify) → Checkout → Thank You (Shopify integration)
Checkout → Offer (EU) / Offer (US) → Thank You (geo-conditional)
Landing → Checkout → Offer → Offer → Thank You (multi-offer)
You can combine any types in any order. The only requirement is that a funnel with payments needs at least one
checkout step, and a complete flow should end with a thankyou step for conversion tracking.Three Approaches
TagadaPay offers three ways to create funnel pages, depending on how much control you need:| Native Checkout | Custom HTML | Plugin SDK | |
|---|---|---|---|
| Setup | Zero code — auto-injected | Deploy raw HTML/CSS/JS | Build a React or JS app |
| Page types | checkout + thankyou only | Any type | Any type |
| Control | TagadaPay handles the UI | Full control, no framework | Full control + SDK hooks |
| Best for | Getting live fast | Quick prototypes, simple pages | Production-grade branded experiences |
| Payments | Automatic | You wire up tokenization | SDK handles tokenization, 3DS, payments |
| Funnels | Automatic navigation | Manual routing | SDK handles step navigation |
| Deployment | 2 steps | 4 steps (inline deploy via API) | CLI: tgd deploy from your repo |
| A/B testing | No | Via API split config | Via API or CLI |
- Native Checkout
- Custom HTML
- Plugin SDK (Recommended for Production)
Native Checkout (Recommended)
When you create a funnel withcheckout and thankyou step types, TagadaPay automatically injects its built-in checkout UI. No plugin deployment, no HTML — just define the flow.Create and activate
import Tagada from '@tagadapay/node-sdk';
const tagada = new Tagada('your-api-key');
// Create funnel — native checkout is auto-injected
const funnel = await tagada.funnels.create({
storeId: 'store_...',
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,
});
// Activate — triggers routing, mounts pages to CDN
const result = await tagada.funnels.update(funnel.id, {
storeId: 'store_...',
config: funnel.config,
});
const funnelCheckoutUrl = result.funnel.config.nodes
.find(n => n.id === 'step_checkout').config.url;
console.log('Funnel live at:', funnelCheckoutUrl);
// Generate a checkout link with a pre-loaded cart
const session = await tagada.checkout.createSession({
storeId: 'store_...',
items: [{ variantId: 'variant_...', quantity: 1 }],
currency: 'USD',
checkoutUrl: funnelCheckoutUrl,
});
console.log('Checkout link:', session.redirectUrl);
No
pluginId or instanceId needed. TagadaPay detects that checkout and thankyou nodes have no plugin assigned and injects the native checkout automatically.The checkoutUrl parameter in createSession is critical — it tells TagadaPay to redirect customers to your funnel’s deployed page instead of the default CMS URL.What you get
The native checkout includes:- Card payment form with real-time validation
- Order summary with product details and pricing
- Multi-currency support based on your store config
- Mobile-responsive layout
- Built-in thank you page with order confirmation
Custom HTML Checkout
Deploy your own checkout and thank you pages as raw HTML. You have full control over the design, layout, and behavior.Step 1: Define your pages
Checkout page — a styled payment form:<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Checkout</title>
<style>
* { box-sizing: border-box; margin: 0; padding: 0; }
body { font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif; background: #f5f5f7; color: #1d1d1f; }
.container { max-width: 480px; margin: 40px auto; padding: 0 20px; }
.card { background: #fff; border-radius: 12px; padding: 32px; box-shadow: 0 2px 12px rgba(0,0,0,0.08); }
h1 { font-size: 22px; font-weight: 600; margin-bottom: 24px; }
.field { margin-bottom: 16px; }
.field label { display: block; font-size: 13px; font-weight: 500; color: #6e6e73; margin-bottom: 6px; }
.field input { width: 100%; padding: 12px; border: 1px solid #d2d2d7; border-radius: 8px; font-size: 15px; outline: none; transition: border-color 0.2s; }
.field input:focus { border-color: #0071e3; box-shadow: 0 0 0 3px rgba(0,113,227,0.1); }
.row { display: flex; gap: 12px; }
.row .field { flex: 1; }
.divider { height: 1px; background: #e5e5ea; margin: 24px 0; }
.summary { display: flex; justify-content: space-between; font-size: 15px; margin-bottom: 8px; }
.summary.total { font-weight: 600; font-size: 17px; margin-top: 12px; }
.btn { width: 100%; padding: 14px; background: #0071e3; color: #fff; border: none; border-radius: 10px; font-size: 16px; font-weight: 600; cursor: pointer; margin-top: 24px; transition: background 0.2s; }
.btn:hover { background: #0077ed; }
.secure { text-align: center; font-size: 12px; color: #86868b; margin-top: 16px; }
</style>
</head>
<body>
<div class="container">
<div class="card">
<h1>Checkout</h1>
<div class="field">
<label>Email</label>
<input type="email" placeholder="you@example.com">
</div>
<div class="field">
<label>Card number</label>
<input type="text" placeholder="4242 4242 4242 4242">
</div>
<div class="row">
<div class="field"><label>Expiry</label><input type="text" placeholder="MM / YY"></div>
<div class="field"><label>CVC</label><input type="text" placeholder="123"></div>
</div>
<div class="divider"></div>
<div class="summary"><span>Premium Plan</span><span>$29.99</span></div>
<div class="summary"><span>Tax</span><span>$0.00</span></div>
<div class="summary total"><span>Total</span><span>$29.99</span></div>
<button class="btn">Pay $29.99</button>
<p class="secure">Secured by TagadaPay</p>
</div>
</div>
</body>
</html>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Thank You</title>
<style>
* { box-sizing: border-box; margin: 0; padding: 0; }
body { font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif; background: #f5f5f7; color: #1d1d1f; }
.container { max-width: 480px; margin: 80px auto; padding: 0 20px; text-align: center; }
.card { background: #fff; border-radius: 12px; padding: 48px 32px; box-shadow: 0 2px 12px rgba(0,0,0,0.08); }
.checkmark { width: 64px; height: 64px; background: #34c759; border-radius: 50%; display: inline-flex; align-items: center; justify-content: center; margin-bottom: 24px; }
.checkmark svg { width: 32px; height: 32px; }
h1 { font-size: 24px; font-weight: 600; margin-bottom: 12px; }
p { font-size: 15px; color: #6e6e73; line-height: 1.5; }
.order-id { display: inline-block; background: #f5f5f7; padding: 8px 16px; border-radius: 8px; font-size: 14px; font-weight: 500; margin-top: 24px; color: #1d1d1f; }
</style>
</head>
<body>
<div class="container">
<div class="card">
<div class="checkmark">
<svg viewBox="0 0 24 24" fill="none" stroke="#fff" stroke-width="3"
stroke-linecap="round" stroke-linejoin="round">
<polyline points="20 6 9 17 4 12"/>
</svg>
</div>
<h1>Thank you!</h1>
<p>Your order has been confirmed.<br>You will receive a confirmation email shortly.</p>
<span class="order-id">Order #TGD-10042</span>
</div>
</div>
</body>
</html>
Step 2: Deploy as a plugin
Upload both pages as base64-encoded inline assets:import Tagada from '@tagadapay/node-sdk';
import { readFileSync } from 'fs';
const tagada = new Tagada('your-api-key');
// If loading from files:
// const checkoutHtml = readFileSync('checkout.html', 'utf-8');
// const thankyouHtml = readFileSync('thankyou.html', 'utf-8');
const deployment = await tagada.plugins.deploy({
storeId: 'store_...',
manifest: {
name: 'my-custom-checkout',
description: 'Custom branded checkout',
mode: 'spa-mode',
version: '1.0.0',
pages: [
{ id: 'checkout', path: '/checkout', name: 'Checkout', isDefault: true },
{ id: 'thankyou', path: '/thankyou', name: 'Thank You' },
],
},
inlineAssets: [
{ path: 'checkout/index.html', content: btoa(checkoutHtml), contentType: 'text/html' },
{ path: 'thankyou/index.html', content: btoa(thankyouHtml), contentType: 'text/html' },
],
autoInstantiate: {
stepType: 'checkout',
isPreview: false,
},
});
const { pluginId, deploymentId, instanceId } = deployment;
console.log('Deployed:', { pluginId, deploymentId, instanceId });
autoInstantiate creates a plugin instance automatically. Without it, you’d need a separate tagada.plugins.instantiate() call.Step 3: Create a funnel using your plugin
ReferencepluginId and instanceId in each funnel node:const funnel = await tagada.funnels.create({
storeId: 'store_...',
config: {
id: 'custom-checkout',
name: 'Custom Checkout',
version: '1.0.0',
nodes: [
{
id: 'step_checkout',
name: 'Checkout',
type: 'checkout',
kind: 'step',
isEntry: true,
position: { x: 0, y: 0 },
config: {
pluginId, instanceId,
instanceVersion: '1.0.0',
variant: 'Default',
path: '/checkout',
metadata: { internalPath: '/checkout', mountPoint: 'default' },
},
},
{
id: 'step_thankyou',
name: 'Thank You',
type: 'thankyou',
kind: 'step',
position: { x: 300, y: 0 },
config: {
pluginId, instanceId,
instanceVersion: '1.0.0',
variant: 'Default',
path: '/thankyou',
metadata: { internalPath: '/thankyou', mountPoint: 'default' },
},
},
],
edges: [
{ id: 'e1', source: 'step_checkout', target: 'step_thankyou' },
],
},
isDefault: true,
});
Step 4: Activate
const result = await tagada.funnels.update(funnel.id, {
storeId: 'store_...',
config: funnel.config,
});
const url = result.funnel.config.nodes[0].config.url;
console.log('Custom checkout live at:', url);
Plugin SDK Checkout
The Plugin SDK (@tagadapay/plugin-sdk) is the professional approach for teams with a codebase. You build a React (or vanilla JS) SPA that uses TagadaPay’s SDK hooks for session management, card tokenization, 3DS, payment processing, funnel navigation, and analytics — then deploy it from your repo with the CLI.This is different from Custom HTML. With raw HTML you handle everything yourself. With the Plugin SDK, you get React hooks (or a standalone JS API) that connect your UI to TagadaPay’s backend — sessions, checkout data, payments, redirects — out of the box.
What you get from the SDK
useCheckoutSession()— cart items, prices, customer datauseCardTokenization()— PCI-compliant card form, Apple Pay, Google PayusePaymentProcessors()— process payments through your PSP routinguseThreeds()— 3DS authentication with automatic challenge handlinguseFunnelNavigation()— step-to-step navigation with data passinguseFunnelData()— shared state across funnel steps- Full TypeScript types
Step 1: Scaffold your project
npm install -g @tagadapay/plugin-cli
tgd login
tgd init my-checkout --template react-checkout
cd my-checkout
my-checkout/
├── src/
│ ├── pages/
│ │ ├── checkout/ # Checkout page component
│ │ └── thankyou/ # Thank you page component
│ └── App.tsx
├── plugin.manifest.json # Plugin metadata + page definitions
├── package.json
└── vite.config.ts # Pre-configured build
Step 2: Build your checkout page
import {
useCheckoutSession,
useCardTokenization,
usePaymentProcessors,
useFunnelNavigation,
} from '@tagadapay/plugin-sdk/react';
export default function CheckoutPage() {
const { session, cart, totals } = useCheckoutSession();
const { tokenizeCard, CardForm } = useCardTokenization();
const { processPayment, isProcessing } = usePaymentProcessors();
const { navigateToNext } = useFunnelNavigation();
async function handlePay() {
const { tagadaToken } = await tokenizeCard();
const result = await processPayment({ tagadaToken });
if (result.status === 'succeeded') {
navigateToNext({ orderId: result.orderId });
}
}
return (
<div className="checkout">
<h1>Checkout</h1>
{/* Cart summary — pulled from session automatically */}
<div className="order-summary">
{cart.items.map(item => (
<div key={item.id}>
<span>{item.name}</span>
<span>{item.formattedPrice}</span>
</div>
))}
<div className="total">{totals.formattedTotal}</div>
</div>
{/* PCI-compliant card form — SDK handles tokenization */}
<CardForm />
<button onClick={handlePay} disabled={isProcessing}>
{isProcessing ? 'Processing...' : `Pay ${totals.formattedTotal}`}
</button>
</div>
);
}
Step 3: Build the thank you page
import { useFunnelData } from '@tagadapay/plugin-sdk/react';
export default function ThankYouPage() {
const { orderId } = useFunnelData();
return (
<div className="thankyou">
<h1>Thank you!</h1>
<p>Your order <strong>{orderId}</strong> has been confirmed.</p>
</div>
);
}
Step 4: Configure the manifest
{
"name": "my-branded-checkout",
"description": "Production checkout with React",
"version": "1.0.0",
"mode": "spa-mode",
"pages": [
{ "id": "checkout", "path": "/checkout", "name": "Checkout", "isDefault": true },
{ "id": "thankyou", "path": "/thankyou", "name": "Thank You" }
]
}
Step 5: Deploy
npm run build
tgd deploy --store store_xxx
✅ Deployed my-branded-checkout@1.0.0
Plugin: plugin_abc123
Instance: inst_xyz789
Checkout: https://my-branded-checkout--store_xxx.cdn.tagadapay.com/checkout
Thank You: https://my-branded-checkout--store_xxx.cdn.tagadapay.com/thankyou
Step 6: Create a funnel and activate
Use the returnedpluginId and instanceId from deployment:import Tagada from '@tagadapay/node-sdk';
const tagada = new Tagada('your-api-key');
const funnel = await tagada.funnels.create({
storeId: 'store_xxx',
config: {
id: 'branded-checkout',
name: 'Branded Checkout',
version: '1.0.0',
nodes: [
{
id: 'step_checkout',
name: 'Checkout',
type: 'checkout',
kind: 'step',
isEntry: true,
position: { x: 0, y: 0 },
config: {
pluginId: 'plugin_abc123',
instanceId: 'inst_xyz789',
instanceVersion: '1.0.0',
variant: 'Default',
path: '/checkout',
metadata: { internalPath: '/checkout', mountPoint: 'default' },
},
},
{
id: 'step_thankyou',
name: 'Thank You',
type: 'thankyou',
kind: 'step',
position: { x: 300, y: 0 },
config: {
pluginId: 'plugin_abc123',
instanceId: 'inst_xyz789',
instanceVersion: '1.0.0',
variant: 'Default',
path: '/thankyou',
metadata: { internalPath: '/thankyou', mountPoint: 'default' },
},
},
],
edges: [
{ id: 'e1', source: 'step_checkout', target: 'step_thankyou' },
],
},
isDefault: true,
});
const result = await tagada.funnels.update(funnel.id, {
storeId: 'store_xxx',
config: funnel.config,
});
console.log('Live at:', result.funnel.config.nodes[0].config.url);
Vanilla JS (no React)
The Plugin SDK also works without React:import { TagadaPlugin } from '@tagadapay/plugin-sdk';
const plugin = new TagadaPlugin();
await plugin.initialize();
const session = plugin.getCheckoutSession();
const tokenizer = plugin.getCardTokenizer();
document.getElementById('pay-btn').addEventListener('click', async () => {
const { tagadaToken } = await tokenizer.tokenize({
cardNumber: document.getElementById('card').value,
expiryDate: document.getElementById('expiry').value,
cvc: document.getElementById('cvc').value,
});
const result = await plugin.processPayment({ tagadaToken });
if (result.status === 'succeeded') {
plugin.navigateToNext({ orderId: result.orderId });
}
});
Updating a deployed plugin
Deploy a new version — zero downtime:# Bump version in plugin.manifest.json
tgd deploy --store store_xxx
For the full Plugin SDK reference, see the Plugin SDK documentation. For CLI commands and configuration, see the Plugin CLI Guide.
Updating a Live Plugin
To update your custom checkout without downtime, deploy a new version with the same plugin name:const updated = await tagada.plugins.deploy({
storeId: 'store_...',
manifest: {
name: 'my-custom-checkout',
version: '1.1.0',
mode: 'spa-mode',
pages: [
{ id: 'checkout', path: '/checkout', name: 'Checkout', isDefault: true },
{ id: 'thankyou', path: '/thankyou', name: 'Thank You' },
],
},
inlineAssets: [/* updated HTML/CSS/JS */],
autoInstantiate: { stepType: 'checkout', isPreview: false },
});
// Point the funnel to the new instance
const config = JSON.parse(JSON.stringify(funnel.config));
for (const node of config.nodes) {
node.config.instanceId = updated.instanceId;
node.config.instanceVersion = '1.1.0';
}
await tagada.funnels.update(funnel.id, {
storeId: 'store_...',
config,
});
A/B Testing
Split traffic between two checkout designs:const variantB = await tagada.plugins.deploy({
storeId: 'store_...',
manifest: {
name: 'checkout-variant-b',
version: '1.0.0',
mode: 'spa-mode',
pages: [
{ id: 'checkout', path: '/checkout', name: 'Checkout B', isDefault: true },
],
},
inlineAssets: [/* variant B HTML */],
autoInstantiate: { stepType: 'checkout', isPreview: false },
});
// Get routeId from the activated funnel
const checkoutNode = result.funnel.config.nodes
.find(n => n.id === 'step_checkout');
const routeId = checkoutNode.config.routeId;
// 50/50 split
await tagada.plugins.configureSplit({
routeId,
storeId: 'store_...',
splitConfig: {
type: 'weighted',
instances: [
{ instanceId: deployment.instanceId, deploymentId: deployment.deploymentId, weight: 50 },
{ instanceId: variantB.instanceId, deploymentId: variantB.deploymentId, weight: 50 },
],
stickyDuration: 3600,
},
});
Direct Mounting (Without Funnel)
For standalone pages (landing pages, portals) outside of a checkout flow:await tagada.plugins.mount({
deploymentId,
deploymentInstanceId: instanceId,
storeId: 'store_...',
alias: 'my-landing-page',
matcher: '.*',
force: true,
});
// → my-landing-page--store_xxx.cdn.tagadapay.com
Custom Domains
By default, pages are served on*.cdn.tagadapay.com. To use your own domain (e.g. checkout.yourstore.com), use tagada.domains.
Step 1 — Register the domain
const { domain } = await tagada.domains.add({
domain: 'checkout.yourstore.com',
});
console.log(domain.id); // cdm_abc123
console.log(domain.isVerified); // false
console.log(domain.verificationToken); // vrf_token_xyz
Step 2 — Configure DNS
Add a CNAME record at your registrar:| Type | Name | Value |
|---|---|---|
| CNAME | checkout | cname.vercel-dns.com |
Use
tagada.domains.getConfig() and tagada.domains.getDnsLookup() to check DNS propagation programmatically before verifying.const config = await tagada.domains.getConfig({
domain: 'checkout.yourstore.com',
});
console.log(config.misconfigured); // true (DNS not propagated yet)
console.log(config.recommendedCNAME); // cname.vercel-dns.com
const dns = await tagada.domains.getDnsLookup({
domain: 'checkout.yourstore.com',
recordType: 'CNAME',
});
console.log(dns.records); // ['cname.vercel-dns.com'] when ready
Step 3 — Verify
Once DNS has propagated:const result = await tagada.domains.verify({
domainId: domain.id,
});
console.log(result.status); // 'Valid Configuration'
console.log(result.ownershipStatus); // 'Verified'
status values: Valid Configuration, Invalid Configuration, Pending Verification, Domain Not Found, Error.
Step 4 — Mount on the custom domain
UsecustomDomain instead of hostname or alias when mounting:
await tagada.plugins.mount({
deploymentId,
deploymentInstanceId: instanceId,
storeId: 'store_...',
customDomain: 'checkout.yourstore.com',
basePath: '/',
matcher: '/',
});
// → https://checkout.yourstore.com/
Managing domains
const { domains } = await tagada.domains.list();
await tagada.domains.remove({ domainId: 'cdm_abc123' });
Promote Staging to Production
After testing on the staging CDN URL (*.cdn.tagadapay.com), promote the funnel to your custom domain in one call. The server handles instance cloning, route setup, and prebuilds automatically.
const result = await tagada.funnels.promote(funnel.id, {
storeId: 'store_...',
customDomain: 'checkout.yourstore.com',
});
console.log(result.success); // true
console.log(result.message); // 'Funnel promoted to checkout.yourstore.com'
The domain must be verified before promoting. If the domain is already in use by another funnel, pass
acknowledgeConflict: true to override:await tagada.funnels.promote(funnel.id, {
storeId: 'store_...',
customDomain: 'checkout.yourstore.com',
acknowledgeConflict: true,
});
Full workflow: staging to production
import Tagada from '@tagadapay/node-sdk';
const tagada = new Tagada('your-api-key');
// 1. Deploy + create funnel (see sections above)
// Your funnel is now live on *.cdn.tagadapay.com (staging)
// 2. Register and verify your domain
const { domain } = await tagada.domains.add({ domain: 'checkout.yourstore.com' });
// ... configure CNAME, wait for DNS ...
await tagada.domains.verify({ domainId: domain.id });
// 3. Promote — one call moves everything to production
await tagada.funnels.promote(funnel.id, {
storeId: 'store_...',
customDomain: 'checkout.yourstore.com',
});
// 4. Create checkout sessions pointing to the production URL
const session = await tagada.checkout.createSession({
storeId: 'store_...',
items: [{ variantId: 'variant_...', quantity: 1 }],
currency: 'USD',
checkoutUrl: 'https://checkout.yourstore.com/checkout',
});
console.log('Live checkout:', session.redirectUrl);
Plugin Management
const plugins = await tagada.plugins.list('store_...');
const instances = await tagada.plugins.listInstances('store_...');
const details = await tagada.plugins.retrieveDeployment(deploymentId);
await tagada.plugins.del(pluginId, 'store_...');
Next Steps
Plugin SDK Reference
Full SDK documentation — hooks, API, examples
Plugin CLI
Deploy plugins from your terminal with
tgd deployMerchant Quick Start
Full 7-step setup from processor to live checkout
Host & A/B Test
Custom domains, A/B testing, and hosting via REST API
