From 88b36d08b83bd1912a0d4c2fed122353ebb49d7c Mon Sep 17 00:00:00 2001 From: Ahmad Abdolsaheb Date: Mon, 18 Sep 2023 19:42:11 +0300 Subject: [PATCH] feat: restrict donations via stripe card (#51598) Co-authored-by: Oliver Eyton-Williams --- api-server/src/server/utils/donation.js | 13 +++++++++++ .../src/components/Donation/donate-form.tsx | 23 ++++++++++++++----- cypress/e2e/third-party/donate-page.ts | 2 +- 3 files changed, 31 insertions(+), 7 deletions(-) diff --git a/api-server/src/server/utils/donation.js b/api-server/src/server/utils/donation.js index 27d5f82a281..fc9921d4486 100644 --- a/api-server/src/server/utils/donation.js +++ b/api-server/src/server/utils/donation.js @@ -217,6 +217,7 @@ export async function createStripeCardDonation(req, res, stripe) { * if user is already donating and the donation isn't one time only, * throw error */ + if (user.isDonating && duration !== 'one-time') { throw { message: `User already has active recurring donation(s).`, @@ -224,6 +225,18 @@ export async function createStripeCardDonation(req, res, stripe) { }; } + /* + * card donations is blocked for new users + */ + + const threeChallengesCompleted = user.completedChallenges.length >= 3; + if (!threeChallengesCompleted) { + throw { + message: `Donate using another method`, + type: 'MethodRestrictionError' + }; + } + let customerId; try { const customer = await stripe.customers.create({ diff --git a/client/src/components/Donation/donate-form.tsx b/client/src/components/Donation/donate-form.tsx index 993fe7c908d..7ad834aa56e 100644 --- a/client/src/components/Donation/donate-form.tsx +++ b/client/src/components/Donation/donate-form.tsx @@ -20,11 +20,13 @@ import { userSelector, isDonatingSelector, signInLoadingSelector, - donationFormStateSelector + donationFormStateSelector, + completedChallengesSelector } from '../../redux/selectors'; import Spacer from '../helpers/spacer'; import { Themes } from '../settings/theme'; import { DonateFormState } from '../../redux/types'; +import type { CompletedChallenge } from '../../redux/prop-types'; import { CENTS_IN_DOLLAR, convertToTimeContributed, @@ -77,6 +79,7 @@ type DonateFormProps = { theme: Themes; updateDonationFormState: (state: DonationApprovalData) => unknown; paymentContext: PaymentContext; + completedChallenges: CompletedChallenge[]; }; const mapStateToProps = createSelector( @@ -85,19 +88,22 @@ const mapStateToProps = createSelector( isDonatingSelector, donationFormStateSelector, userSelector, + completedChallengesSelector, ( showLoading: DonateFormProps['showLoading'], isSignedIn: DonateFormProps['isSignedIn'], isDonating: DonateFormProps['isDonating'], donationFormState: DonateFormState, - { email, theme }: { email: string; theme: Themes } + { email, theme }: { email: string; theme: Themes }, + completedChallenges: CompletedChallenge[] ) => ({ isSignedIn, isDonating, showLoading, donationFormState, email, - theme + theme, + completedChallenges }) ); @@ -199,7 +205,8 @@ class DonateForm extends Component { isSignedIn, isDonating, editAmount, - selectedDonationAmount + selectedDonationAmount, + completedChallenges } = this.props; const donationAmount: DonationAmount = selectedDonationAmount || defaultAmount; @@ -207,8 +214,12 @@ class DonateForm extends Component { const walletlabel = `${t('donate.wallet-label-1', { usd: donationAmount / CENTS_IN_DOLLAR })}:`; - console.log(formattedAmountLabel(donationAmount)); - const showMinimalPayments = isSignedIn && (isMinimalForm || !isDonating); + + const threeChallengesCompleted = completedChallenges.length >= 3; + + const showMinimalPayments = + isSignedIn && (isMinimalForm || !isDonating) && threeChallengesCompleted; + const confirmationMessage = t('donate.confirm-monthly', { usd: formattedAmountLabel(donationAmount) }); diff --git a/cypress/e2e/third-party/donate-page.ts b/cypress/e2e/third-party/donate-page.ts index e329a25761a..6ec6024613c 100644 --- a/cypress/e2e/third-party/donate-page.ts +++ b/cypress/e2e/third-party/donate-page.ts @@ -1,6 +1,6 @@ describe('Donate page', () => { it('Donation ', () => { - cy.task('seed'); + cy.task('seed', ['certified-user']); cy.login(); cy.visit('/donate'); cy.get('.donation-elements', { timeout: 10000 }).within(() => {