curl --request POST \
--url https://api.fanvue.com/v1/creators/{creatorUserUuid}/checkout-links/payments/{invoiceNumber}/refund-requests \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--header 'X-Fanvue-API-Version: <x-fanvue-api-version>' \
--data '{}'import requests
url = "https://api.fanvue.com/v1/creators/{creatorUserUuid}/checkout-links/payments/{invoiceNumber}/refund-requests"
payload = {}
headers = {
"X-Fanvue-API-Version": "<x-fanvue-api-version>",
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {
'X-Fanvue-API-Version': '<x-fanvue-api-version>',
Authorization: 'Bearer <token>',
'Content-Type': 'application/json'
},
body: JSON.stringify({})
};
fetch('https://api.fanvue.com/v1/creators/{creatorUserUuid}/checkout-links/payments/{invoiceNumber}/refund-requests', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));{
"uuid": "3f2b1a09-8c7d-4e6f-9a0b-1c2d3e4f5a6b",
"paymentId": "FVE-20260619-1234",
"status": "pending",
"reason": "requested_by_customer",
"note": "Fan bought the wrong tier",
"reviewNote": null,
"createdAt": "2026-06-20T09:00:00.000Z",
"resolvedAt": null
}{
"error": "<string>",
"message": "<string>"
}{
"error": "<string>"
}{
"error": "<string>"
}{
"message": "<string>"
}{
"message": "<string>"
}{
"error": "<string>",
"message": "<string>",
"nextVersion": "<string>"
}{
"message": "<string>"
}{
"error": "<string>"
}Ask Fanvue to refund a checkout-link payment
Open a request that Fanvue refund the specified payment in full. This does not move money: Fanvue reviews the request, and only an approved one produces a refund. Track the outcome with the refund-requests list or the checkout_link.refund.* webhooks.
A payment can hold only one open request at a time, and only settled card payments inside Fanvue’s refund window can carry one. Returns 404 if the payment does not exist or does not belong to this creator, 409 if it already has an open request or its last request was declined recently, and 422 if it can never be refunded or has fallen outside the window (the message says which).
The checkout_link.refund.requested and checkout_link.refund.created webhook events announce the new request and a completed refund. Rejected, failed, withdrawn and chargebacked outcomes do not emit an event yet, so poll the refund-requests list by status to observe those.
curl --request POST \
--url https://api.fanvue.com/v1/creators/{creatorUserUuid}/checkout-links/payments/{invoiceNumber}/refund-requests \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--header 'X-Fanvue-API-Version: <x-fanvue-api-version>' \
--data '{}'import requests
url = "https://api.fanvue.com/v1/creators/{creatorUserUuid}/checkout-links/payments/{invoiceNumber}/refund-requests"
payload = {}
headers = {
"X-Fanvue-API-Version": "<x-fanvue-api-version>",
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {
'X-Fanvue-API-Version': '<x-fanvue-api-version>',
Authorization: 'Bearer <token>',
'Content-Type': 'application/json'
},
body: JSON.stringify({})
};
fetch('https://api.fanvue.com/v1/creators/{creatorUserUuid}/checkout-links/payments/{invoiceNumber}/refund-requests', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));{
"uuid": "3f2b1a09-8c7d-4e6f-9a0b-1c2d3e4f5a6b",
"paymentId": "FVE-20260619-1234",
"status": "pending",
"reason": "requested_by_customer",
"note": "Fan bought the wrong tier",
"reviewNote": null,
"createdAt": "2026-06-20T09:00:00.000Z",
"resolvedAt": null
}{
"error": "<string>",
"message": "<string>"
}{
"error": "<string>"
}{
"error": "<string>"
}{
"message": "<string>"
}{
"message": "<string>"
}{
"error": "<string>",
"message": "<string>",
"nextVersion": "<string>"
}{
"message": "<string>"
}{
"error": "<string>"
}write:creator— Modify creator profiles, settings, and creator-specific data.
Authorizations
OAuth 2.0 access token, presented as a JWT bearer token in the Authorization header. Obtain a token via the authorization-code flow; the scopes granted to the token determine which operations it may call.
Headers
API version to use for the request
"2025-06-26"
Path Parameters
Fanvue payment identifier (invoice number).
Body
Response
Refund request opened
Fanvue's unique refund-request identifier.
Invoice number of the payment this request is against (invoiceNumber).
Where the request stands. pending is awaiting review; approved means Fanvue accepted it and is reversing the payment; failed means a reversal attempt did not go through and Fanvue is still working it (not a decision against the request); refunded is the money back with the fan, and also fires checkout_link.refund.created; rejected is refused, with the reason in reviewNote; withdrawn is the creator taking their own request back; chargebacked means the fan disputed the payment with their bank before the request was settled, so the money went back through the dispute instead (see the checkout_link.dispute.* events). The Fanvue dashboard shows approved and failed together as "processing".
pending, approved, failed, refunded, rejected, withdrawn, chargebacked Why the creator is asking for the payment to be refunded.
duplicate, fraudulent, requested_by_customer, other The note the creator sent with the request.
Fanvue's reason for the decision; populated when status is rejected.
When the request was opened.
When the request reached a final state, or null while it is still open.
Was this page helpful?