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

# One-time Items

> Sell consumables like credit packs through app_ checkout links: setup, attribution with client_reference_id, fulfilment, and reconciliation.

One-time items are consumables sold alongside your app: credit packs, boosts, top-ups. They are independent of your pricing plans: buying one doesn't affect installation or subscriptions, and the same item can be bought any number of times.

Items are sold through **checkout links**: your app decides when to offer them, typically a "Buy more credits" button pointing at the item's checkout URL.

## Create an item

In the Builder (Developer area), open your app and go to **Store Listing → Pricing**, then **Add Item** under **One-time items**.

| Field       | Constraints                              |
| ----------- | ---------------------------------------- |
| Item name   | Up to 20 characters (e.g. "500 credits") |
| Description | Up to 500 characters                     |
| Price       | Between **\$3.99** and **\$500.00**      |

You can configure up to **10 one-time items per app**. The same 20/80 revenue split applies as for [pricing plans](/docs/app-store/payments/pricing-plans).

## Selling an item

Each item has a copyable **checkout URL** of the form:

```text theme={null}
https://www.fanvue.com/checkout/app_<slug>
```

Copy it from the item's row in the **Pricing** tab (also listed on the dashboard's **Checkout links** page) and put it behind your purchase CTA.

<Note>
  Item checkout requires the buyer to be **signed in to Fanvue**. Items are independent of plans, so whether they work as a first purchase or an in-app top-up is down to how you've built your app.
</Note>

## Attribution

To tie a purchase back to a record in your own system, append a `client_reference_id` to the checkout URL:

```text theme={null}
https://www.fanvue.com/checkout/app_<slug>?client_reference_id=your-order-123
```

It's echoed as `data.client_reference_id` on the resulting [`app.payment.*`](/docs/app-store/webhooks/payments) and [`app.refund.created`](/docs/app-store/webhooks/refunds-disputes) events. Passthrough-only; don't put secrets in it. (`metadata` is not captured and remains `{}`.)

## Fulfilment

Fulfil off [`app.payment.succeeded`](/docs/app-store/webhooks/payments):

1. **Identify the purchase**: `billing_reason` is `one_time` and `purchase_reference` carries the `appotp_` prefix. `item.uuid` tells you which item was bought; `buyer.uuid` who bought it.
2. **Dedupe before crediting**: the event `id` is stable across delivery retries, so record it and skip duplicates.
3. **Credit the buyer**, then reconcile revenue against the payment's invoice number (`data.id`).

Don't fulfil on `app.payment.pending`; wait for `.succeeded`.

## Refunds and disputes

[`app.refund.created`](/docs/app-store/webhooks/refunds-disputes) fires on refund, chargeback, or cancellation (branch on `reason`); `app.dispute.flagged` and `app.dispute.created` warn you of chargebacks. Claw back credited balances keyed on `payment_id`, the invoice number of the original payment.

## Reconciling

Re-read one-time payments any time with the read-only app payments endpoints, owner-scoped or buyer-scoped:

| Endpoint                                          | Returns                                           |
| ------------------------------------------------- | ------------------------------------------------- |
| `GET /apps/{appUuid}/payments`                    | All buyers' one-time payments for an app you own  |
| `GET /apps/{appUuid}/payments/{invoiceNumber}`    | One payment by Fanvue invoice number              |
| `GET /apps/{appUuid}/payments/me`                 | The authenticated user's own payments for the app |
| `GET /apps/{appUuid}/payments/me/{invoiceNumber}` | The caller's own payment by invoice number        |

See [Reconciliation](/docs/app-store/webhooks#reconciliation) for how invoice numbers match across webhooks and endpoints.
