Features Pricing Services
Compare
Resources
Contact Start Free Trial
Home/Docs/Commissions

Commission Rules

Soryk's commission engine answers one question per order: how much, to whom? The answer is a function of (a) the rules you've defined, (b) the agent attribution on the order, and (c) any overrides you've recorded. Everything is computed on demand from paid Shopify orders — there's no separate "commissions ledger" to keep in sync.

The mental model

Five concepts, in order:

  1. Rules — definitions you write: scope, base, rate, priority. Stored as soryk_commission_rule metaobjects.
  2. Earnings — computed at read-time by matching the most specific rule against each paid order. Never stored — always re-derivable.
  3. Payouts — when you mark earnings as paid (bulk action). Stored as soryk_commission_payment.
  4. Alerts — automatic flags when a refund hits an order whose commission was already paid.
  5. Overrides — manual corrections for ambiguous attributions. Take priority over everything.
i

Why earnings aren't stored. Computing on read means rule changes apply retroactively to unpaid orders, you can't have stale data, and the audit trail is the union of (rules + paid Shopify orders) — both of which you fully own.

Creating rules

Go to Admin → Commissions → Regole (Rules) → Create rule.

Scope

ScopeApplies toTypical use
globalEvery agent, every orderThe baseline: "5% on everything".
agentOne specific agent, all their orders"Marco gets 7%, everyone else gets 5%."
collectionAny agent, any order containing items in this collection"Premium wines pay 8%, base catalog pays 5%."
variantAny agent, any order containing this exact SKUSKU-level promotions or specific high-margin items.

Base

What number to multiply the rate against.

totalOrder total — includes everything (subtotal + tax + shipping − discounts).
subtotalJust the line items, before tax and shipping.
no_shippingTotal minus shipping.
no_tax_no_shippingTotal minus tax and shipping. Most common — agents shouldn't earn commission on tax revenue you forward to the government.

Priority

An integer for tie-breaks. Higher wins. When two rules apply to the same order, the engine picks the one with the highest priority. If priorities tie, the more specific scope wins (variant > collection > agent > global).

Deduct on refund

If on, refunds against an already-paid commission raise an alert for you to resolve. If off, refunds are silently ignored and the agent keeps the commission.

How the engine calculates

For each paid Shopify order:

  1. Identify the agent. Lookup order: soryk_commission_override → tag soryk_agent:<email> → multi-agent fallback (companyId → agents map).
  2. Find candidate rules whose scope matches (agent + collection/variant filters applied).
  3. Pick the rule with the highest priority. Ties resolved by scope specificity.
  4. Compute earning = base amount × rate %.
  5. Mark the earning as paid if it appears in any soryk_commission_payment for this agent.
i

Performance. The engine pre-builds a companyId → agents[] index and an email → agent map (raw + sanitized) so the per-order work is O(1). Tested smoothly past 10,000 orders per shop.

Recording payouts

  1. Open Commissions → Da pagare (To pay).
  2. The list shows all unpaid earnings, grouped by agent.
  3. Multi-select the rows you want to pay (or use "Select all by agent").
  4. Click Paga commissioni (Pay commissions).
  5. In the modal: pick a method (bank_transfer, cash, paypal, custom), add a note, set the date.
  6. Save. A soryk_commission_payment is created and those orders flip to "paid" in the engine output.

To revoke: open Commissions → Pagate (Paid), click the payment, click Delete. The earnings revert to pending.

!

Idempotency. The bulk-pay endpoint refuses to create a duplicate payment with HTTP 409 if any of the orders are already in another payment for the same agent. This is intentional — it prevents accidental double-payment when two admins are clicking at the same time.

Refund alerts

When Shopify fires a refunds/create webhook on an order whose commission has already been paid, Soryk raises a soryk_commission_alert. You'll see a red banner on the admin home with a "Review →" link.

Resolve from Commissions → Alerts. Options:

Alerts are deduplicated on (orderId, paymentId) so refund webhook re-deliveries don't create duplicates.

Manual overrides

For orders where attribution is wrong or ambiguous (e.g. two agents on one company, no explicit tag), use Fix attribution.

  1. On Da pagare, you'll see a banner: "N orders have ambiguous attribution".
  2. Click Fix attribution (N).
  3. For each row, pick the correct agent from the dropdown.
  4. Save. Each row creates a soryk_commission_override that takes precedence over tags and fallback.

An override can also be deleted to fall back to the regular attribution logic.

Multi-agent fallback

When an order doesn't have a soryk_agent:<email> tag (e.g. placed via the customer app or imported from elsewhere), the engine looks up the order's company and checks how many agents are assigned:

Manager override (Pro tier)

If an agent has a manager set up, the manager can earn an additional override % on top of the regular commission for that agent's orders. Defined per-manager in their profile (manager_override_percent).

Example: Marco's order pays 5% to Marco. His manager Laura has a 1% override. Engine emits two earning rows: 5% to Marco, 1% to Laura.

Online orders inclusion

By default, only agent-mediated draft orders count. To include orders placed directly through the online storefront (no agent involved), turn on commissionsOnOnlineOrders in Settings → Commissions. The multi-agent fallback then determines who earns.

CSV export

From Commissions, click Export CSV. Three datasets:

Useful for accounting hand-off and external payout systems (e.g. cargando a un gestionale paghe).

Worked examples

Example A — Tiered by collection

Rule 1 (priority 1): global, no_tax_no_shipping, 5%, deduct_on_refund=true
Rule 2 (priority 10): collection "Premium Wines", no_tax_no_shipping, 8%, deduct_on_refund=true

Order with €1,000 in regular wine + €500 in Premium → Rule 2 wins (highest priority, scope match). Earning = €1,500 × 8% = €120.

Order with €1,000 in regular wine only → Rule 2 doesn't match. Rule 1 wins. Earning = €1,000 × 5% = €50.

Example B — Manager + agent split

Rule 1: agent "Marco", no_tax_no_shipping, 6%, priority 5
Marco's manager Laura has manager_override_percent = 1.5

Marco places a €2,000 order → Marco earns €120 (6%), Laura earns €30 (1.5% override).

Example C — Override on ambiguous order

An order arrives via customer app for company "Acme S.r.l." which has both Marco and Sara assigned. Engine puts it in the ambiguous pile. You open Fix attribution, pick Sara, save. From now on, this specific order pays Sara — even if rules change later.

Was this helpful?
Edit this page on GitHub