curl --request POST \
--url https://firstpromoter.com/api/v1/track/refund \
--header 'X-API-KEY: <api-key>'import requests
url = "https://firstpromoter.com/api/v1/track/refund"
headers = {"X-API-KEY": "<api-key>"}
response = requests.post(url, headers=headers)
print(response.text)const options = {method: 'POST', headers: {'X-API-KEY': '<api-key>'}};
fetch('https://firstpromoter.com/api/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://firstpromoter.com/api/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_HTTPHEADER => [
"X-API-KEY: <api-key>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"net/http"
"io"
)
func main() {
url := "https://firstpromoter.com/api/v1/track/refund"
req, _ := http.NewRequest("POST", url, nil)
req.Header.Add("X-API-KEY", "<api-key>")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://firstpromoter.com/api/v1/track/refund")
.header("X-API-KEY", "<api-key>")
.asString();require 'uri'
require 'net/http'
url = URI("https://firstpromoter.com/api/v1/track/refund")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["X-API-KEY"] = '<api-key>'
response = http.request(request)
puts response.read_body{
"id": 33847726,
"type": "refund",
"amount_cents": -1000,
"reward": {
"id": 10940148,
"status": "approved",
"amount": -200,
"unit": "cash",
"created_at": "2024-09-11T14:36:01.016Z",
"lead": {
"id": 20738339,
"state": "cancelled",
"email": "hello@testmintli.com",
"uid": null,
"customer_since": "2024-09-11T14:22:12.160Z",
"cancelled_at": "2024-09-11T15:07:46.174Z",
"plan_name": null,
"suspicion": "no_suspicion",
"username": null,
"website": null,
"created_at": "2024-09-09T16:22:44.168Z",
"split_promotion_id": null,
"custom_fields": null,
"split_percentage_value": null,
"visitor_sub_id": null
},
"event_id": "test_sale_12340987_refund",
"conversion_amount": -1000,
"tier_level": 1,
"split_type": null
},
"lead": {
"id": 20738339,
"state": "cancelled",
"email": "hello@testmintli.com",
"uid": null,
"customer_since": "2024-09-11T14:22:12.160Z",
"cancelled_at": "2024-09-11T15:07:46.174Z",
"plan_name": null,
"suspicion": "no_suspicion",
"username": null,
"website": null,
"created_at": "2024-09-09T16:22:44.168Z",
"split_promotion_id": null,
"custom_fields": null,
"split_percentage_value": null,
"visitor_sub_id": null
},
"promoter": {
"id": 3920164,
"status": "active",
"cust_id": "",
"email": "peluwydo@mailinator.com",
"created_at": "2022-04-26T15:28:24.800Z",
"temp_password": "xxxxxxxxxx",
"default_promotion_id": 4210919,
"pref": "db1znwe",
"default_ref_id": "8yi2epelut",
"note": "This is a note",
"w8_form_url": null,
"w9_form_url": null,
"parent_promoter_id": 577918,
"earnings_balance": {
"cash": 50744
},
"current_balance": {
"cash": 20044
},
"paid_balance": {
"cash": 30700
},
"auth_token": "xxxxxxxxxxxxxx"
}
}{
"message": "Error. Amount blank or invalid."
}{
"message": "The 'refund' event with the id 'test_sale_12340987_refund' already exists."
}Tracking refunds and negative commissions
The refund call is similar to the sale call. It works the same way, except that it generates negative commissions.
POST https://firstpromoter.com/api/v1/track/refundcurl --request POST \
--url https://firstpromoter.com/api/v1/track/refund \
--header 'X-API-KEY: <api-key>'import requests
url = "https://firstpromoter.com/api/v1/track/refund"
headers = {"X-API-KEY": "<api-key>"}
response = requests.post(url, headers=headers)
print(response.text)const options = {method: 'POST', headers: {'X-API-KEY': '<api-key>'}};
fetch('https://firstpromoter.com/api/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://firstpromoter.com/api/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_HTTPHEADER => [
"X-API-KEY: <api-key>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"net/http"
"io"
)
func main() {
url := "https://firstpromoter.com/api/v1/track/refund"
req, _ := http.NewRequest("POST", url, nil)
req.Header.Add("X-API-KEY", "<api-key>")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://firstpromoter.com/api/v1/track/refund")
.header("X-API-KEY", "<api-key>")
.asString();require 'uri'
require 'net/http'
url = URI("https://firstpromoter.com/api/v1/track/refund")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["X-API-KEY"] = '<api-key>'
response = http.request(request)
puts response.read_body{
"id": 33847726,
"type": "refund",
"amount_cents": -1000,
"reward": {
"id": 10940148,
"status": "approved",
"amount": -200,
"unit": "cash",
"created_at": "2024-09-11T14:36:01.016Z",
"lead": {
"id": 20738339,
"state": "cancelled",
"email": "hello@testmintli.com",
"uid": null,
"customer_since": "2024-09-11T14:22:12.160Z",
"cancelled_at": "2024-09-11T15:07:46.174Z",
"plan_name": null,
"suspicion": "no_suspicion",
"username": null,
"website": null,
"created_at": "2024-09-09T16:22:44.168Z",
"split_promotion_id": null,
"custom_fields": null,
"split_percentage_value": null,
"visitor_sub_id": null
},
"event_id": "test_sale_12340987_refund",
"conversion_amount": -1000,
"tier_level": 1,
"split_type": null
},
"lead": {
"id": 20738339,
"state": "cancelled",
"email": "hello@testmintli.com",
"uid": null,
"customer_since": "2024-09-11T14:22:12.160Z",
"cancelled_at": "2024-09-11T15:07:46.174Z",
"plan_name": null,
"suspicion": "no_suspicion",
"username": null,
"website": null,
"created_at": "2024-09-09T16:22:44.168Z",
"split_promotion_id": null,
"custom_fields": null,
"split_percentage_value": null,
"visitor_sub_id": null
},
"promoter": {
"id": 3920164,
"status": "active",
"cust_id": "",
"email": "peluwydo@mailinator.com",
"created_at": "2022-04-26T15:28:24.800Z",
"temp_password": "xxxxxxxxxx",
"default_promotion_id": 4210919,
"pref": "db1znwe",
"default_ref_id": "8yi2epelut",
"note": "This is a note",
"w8_form_url": null,
"w9_form_url": null,
"parent_promoter_id": 577918,
"earnings_balance": {
"cash": 50744
},
"current_balance": {
"cash": 20044
},
"paid_balance": {
"cash": 30700
},
"auth_token": "xxxxxxxxxxxxxx"
}
}{
"message": "Error. Amount blank or invalid."
}{
"message": "The 'refund' event with the id 'test_sale_12340987_refund' already exists."
}Authorizations
Query Parameters
required if uid is null
Email of the lead/sign-up
required if email is null
uid of the lead added on signup tracking
Transaction or refund event ID. It's required to avoid generating duplicate refunds in case you mistakenly send the same API call multiple times.
The refund amount in cents. It's used to calculate the negative commissions/rewards.
This field is only required if the currency of the sale/refund is not the same as the one set on FirstPromoter settings. We'll automatically convert the amount from this currency to the default one set on your FirstPromoter account.
Number of subscriptions/items refunded. If it's only one, you can skip this parameter.
The event id of the sale for which the refund is processed. This value must match the event_id value sent in the sale tracking API call. (Note: This field is marked as optional, but if you track multiple products or change the commission level often, it becomes required to track refunds correctly)
Set this to true to skip email notifications. Default is false.
ISO 8601 date string of when the refund occurred. Defaults to now.
Set to true for e-commerce refunds (non-subscription).