Model a 3-month 20% promo discount and apply it at billing

This tests separating coupon rules from per-user redemptions. Good answers use a coupons table for the 20%/3-month rule, a redemptions table for usage, and apply the discount to the first three invoices. A red flag is hard-coding the discount on the user row.
What's really being asked
This question evaluates whether you understand how to decouple a reusable business rule from its per-customer application in a billing system. The interviewer wants to see that you can model time-bounded discounts without hard-coding logic into a user record, and that you think about auditability, idempotency, and edge cases like proration or mid-cycle redemptions.
The full answer
A good answer hits four things in order. First, a coupons table that defines the discount parameters, such as a 20% percentage off, a duration of three months, and optional constraints like max redemptions or an expiration date. Second, a promotion_codes or redemptions table that maps a customer to a specific code, tracks when it was applied, and stores metadata like the remaining duration or the original coupon ID. Third, an invoice generation or billing pipeline that looks up active redemptions for the customer, decrements the remaining duration, and applies the discount only to line items eligible for that coupon. Fourth, handling edge cases such as prorated first invoices, pausing or upgrading a subscription mid-discount, and ensuring the discount does not apply after the third invoice.
The mistakes people make
The biggest red flag is adding a discount_percent column directly to the users table with no expiration mechanism, which makes the logic brittle and impossible to audit. Another weak pattern is storing the promo code as a plain string on the user record without referencing a central coupon definition, because changing the terms later requires migrating user rows. A third mistake is applying the discount at the payment processor level only without recording it in your own ledger, which creates reconciliation headaches.
What usually comes next
Interviewers often ask how you would handle stacking multiple coupons, what happens if a user upgrades their plan during the promotional period, or how you would support amount-off versus percentage-off coupons. They may also dig into race conditions when two invoices generate simultaneously, or ask how you would backfill redemptions if you migrate from an old system.
A concrete example
Imagine a coupons row with id promo_20_3mo, type percentage, value 20, duration_in_months 3, and applies_to_all_products true. When Alice signs up with code FALL20, you create a redemptions row with coupon_id promo_20_3mo, customer_id alice, remaining_months 3, and redeemed_at timestamp. During the monthly invoice job, the system selects active redemptions where remaining_months is greater than zero, applies a 20% discount to the subscription line item, creates an invoice_discount record for audit, and decrements remaining_months by one. After three invoices, the redemption is exhausted and the pipeline ignores it.
Interview question
Which approach correctly separates the 20% / 3-month promotional rule from its per-customer application in a billing system?
- a.Store the promo code as a plain string on the user record without referencing a central coupon definition
- b.Create a coupons table for the 20% and 3-month policy and a redemptions table that tracks usage per customerCorrect
- c.Apply the discount exclusively in the payment processor without recording it in your own ledger
- d.Add a discount_percent column directly to the users table with no expiration mechanism
Why? this is the answer
This approach decouples the reusable business rule from its per-customer application, enabling auditability and clean expiration after three invoices. The most tempting distractor hard-codes the discount on the user row, which makes the logic brittle and impossible to audit centrally.
Just read this? Test yourself on what you have been reading.
Read the original → docs.stripe.com
- #promo codes
- #billing
- #database design
- #stripe
- #growth
You just looked this up. Could you explain it out loud?
That is the part interviews actually test. Tezvyn takes questions like this one and gives you what the interviewer is really checking, the answer that lands, and the mistake that ends the conversation, in the four minutes before your next meeting.
The iPhone app is on the way
We are building it. Until it lands, nothing here is held back from you: every interview card, your saved cards, streaks and the job board all work in Safari, plus hundreds of free practice quizzes of thirty questions each. Sign in and it all carries over to the app the day it arrives.
Want it as an icon? Tap Share at the bottom of Safari, then Add to Home Screen. It opens full screen and the cards you have read stay available offline.
We are hiring for this. Every open role lists the topics its interview covers, so you can prepare for the real thing rather than guessing.
See open roles