Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add demo payment component, remove multi-gateway configuration #1099

Draft
wants to merge 1 commit into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
57 changes: 57 additions & 0 deletions src/checkout/sections/PaymentSection/Demo/PaymentOptions.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
import type { FormEventHandler } from "react";
import { useCheckoutValidationActions } from "@/checkout/state/checkoutValidationStateStore";
import { useUser } from "@/checkout/hooks/useUser";
import { useCheckoutUpdateStateActions } from "@/checkout/state/updateStateStore";
import { useEvent } from "@/checkout/hooks/useEvent";
import { useCheckoutCompleteMutation, useTransactionInitializeMutation } from "@/checkout/graphql";
import { useCheckout } from "@/checkout/hooks/useCheckout";
import { replaceUrl } from "@/checkout/lib/utils/url";
import { Button } from "@/checkout/components";

export const DemoPayment = () => {
const { checkout } = useCheckout();
const { authenticated } = useUser();
const { validateAllForms } = useCheckoutValidationActions();
const { setSubmitInProgress, setShouldRegisterUser } = useCheckoutUpdateStateActions();
const [__, mutation] = useTransactionInitializeMutation();
const [_, completeMutation] = useCheckoutCompleteMutation();
const onSubmit: FormEventHandler<HTMLFormElement> = useEvent(async (e) => {
e.preventDefault();
validateAllForms(authenticated);
setShouldRegisterUser(true);
setSubmitInProgress(true);
await mutation({
checkoutId: checkout.id,
paymentGateway: {
id: process.env.NEXT_PUBLIC_PAYMENT_GATEWAY as string,
data: {
details: "valid-details",
},
},
});
const { data } = await completeMutation({
checkoutId: checkout.id,
});

const order = data?.checkoutComplete?.order;

if (order) {
const newUrl = replaceUrl({
query: {
order: order.id,
},
replaceWholeQuery: true,
});
window.location.href = newUrl;
}
});

return (
<form onSubmit={onSubmit}>
{/* eslint-disable-next-line react/jsx-no-undef */}
<button type={"submit"}>
<Button label={"Pay"} />
</button>
</form>
);
};
17 changes: 3 additions & 14 deletions src/checkout/sections/PaymentSection/PaymentMethods.tsx
Original file line number Diff line number Diff line change
@@ -1,32 +1,21 @@
import { paymentMethodToComponent } from "./supportedPaymentApps";
import { PaymentSectionSkeleton } from "@/checkout/sections/PaymentSection/PaymentSectionSkeleton";
import { usePayments } from "@/checkout/sections/PaymentSection/usePayments";
import { useCheckoutUpdateState } from "@/checkout/state/updateStateStore";
import { DemoPayment } from "@/checkout/sections/PaymentSection/Demo/PaymentOptions";

export const PaymentMethods = () => {
const { availablePaymentGateways, fetching } = usePayments();
const {
changingBillingCountry,
updateState: { checkoutDeliveryMethodUpdate },
} = useCheckoutUpdateState();

// delivery methods change total price so we want to wait until the change is done
if (changingBillingCountry || fetching || checkoutDeliveryMethodUpdate === "loading") {
if (changingBillingCountry || checkoutDeliveryMethodUpdate === "loading") {
return <PaymentSectionSkeleton />;
}

return (
<div className="gap-y-8">
{availablePaymentGateways.map((gateway) => {
const Component = paymentMethodToComponent[gateway.id];
return (
<Component
key={gateway.id}
// @ts-expect-error -- gateway matches the id but TypeScript doesn't know that
config={gateway}
/>
);
})}
<DemoPayment />
</div>
);
};
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import { useCheckout } from "@/checkout/hooks/useCheckout";
import { useSubmit } from "@/checkout/hooks/useSubmit";
import { type MightNotExist } from "@/checkout/lib/globalTypes";
import { type ParsedPaymentGateways } from "@/checkout/sections/PaymentSection/types";
import { getFilteredPaymentGateways } from "@/checkout/sections/PaymentSection/utils";

export const usePaymentGatewaysInitialize = () => {
const {
Expand All @@ -30,10 +29,12 @@ export const usePaymentGatewaysInitialize = () => {
onSubmit: paymentGatewaysInitialize,
parse: () => ({
checkoutId,
paymentGateways: getFilteredPaymentGateways(availablePaymentGateways).map(({ config, id }) => ({
id,
data: config,
})),
paymentGateways: availablePaymentGateways
.filter((x) => x.id === process.env.NEXT_PUBLIC_PAYMENT_GATEWAY)
.map(({ config, id }) => ({
id,
data: config,
})),
}),
onSuccess: ({ data }) => {
const parsedConfigs = (data.gatewayConfigs || []) as ParsedPaymentGateways;
Expand Down
30 changes: 0 additions & 30 deletions src/checkout/sections/PaymentSection/utils.ts
Original file line number Diff line number Diff line change
@@ -1,42 +1,12 @@
import { compact } from "lodash-es";
import { adyenGatewayId } from "./AdyenDropIn/types";
import { stripeGatewayId } from "./StripeElements/types";
import {
type CheckoutAuthorizeStatusEnum,
type CheckoutChargeStatusEnum,
type OrderAuthorizeStatusEnum,
type OrderChargeStatusEnum,
type PaymentGateway,
} from "@/checkout/graphql";
import { type MightNotExist } from "@/checkout/lib/globalTypes";
import { getUrl } from "@/checkout/lib/utils/url";
import { type PaymentStatus } from "@/checkout/sections/PaymentSection/types";

export const supportedPaymentGateways = [adyenGatewayId, stripeGatewayId] as const;

export const getFilteredPaymentGateways = (
paymentGateways: MightNotExist<PaymentGateway[]>,
): PaymentGateway[] => {
if (!paymentGateways) {
return [];
}

// we want to use only payment apps, not plugins
return compact(paymentGateways).filter(({ id, name }) => {
const shouldBeIncluded = supportedPaymentGateways.includes(id);
const isAPlugin = !id.startsWith("app.");

// app is missing in our codebase but is an app and not a plugin
// hence we'd like to have it handled by default
if (!shouldBeIncluded && !isAPlugin) {
console.warn(`Unhandled payment gateway - name: ${name}, id: ${id}`);
return false;
}

return shouldBeIncluded;
});
};

export const getUrlForTransactionInitialize = () => getUrl({ query: { processingPayment: true } });

export const usePaymentStatus = ({
Expand Down
Loading