
Record the agreement behind a referral
A referral connects the customer making an introduction with the customer accepting it. Wildo provides a record for the code, both accounts, conversion dates and the reward promised to each side.
Your application implements the sharing, acceptance and reward workflow around that record. This gives the programme a common data structure while leaving its commercial rules explicit.
Example — Define a reward for an introduction
An application promises credits to both customers after a qualifying purchase. The referral stores both reward definitions; the application’s conversion workflow decides when the qualification is met and applies each reward.
For engineers
ReferralSchema carries the referrer account, the referred account, a globally unique code, status, dates and two reward-applied flags. Each account reference has its own scope discriminator, so one relationship cannot assume the other account is also organisation-scoped.
The referrer reward contract is:
export const ReferrerRewardSchema = z.object({
type: z.enum(ReferrerRewardType),
/** Credit amount (for CREDIT type), discount percentage (for DISCOUNT), etc. */
value: z.number().min(0),
/** Credit pool key (for CREDIT type) */
creditPoolKey: z.string().optional(),
/** Feature key (for FEATURE type) */
featureKey: z.string().optional(),
/** Duration in days (for temporary rewards) */
durationDays: z.number().min(1).optional(),
/** Commission percentage (for COMMISSION type) */
commissionPercentage: z.number().min(0).max(100).optional(),
});
export type ReferrerReward = z.infer<typeof ReferrerRewardSchema>;
This is the actual model declaration. It can represent credit, feature, discount or commission details according to the reward kind; the referred reward additionally supports trial extension. A declared durationDays is stored policy, not an automatic scheduler.
Supply the application-owned steps
| Step | Application responsibility |
|---|---|
| Issue and share | Generate a unique code and provide an authorised customer surface |
| Accept | Validate the code and bind the referred account with its correct scope |
| Qualify | Decide which purchase or event counts, and record conversion |
| Reward | Apply each promised benefit with a retry-safe state transition |
| Reconcile | Confirm the benefit actually landed before marking its applied flag |
The engine’s referral resource exposes internal operations. There is no standard customer share-code route or automatic subscription-to-referral conversion service. Invoke the registered resource through trusted backend code; author a public flow only with its own access and input rules.
Keep reward state honest
The applied booleans are bookkeeping fields, not a transaction or deduplication mechanism by themselves. The application must arrange the claim and reward effect so repeated events cannot pay twice, and failed effects remain distinguishable from completed ones. Credit-pool balance operations can supply the credit mutation, but the referral still owns when and why it happens.
Treat the schema’s lifecycle commentary as the intended shape, not proof of a running reward engine. A promotion typed as a referral programme can describe the offer without executing this workflow. The referral code’s usage-data classification also matters when designing retention and subject-data handling.