Skip to main content

Upsells & Offers

The offers module handles upsells, order bumps, and post-purchase offers. It covers three distinct flows:
  1. Preview + Pay — preview an offer’s pricing, then charge with one click (reuses stored payment instrument)
  2. Order Bumps — toggle add-ons on/off during checkout
  3. Post-Purchase Offers — display and accept/decline offers after the main order

Get an Offer

const offer = await tagada.offers.getOffer('offer_xxx');

// offer.id          -- offer ID
// offer.title       -- "Upgrade to VIP Coaching Pack"
// offer.type        -- 'upsell' | 'orderbump' | 'downsell'
// offer.lineItems   -- products in the offer
// offer.pricing     -- { amount, currency, compareAtAmount? }

List Offers

const upsells = await tagada.offers.listOffers({ type: 'upsell' });
const orderBumps = await tagada.offers.listOffers({ type: 'orderbump' });

Preview + Pay (One-Click Upsell)

Two-step flow: preview pricing, then charge using the stored instrument from the main order.
// 1. Preview — get the pricing breakdown
const preview = await tagada.offers.previewOffer({
  offerId: 'offer_xxx',
});
// preview.items, preview.totalAmount, preview.totalAdjustedAmount, preview.currency

// 2. Pay — one-click charge (reuses payment instrument from mainOrderId)
const result = await tagada.offers.payPreviewedOffer({
  offerId: 'offer_xxx',
  mainOrderId: 'order_yyy',
});

if (result.success) {
  console.log('Upsell order created:', result.orderId);
}

Order Bumps

Order bumps are shown on the checkout page (before payment). Toggle them on/off:
await tagada.offers.toggleOrderBump({
  checkoutSessionId: session.id,
  orderBumpOfferId: bumps[0].id,
  selected: true,
});
The parameter is orderBumpOfferId (not offerId).

Post-Purchase Offers

After a successful order, list available post-purchase offers and let the customer accept or decline:
// List post-purchase offers for an order
const offers = await tagada.offers.listPostPurchaseOffers('order_yyy');

// Accept
await tagada.offers.acceptPostPurchaseOffer({
  orderId: 'order_yyy',
  offerId: offers[0].id,
});

// Decline
await tagada.offers.declinePostPurchaseOffer({
  orderId: 'order_yyy',
  offerId: offers[0].id,
});

React Hook

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

function UpsellPage({ offerId, orderId }: { offerId: string; orderId: string }) {
  const {
    offer,
    getOffer,
    previewOffer,
    payPreviewedOffer,
    listPostPurchaseOffers,
    acceptPostPurchaseOffer,
    declinePostPurchaseOffer,
    isLoading,
  } = useOffers();

  useEffect(() => { getOffer(offerId); }, [offerId]);

  if (isLoading) return <p>Loading...</p>;

  return (
    <div>
      <h2>{offer?.title}</h2>
      <button onClick={() => payPreviewedOffer({ offerId, mainOrderId: orderId })}>
        Yes, Add It!
      </button>
      <button onClick={() => declinePostPurchaseOffer({ orderId, offerId })}>
        No Thanks
      </button>
    </div>
  );
}

Full Hook API

MethodDescription
getOffer(offerId)Load a single offer (sets offer state)
listOffers({ type? })List offers filtered by 'upsell' or 'orderbump'
previewOffer({ offerId })Preview pricing (sets preview state)
payPreviewedOffer({ offerId, mainOrderId })One-click charge using stored instrument
toggleOrderBump({ checkoutSessionId, orderBumpOfferId, selected })Toggle a bump on/off
listPostPurchaseOffers(orderId)List post-purchase offers for an order
acceptPostPurchaseOffer({ orderId, offerId })Accept a post-purchase offer
declinePostPurchaseOffer({ orderId, offerId })Decline a post-purchase offer