Skip to main content
By default, Partnero uses customer-based attribution — a customer is permanently linked to one partner, and all their transactions generate commissions for that partner. Transaction-based attribution changes this. Instead of looking at who the customer belongs to, Partnero looks for a partner_key in the payment metadata to decide which partner should receive the commission. This means the same customer can generate commissions for different partners on different transactions.

When to use this

  • A marketplace where the same buyer purchases from different sellers, each represented by a different partner
  • A SaaS platform where customers can be upsold by different agencies, and each agency should earn commission on the deals they close
  • A business where the referring partner is tracked at the payment level (e.g., stored in Stripe charge metadata) rather than at the customer level

Setting up

  1. Go to Program Settings → Edit program
  2. Find Commission attribution model
  3. Select Transaction-based
  4. Save
This setting only affects how new incoming transactions are attributed. Existing customers and commissions are not modified.

How it works

When a payment webhook arrives (or an API call is made), Partnero checks for a partner_key field in the payment metadata before any other customer lookup.
  1. Read partner_key from payment metadata
  2. Find the partner matching that key
  3. Find or create a customer record linked to that specific partner
  4. Calculate commission for that partner
If no partner_key is found, Partnero falls back to the standard customer-based attribution logic.

Customer records

To support the same real-world customer being linked to multiple partners, Partnero creates separate customer records with a composite identifier:
{customer_id}__pkey_{partner_identifier}
For example, Stripe customer cus_123 attributed to partner PARTNER_A becomes stripe_cus_123__pkey_PARTNER_A. This happens automatically — no action required on your part.

Examples

Imagine Stripe customer cus_123 making three separate purchases over time.

Partner key is present

Chargepartner_key in metadataResult
First chargePARTNER_ANew customer created, linked to Partner A. Commission → Partner A
Second chargePARTNER_BSeparate customer record created for Partner B. Commission → Partner B
Third chargePARTNER_AExisting customer record found. Commission → Partner A (no new record)
Each partner gets commission only for the transactions that carry their key. The same Stripe customer generated commissions for two different partners.

No partner key or invalid key

Chargepartner_key in metadataResult
Charge with no key(empty)Falls back to standard customer-based attribution. If the customer is already linked to a partner, that partner gets the commission.
Charge with invalid keyINVALID_KEYPartner not found. Falls back to standard customer-based attribution.
Transaction-based attribution is additive — it only changes behavior when a valid partner_key is present. All existing attribution methods (referral links, promotion codes, customer matching) continue to work as a fallback.

Integration guides

Stripe

Add partner_key to the metadata of charges, subscriptions, invoices, or the Stripe customer object. Partnero checks all of these locations. Checkout Session:
const session = await stripe.checkout.sessions.create({
  line_items: [{ price: 'price_xxx', quantity: 1 }],
  mode: 'payment',
  success_url: 'https://yoursite.com/success',
  cancel_url: 'https://yoursite.com/cancel',
  metadata: {
    partner_key: 'PARTNER_A'
  }
});
Subscription:
const subscription = await stripe.subscriptions.create({
  customer: 'cus_123',
  items: [{ price: 'price_xxx' }],
  metadata: {
    partner_key: 'PARTNER_A'
  }
});
One-time charge:
const charge = await stripe.charges.create({
  amount: 9999,
  currency: 'usd',
  customer: 'cus_123',
  metadata: {
    partner_key: 'PARTNER_A'
  }
});
Stripe customer metadata (applies to all future charges for this customer unless overridden per charge):
await stripe.customers.update('cus_123', {
  metadata: {
    partner_key: 'PARTNER_A'
  }
});
Partnero checks metadata in this order: charge/invoice metadata → subscription metadata → Stripe customer metadata. A partner_key on a specific charge overrides one set on the customer.

Paddle

Add partner_key to the custom_data object on transactions or subscriptions.
Paddle.Checkout.open({
  items: [{ priceId: 'pri_xxx', quantity: 1 }],
  customData: {
    partner_key: 'PARTNER_A'
  }
});
Or server-side:
curl https://api.paddle.com/transactions \
  -H "Authorization: Bearer YOUR_PADDLE_KEY" \
  -d '{
    "items": [{"price_id": "pri_xxx", "quantity": 1}],
    "custom_data": {
      "partner_key": "PARTNER_A"
    }
  }'

WooCommerce

Add partner_key to the order meta data. This can be done via a plugin, custom code, or the WooCommerce REST API.
curl https://yourstore.com/wp-json/wc/v3/orders \
  -u consumer_key:consumer_secret \
  -d '{
    "meta_data": [
      {
        "key": "partner_key",
        "value": "PARTNER_A"
      }
    ]
  }'

Chargebee

Partnero reads the partner key from the Chargebee customer custom fields cf_partnero_partner or cf_referral_code. Set these fields on the customer in Chargebee, and Partnero will use them for per-transaction attribution when transaction-based mode is enabled.

API

When using the Partnero API directly, include the partner field in your transaction request. The customer is automatically created and linked to that partner.
curl https://api.partnero.com/v1/transactions \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "partner": {
      "key": "PARTNER_A"
    },
    "customer": {
      "key": "customer_123",
      "email": "[email protected]"
    },
    "key": "invoice_789",
    "amount": 99.99,
    "action": "sale"
  }'
With transaction-based attribution via the API, you don’t need to create the customer separately — it’s created automatically when the transaction is recorded.

Where partner_key is read from

IntegrationMetadata location
StripeCharge metadata → invoice/subscription metadata → Stripe customer metadata
PaddleTransaction or subscription custom_data
WooCommerceOrder meta_data
ChargebeeCustomer fields cf_partnero_partner or cf_referral_code
APIpartner field in request body

Next steps