> ## Documentation Index
> Fetch the complete documentation index at: https://docs.tagada.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Upsells & Offers

> Post-purchase offers, order bumps, and one-click upsells

# 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

```typescript theme={null}
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

```typescript theme={null}
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.

```typescript theme={null}
// 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:

```typescript theme={null}
await tagada.offers.toggleOrderBump({
  checkoutSessionId: session.id,
  orderBumpOfferId: bumps[0].id,
  selected: true,
});
```

<Note>
  The parameter is `orderBumpOfferId` (not `offerId`).
</Note>

***

## Post-Purchase Offers

After a successful order, list available post-purchase offers and let the customer accept or decline:

```typescript theme={null}
// 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

```tsx theme={null}
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

| Method                                                               | Description                                         |
| -------------------------------------------------------------------- | --------------------------------------------------- |
| `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                       |
