Repository navigation
fix(payment): suppress checkout trial_period_days when promotion code is applied (#23300) - #23740
ducanh3005 wants to merge 1 commit into
Conversation
|
Submitted standalone fix for #23300 (suppressing Payout Wallet (Base / BSC / EVM): |
b990c3a to
5ec0c9b
Compare
|
The technical fix is correct and tightly scoped — one open product question below needs a maintainer call before merge. Findings:
Product question: this module's own docstring says a client that asked for a trial was "promised something this checkout cannot give, so refuse rather than charge at once" — that is the rationale for Performance: no new API calls (the USER IMPACT: users applying a promo code at checkout no longer hit "your order doesn't meet the minimum amount" — the code now applies; the tradeoff is the free trial is silently skipped and the discounted charge starts immediately. Still want as a reviewer: a maintainer decision on the silent trial suppression, and a short code comment at Leaving the billing/UX tradeoff above for human maintainer review before merge. by AI on behalf of David — if you need David’s attention urgently, please @Git-on-my-level and escalate with |
|
Verdict: the fix is correct, minimal, and well tested; one billing-behavior design point below needs maintainer sign-off before merge. Correctness (verified at head 5ec0c9b):
UX (material): a checkout that combines a promotion code with a requested trial now silently drops the trial — the user is charged the discounted first invoice immediately instead of after the trial. Previously Stripe rejected the whole checkout ("order doesn't meet the minimum amount"), so this strictly improves on a hard failure, but note the suppression applies to ALL promo codes, not only minimum_amount-restricted ones. If you want the narrower behavior, it could be scoped to codes whose Security: no new auth, secrets, dependencies, or workflows; promo-code resolution logic is pre-existing and untouched. Blast radius: only checkouts that pass both USER IMPACT: users who apply a promo code at checkout will be charged the discounted first invoice immediately rather than starting with a free trial — checkout succeeds instead of erroring. What I'd still want: a maintainer decision on whether unconditional trial suppression (vs. only for minimum_amount codes) is the intended billing behavior, and whether the client should tell the user the trial was replaced by the promo. Leaving for human maintainer review: the charge-immediately-vs-trial tradeoff is a billing/product decision on a revenue surface, which is why Feedback generated by Omi's AI maintainer assistant on behalf of the maintainers. by AI on behalf of David — if you need David’s attention urgently, please @Git-on-my-level and escalate with |
|
Verdict: the production change is correct, nicely scoped, and well tested — leaving for maintainer sign-off on one product trade-off, not on correctness.
UX / product trade-off to confirm: suppression is keyed on ANY resolved promotion code, not only minimum_amount-restricted ones. Before this change a promo+trial combination could succeed (user got both); now the trial is silently dropped whenever a code is applied, and the client gets no signal its trial_days was ignored. That is the right fix direction for #23300, but it is a billing-behavior decision a maintainer should confirm as intended. Security/blast radius: payment/billing surface, but the change only removes a subscription_data field — no new money paths, no raw coupon fallback, redemption tracking via promotion_code preserved. USER IMPACT: subscribers who apply a promo code at checkout will be charged (at the discounted price) immediately instead of after a free trial period. Still wanted: (1) maintainer confirmation that dropping the trial for all promo codes — not just minimum-amount codes — is the intended product behavior; (2) optionally a log line or response hint when trial_days is suppressed so support can explain charges. Human maintainer review is needed for the billing trade-off above before merge. by AI on behalf of David — if you need David’s attention urgently, please @Git-on-my-level and escalate with |
aryanorastar
left a comment
There was a problem hiding this comment.
Approved 5ec0c9bc2e12c8d6ff344a7526658d1d220a7f47. backend/routers/payment.py on main still sets trial_period_days = request.trial_days or None beside a promotion code. This head suppresses both and Hygiene succeeded.
Summary
Closes #23300
Suppress
trial_period_dayswhen creating a subscription Checkout session with a resolved promotion code so Stripe'sminimum_amountrestriction is evaluated against the subscription's first-period invoice rather than a$0free-trial invoice.Root Cause
Single-use first-year Unlimited promotion codes carry a
minimum_amount: 26900($269.00USD) restriction:$269.00USD) was resolved by pinningadaptive_pricing={'enabled': False}in fix(payment): pin promo-code checkout presentment to USD so the $269 minimum passes (#23299) #23557 / fix(payment): charge the displayed currency on every Stripe checkout (Play rejection of 1504) #23604.trial_days(e.g., 7-day trial) alongside a promotion code, settingsubscription_data.trial_period_daysmakes the initial Checkout invoice$0.00due at checkout. Stripe evaluates the promotion code'sminimum_amountagainst that$0.00initial invoice and rejects the valid code with:This code is valid, but your order doesn't meet the minimum amount.Changes
backend/routers/payment.py(create_checkout_session_endpoint): Passtrial_period_days=Nonewhenresolved_checkout_promo_idis present while preserving thetrial_unavailableguard for returning customers.backend/utils/stripe.py(create_subscription_checkout_session): Only setsession_params['subscription_data']['trial_period_days']whenpromotion_code_idis not provided. No raw coupon fallback is introduced, preserving Stripe-side promotion-code restrictions and redemption tracking (test_upgrade_uses_promotion_code_id_not_coupon).backend/tests/unit/test_payment_checkout_trial.py: Added unit tests verifying trial suppression on bothcreate_checkout_session_endpointandcreate_subscription_checkout_sessionwhen a promotion code is applied.Failure-Class
Failure-Class: none
Product invariants affected
Testing
pytest backend/tests/unit/test_payment_checkout_trial.py backend/tests/unit/test_payment_promotion_codes.py backend/tests/unit/test_payment_promo_adaptive_pricing.pyPayout Wallet (Base / BSC / EVM):
0xdF4Ff9D2f45f99f11A90b16F277D4B7EddDB72A5