Open
Conversation
…tionality-to-supporter-form
…rs for monthly and one-off
…ss in supporter mode Tests verify that onCompleted receives native boolean for recurDonation and native number for donationAmount — not the strings produced by the hidden input approach.
…r mode
Hidden inputs registered via ref produced string values ("true"/"false", "5") rather
than native booleans and numbers. Removed the hidden inputs; handleSubmit now derives
recurDonation (boolean) from isMonthly state and donationAmount (number) from
selectedTier/otherDonationAmount directly — matching the wire format used everywhere
else in the codebase.
Direct Debit (GoCardless) does not support one-off donations. When USE_STRIPE is false, the One-off button is disabled and an inline note explains the limitation.
conatus
commented
Mar 23, 2026
Member
Author
conatus
left a comment
There was a problem hiding this comment.
Some minor comments, but mostly looks good.
In supporter mode, donationAmount was passed non-zero to createSubscription, which added a separate Supporter Donation item on top of the membership plan item. The plan price IS the donation — no separate item should be created. Also fixes membership not updating when the user selects a tier that differs from the default: now resolves to the plan whose amount matches the selected tier.
Threads donationSupporterMode flag from frontend initial state through to StripeService::getOrCreateProductForMembershipTier, which uses 'Donation:' as the product name prefix instead of 'Membership:' when in supporter mode.
A Mailchimp failure should not block a successful join, matching the same behaviour applied to Zetkin in 1.3.18. The member record can be retro-added to Mailchimp once the underlying issue is resolved.
…ter mode subscription Products are created during plan save without supporter mode context, so they get 'Membership:' prefix. On first subscription creation in supporter mode, trigger getOrCreateProductForMembershipTier to detect the name mismatch and rename the product to 'Donation: <label>'.
…tePaymentIntent automatic_payment_methods conflicts with explicit paymentMethodTypes set in Stripe Elements, causing confirmation to fail with an invalid_request_error.
One-off payments require card. Without this, a stale directDebit value in session storage causes provider detection to fail in PaymentDetailsPage. Also disable the One-off button when STRIPE_DIRECT_DEBIT_ONLY is set, as card payments are unavailable in that configuration.
155bde2 to
a92f853
Compare
One-off supporter donations go through a PaymentIntent, not a subscription, so removeExistingSubscriptions and the amount comparison must be bypassed.
…Amount flag In supporter mode the custom amount field is always meaningful, so remove the allowCustomAmount gate on both the frontend (donation.page.tsx) and the backend (StripeService::createSubscription) to ensure the entered amount flows through to the Stripe price.
Member
Author
|
Doing pretty well with the testing, but Scenario 7, which is "Supporter mode — monthly, custom amount", is breaking, so looking into this. |
Custom amounts in supporter mode were creating prices under the base plan's product (e.g. "Donation: Tenner a month") regardless of the amount entered. Use getOrCreateDonationProduct() instead so custom amounts are grouped under "Supporter Donation", keeping plan-named products for fixed tier amounts only.
Pure helper makes the custom-amount routing logic (supporter vs plan product, bypass of allow_custom_amount gate) independently testable without Stripe API calls. Seven assertions cover all branching paths.
Covers the bugs where custom amounts were silently dropped: verifies customMembershipAmount is forwarded for non-tier amounts, donationAmount is set correctly for one-off, paymentMethod is forced to creditCard on one-off, and tier-matched plans do not set customMembershipAmount.
Member
Author
|
Got as far as Scenario 8. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Adds a new Donation Supporter Mode checkbox to the CK Join Form block. When enabled, donation becomes the primary purpose of the form rather than a bolt-on upsell after membership selection.
Prerequisites
Test plan
Automated checks
cd packages/join-flow && npm test— all 18 tests passnpm run build— no TypeScript errors1. Standard join flow (no upsell, no supporter mode)
Config:
ASK_FOR_ADDITIONAL_DONATIONoff,DONATION_SUPPORTER_MODEoff, Stripe enabledMembership: <plan name>2. Standard join — upsell, one-off donation
Config:
ASK_FOR_ADDITIONAL_DONATIONon,DONATION_SUPPORTER_MODEoff3. Standard join — upsell, recurring donation
Config:
ASK_FOR_ADDITIONAL_DONATIONon,DONATION_SUPPORTER_MODEoff4. Standard join — both flags on (
ASK_FOR_ADDITIONAL_DONATION+DONATION_SUPPORTER_MODE)Config: Both on
5. Supporter mode — monthly, card
Config:
DONATION_SUPPORTER_MODEon, Stripe card enabled, membership plans configured as donation tiersDonation: <tier name>at correct amount6. Supporter mode — monthly, Direct Debit
Config:
DONATION_SUPPORTER_MODEon,STRIPE_DIRECT_DEBITonDonation: <tier name>subscription via BACS7. Supporter mode — monthly, custom amount
Config:
DONATION_SUPPORTER_MODEon, at least one plan withallow_custom_amount8. Supporter mode — one-off, card
Config:
DONATION_SUPPORTER_MODEon, Stripe card enabled,STRIPE_DIRECT_DEBIT_ONLYoff9. Supporter mode — one-off disabled when Direct Debit only
Config:
DONATION_SUPPORTER_MODEon,STRIPE_DIRECT_DEBIT_ONLYon10. Supporter mode — no plans configured
Config:
DONATION_SUPPORTER_MODEon, no membership plans on the block11. Free membership (zero-price plan)
Config: Plan with amount = 0, no upsell
12. Mailchimp errors are non-fatal
Config: Mailchimp enabled, use an address that triggers a Mailchimp error (e.g.
someone@example.com)13. Product naming
Membership: <plan label>Donation: <plan label>