Rewards and delivery

How a Reward is earned, how each delivery method works, the delivery statuses, cash payouts, refunds, and voids.

A Reward is what a participant earned from one Event under one terms version. Earning and delivery are separate: the Reward is an accounting fact, and its fulfillment record says whether it reached the beneficiary.

How a Reward is earned

  1. RefRef decides the Event: attributed to a referral, or not.
  2. Each benefit rule of the Event's type evaluates it with the terms version in effect when the Event occurred.
    • A referrer rule earns only while the referrer is enrolled in the Program when RefRef evaluates the Event.
    • A referee rule earns for the referred customer of the referral.
    • A subject rule of a loyalty Program earns for the participant of the Event.
  3. The rule's duration and limit decide whether this Event still earns. A purchase rule can wait for proof of the participant's paid history.
  4. RefRef records the Reward and its fulfillment record, and sends reward.earned.

An earned Reward never changes. A refund or a lost dispute adds an adjustment that lowers its net amount; a restoration raises it again.

Delivery methods

The Program's Delivery settings choose the method for each Reward kind when the Reward is earned. See Programs.

MethodWho delivers
operatorYour product. RefRef sends reward.earned; your product grants the Reward and confirms it. This is the default for credit, discounts, and custom Rewards.
manualYour team, by hand. Then an owner or admin selects Mark granted or Mark paid in the Console.
billing_creditRefRef adds account credit through your billing provider (Stripe, Dodo Payments, or Shopify store credit)
billing_discountRefRef creates a discount for the customer in your billing provider or store
billing_plan_upgradeRefRef moves the customer's subscription to a higher plan for free periods
payoutRefRef pays cash to the beneficiary's PayPal address, in US dollars. This is the default for cash.

Which billing methods a provider supports is on each integration page.

Through your product

Subscribe a webhook endpoint to reward.earned. Grant the Reward, using the Reward ID as the idempotency key, then confirm:

  • In the default on_delivery mode, a 2xx answer records the fulfillment. Answer 202 Accepted to a Reward that this endpoint does not grant.
  • In the explicit mode, call POST /v1/rewards/{rewardId}/fulfillment after the grant.

To find Rewards that a webhook did not reach, read GET /v1/rewards?deliveryMethod=operator&fulfillmentStatus=pending.

Through your billing provider

RefRef delivers at the billing provider where the beneficiary pays: the provider of their active subscription, else of their latest purchase, else the one connected provider that can deliver the Reward. It delivers to the beneficiary's customer in that provider, which it learns from the customer's payments, or from billingIds that you set with PUT /v1/participants. A Reward whose beneficiary has no customer ID there waits. When the beneficiary pays at two providers, or the provider where they pay cannot deliver the Reward, the Reward waits with billing_provider_ambiguous or billing_provider_unsupported (plan_upgrade_unmapped for a plan upgrade without a plan at that provider): on the Rewards page, choose the connection with Deliver through, mark it granted if you delivered it yourself, or void it. RefRef never delivers through another provider by itself. The Account reward hold delays these deliveries. RefRef retries a failed call with backoff, up to 12 attempts. A delivery is the provider's success answer: RefRef does not track whether the customer used the credit or the code.

Delivery statuses

StatusMeaning
pendingWaiting: for your product, a hold, a customer ID, payout details, or the next payout
in_progressRefRef is delivering it, or the cash is on a payout statement or in a transfer
fulfilledDelivered, granted, or paid
failedThe delivery failed and needs you
cancelledNot delivered: voided before delivery, or the purchase was fully refunded first
revocation_pendingVoided or fully refunded after delivery; the grant must be taken back
revokedThe grant was taken back

A Reward's delivery.reason says why it waits or failed, for example awaiting_operator, missing_billing_id, billing_provider_ambiguous, awaiting_payout_details, or provider_error.

On the Rewards page, owners and admins can Mark granted, Mark paid, Mark taken back, Retry delivery, Deliver through a connection, and Void reward….

Cash Rewards and payouts

With Paid out by RefRef, RefRef pays cash Rewards to referrers:

  • Cash is paid in US dollars, to a PayPal address.
  • The referrer enters the PayPal address, the country, and the acceptance of the payout terms in the Widget. A Reward waits until the details exist.
  • A Reward waits for the Payout hold (30 days by default), then joins the next payout when the referrer's total reaches the Minimum payout.
  • RefRef drafts a statement before each payout cycle. Your Workspace pays the statement, then RefRef pays the referrers. The Payouts page shows statements and transfers, read-only.
  • payout.paid, payout.failed, and payout.returned webhooks report each transfer.
  • In a Sandbox Project, payouts go through a simulated provider and move no money.

Partners cannot enter payout details in the Partner app. A partner's cash Reward paid out by RefRef waits; use Paid by you, recorded by hand for partners that you pay yourself.

With Paid by you, recorded by hand, you pay the referrer, then select Mark paid.

Refunds

A refund or a lost dispute of a purchase reduces the Rewards that were calculated from it, in proportion. A full refund before a billing delivery cancels the delivery. When a purchase is fully refunded (or lost in a dispute, or cancelled), RefRef also takes back a non-cash Reward that it already delivered, as a void does: it debits the account credit, removes the discount code, or switches the plan back. A Reward that you deliver yourself waits in revocation_pending until you record the removal. A partial refund leaves a delivered Reward in place, and a later restoration does not deliver it again. If the customer already spent the credit, the take-back stops for you to decide. A refund is not a void: the Reward still counts toward its caps.

Void a Reward

Owners and admins void a Reward on the Rewards page with Void reward…. Choose a reason (Fraud, Duplicate, Operator error, Other) and write a note.

  • A void is final. There is no reinstatement.
  • The net amount becomes 0. The Reward still counts against the rule's duration, but it frees one place under the rule's limit.
  • A delivery that did not start is cancelled.
  • A delivered credit, discount, or custom Reward moves to revocation_pending. Take it back in your product and record it with Mark taken back or POST /v1/rewards/{rewardId}/revocation. RefRef takes back billing deliveries itself.
  • Cash that RefRef already paid is not recovered; the amount comes off the referrer's next payouts.

RefRef sends reward.voided, and reward.revoked after the take-back.

A Reward does not prove that money, credit, or a discount reached the customer, and a void does not recover what your product already delivered.

On this page