curl --request POST \
--url https://go.affixo.dev/v1/track/refund \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"external_id": "order_1234",
"refunded_amount": 25,
"refunded_amount_cents": 2500,
"currency": "usd"
}
'import requests
url = "https://go.affixo.dev/v1/track/refund"
payload = {
"external_id": "order_1234",
"refunded_amount": 25,
"refunded_amount_cents": 2500,
"currency": "usd"
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({
external_id: 'order_1234',
refunded_amount: 25,
refunded_amount_cents: 2500,
currency: 'usd'
})
};
fetch('https://go.affixo.dev/v1/track/refund', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://go.affixo.dev/v1/track/refund",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'external_id' => 'order_1234',
'refunded_amount' => 25,
'refunded_amount_cents' => 2500,
'currency' => 'usd'
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: application/json"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://go.affixo.dev/v1/track/refund"
payload := strings.NewReader("{\n \"external_id\": \"order_1234\",\n \"refunded_amount\": 25,\n \"refunded_amount_cents\": 2500,\n \"currency\": \"usd\"\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Authorization", "Bearer <token>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://go.affixo.dev/v1/track/refund")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"external_id\": \"order_1234\",\n \"refunded_amount\": 25,\n \"refunded_amount_cents\": 2500,\n \"currency\": \"usd\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://go.affixo.dev/v1/track/refund")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"external_id\": \"order_1234\",\n \"refunded_amount\": 25,\n \"refunded_amount_cents\": 2500,\n \"currency\": \"usd\"\n}"
response = http.request(request)
puts response.read_body{
"ok": true,
"conversion_id": "<string>",
"refund": "full"
}{
"error": "invalid_json"
}{
"error": "unauthorized"
}{
"error": "currency_mismatch",
"message": "<string>",
"sale_currency": "usd"
}{
"error": "conversion_failed"
}Refund a sale
Refunds the sale recorded under external_id, which is required, and shrinks or claws back its commission. Send refunded_amount (major units) or refunded_amount_cents (minor units, converted in the sale’s currency) as the TOTAL refunded so far on that order, not the amount of this one refund. If it is below the sale amount the refund is partial and the commission shrinks in proportion. If it is at or above the sale amount, or you leave it out, the whole sale is refunded. Commission that was already paid becomes a clawback. A refund that arrives before its sale is held and applied when the sale arrives; if the held amount covers the whole sale, the sale is fully refunded. A refund is always in the sale’s currency. You can leave currency out, but if you send one that differs from the sale’s you get 422 currency_mismatch and nothing is recorded. A refund with an amount that arrives before its sale has no sale currency to go by, so it needs currency (422 currency_required without one). Safe to retry. MCP connector tokens get 403 insufficient_scope.
curl --request POST \
--url https://go.affixo.dev/v1/track/refund \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"external_id": "order_1234",
"refunded_amount": 25,
"refunded_amount_cents": 2500,
"currency": "usd"
}
'import requests
url = "https://go.affixo.dev/v1/track/refund"
payload = {
"external_id": "order_1234",
"refunded_amount": 25,
"refunded_amount_cents": 2500,
"currency": "usd"
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({
external_id: 'order_1234',
refunded_amount: 25,
refunded_amount_cents: 2500,
currency: 'usd'
})
};
fetch('https://go.affixo.dev/v1/track/refund', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://go.affixo.dev/v1/track/refund",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'external_id' => 'order_1234',
'refunded_amount' => 25,
'refunded_amount_cents' => 2500,
'currency' => 'usd'
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: application/json"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://go.affixo.dev/v1/track/refund"
payload := strings.NewReader("{\n \"external_id\": \"order_1234\",\n \"refunded_amount\": 25,\n \"refunded_amount_cents\": 2500,\n \"currency\": \"usd\"\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Authorization", "Bearer <token>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://go.affixo.dev/v1/track/refund")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"external_id\": \"order_1234\",\n \"refunded_amount\": 25,\n \"refunded_amount_cents\": 2500,\n \"currency\": \"usd\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://go.affixo.dev/v1/track/refund")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"external_id\": \"order_1234\",\n \"refunded_amount\": 25,\n \"refunded_amount_cents\": 2500,\n \"currency\": \"usd\"\n}"
response = http.request(request)
puts response.read_body{
"ok": true,
"conversion_id": "<string>",
"refund": "full"
}{
"error": "invalid_json"
}{
"error": "unauthorized"
}{
"error": "currency_mismatch",
"message": "<string>",
"sale_currency": "usd"
}{
"error": "conversion_failed"
}Authorizations
Workspace API key, e.g. sa_live_…. Scopes: read / write / track / *.
Body
"order_1234"
Total refunded so far, in major units.
25
Total refunded so far, in minor units. Don't send it together with refunded_amount.
x >= 02500
The sale's currency. Optional once the sale is recorded, and must match it. Required when the refund carries an amount and its sale hasn't arrived yet.
"usd"