Skip to main content

Promotions & Discount Codes

Time: ~10 minutes | Difficulty: Intermediate Use the Node SDK to define promotions (automatic or code-based discounts) with rules (when they apply) and actions (what they do). Attach human-readable promotion codes so customers can enter coupons at checkout.
Promotions are scoped to a store (storeId). Amounts in money fields are typically in the smallest currency unit (e.g. cents for USD) unless noted otherwise in your dashboard.

Prerequisites

RequirementHow to get it
Node.js 18+nodejs.org
@tagadapay/node-sdknpm install @tagadapay/node-sdk
API keyDashboard → Settings → API Keys
A storeMerchant Quick Start
import Tagada from '@tagadapay/node-sdk';

const tagada = new Tagada('your-api-key');
const STORE_ID = 'store_...';

Initialize and (optional) create a target product

Line-item discounts often reference a product id. For a store-wide percentage off, you can skip this.
const product = await tagada.products.create({
  storeId: STORE_ID,
  name: 'Promo target product',
  active: true,
  isShippable: false,
  isTaxable: false,
  variants: [{
    name: 'Default',
    sku: 'PROMO-001',
    grams: null,
    active: true,
    default: true,
    price: null,
    compareAtPrice: null,
    prices: [{
      currencyOptions: { USD: { amount: 5000 } },
      recurring: false,
      billingTiming: 'usage',
      interval: null,
      intervalCount: 1,
      default: true,
    }],
  }],
});
5000 in currencyOptions = $50.00 when the currency is USD (cents).

Create a percentage order discount (20% off)

Apply a percentage to the whole order with OrderAdjustment and adjustmentType: 'percentage'.
const promotion = await tagada.promotions.create({
  storeId: STORE_ID,
  name: '20% off entire order',
  enabled: true,
  automatic: true,
  actions: [{
    type: 'OrderAdjustment',
    adjustmentType: 'percentage',
    adjustmentPercentage: 20,
  }],
});
automatic: true means the promotion can apply without a coupon when your rules (if any) are satisfied. Set automatic: false when you only want it to apply via a promotion code.

Create a fixed line-item discount ($10 off a specific product)

Use LineItemAdjustment with adjustmentType: 'amount' and adjustmentAmount in the full currency object shape (not just { USD: 1000 }).
const lineItemPromo = await tagada.promotions.create({
  storeId: STORE_ID,
  name: '$10 off selected product',
  enabled: true,
  automatic: false,
  actions: [{
    type: 'LineItemAdjustment',
    adjustmentType: 'amount',
    adjustmentAmount: {
      USD: {
        amount: 1000, // $10.00 in cents
        rate: 1,
        lock: false,
        date: '2026-01-01',
      },
    },
    targetProductId: product.id,
    targetVariantIds: null,
    maxQuantityDiscounted: null,
    appliesOnEachItem: false,
  }],
});
adjustmentAmount format: each currency key maps to { amount, rate, lock, date }. Use an ISO date string (or timestamp) for date as required by your environment. rate, lock, and date participate in currency conversion and locking behavior on the platform.

Conditional promotion: free shipping over $30

Combine OrderAmountMinimum in rules with ShippingAdjustment in actions.
const freeShippingPromo = await tagada.promotions.create({
  storeId: STORE_ID,
  name: 'Free shipping on orders $30+',
  enabled: true,
  automatic: true,
  rules: [{
    type: 'OrderAmountMinimum',
    minimumAmount: {
      USD: {
        amount: 3000, // $30.00
        rate: 1,
        lock: false,
        date: '2026-01-01',
      },
    },
  }],
  actions: [{
    type: 'ShippingAdjustment',
    freeShipping: true,
  }],
});

Create a promotion code (coupon)

Link a reusable code to an existing promotion. Customers enter the code at checkout; the promotion’s rules and actions then apply.
const promotionCode = await tagada.promotionCodes.create({
  promotionId: lineItemPromo.id,
  code: 'SAVE10',
  active: true,
});
Create the promotion first, then call promotionCodes.create with its promotionId. You can attach multiple codes to the same promotion if your workflow allows it.

List, retrieve, update, and delete promotions

List

const listResult = await tagada.promotions.list({ storeId: STORE_ID });
// Shape may include `promotions`, `items`, or a raw array — normalize in your app

Retrieve

storeId is required for a reliable lookup in multi-store accounts.
const one = await tagada.promotions.retrieve(promotion.id, STORE_ID);

Update

Updates are wrapped in a data object alongside id.
const updated = await tagada.promotions.update({
  id: promotion.id,
  data: {
    storeId: STORE_ID,
    name: '25% off entire order',
    enabled: true,
    automatic: true,
    actions: [{
      type: 'OrderAdjustment',
      adjustmentType: 'percentage',
      adjustmentPercentage: 25,
    }],
  },
});

Delete

Pass an array of ids and storeId.
await tagada.promotions.del([promotion.id, lineItemPromo.id], STORE_ID);
Some API responses nest the resource under promotion or promotionCode. When creating resources, read result.id or result.promotion?.id depending on the payload shape.

Promotion rules reference

Rule typePurpose
ContainsProductOrder must include specific product(s) / variant(s)
OrderAmountMinimumSubtotal (or qualifying amount) must meet a minimum, using currency objects
OrderMinQuantityMinimum total line-item quantity on the order
OrderMaxQuantityMaximum total line-item quantity on the order
MaxProductQuantityCap quantity eligible for the discount per product
PaymentIntegrationSelectedRestrict to orders using a specific processor / payment integration

Promotion actions reference

Action typeWhat it doesCommon fields
LineItemAdjustmentDiscount specific linesadjustmentType: 'percentage' | 'amount'; adjustmentPercentage or adjustmentAmount; optional targetProductId, targetVariantIds, maxQuantityDiscounted, appliesOnEachItem
OrderAdjustmentDiscount the whole orderadjustmentType: 'percentage' | 'amount'; adjustmentPercentage or order-level adjustmentAmount
ShippingAdjustmentChange shipping chargese.g. freeShipping: true
CreateLineItemAdd a line item when the promotion firesProduct / variant / quantity configuration (per your store setup)
SubscriptionLineItemFreeTrialApply a free trial on subscription line itemsTrial duration / terms as supported by the platform

SDK methods: tagada.promotions

MethodSignature (conceptual)Description
createpromotions.create({ storeId, name, enabled, automatic, actions, rules, ... })Create a promotion
listpromotions.list({ storeId })List promotions for a store
retrievepromotions.retrieve(id, storeId)Get one promotion; storeId required
updatepromotions.update({ id, data: { storeId, name, ... } })Update fields inside data
delpromotions.del(ids[], storeId)Delete one or more promotions

SDK methods: tagada.promotionCodes

MethodSignature (conceptual)Description
createpromotionCodes.create({ promotionId, code, active })Create a coupon linked to a promotion
listpromotionCodes.list()List promotion codes
updatepromotionCodes.update({ ... })Update an existing code (e.g. deactivate)
delpromotionCodes.del(ids[])Delete codes by id

Currency amount shape

Whenever the API expects a currency map (e.g. adjustmentAmount, minimumAmount), use:
{
  USD: {
    amount: 1000,       // smallest unit (e.g. cents)
    rate: 1,
    lock: false,
    date: '2026-01-01', // ISO date string
  },
}
Repeat keys (EUR, GBP, …) for multi-currency stores as needed.

Next steps

Merchant Quick Start

Store, product, funnel, and checkout session setup

Upsell & Downsell Funnel

Post-purchase offers and conditional funnel routing

Custom Checkout

Advanced checkout flows with the Node SDK

API Reference

Full REST API documentation