Skip to main content

Upsells & Offers

The offers module lets you load post-purchase offers (configured in the CRM), display them in your own UI, and accept or decline them with one-click charging.

Load an Offer

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

// offer.title         -- "Upgrade to VIP Coaching Pack"
// offer.description   -- optional description
// offer.lineItems     -- products in the offer
// offer.pricing       -- { amount: 9900, currency: 'USD' }

Accept (One-Click Upsell)

Charges the stored payment instrument from the main checkout order:
const result = await tagada.offers.acceptOffer({
  offerId: offer.id,
  checkoutSessionId: 'cs_xxx',
});

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

Decline

await tagada.offers.declineOffer({
  offerId: offer.id,
  checkoutSessionId: 'cs_xxx',
});

Order Bumps

Order bumps are shown on the checkout page (before payment). List and toggle them:
// List available bumps for this session
const bumps = await tagada.offers.listOrderBumps(session.id);

// Toggle a bump on/off
await tagada.offers.toggleOrderBump({
  checkoutSessionId: session.id,
  offerId: bumps[0].id,
  selected: true,
});

List All Offers

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

React Hook

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

function UpsellPage({ offerId, sessionId }) {
  const { offer, loadOffer, acceptOffer, declineOffer, isLoading } = useOffers();

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

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

  return (
    <div>
      <h2>{offer?.title}</h2>
      <p>${((offer?.pricing?.amount ?? 0) / 100).toFixed(2)}</p>
      <button onClick={() => acceptOffer({ offerId, checkoutSessionId: sessionId })}>
        Yes, Add It!
      </button>
      <button onClick={() => declineOffer({ offerId, checkoutSessionId: sessionId })}>
        No Thanks
      </button>
    </div>
  );
}