Developer notes
Data model
Section titled “Data model”| Table | Contents |
|---|---|
?:kv_rp_codes |
user_id, code (unique, upper case), last_ip (self-referral check) |
?:kv_rp_clicks |
owner_id, visitor (random id), ip_hash, day (unique per owner, visitor and day), landing, referrer_host |
?:kv_rp_referrals |
friend_id, referrer_id, source (link, code, invite), status (J joined, O ordered, R rewarded, X not eligible), welcome coupon code, promotion, state (A active, U used, E expired), expiry |
?:kv_rp_orders |
order_id, parent_order_id, checkout_id, owner_id, kind (R referral, A affiliate), method (cookie, form, code, account), code, customer_id |
?:kv_rp_ledger |
entry_id, uniq, type (R reward, C commission, A adjustment), user_id (beneficiary), friend_id, friend_email, order_id, checkout_id, base, rate, amount, points, method (wallet, points, coupon, cash), status (P, W, A, D, R), hold_until, flags, coupon_code, ref, payout_id, note |
?:kv_rp_affiliates |
user_id, status (P, A, D, S), website, promotion, payout_method, payout_details, rate_type, rate_value, admin_note |
?:kv_rp_rates |
category_id, rate (%) |
?:kv_rp_payouts |
payout_id, user_id, amount, status (R requested, D paid, X rejected), method, details, reference, note |
?:kv_rp_invites |
invite_id, user_id, email (normalised), joined_user_id |
uniq makes entries idempotent: R:<md5 of the friend's normalised e-mail> (one reward per friend), C:<order_id>, A:<entry_id>.
- Capture.
window.kvRpConfigis printed inindex:footer(built indispatch_before_display, the same for every visitor).js/addons/kv_referral_program/func.jsreads?ref=, storesCODE.timestampin thekv_rpcookie (consent-aware viawindow.kvConsent) or sessionStorage, posts a click beacon tokv_referral_program.click(writes only?:kv_rp_clicks, returns the welcome bar text) and adds the hidden fieldkv_rp_refto POST forms. No session or?:storage_datawrites from storefront GETs. - Attribution.
place_order: the code comes from thekv_rp_codefield, thekv_rp_reffield or the cookie (storefront only), else from the customer’s referrer (?:kv_rp_referrals, also for admin orders). Vendor orders copy the parent’s row. Order edits and API orders are not attributed. Suspended affiliates and own links are ignored. - Entries. Leaf orders get a commission (approved affiliate) or the friend’s referral reward (first checkout per mailbox). Fraud flags (
Fraud::check(),Fraud::duplicateFriend()), caps and the existing-customer check run here. - Hold.
change_order_status_post: a paid status setshold_until; a refund/cancel status rejects (reward: when all vendor orders of the checkout are in such a status); a paid commission gets an adjustment.Engine::release()(scheduler, or at once with hold 0) recomputes the reward base from the paid vendor orders, checks the minimum, sends flagged/manual entries to review and delivers rewards (fn_kv_customer_wallet_credit(),fn_change_user_points(), or a code of the promotion). - Coupons.
Coupons::issue()appends a code to the promotion’sauto_couponscondition under a named DB lock; codes used in an order (place_order,$cart['coupons']) or expired are withdrawn. The hookpromotion_apply_before_get_promotions(priority 2000) drops the core’s per-request cache of cart promotions after a code list changed.
Hooks used
Section titled “Hooks used”place_order, change_order_status_post, delete_order, update_profile (new storefront customer), post_delete_user, dispatch_before_display (script configuration, menu flags), before_dispatch (scheduler fallback), promotion_apply_before_get_promotions. Signatures are identical in 4.17.2 and 4.21.2.
Template hooks: index:scripts, index:footer, profiles:my_account_menu, profiles:account_info (referral code field on registration).
PHP API
Section titled “PHP API”fn_kv_referral_program_get_code($user_id); // the customer's code ('' when the add-on is off)fn_kv_referral_program_get_referrer($user_id); // who referred the customer (user id or 0)JavaScript: window.kvRp.get() returns the stored code of the visitor or ''.
REST API (read only)
Section titled “REST API (read only)”| Request | Returns |
|---|---|
GET /api/kv_referrals |
ledger entries; filters type, status, user_id, order_id, page, items_per_page |
GET /api/kv_referrals/<entry_id> |
one entry |
GET /api/kv_affiliates |
affiliates with status, code, rate, clicks, orders, balance, paid, pending; filter status |
GET /api/kv_affiliates/<user_id> |
one affiliate |
Privilege: View referral program. Other methods are refused.
Coexistence
Section titled “Coexistence”Store Credit Wallet (rewards with source = kv_referral_program, payouts), Reward points (points with a readable reason), Cookie Consent Mode (kvConsent.get()/on('change')), Order Source & UTM Attribution (UTM tags utm_source=referral_program, utm_medium=referral|affiliate), Loyalty Program with VIP Tiers and core promotions work side by side. Full page cache: guests get identical pages; per-visitor data comes from the beacon response.
File map
Section titled “File map”app/addons/kv_referral_program/ addon.xml, init.php, func.php controllers/backend/kv_referral_program.php ledger, affiliates, affiliate page, payouts, rates, referrers, approve/reject, payouts, CSV, quick promotion, console cron controllers/backend/kv_referral_program_license.php controllers/frontend/kv_referral_program.php Refer a friend, Affiliate program, invite, apply, payout request, link builder, click beacon, cron URL schemas/menu, permissions, settings, security (CSRF of the account forms) Tygh/Addons/KvReferralProgram/ Config, Codes, Coupons, Tracking, Referrals, Engine, Fraud, Commission, Rewards, Ledger, Affiliates, Payouts, Invites, Notifier, Scheduler, Account, Install, StorageData, License/, Upgrade/Synchronizer Tygh/Api/Entities/KvReferrals.php, KvAffiliates.phpdesign/backend/templates/addons/kv_referral_program/ views (manage, affiliates, affiliate, payouts, rates, referrers), components, settings/cron_info.tpl, hooks, license/design/backend/css/addons/kv_referral_program/ styles.less, license.lessvar/themes_repository/responsive/templates/addons/kv_referral_program/ views (view, affiliate), hooks (index, profiles)var/themes_repository/responsive/css/addons/kv_referral_program/styles.lessjs/addons/kv_referral_program/func.jsvar/langs/en/addons/kv_referral_program.poLicense
Section titled “License”The add-on ships the generated License\Client. Gated (switched off without a valid license): the storefront script configuration and click recording, new attributions at checkout and sign-up, welcome coupons, invitations, affiliate applications and the Refer a friend page. Not gated: releasing and reversing existing entries, admin approval and rejection, the affiliate dashboard and payout requests of existing balances, marking payouts paid, CSV and the REST API.