Skip to content

Commit ca5be40

Browse files
committed
feat(payment): PAYPAL-0 POC + Whitelisting
1 parent 4845d87 commit ca5be40

File tree

14 files changed

+747
-4
lines changed

14 files changed

+747
-4
lines changed

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

Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,12 @@
1+
import { removeEdgesAndNodes } from '@bigcommerce/catalyst-client';
12
import { cache } from 'react';
23

34
import { getSessionCustomerAccessToken } from '~/auth';
45
import { client } from '~/client';
56
import { graphql, VariablesOf } from '~/client/graphql';
67
import { revalidate } from '~/client/revalidate-target';
78
import { TAGS } from '~/client/tags';
9+
import { getPreferredCurrencyCode } from '~/lib/currency';
810

911
export const PhysicalItemFragment = graphql(`
1012
fragment PhysicalItemFragment on CartPhysicalItem {
@@ -202,6 +204,9 @@ const CartPageQuery = graphql(
202204
discountedAmount {
203205
...MoneyFieldsFragment
204206
}
207+
amount {
208+
value
209+
}
205210
lineItems {
206211
physicalItems {
207212
...PhysicalItemFragment
@@ -291,6 +296,101 @@ const SupportedShippingDestinationsQuery = graphql(`
291296
}
292297
}
293298
`);
299+
const PaymentWalletsQuery = graphql(`
300+
query PaymentWalletsQuery($filters: PaymentWalletsFilterInput) {
301+
site {
302+
paymentWallets(filter: $filters) {
303+
edges {
304+
node {
305+
entityId
306+
methodName
307+
id
308+
}
309+
}
310+
}
311+
}
312+
}
313+
`);
314+
315+
type PaymentWalletsVariables = VariablesOf<typeof PaymentWalletsQuery>;
316+
317+
export const getPaymentWallets = async (variables: PaymentWalletsVariables) => {
318+
const customerAccessToken = await getSessionCustomerAccessToken();
319+
320+
const { data } = await client.fetch({
321+
document: PaymentWalletsQuery,
322+
customerAccessToken,
323+
fetchOptions: { cache: 'no-store' },
324+
variables,
325+
});
326+
327+
console.log(data.site.paymentWallets, 'data.site.paymentWallets');
328+
329+
return removeEdgesAndNodes(data.site.paymentWallets).map(({ entityId }) => entityId);
330+
};
331+
332+
const PaymentWalletWithInitializationDataQuery = graphql(`
333+
query PaymentWalletWithInitializationDataQuery($entityId: String!, $cartId: String!) {
334+
site {
335+
paymentWalletWithInitializationData(
336+
filter: { paymentWalletEntityId: $entityId, cartEntityId: $cartId }
337+
) {
338+
clientToken
339+
initializationData
340+
}
341+
}
342+
}
343+
`);
344+
345+
export const getPaymentWalletWithInitializationData = async (entityId: string, cartId: string) => {
346+
const { data } = await client.fetch({
347+
document: PaymentWalletWithInitializationDataQuery,
348+
variables: {
349+
entityId,
350+
cartId,
351+
},
352+
customerAccessToken: await getSessionCustomerAccessToken(),
353+
fetchOptions: { cache: 'no-store' },
354+
});
355+
356+
return data.site.paymentWalletWithInitializationData;
357+
};
358+
359+
const CurrencyQuery = graphql(`
360+
query Currency($currencyCode: currencyCode!) {
361+
site {
362+
currency(currencyCode: $currencyCode) {
363+
display {
364+
decimalPlaces
365+
symbol
366+
}
367+
name
368+
code
369+
}
370+
}
371+
}
372+
`);
373+
374+
export const getCurrencyData = async (currencyCode?: string) => {
375+
const code = await getPreferredCurrencyCode(currencyCode);
376+
377+
if (!code) {
378+
throw new Error('Could not get currency code');
379+
}
380+
381+
const customerAccessToken = await getSessionCustomerAccessToken();
382+
383+
const { data } = await client.fetch({
384+
document: CurrencyQuery,
385+
fetchOptions: { cache: 'no-store' },
386+
variables: {
387+
currencyCode: code,
388+
},
389+
customerAccessToken,
390+
});
391+
392+
return data.site.currency;
393+
};
294394

295395
export const getShippingCountries = cache(async () => {
296396
const { data } = await client.fetch({

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

Lines changed: 52 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,13 @@ import { updateLineItem } from './_actions/update-line-item';
1313
import { updateShippingInfo } from './_actions/update-shipping-info';
1414
import { CartViewed } from './_components/cart-viewed';
1515
import { CheckoutPreconnect } from './_components/checkout-preconnect';
16-
import { getCart, getShippingCountries } from './page-data';
16+
import {
17+
getCart,
18+
getCurrencyData,
19+
getPaymentWallets,
20+
getPaymentWalletWithInitializationData,
21+
getShippingCountries,
22+
} from './page-data';
1723

1824
interface Props {
1925
params: Promise<{ locale: string }>;
@@ -29,6 +35,40 @@ export async function generateMetadata({ params }: Props): Promise<Metadata> {
2935
};
3036
}
3137

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

@@ -89,6 +129,16 @@ export default async function Cart({ params }: Props) {
89129
);
90130
}
91131

132+
const walletButtons = await getPaymentWallets({
133+
filters: {
134+
cartEntityId: cartId,
135+
},
136+
});
137+
138+
const walletButtonsInitOptions = Streamable.from(() =>
139+
createWalletButtonsInitOptions(walletButtons, cart),
140+
);
141+
92142
const lineItems = [...cart.lineItems.physicalItems, ...cart.lineItems.digitalItems];
93143

94144
const formattedLineItems = lineItems.map((item) => ({
@@ -282,6 +332,7 @@ export default async function Cart({ params }: Props) {
282332
}}
283333
summaryTitle={t('CheckoutSummary.title')}
284334
title={t('title')}
335+
walletButtonsInitOptions={walletButtonsInitOptions}
285336
/>
286337
</CartAnalyticsProvider>
287338
<CartViewed

0 commit comments

Comments
 (0)