Create an item
In the Developer Area, open your app, go to Store listing, then Pricing, and click Add item under One-time items.
An app holds at most 10 one-time items that are not withdrawn, separate from the 5-plan limit. You receive 80% of each sale, the same revenue split as pricing plans.
Selling an item
Items sell through their Fanvue-hosted checkout URL only. Your app decides when to offer one, typically with a “Buy more credits” button pointing at the item’scheckoutUrl:
checkoutUrl on the item in GET /apps/{appUuid}/subscription-status, and put it behind your purchase button. The URL is null while the item is pending setup or withdrawn.
Item checkout accepts buyers who are signed in to Fanvue. Because items are independent of plans, whether one works as a first purchase or an in-app top-up depends on how your app gates its features.
Items can’t be deeplinked. The ?plan= parameter on your listing targets subscription plans and treats an item UUID as invalid.
Attribution
To tie a purchase back to your own records, appendclient_reference_id and metadata[<key>] query parameters to the checkout URL:
app.payment.* and app.refund.created events as data.client_reference_id and data.metadata. The limits match checkout link attribution: 200 characters for client_reference_id, and up to 10 metadata keys of 40 characters with values of 200 characters. Both are passthrough only. Never put secrets in them, because every receiver of the event sees them.
Fulfilment
Fulfil offapp.payment.succeeded:
- Identify the purchase.
billing_reasonisone_timeandpurchase_referencestarts withappotp_.item.uuidnames the item bought andbuyer.uuidthe creator who bought it. - Dedupe before crediting. The event
idis stable across delivery retries, so record it and skip a repeat. - Credit the buyer, then reconcile revenue against the payment’s invoice number in
data.id.
app.payment.pending. A pending payment can still fail, and crediting it leaves the buyer with goods Fanvue never charged for.
Refunds and disputes
app.refund.created fires when a payment is reversed, and you branch on its 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
You can re-read one-time payments at any time with the app payments endpoints.
The invoice number on each payment matches
data.id on the app.payment.* event.