Get one action purchase by its purchase reference

Fetches a single action purchase by the expact_… reference your webhook carried.

**Fulfil on the webhook, never on the bridge result.** Grant the action when you receive `app.experience.action.payment.succeeded`, keyed on `purchase_reference` so a redelivery grants nothing twice. The `purchaseResult` message your iframe receives from Fanvue is UX only — it tells your surface to stop showing a spinner, and it is never proof that money moved. This read is the reconciliation path: poll it when you think you missed a webhook, or to confirm one you are unsure about.

Owner app only. A reference that belongs to another app, to another experience, or to nothing at all all answer 404 alike — the read never confirms that a reference exists somewhere you cannot see.
get/experiences/{experienceUuid}/action-purchases/{purchaseReference}

Path parameters

experienceUuidstring uuid required
Example:00000000-0000-4000-8000-000000000010
purchaseReferencestring required
Example:expact_5c9a1f0e-9f3f-4c2a-8f31-1d0f6a2b7c44

Headers

X-Fanvue-API-Versionstring required
Example:2025-06-26

API version to use for the request

Response

The action purchase

purchaseReferencestring required

The expact_… reference minted with the purchase attempt. THE fulfilment idempotency key: grant the action at most once per reference, and only for a purchase whose status is succeeded.

experienceUuidstring uuid required

The experience the action belongs to.

externalActionIdstring required

The app's own stable key for the action that was bought.

clientReferenceIdstring nullable required

The app-supplied reference carried through the purchase, or null when the app supplied none.

buyerUuidstring uuid required

UUID of the fan who bought the action. The only identifier of the buyer this surface carries — no handle, no display name, no email.

amountinteger required

Price in minor currency units (cents), frozen at the purchase attempt. A later re-pricing of the action does not move it.

currencystring required

ISO 4217 code of the amount. USD only today.

status'pending' | 'succeeded' | 'failed' | 'refunded' | 'disputed' | 'cancelled' required

Where the money for this purchase attempt ended up. Fulfil only on succeeded. refunded, disputed and cancelled all mean the money is not the creator's, so revoke on any of them — the difference between them only records how the reversal was written, not whether to act. refunded is a reversal carrying a refund reference (a settled payment paid back, or an authorisation voided before capture); disputed is a chargeback that was lost and reversed; cancelled is a reversal carrying neither reference (a delayed capture that failed, or the uncaptured-invoice sweeper). An open dispute that has not been lost is still succeeded here — the money has not moved — so watch app.experience.action.dispute.* for that, not this field. A refund the processor accepted and then rejected also reports succeeded again: this field is where the money ended up, not what was attempted.

invoiceNumberstring required

Fanvue invoice number for the charge. For support and accounting, not fulfilment.

createdAtstring date-time required

When the purchase attempt was opened.

paidAtstring date-time nullable required

When the charge settled, or null while it has not.

Example response

{
  "purchaseReference": "expact_5c9a1f0e-9f3f-4c2a-8f31-1d0f6a2b7c44",
  "experienceUuid": "00000000-0000-4000-8000-000000000010",
  "externalActionId": "spin",
  "clientReferenceId": "round-42",
  "buyerUuid": "00000000-0000-4000-8000-000000000003",
  "amount": 700,
  "currency": "USD",
  "invoiceNumber": "FVE-20260904-1234",
  "createdAt": "2026-09-04T10:00:00.000Z",
  "paidAt": "2026-09-04T10:00:02.000Z"
}

Changes