Skip to content

Commit

Permalink
Merge pull request #471 from Plant-for-the-Planet-org/feature/expand-…
Browse files Browse the repository at this point in the history
…planetcash-usage

Allow PlanetCash payments for more types of donations
  • Loading branch information
mariahosfeld authored Dec 3, 2024
2 parents 83e1544 + 2eced0a commit b7cb75c
Show file tree
Hide file tree
Showing 5 changed files with 107 additions and 37 deletions.
8 changes: 8 additions & 0 deletions src/Common/Types/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -227,6 +227,7 @@ export interface Gateways {
paypal: Paypal;
stripe: Stripe;
offline?: Offline;
"planet-cash"?: PlanetCashGateway;
}
export interface Paypal {
methods?: string[] | null;
Expand Down Expand Up @@ -254,6 +255,13 @@ export interface Offline {
account: string;
}

export interface PlanetCashGateway {
account: string;
balance: number;
creditLimit: number;
available: number;
}

export interface OptionsEntity {
id?: string;
caption: string | null;
Expand Down
28 changes: 9 additions & 19 deletions src/Donations/Components/DonationsForm.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ import {
import { PaymentMethod } from "@stripe/stripe-js/types/api/payment-methods";
import { PaymentRequest } from "@stripe/stripe-js/types/stripe-js/payment-request";
import { NON_GIFTABLE_PROJECT_PURPOSES } from "src/Utils/projects/constants";
import { isPlanetCashAllowed } from "src/Utils/donationOptions";

function DonationsForm(): ReactElement {
const {
Expand Down Expand Up @@ -117,19 +118,14 @@ function DonationsForm(): ReactElement {
const [isPaymentProcessing, setIsPaymentProcessing] = React.useState(false);
const [paymentError, setPaymentError] = React.useState(""); //TODOO - confirm and remove

const canPayWithPlanetCash =
projectDetails !== null &&
projectDetails.purpose !== "funds" &&
projectDetails.purpose !== "planet-cash" &&
paymentSetup?.unitType === "tree" && //Enables planetcash for restoration projects with unitType tree only (TEMP)
profile !== null &&
isSignedUp &&
profile.planetCash !== null &&
projectDetails.taxDeductionCountries?.includes(
profile.planetCash.country
) &&
!(isGift && giftDetails.recipientName === "") &&
!(onBehalf && onBehalfDonor.firstName === "");
const canPayWithPlanetCash = isPlanetCashAllowed({
profile,
isSignedUp,
projectDetails,
isGift,
giftDetails,
hasPlanetCashGateway: paymentSetup?.gateways["planet-cash"] !== undefined,
});

const canSendDirectGift =
projectDetails !== null &&
Expand Down Expand Up @@ -298,11 +294,6 @@ function DonationsForm(): ReactElement {
const handlePlanetCashDonate = async () => {
if (projectDetails) {
setShowDisablePlanetCashButton(true);
const _onBehalfDonor = {
firstname: onBehalfDonor.firstName,
lastname: onBehalfDonor.lastName,
email: onBehalfDonor.email,
};

const _metadata = {
utm_campaign: utmCampaign,
Expand Down Expand Up @@ -385,7 +376,6 @@ function DonationsForm(): ReactElement {
{projectDetails.purpose !== "funds" && (
<p className="title-text">{t("donate")}</p>
)}
{/* show PlanetCashSelector only if user is signed up and have a planetCash account */}
{canPayWithPlanetCash && <PlanetCashSelector />}
{(canSendDirectGift && hasDirectGift) || canSendInvitationGift ? (
<div className="donations-gift-container mt-10">
Expand Down
47 changes: 30 additions & 17 deletions src/Layout/QueryParamContext.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ import ErrorPopup from "src/Common/ErrorPopup/ErrorPopup";
import { APIError, handleError, SerializedError } from "@planet-sdk/common";
import { PaymentRequest } from "@stripe/stripe-js/types/stripe-js/payment-request";
import { createProjectDetails } from "src/Utils/createProjectDetails";
import { useDebouncedEffect } from "src/Utils/useDebouncedEffect";

export const QueryParamContext =
createContext<QueryParamContextInterface>(null);
Expand Down Expand Up @@ -346,23 +347,27 @@ const QueryParamProvider: FC = ({ children }) => {
router.query.token,
]);

useEffect(() => {
const regex = /^pcash_/;
if (
router.query.to &&
!regex.test(router.query.to as string) &&
country !== undefined &&
country !== "" &&
router.query.to?.toString().toLowerCase() !== "planetcash"
) {
const to = String(router.query.to).replace(/\//g, "");
loadPaymentSetup({
projectGUID: to,
paymentSetupCountry: country,
shouldSetPaymentDetails: true,
});
}
}, [router.query.to, country]);
useDebouncedEffect(

Check notice on line 350 in src/Layout/QueryParamContext.tsx

View check run for this annotation

codefactor.io / CodeFactor

src/Layout/QueryParamContext.tsx#L301-L350

Complex Method
() => {
const regex = /^pcash_/;
if (
router.query.to &&
!regex.test(router.query.to as string) &&
country !== undefined &&
country !== "" &&
router.query.to?.toString().toLowerCase() !== "planetcash"
) {
const to = String(router.query.to).replace(/\//g, "");
loadPaymentSetup({
projectGUID: to,
paymentSetupCountry: country,
shouldSetPaymentDetails: true,
});
}
},
1000,
[router.query.to, country, profile?.slug]
);

async function loadConfig() {
try {
Expand Down Expand Up @@ -488,11 +493,19 @@ const QueryParamProvider: FC = ({ children }) => {
paymentSetupCountry: string;
shouldSetPaymentDetails?: boolean;
}) => {
const token =
profile === null
? null
: queryToken ||
(router.query.token as string) ||
(await getAccessTokenSilently());

setIsPaymentOptionsLoading(true);
try {
const requestParams = {
url: `/app/paymentOptions/${projectGUID}?country=${paymentSetupCountry}`,
setshowErrorCard,
token,
tenant,
locale: i18n.language,
};
Expand Down
43 changes: 43 additions & 0 deletions src/Utils/donationOptions.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import { NoGift, User } from "@planet-sdk/common";
import {
PLANETCASH_ALLOWED_PROJECT_PURPOSES,
PLANETCASH_DISALLOWED_PROJECT_CLASSIFICATIONS,
} from "./projects/constants";
import { FetchedProjectDetails, GiftDetails } from "src/Common/Types";

interface PlanetCashAllowedParams {
profile: User | null;
isSignedUp: boolean;
projectDetails: FetchedProjectDetails | null;
isGift: boolean;
giftDetails: GiftDetails | NoGift;
hasPlanetCashGateway: boolean;
}

/**
* Determines if Planet Cash is allowed for the current donation
*/
export const isPlanetCashAllowed = ({
profile,
isSignedUp,
projectDetails,
isGift,
giftDetails,
hasPlanetCashGateway,
}: PlanetCashAllowedParams): boolean => {
return (
profile !== null &&
isSignedUp &&
profile.planetCash !== null &&
hasPlanetCashGateway &&
projectDetails !== null &&
PLANETCASH_ALLOWED_PROJECT_PURPOSES.includes(projectDetails.purpose) &&
(projectDetails.classification === null ||
!PLANETCASH_DISALLOWED_PROJECT_CLASSIFICATIONS.includes(
projectDetails.classification
)) &&
projectDetails.taxDeductionCountries !== undefined &&
projectDetails.taxDeductionCountries.includes(profile.planetCash.country) &&
!(isGift && giftDetails.recipientName === "")
);
};
18 changes: 17 additions & 1 deletion src/Utils/projects/constants.ts
Original file line number Diff line number Diff line change
@@ -1 +1,17 @@
export const NON_GIFTABLE_PROJECT_PURPOSES = ["planet-cash", "bouquet"];
import { ProjectPurpose, TreeProjectClassification } from "@planet-sdk/common";
import { FundsProjectClassification } from "src/Common/Types";

export const NON_GIFTABLE_PROJECT_PURPOSES: Array<ProjectPurpose> = [
"planet-cash",
"bouquet",
];

export const PLANETCASH_ALLOWED_PROJECT_PURPOSES: Array<ProjectPurpose> = [
"trees",
"conservation",
"funds",
];

export const PLANETCASH_DISALLOWED_PROJECT_CLASSIFICATIONS: Array<
FundsProjectClassification | TreeProjectClassification
> = ["membership", "endowment"];

0 comments on commit b7cb75c

Please sign in to comment.