A Refund returns all or part of a captured payment to the buyer. Fluveo reserves the amount in the store's books before it sends the refund, so a refund the store cannot cover is refused before any money moves.
Send every request to https://api.fluveo.com/v1 with your secret key as a Bearer token. This page lists only what Fluveo serves; the OpenAPI file holds the same operations.
Creates a refund#
POST/v1/refundsrak_charge_write
Send a unique key, 1 to 255 characters, on every POST. A retry with the same key and the same body returns the first answer instead of acting twice (with Idempotent-Replayed: true); the same key with another body is refused. Keys are kept 7 days, except on POST /v1/checkout/sessions, POST /v1/checkout/sessions/{session} and POST /v1/webhook_endpoints, where a key holds 24 hours; webhook endpoint keys are also capped at the newest 32 per store and mode. Do not rely on a replay after that window. GET and DELETE ignore it.
Optional. The only version Fluveo serves is 2026-05-27.dahlia; any other value is refused with a 400. Every answer names that version in its own Fluveo-Version header, except the refusals Fluveo gives before it reads the request (no key, an unknown key, an unknown URL, a body that is not a form) and a file's bytes, which name no version and no Request-Id.
One of:
2026-05-27.dahlia.
How much to refund, in the smallest unit. Leave it out to refund what is left.
The charge to refund (ch_...). Send charge or payment_intent.
Up to 50 key-value pairs of your own, sent as metadata[key]=value: keys of 1 to 40 characters, values up to 500. Keys starting with fluveo_ are reserved. On an update, an empty value removes a key.
The PaymentIntent to refund (pi_...). Send payment_intent or charge.
Why you refund.
One of:
duplicate,fraudulent,requested_by_customer.
Use only the documented body parameters. Send a new Idempotency-Key with each new request, and the same key again only to retry that request.
Returns a refund object.
curl https://api.fluveo.com/v1/refunds \
-H "Authorization: Bearer sk_test_..." \
-H "Idempotency-Key: $(uuidgen)" \
--data-urlencode "amount=500" \
--data-urlencode "payment_intent=pi_123" \
--data-urlencode "reason=requested_by_customer"const response = await fetch("https://api.fluveo.com/v1/refunds", {
method: "POST",
headers: {
"Authorization": "Bearer sk_test_...",
"Idempotency-Key": crypto.randomUUID(),
},
body: new URLSearchParams([["amount","500"],["payment_intent","pi_123"],["reason","requested_by_customer"]]),
});
console.log(await response.json());import uuid
import requests
response = requests.post(
"https://api.fluveo.com/v1/refunds",
headers={"Authorization": "Bearer sk_test_...", "Idempotency-Key": str(uuid.uuid4())},
data=[("amount", "500"), ("payment_intent", "pi_123"), ("reason", "requested_by_customer")],
)
print(response.json())<?php
$ch = curl_init("https://api.fluveo.com/v1/refunds");
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_HTTPHEADER => [
"Authorization: Bearer sk_test_...",
"Idempotency-Key: " . bin2hex(random_bytes(16)),
],
CURLOPT_POSTFIELDS => "amount=500&payment_intent=pi_123&reason=requested_by_customer",
]);
echo curl_exec($ch);{
"amount": 500,
"charge": "ch_123",
"created": 1767225600,
"currency": "usd",
"id": "re_123",
"metadata": {},
"object": "refund",
"payment_intent": "pi_123",
"reason": "requested_by_customer",
"status": "succeeded"
}Lists refund objects, newest first#
GET/v1/refundsrak_charge_read
Only the refunds of this charge.
Filter on the creation time, a Unix timestamp: created=<t> for an exact match, or created[gt], created[gte], created[lt], created[lte].
Cursor: the id of the first object of the current page, to get the previous page. Do not send it with starting_after.
How many objects to return, from 1 to 100. Default 10.
Only the refunds of this PaymentIntent.
Cursor: the id of the last object of the previous page, to get the next page. Do not send it with ending_before.
Optional. The only version Fluveo serves is 2026-05-27.dahlia; any other value is refused with a 400. Every answer names that version in its own Fluveo-Version header, except the refusals Fluveo gives before it reads the request (no key, an unknown key, an unknown URL, a body that is not a form) and a file's bytes, which name no version and no Request-Id.
One of:
2026-05-27.dahlia.
Returns a list of refund objects.
curl -G https://api.fluveo.com/v1/refunds \
-H "Authorization: Bearer sk_test_..." \
--data-urlencode "payment_intent=pi_123"const response = await fetch("https://api.fluveo.com/v1/refunds" + "?" + new URLSearchParams([["payment_intent","pi_123"]]), {
method: "GET",
headers: {
"Authorization": "Bearer sk_test_...",
},
});
console.log(await response.json());import requests
response = requests.get(
"https://api.fluveo.com/v1/refunds",
headers={"Authorization": "Bearer sk_test_..."},
params=[("payment_intent", "pi_123")],
)
print(response.json())<?php
$ch = curl_init("https://api.fluveo.com/v1/refunds?payment_intent=pi_123");
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_CUSTOMREQUEST => "GET",
CURLOPT_HTTPHEADER => [
"Authorization: Bearer sk_test_...",
],
]);
echo curl_exec($ch);{
"count": 1,
"data": [
{
"amount": 500,
"charge": "ch_123",
"created": 1767225600,
"currency": "usd",
"id": "re_123",
"metadata": {},
"object": "refund",
"payment_intent": "pi_123",
"reason": "requested_by_customer",
"status": "succeeded"
}
],
"has_more": false,
"object": "list",
"url": "/v1/refunds"
}Updates a refund#
POST/v1/refunds/{refund}rak_charge_write
The Refund's id.
Send a unique key, 1 to 255 characters, on every POST. A retry with the same key and the same body returns the first answer instead of acting twice (with Idempotent-Replayed: true); the same key with another body is refused. Keys are kept 7 days, except on POST /v1/checkout/sessions, POST /v1/checkout/sessions/{session} and POST /v1/webhook_endpoints, where a key holds 24 hours; webhook endpoint keys are also capped at the newest 32 per store and mode. Do not rely on a replay after that window. GET and DELETE ignore it.
Optional. The only version Fluveo serves is 2026-05-27.dahlia; any other value is refused with a 400. Every answer names that version in its own Fluveo-Version header, except the refusals Fluveo gives before it reads the request (no key, an unknown key, an unknown URL, a body that is not a form) and a file's bytes, which name no version and no Request-Id.
One of:
2026-05-27.dahlia.
Up to 50 key-value pairs of your own, sent as metadata[key]=value: keys of 1 to 40 characters, values up to 500. Keys starting with fluveo_ are reserved. On an update, an empty value removes a key.
Use only the documented body parameters. Send a new Idempotency-Key with each new request, and the same key again only to retry that request.
Returns a refund object.
curl https://api.fluveo.com/v1/refunds/re_123 \
-H "Authorization: Bearer sk_test_..." \
-H "Idempotency-Key: $(uuidgen)" \
--data-urlencode "metadata[ticket]=4411"const response = await fetch("https://api.fluveo.com/v1/refunds/re_123", {
method: "POST",
headers: {
"Authorization": "Bearer sk_test_...",
"Idempotency-Key": crypto.randomUUID(),
},
body: new URLSearchParams([["metadata[ticket]","4411"]]),
});
console.log(await response.json());import uuid
import requests
response = requests.post(
"https://api.fluveo.com/v1/refunds/re_123",
headers={"Authorization": "Bearer sk_test_...", "Idempotency-Key": str(uuid.uuid4())},
data=[("metadata[ticket]", "4411")],
)
print(response.json())<?php
$ch = curl_init("https://api.fluveo.com/v1/refunds/re_123");
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_HTTPHEADER => [
"Authorization: Bearer sk_test_...",
"Idempotency-Key: " . bin2hex(random_bytes(16)),
],
CURLOPT_POSTFIELDS => "metadata%5Bticket%5D=4411",
]);
echo curl_exec($ch);{
"amount": 500,
"charge": "ch_123",
"created": 1767225600,
"currency": "usd",
"id": "re_123",
"metadata": {},
"object": "refund",
"payment_intent": "pi_123",
"reason": "requested_by_customer",
"status": "succeeded"
}Retrieves a refund#
GET/v1/refunds/{refund}rak_charge_read
The Refund's id.
Optional. The only version Fluveo serves is 2026-05-27.dahlia; any other value is refused with a 400. Every answer names that version in its own Fluveo-Version header, except the refusals Fluveo gives before it reads the request (no key, an unknown key, an unknown URL, a body that is not a form) and a file's bytes, which name no version and no Request-Id.
One of:
2026-05-27.dahlia.
Returns a refund object.
curl https://api.fluveo.com/v1/refunds/re_123 \
-H "Authorization: Bearer sk_test_..."const response = await fetch("https://api.fluveo.com/v1/refunds/re_123", {
method: "GET",
headers: {
"Authorization": "Bearer sk_test_...",
},
});
console.log(await response.json());import requests
response = requests.get(
"https://api.fluveo.com/v1/refunds/re_123",
headers={"Authorization": "Bearer sk_test_..."},
)
print(response.json())<?php
$ch = curl_init("https://api.fluveo.com/v1/refunds/re_123");
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_CUSTOMREQUEST => "GET",
CURLOPT_HTTPHEADER => [
"Authorization: Bearer sk_test_...",
],
]);
echo curl_exec($ch);{
"amount": 500,
"charge": "ch_123",
"created": 1767225600,
"currency": "usd",
"id": "re_123",
"metadata": {},
"object": "refund",
"payment_intent": "pi_123",
"reason": "requested_by_customer",
"status": "succeeded"
}Lists refund objects of the parent object#
GET/v1/charges/{charge}/refundsrak_charge_read
The Charge's id.
Cursor: the id of the first object of the current page, to get the previous page. Do not send it with starting_after.
How many objects to return, from 1 to 100. Default 10.
Cursor: the id of the last object of the previous page, to get the next page. Do not send it with ending_before.
Optional. The only version Fluveo serves is 2026-05-27.dahlia; any other value is refused with a 400. Every answer names that version in its own Fluveo-Version header, except the refusals Fluveo gives before it reads the request (no key, an unknown key, an unknown URL, a body that is not a form) and a file's bytes, which name no version and no Request-Id.
One of:
2026-05-27.dahlia.
Returns a list of refund objects.
curl https://api.fluveo.com/v1/charges/ch_123/refunds \
-H "Authorization: Bearer sk_test_..."const response = await fetch("https://api.fluveo.com/v1/charges/ch_123/refunds", {
method: "GET",
headers: {
"Authorization": "Bearer sk_test_...",
},
});
console.log(await response.json());import requests
response = requests.get(
"https://api.fluveo.com/v1/charges/ch_123/refunds",
headers={"Authorization": "Bearer sk_test_..."},
)
print(response.json())<?php
$ch = curl_init("https://api.fluveo.com/v1/charges/ch_123/refunds");
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_CUSTOMREQUEST => "GET",
CURLOPT_HTTPHEADER => [
"Authorization: Bearer sk_test_...",
],
]);
echo curl_exec($ch);{
"data": [
{
"amount": 500,
"charge": "ch_123",
"created": 1767225600,
"currency": "usd",
"id": "re_123",
"metadata": {},
"object": "refund",
"payment_intent": "pi_123",
"reason": "requested_by_customer",
"status": "succeeded"
}
],
"has_more": false,
"object": "list",
"url": "/v1/charges/{charge}/refunds"
}Retrieves a refund#
GET/v1/charges/{charge}/refunds/{refund}rak_charge_read
Optional. The only version Fluveo serves is 2026-05-27.dahlia; any other value is refused with a 400. Every answer names that version in its own Fluveo-Version header, except the refusals Fluveo gives before it reads the request (no key, an unknown key, an unknown URL, a body that is not a form) and a file's bytes, which name no version and no Request-Id.
One of:
2026-05-27.dahlia.
Returns a refund object.
curl https://api.fluveo.com/v1/charges/ch_123/refunds/re_123 \
-H "Authorization: Bearer sk_test_..."const response = await fetch("https://api.fluveo.com/v1/charges/ch_123/refunds/re_123", {
method: "GET",
headers: {
"Authorization": "Bearer sk_test_...",
},
});
console.log(await response.json());import requests
response = requests.get(
"https://api.fluveo.com/v1/charges/ch_123/refunds/re_123",
headers={"Authorization": "Bearer sk_test_..."},
)
print(response.json())<?php
$ch = curl_init("https://api.fluveo.com/v1/charges/ch_123/refunds/re_123");
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_CUSTOMREQUEST => "GET",
CURLOPT_HTTPHEADER => [
"Authorization: Bearer sk_test_...",
],
]);
echo curl_exec($ch);{
"amount": 500,
"charge": "ch_123",
"created": 1767225600,
"currency": "usd",
"id": "re_123",
"metadata": {},
"object": "refund",
"payment_intent": "pi_123",
"reason": "requested_by_customer",
"status": "succeeded"
}The refund object#
Ids start with re_.
amountintegerOne of:
null.An id by default; send
expand[]=balance_transactionto get the full balance_transaction object.An id by default; send
expand[]=chargeto get the full charge object.createdintegercurrencystringAn id by default; send
expand[]=customerto get the full customer or deleted_customer object.One of:
null.descriptionstringdestination_detailsobjectAn id by default; send
expand[]=failure_balance_transactionto get the full balance_transaction object.failure_reasonstringidstringinstructions_emailstringnext_actionobjectobjectenumOne of:
refund.An id by default; send
expand[]=payment_intentto get the full payment_intent object.An id by default; send
expand[]=payment_methodto get the full payment_method object.pending_reasonenumOne of:
charge_pending,insufficient_funds,processing.presentment_detailsobjectOne of:
duplicate,expired_uncaptured_charge,fraudulent,requested_by_customer.