stripe: per-cadence cooling-off + manage-subscription button
Bundles three related pieces that came out of the operator's first
end-to-end test of the paid flow:
1. Manage subscription button on /settings (paid users with a real
Stripe sub — i.e. not credit-granted access). POSTs to the existing
/api/stripe/portal endpoint; Stripe-hosted customer portal handles
card updates, cancellation, monthly↔annual switch, invoice history.
Replaces the stale "Paid features unlock with Paddle (D.3) or
invite credits" hint for free users with a live link to /pricing.
2. Per-cadence cooling-off treatment:
- **Annual £70**: 14-day free trial via
subscription_data.trial_period_days=14. No money moves during
the trial, so the CCR 2013 14-day refund question doesn't arise
(nothing paid = nothing to refund). Card is still required at
checkout so Stripe can charge on day 15.
- **Monthly £7**: bills immediately. A 14-day trial there would
give away ~50% of cycle one. Instead, /pricing now carries a
required tick-box above the Subscribe buttons (subscribe stays
disabled until checked) — by ticking, the user expressly
consents to begin performance immediately and acknowledges that
this extinguishes their statutory 14-day right under Reg 36
CCR 2013. Consent collected on our own page (not via Stripe's
account-wide consent_collection.terms_of_service) so each
product can keep its own Terms URL as we add more.
3. T&C §6 clause 1 split into 1a (annual / trial substitute) +
1b (monthly / Reg 36 waiver via on-page tick-box). Clause 2
(post-cooling-off cancellation) unchanged.
Settings page shows "Free trial — N days remaining" while the
sub is in `trialing` status, falling back to "Paid subscription
active." once it transitions to active. Countdown is computed
server-side from User.stripe_trial_end_at (new column, migration
0020) populated by the subscription.created/updated webhook from
the Stripe trial_end timestamp; cleared on the trialing→active
transition and on revoke.
Drive-by: fixed a structlog kwarg-name collision on
`log.warning(..., event=event_type, ...)` in both polar_webhook.py
and stripe_billing.py — `event` is structlog's positional event
name and "got multiple values" crashed the user-not-found log
path. Renamed to `event_type=` everywhere it appeared. Caught by
the new trialing-stores-trial-end test.
Tests
- 4 new in test_stripe_billing.py covering monthly (no trial, no
consent_collection), annual (trial, no consent), trialing stores
trial_end, trialing→active clears trial_end.
- 1 existing test renamed + reworked for the consent split.
- Full suite: 224 passed, 5 skipped.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
parent
62960d5bea
commit
a07fd144ea
10 changed files with 390 additions and 31 deletions
|
|
@ -98,13 +98,32 @@
|
|||
<section class="public-section">
|
||||
<h2 class="public-section__head">6. Refunds</h2>
|
||||
<p>
|
||||
<strong>14-day cooling-off (UK / EU consumers).</strong> If you buy a
|
||||
paid subscription as a consumer, you have 14 days from the day of
|
||||
purchase to cancel and receive a full refund of that purchase, under
|
||||
the Consumer Contracts (Information, Cancellation and Additional
|
||||
Charges) Regulations 2013. As noted in clause 5, if you start using
|
||||
a paid feature inside the cancellation window you lose the right to
|
||||
cancel in respect of digital content already delivered.
|
||||
<strong>14-day cooling-off period (UK / EU consumers).</strong>
|
||||
The Consumer Contracts (Information, Cancellation and Additional
|
||||
Charges) Regulations 2013 give consumers a 14-day right to cancel
|
||||
digital service contracts. We honour this right in different ways
|
||||
depending on your billing cadence.
|
||||
</p>
|
||||
<p>
|
||||
<strong>1a. Annual subscriptions.</strong> Every new annual
|
||||
subscription begins with a 14-day free trial. No payment is taken
|
||||
during the trial; cancel any time before the trial ends and you
|
||||
are not charged. This is offered as a substitute for, and is at
|
||||
least as generous as, the statutory 14-day refund right. After
|
||||
the trial ends and the first payment is taken, the rules in
|
||||
paragraph 2 below apply.
|
||||
</p>
|
||||
<p>
|
||||
<strong>1b. Monthly subscriptions.</strong> Monthly subscribers
|
||||
receive immediate access to paid features at checkout and are
|
||||
billed on day one. Before you can start a monthly subscription
|
||||
you must tick a required consent box on the pricing page in
|
||||
which you (i) agree to these Terms, (ii) give express consent to
|
||||
begin performance immediately, and (iii) acknowledge that, under
|
||||
Regulation 36 of the Consumer Contracts Regulations 2013, doing
|
||||
so extinguishes your statutory 14-day right to cancel in respect
|
||||
of digital content already delivered. The rules in paragraph 2
|
||||
below apply from the first day.
|
||||
</p>
|
||||
<p>
|
||||
<strong>Cancellation after the cooling-off window.</strong> You can
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue