Track Refund

Reverse a commission when a sale is refunded

Last updated Oct 15, 2026

POST /api/v1/track/refund

Reverses the affiliate commission tied to a previously tracked sale. Send one call per refund. Each call's refund_amount_cents is added to what was already refunded on the sale (capped at the sale amount), and the commission is reduced proportionally: refunded while part of the sale remains, reversed once all of it is refunded. Omitting refund_amount_cents refunds everything that is left. This is the non-Stripe counterpart to the Stripe refund webhook — both use the same underlying reversal logic.


Authentication

All requests must include your program API key as a Bearer token.

Authorization: Bearer YOUR_PROGRAM_API_KEY
Content-Type: application/json

The key is scoped to a single program. The refund lookup is restricted to sales that belong to the authenticated program.


Request

Fields

transaction_idstringRequired

The transaction_id originally passed to POST /api/v1/track/sale. Used to locate the sale record.

refund_amount_centsintegerOptional

This refund's amount in the same unit as the sale's amount_cents — not the running total refunded so far. Omit or set to 0 to refund the rest of the sale. Must be a positive integer when provided.

refund_idstringOptional

Your own id for this refund (for example the Stripe refund id). Recommended. A refund whose refund_id was already applied is ignored, so retries are safe. Without it, a second call with the same amount for the same sale is treated as a retry and ignored. Ignored when the amount is omitted or 0 (refunding the rest is already safe to retry).

refund_reasonstringOptional

Human-readable reason for the refund. Recorded on the commission and included in partner/advertiser notifications.

reasonstringOptional

refund or chargeback. Recorded as the reason when refund_reason is not sent or empty.

refundchargeback

Example request body

curl -X POST https://api.affitor.com/api/v1/track/refund \
-H "Authorization: Bearer YOUR_PROGRAM_API_KEY" \
-H "Content-Type: application/json" \
-d '{
  "transaction_id": "txn_abc123",
  "refund_amount_cents": 5000,
  "refund_id": "re_123",
  "refund_reason": "Customer requested cancellation"
}'

Multiple refunds and retries

  • Two partial refunds of $30 and $20 on a $100 sale: send 3000 then 2000 (each with its own refund_id). The commission is reduced by 50% in total.
  • Retries: resending a call with the same refund_id returns status: "skipped" and changes nothing. Without refund_id, the amount is used to detect the retry.

Response

Success — commission reversed or refunded

{
  "success": true,
  "status": "reversed",
  "deductionAmount": 25.00,
  "commission_id": 88
}
FieldTypeDescription
successbooleanAlways true on a 200 response.
statusstring"reversed" (sale fully refunded), "refunded" (partially refunded), or "skipped" (refund already applied, or commission already reversed).
deductionAmountnumberCommission amount reversed by this call, in the commission's currency. Taken from the partner's balance only when the commission was already credited (past pending, not a test). Present when status is reversed or refunded.
commission_idintegerID of the affected commission record.

Success — sale has no commission

{
  "success": true,
  "status": "no_commission",
  "message": "Sale has no commission to reverse"
}

Already-processed refund (idempotent)

{
  "success": true,
  "status": "skipped",
  "reason": "already reversed",
  "commission_id": 88
}

Errors

Errors use the platform envelope with a stable error.code, except a retired API key and rate limiting, which use the typed envelope.

Statuserror.codeWhen
400invalid_requesttransaction_id is missing, or reason is not refund or chargeback.
401unauthorizedAuthorization header is missing, malformed, or the API token is invalid.
404not_foundNo sale record found for the given transaction_id in the authenticated program.
500internal_errorInternal error during commission reversal.

Side Effects

When a commission is reversed or refunded, Affitor:

  • transitions the commission to reversed or refunded status
  • if the commission was already credited to the partner (any status past pending, and not a test), deducts the proportional amount from the partner's balance in the same transaction as the status change; the balance can go negative, and open withdrawals are reduced to fit
  • sends an in-app notification to the partner
  • sends a manual-review warning to the advertiser if the commission had already been paid out

The status change and the deduction are applied before the response. The notifications are sent afterwards and never change the response.