Skip to content

Commit 4b0e56a

Browse files
committed
feat(payment): PAYPAL-0 POC
1 parent ff57b8a commit 4b0e56a

File tree

15 files changed

+921
-20
lines changed

15 files changed

+921
-20
lines changed

core/app/[locale]/(default)/cart/page-data.ts

Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,11 @@
1+
import { removeEdgesAndNodes } from '@bigcommerce/catalyst-client';
2+
13
import { getSessionCustomerAccessToken } from '~/auth';
24
import { client } from '~/client';
35
import { FragmentOf, graphql, VariablesOf } from '~/client/graphql';
46
import { getShippingZones } from '~/client/management/get-shipping-zones';
57
import { TAGS } from '~/client/tags';
8+
import { getPreferredCurrencyCode } from '~/lib/currency';
69

710
export const PhysicalItemFragment = graphql(`
811
fragment PhysicalItemFragment on CartPhysicalItem {
@@ -262,6 +265,98 @@ export const getCart = async (variables: Variables) => {
262265
return data;
263266
};
264267

268+
const PaymentWalletsQuery = graphql(`
269+
query PaymentWalletsQuery($filters: PaymentWalletsFilterInput) {
270+
site {
271+
paymentWallets(filter: $filters) {
272+
edges {
273+
node {
274+
entityId
275+
}
276+
}
277+
}
278+
}
279+
}
280+
`);
281+
282+
type PaymentWalletsVariables = VariablesOf<typeof PaymentWalletsQuery>;
283+
284+
export const getPaymentWallets = async (variables: PaymentWalletsVariables) => {
285+
const customerAccessToken = await getSessionCustomerAccessToken();
286+
287+
const { data } = await client.fetch({
288+
document: PaymentWalletsQuery,
289+
customerAccessToken,
290+
fetchOptions: { cache: 'no-store' },
291+
variables,
292+
});
293+
294+
return removeEdgesAndNodes(data.site.paymentWallets).map(({ entityId }) => entityId);
295+
};
296+
297+
const PaymentWalletWithInitializationDataQuery = graphql(`
298+
query PaymentWalletWithInitializationDataQuery($entityId: String!, $cartId: String!) {
299+
site {
300+
paymentWalletWithInitializationData(
301+
filter: { paymentWalletEntityId: $entityId, cartEntityId: $cartId }
302+
) {
303+
clientToken
304+
initializationData
305+
}
306+
}
307+
}
308+
`);
309+
310+
export const getPaymentWalletWithInitializationData = async (entityId: string, cartId: string) => {
311+
const { data } = await client.fetch({
312+
document: PaymentWalletWithInitializationDataQuery,
313+
variables: {
314+
entityId,
315+
cartId,
316+
},
317+
customerAccessToken: await getSessionCustomerAccessToken(),
318+
fetchOptions: { cache: 'no-store' },
319+
});
320+
321+
return data.site.paymentWalletWithInitializationData;
322+
};
323+
324+
const CurrencyQuery = graphql(`
325+
query Currency($currencyCode: currencyCode!) {
326+
site {
327+
currency(currencyCode: $currencyCode) {
328+
display {
329+
decimalPlaces
330+
symbol
331+
}
332+
name
333+
code
334+
}
335+
}
336+
}
337+
`);
338+
339+
export const getCurrencyData = async (currencyCode?: string) => {
340+
const code = await getPreferredCurrencyCode(currencyCode);
341+
342+
if (!code) {
343+
throw new Error('Could not get currency code');
344+
}
345+
346+
const customerAccessToken = await getSessionCustomerAccessToken();
347+
348+
const { data } = await client.fetch({
349+
document: CurrencyQuery,
350+
fetchOptions: { cache: 'no-store' },
351+
variables: {
352+
currencyCode: code,
353+
},
354+
customerAccessToken,
355+
});
356+
357+
return data.site.currency;
358+
};
359+
265360
export const getShippingCountries = async (geography: FragmentOf<typeof GeographyFragment>) => {
266361
const hasAccessToken = Boolean(process.env.BIGCOMMERCE_ACCESS_TOKEN);
267362
const shippingZones = hasAccessToken ? await getShippingZones() : [];

core/app/[locale]/(default)/cart/page.tsx

Lines changed: 48 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,13 @@ import { updateCouponCode } from './_actions/update-coupon-code';
1212
import { updateLineItem } from './_actions/update-line-item';
1313
import { updateShippingInfo } from './_actions/update-shipping-info';
1414
import { CartViewed } from './_components/cart-viewed';
15-
import { getCart, getShippingCountries } from './page-data';
15+
import {
16+
getCart,
17+
getCurrencyData,
18+
getPaymentWallets,
19+
getPaymentWalletWithInitializationData,
20+
getShippingCountries,
21+
} from './page-data';
1622

1723
interface Props {
1824
params: Promise<{ locale: string }>;
@@ -28,6 +34,36 @@ export async function generateMetadata({ params }: Props): Promise<Metadata> {
2834
};
2935
}
3036

37+
const createWalletButtonsInitOptions = async (
38+
walletButtons: string[],
39+
cart: {
40+
entityId: string;
41+
currencyCode: string;
42+
},
43+
) => {
44+
const currencyData = await getCurrencyData(cart.currencyCode);
45+
46+
return Streamable.all(
47+
walletButtons.map(async (entityId) => {
48+
const initData = await getPaymentWalletWithInitializationData(entityId, cart.entityId);
49+
const methodId = entityId.split('.').join('');
50+
51+
return {
52+
methodId,
53+
containerId: `${methodId}-button`,
54+
[methodId]: {
55+
cartId: cart.entityId,
56+
currency: {
57+
code: currencyData?.code,
58+
decimalPlaces: currencyData?.display.decimalPlaces,
59+
},
60+
...initData,
61+
},
62+
};
63+
}),
64+
);
65+
};
66+
3167
const getAnalyticsData = async (cartId: string) => {
3268
const data = await getCart({ cartId });
3369

@@ -88,6 +124,16 @@ export default async function Cart({ params }: Props) {
88124
);
89125
}
90126

127+
const walletButtons = await getPaymentWallets({
128+
filters: {
129+
cartEntityId: cartId,
130+
},
131+
});
132+
133+
const walletButtonsInitOptions = Streamable.from(() =>
134+
createWalletButtonsInitOptions(walletButtons, cart),
135+
);
136+
91137
const lineItems = [...cart.lineItems.physicalItems, ...cart.lineItems.digitalItems];
92138

93139
const formattedLineItems = lineItems.map((item) => ({
@@ -277,6 +323,7 @@ export default async function Cart({ params }: Props) {
277323
}}
278324
summaryTitle={t('CheckoutSummary.title')}
279325
title={t('title')}
326+
walletButtonsInitOptions={walletButtonsInitOptions}
280327
/>
281328
</CartAnalyticsProvider>
282329
<CartViewed

0 commit comments

Comments
 (0)