Overview
Use Affonso’s server-side event endpoints when your backend already knows that something happened and you want Affonso to:- resolve the correct referral
- match the correct incentive rule
- calculate commissions automatically when applicable
- advance referral lifecycle state from trusted backend events
- process full or partial refunds
- enforce idempotency on retries
- emit the standard transaction webhooks
Which Endpoint to Use
UsePOST /conversions when:
- you want Affonso to calculate the commission for you
- you have a billing event, order, invoice, or checkout completion on your server
- you want retry-safe idempotency with
external_event_id
POST /events when:
- you want to send a normalized event from your backend
- the event may represent a conversion, lead, trial, or milestone
- you want one endpoint for both revenue and non-revenue lifecycle events
POST /conversions/{id}/refund when:
- you already recorded a conversion in Affonso
- you need to apply a full or partial refund
- you want Affonso to update the transaction and commission state for you
POST /commissions when:
- you already know the exact commission amount
- you are importing historical payouts or backfilling data
- you need a manual override rather than incentive-based calculation
Canonical Event Model
All Phase 2 server-side endpoints normalize into one internal event model before business logic runs. Shared fields:event_nameevent_type- at least one identifier:
referral_id,customer_id,external_user_id, orclick_id - optional
external_event_idfor idempotency - optional
metadata
sale_amountsale_amount_currencyexternal_event_id
product_idsprice_idsintervalis_subscription
Idempotency and Retries
external_event_id is the provider-side idempotency key whenever you want
retry-safe ingestion. Use a stable unique identifier from your system, such as:
- order ID
- invoice ID
- checkout session ID
- payment event ID Behavior by endpoint:
-
POST /conversionsstays idempotent onexternal_event_id -
POST /eventsis idempotent whenexternal_event_idis present -
POST /conversions/{id}/refundis idempotent whenexternal_event_idis present
external_event_id when retrying the same upstream event.
Choosing the Identifier
Use the identifier you can trust most in your integration:customer_id: best when the referral is already linked to your internal customer recordexternal_user_id: useful when you sync your application user ID into Affonsoclick_id: best when converting a specific tracked click into a purchasereferral_id: best when you already know the exact referral record to credit
Request Signing
Request signing is optional and non-breaking. When no signing secret is configured, standard Bearer API-key requests continue to work without extra headers.Environment Variables
S2S_REQUEST_SIGNING_SECRET
Required Headers for Signed Requests
X-Affonso-Timestamp: Unix timestamp in secondsX-Affonso-Signature: hexHMAC_SHA256(secret, "<timestamp>.<raw_body>")
What Affonso Creates
Conversion event
On a successful conversion, Affonso always records the underlying transaction. If the matched incentive is eligible, Affonso also creates the affiliate earning automatically. If no incentive matches, or if the commission is fully capped, the conversion can still succeed withcommission_amount: 0,
commission_currency: null, and earning_id: null.
Milestone event
For lead, trial, and milestone events, Affonso updates the referral lifecycle state and may create a lead incentive transaction when your program rules allow it.Refund event
Refunds reduce the remaining sale amount on the transaction. Partial refunds setsales_status to partial_refunded. Full refunds set sales_status to
refunded, and if an affiliate earning exists, its commission amount is
reduced proportionally.
Example Flows
Backend purchase
Next Steps
Conversions API Reference
Full request and response field reference for POST /conversions
Events API Reference
Send normalized conversion, lead, trial, and milestone events
Refund Conversion
Apply a full or partial refund to an existing conversion
Manual Commissions
Use the manual endpoint when you need to set the commission amount yourself
