Abuse Prevention

    The referral system includes multiple layers of server-side fraud detection to prevent gaming and ensure rewards go to legitimate referrals.

    1. Self-referral blocking

    The system compares the referee's phone number against the referrer's phone number (after normalisation). If they match, the code is rejected with the message: "You cannot use your own referral code."

    2. Existing customer detection

    Referral codes are for new customers only. The system checks if the referee's phone number has any previous completed or paid orders at the restaurant. If they do, the code is rejected. This check handles multiple phone number formats (with and without country code prefix) to prevent bypass attempts.

    3. Monthly rate limiting

    Each referral code has a configurable monthly limit (default: 10). Once a referrer reaches this limit within a rolling 30-day window, their code temporarily stops working. This prevents mass-referral schemes and limits liability.

    4. Minimum order enforcement

    If a minimum order value is configured, the referee's subtotal must meet or exceed it. This prevents people from placing tiny orders solely to claim a referral reward.

    5. Duplicate usage prevention

    Each referee can only use a specific referral code once. The system checks against previous redemptions by the same phone number to block repeat usage.

    6. Same-household address matching

    To detect family/household gaming, the system compares delivery addresses between the referrer and referee. Addresses are normalised (lowercased, whitespace-trimmed) before comparison. If a match is found, the code is rejected with: "This referral code cannot be used for customers at the same address."

    This check is non-blocking if address data is unavailable — it only applies when both parties have saved addresses on file.

    7. API rate limiting

    The validation endpoint enforces IP-based rate limiting (max 10 requests per minute per IP) to prevent brute-force code guessing or automated abuse.

    Note: All abuse checks are performed server-side and cannot be bypassed from the client. Error messages are intentionally generic for security reasons — they do not reveal which specific check failed beyond the user-facing message.