Sales
The sales list view, statuses, refund flow, and external event IDs.
A sale is any natively tracked payment-processor event or server-to-server event that produces a commission. The list at /dashboard/sales is the source-of-truth view for commission tracking: everything that has been credited to an affiliate. The page is titled "Conversions" because the same list also covers leads and click rewards; the nav item and these docs say "Sales" for the dominant case.

What you see
The sales table has these columns:
- Date: when the sale was created
- Affiliate and Campaign: who earned it and the campaign it belongs to
- Type: Sale, Recurring, Click, or Lead
- Source: how the sale was attributed (see below)
- Amount: the underlying order or invoice amount from the processor (or the amount you send via S2S)
- Commission: the calculated commission in your currency
- Status: Pending, Approved, Paid, Refunded, Denied, or Invalidated
- Stripe metadata: subscription ID, customer ID, external event ID (where applicable)
Filter by type with the All / Sales / Leads chips at the top.
Source (how a sale was attributed)
The Source column makes it obvious how each sale was credited, so a coupon redemption is as visible as a link click. No setup is required; the tag is derived automatically from how Rekomi attributed the sale:
- Coupon: a redeemed affiliate coupon code. The code is shown inline (for example "Coupon · SARAH20").
- Link: a tracked click, or referral metadata carried on the payment processor.
- Customer match: a returning customer or a prior lead matched to an affiliate.
- Click: a pay-per-click reward rollup.
- Lead: a lead or signup capture. A free identified signup carries no commission; on a per-lead (CPL) campaign, a qualified lead form submission earns the campaign's fixed per-lead fee.
- Override: a sub-affiliate recruiter override row.
- Server: a server-to-server (S2S) postback.
- Imported: migrated from another platform.
Status meanings
- Pending: the normal state. The commission is calculated and becomes payable automatically once the refund-hold window passes; the label does not change when that happens. Default hold is 30 days from the date the sale was recorded; you can change the window in Payout settings (the grace window).
- Approved: explicitly approved (via the API or an import). Like a matured Pending sale, it is payable.
- Paid: appears on rows imported from another platform. For sales tracked in Rekomi, what has actually been paid out is shown on the affiliate's Payouts tab and in payout history rather than in this column.
- Refunded: Stripe refunded the customer; commission was clawed back.
- Denied: manually denied (via the API; the dashboard's manual controls are Validate and Invalidate). Rare. Typically only used for disputed sales where you have evidence the affiliate did not actually drive the customer.
- Invalidated: a CPC/CPL click or lead quarantined as invalid traffic (fraud-scored high-risk). Not payable. It shows an Invalidated badge with two actions: Validate to release a false positive back to payable, or Invalidate a Pending row you judge fraudulent. See CPC and CPL.
How sales are created
Sale creation paths:
- Native processor webhook. Most sales. Stripe, Paddle, Braintree, Shopify, Wix, Lemon Squeezy, Chargebee, Polar, Recurly, Gumroad, Creem, and Dodo Payments all connect natively: when a paid event fires (for Stripe,
invoice.paid) for a customer referred by an affiliate within the cookie window, Rekomi creates aConversionrow automatically. - S2S API. For any other payment gateway, or events that do not flow through a connected processor. Your backend POSTs to
/api/tracking/s2swith anexternalEventId(for de-dup),affiliateSlug,amountCents,currency. See S2S tracking. - Manual. The Add sale or bonus button (on the Sales page, and on an affiliate's detail page with that affiliate preselected) records a sale that happened outside your billing, or gives a one-off bonus commission. Pick the campaign and an approved affiliate (the seeded Test Affiliate is excluded so test rows never become payable), enter the sale amount, and Rekomi computes the commission from the campaign's rules; you can override the commission, capped at 5x the sale amount. Optional fields: customer email, a date (which backdates the record; a backdated sale already past your refund hold becomes payable right away), and a note. A bonus skips the sale amount and carries just the commission. Both follow your normal refund hold before becoming payable. Programmatically, the same action is
POST /api/conversions(see the API reference).
Not every signup is a paid sale on day one. Free signups are captured as leads (automatic for Stripe and Paddle, one line of code otherwise), so a later paid upgrade is still credited to the affiliate by email. See Track leads and signups.
External event IDs
externalEventId is the de-dup key. For Stripe webhooks it is the Stripe invoice ID. For S2S it is whatever you supply. Within an organization, the same externalEventId will never create two sales; the second call is a no-op and returns deduped = true. This makes retried webhooks and replayed S2S calls safe.
Refunds
When Stripe sends a refund webhook (charge.refunded or customer.subscription.deleted within the refund-hold window), Rekomi flips the sale status to Refunded. The affiliate's pending balance drops by the clawed-back amount. If the commission had already been paid out (rare with default 30-day hold), the next payout batch debits the overpayment.
This happens automatically. There is no manual refund button in the dashboard because Stripe is the source of truth.
Inspecting Stripe metadata
Each sale row exposes the underlying Stripe identifiers (subscription ID, customer ID, invoice ID) so you can cross-reference in your Stripe dashboard. Useful for debugging "why was this affiliate credited" questions or for audit trails.
Export
The sales table has a CSV export button in the top-right that downloads the current filtered view. The CSV includes attribution_method and coupon_code as the last two columns, so coupon attribution survives the export. For programmatic exports, use the Sales read API: GET /api/conversions?affiliateId=...&status=Approved&since=2026-01-01 returns paginated rows including attributionMethod and couponCode. Pagination cursor take maxes at 200. (The endpoint path keeps /conversions so existing integrations don't break; the UI is at /dashboard/sales.)
Reporting view
For aggregate metrics (clicks, sales, conversion rate, top affiliates), see Reports. The sales list is the raw event log; reports is the rollup.