Skip to content

Commit

Permalink
feat(payment): PAYPAL-4937 updates related to new requirements
Browse files Browse the repository at this point in the history
  • Loading branch information
bc-nick committed Feb 27, 2025
1 parent df96d5d commit 060d1b0
Show file tree
Hide file tree
Showing 18 changed files with 99 additions and 258 deletions.
15 changes: 2 additions & 13 deletions packages/core/src/cart/cart-action-creator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ import { RequestOptions } from '@bigcommerce/checkout-sdk/payment-integration-ap
import { InternalCheckoutSelectors } from '../checkout';
import { cachableAction } from '../common/data-store';
import ActionOptions from '../common/data-store/action-options';
import { MissingDataError, MissingDataErrorType } from '../common/error/errors';

import { CartActionType, LoadCartAction } from './cart-actions';
import CartRequestSender from './cart-request-sender';
Expand All @@ -22,22 +21,12 @@ export default class CartActionCreator {
return (store) => {
return Observable.create((observer: Observer<LoadCartAction>) => {
const state = store.getState();
const jwtToken = state.config.getStorefrontJwtToken();

if (!jwtToken) {
throw new MissingDataError(MissingDataErrorType.MissingPaymentToken);
}
const host = state.config.getHost();

observer.next(createAction(CartActionType.LoadCartRequested, undefined));

this._cartRequestSender
.loadCard(cartId, {
headers: {
Authorization: `Bearer ${jwtToken}`,
'Content-Type': 'application/json',
},
...options,
})
.loadCard(cartId, host, options)
.then((response) => {
observer.next(
createAction(CartActionType.LoadCartSucceeded, response.body),
Expand Down
135 changes: 19 additions & 116 deletions packages/core/src/cart/cart-request-sender.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,29 +6,18 @@ import { ContentType, RequestOptions, SDK_VERSION_HEADERS } from '../common/http

import { LineItemMap } from './index';

interface LoadCartRequestOptions extends RequestOptions {
body?: { query: string };
headers: { Authorization: string; [key: string]: string };
}

interface LoadCartResponse {
data: {
site: {
cart: {
amount: {
currencyCode: string;
};
entityId: string;
lineItems: {
physicalItems: Array<{
name: string;
entityId: string;
quantity: string;
productEntityId: string;
}>;
};
};
};
amount: {
currencyCode: string;
};
entityId: string;
lineItems: {
physicalItems: Array<{
name: string;
entityId: string;
quantity: string;
productEntityId: string;
}>;
};
}

Expand All @@ -48,113 +37,27 @@ export default class CartRequestSender {
return this._requestSender.post(url, { body, headers, timeout });
}

loadCard(cartId: string, options: LoadCartRequestOptions): Promise<Response<Cart>> {
const url = `/graphql`;

const graphQLQuery = `
query {
site {
cart(entityId: "${cartId}") {
currencyCode
entityId
id
isTaxIncluded
discounts {
entityId
discountedAmount {
currencyCode
value
}
}
discountedAmount {
currencyCode
value
}
baseAmount {
currencyCode
value
}
amount {
currencyCode
value
}
lineItems {
physicalItems {
brand
couponAmount {
value
}
discountedAmount {
value
}
discounts {
discountedAmount {
value
}
entityId
}
extendedListPrice {
value
}
extendedSalePrice {
value
}
giftWrapping {
amount {
value
}
message
name
}
isShippingRequired
isTaxable
listPrice {
value
}
name
originalPrice {
value
}
entityId
quantity
salePrice {
value
}
sku
url
}
}
}
}
}`;
loadCard(cartId: string, host?: string, options?: RequestOptions): Promise<Response<Cart>> {
const path = 'cart-information';
const url = host ? `${host}/${path}` : `/${path}`;

const requestOptions: LoadCartRequestOptions = {
const requestOptions: RequestOptions = {
...options,
headers: {
...options.headers,
'Content-Type': 'application/json',
},
body: {
query: graphQLQuery,
params: {
cartId,
},
};

return this._requestSender
.post<LoadCartResponse>(url, {
.get<LoadCartResponse>(url, {
...requestOptions,
})
.then(this.transformToCartResponse);
}

private transformToCartResponse(response: Response<LoadCartResponse>): Response<Cart> {
const {
body: {
data: {
site: {
cart: { amount, entityId, lineItems },
},
},
},
body: { amount, entityId, lineItems },
} = response;

const mappedLineItems: LineItemMap = {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,14 +14,12 @@ import HeadlessCheckoutWalletStrategyActionCreator from './headless-checkout-wal
export default function createHeadlessCheckoutWalletInitializer(
options?: HeadlessCheckoutWalletInitializerOptions,
): HeadlessCheckoutWalletInitializer {
const { host, locale = 'en', storefrontJwtToken, siteLink } = options ?? {};
const { host, locale = 'en' } = options ?? {};

const config: ConfigState = {
meta: {
host,
locale,
storefrontJwtToken,
siteLink,
},
errors: {},
statuses: {},
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
export default interface HeadlessCheckoutWalletInitializerOptions {
host?: string;
locale?: string;
storefrontJwtToken?: string;
siteLink?: string;
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@ import { isElementId, setUniqueElementId } from '../common/dom';

import { CheckoutButtonInitializeOptions, CheckoutButtonOptions } from './checkout-button-options';
import CheckoutButtonSelectors from './checkout-button-selectors';
import HeadlessCheckoutWalletStrategyActionCreator from './headless-checkout-wallet-strategy-action-creator';
import createCheckoutButtonSelectors from './create-checkout-button-selectors';
import HeadlessCheckoutWalletStrategyActionCreator from './headless-checkout-wallet-strategy-action-creator';

@bind
export default class HeadlessCheckoutWalletInitializer {
Expand Down
14 changes: 0 additions & 14 deletions packages/core/src/config/config-selector.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,6 @@ export default interface ConfigSelector {
getHost(): string | undefined;
getLocale(): string | undefined;
getVariantIdentificationToken(): string | undefined;
getStorefrontJwtToken(): string | undefined;
getSiteLink(): string | undefined;
getLoadError(): Error | undefined;
isLoading(): boolean;
}
Expand Down Expand Up @@ -102,16 +100,6 @@ export function createConfigSelectorFactory(): ConfigSelectorFactory {
(data) => () => data,
);

const getStorefrontJwtToken = createSelector(
(state: ConfigState) => state.meta && state.meta.storefrontJwtToken,
(data) => () => data,
);

const getSiteLink = createSelector(
(state: ConfigState) => state.meta && state.meta.siteLink,
(data) => () => data,
);

const getLoadError = createSelector(
(state: ConfigState) => state.errors.loadError,
(error) => () => error,
Expand All @@ -134,8 +122,6 @@ export function createConfigSelectorFactory(): ConfigSelectorFactory {
getHost: getHost(state),
getLocale: getLocale(state),
getVariantIdentificationToken: getVariantIdentificationToken(state),
getStorefrontJwtToken: getStorefrontJwtToken(state),
getSiteLink: getSiteLink(state),
getLoadError: getLoadError(state),
isLoading: isLoading(state),
};
Expand Down
2 changes: 0 additions & 2 deletions packages/core/src/config/config-state.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,6 @@ export interface ConfigMetaState {
variantIdentificationToken?: string;
host?: string;
locale?: string;
storefrontJwtToken?: string;
siteLink?: string;
}

export interface ConfigErrorsState {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,6 @@ export default function createPaymentIntegrationSelectors({
getStoreConfig,
getStoreConfigOrThrow,
getConfig,
getStorefrontJwtToken,
getSiteLink,
},
consignments: { getConsignments, getConsignmentsOrThrow },
countries: { getCountries },
Expand Down Expand Up @@ -82,8 +80,6 @@ export default function createPaymentIntegrationSelectors({
getPaymentStatusOrThrow,
getPaymentRedirectUrl,
getPaymentRedirectUrlOrThrow,
getStorefrontJwtToken,
getSiteLink,
getPaymentMethod: clone(getPaymentMethod),
getPaymentMethodOrThrow: clone(getPaymentMethodOrThrow),
getPaymentMethodsMeta: clone(getPaymentMethodsMeta),
Expand Down
15 changes: 2 additions & 13 deletions packages/core/src/payment/payment-method-action-creator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import { Observable, Observer } from 'rxjs';

import { InternalCheckoutSelectors } from '../checkout';
import { ActionOptions, cachableAction } from '../common/data-store';
import { MissingDataError, MissingDataErrorType } from '../common/error/errors';
import { RequestOptions } from '../common/http-request';

import {
Expand Down Expand Up @@ -169,11 +168,7 @@ export default class PaymentMethodActionCreator {
return (store) =>
Observable.create((observer: Observer<LoadPaymentMethodAction>) => {
const state = store.getState();
const jwtToken = state.config.getStorefrontJwtToken();

if (!jwtToken) {
throw new MissingDataError(MissingDataErrorType.MissingPaymentToken);
}
const host = state.config.getHost();

observer.next(
createAction(PaymentMethodActionType.LoadPaymentMethodRequested, undefined, {
Expand All @@ -182,13 +177,7 @@ export default class PaymentMethodActionCreator {
);

this._requestSender
.loadPaymentWalletWithInitializationData(methodId, {
headers: {
Authorization: `Bearer ${jwtToken}`,
'Content-Type': 'application/json',
},
...options,
})
.loadPaymentWalletWithInitializationData(methodId, host, options)
.then((response) => {
observer.next(
createAction(
Expand Down
35 changes: 8 additions & 27 deletions packages/core/src/payment/payment-method-request-sender.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,6 @@ const paymentMethodConfig: Record<string, HeadlessPaymentMethodType> = {
paypalcommercecredit: HeadlessPaymentMethodType.PAYPALCOMMERCECREDIT,
};

interface LoadPaymentWalletWithInitializationDataRequestOptions extends RequestOptions {
body?: { query: string };
headers: { Authorization: string; [key: string]: string };
}

interface LoadPaymentMethodResponse<T = any> {
data: {
site: {
Expand Down Expand Up @@ -78,31 +73,17 @@ export default class PaymentMethodRequestSender {

loadPaymentWalletWithInitializationData(
methodId: string,
options: LoadPaymentWalletWithInitializationDataRequestOptions,
host?: string,
{ timeout }: RequestOptions = {},
): Promise<Response<PaymentMethod>> {
const url = `/graphql`;

const entityId = this.getPaymentEntityId(methodId);

const graphQLQuery = `
query {
site {
paymentWalletWithInitializationData(filter: {paymentWalletEntityId: "${entityId}"}) {
clientToken
initializationData
}
}
}
`;

const requestOptions: LoadPaymentWalletWithInitializationDataRequestOptions = {
headers: {
...options.headers,
'Content-Type': 'application/json',
},
const path = 'get-initialization-data';
const url = host ? `${host}/${path}` : `/${path}`;

const requestOptions = {
body: {
query: graphQLQuery,
entityId: this.getPaymentEntityId(methodId),
},
timeout,
};

return this._requestSender
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -83,10 +83,6 @@ export default interface PaymentIntegrationSelectors {

getConfig(): Config | undefined;

getStorefrontJwtToken(): string | undefined;

getSiteLink(): string | undefined;

getInstrumentsMeta(): InstrumentMeta | undefined;

getOrderMeta(): OrderMetaState | undefined;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,8 +59,6 @@ const state = {
getPaymentRedirectUrl: jest.fn(),
getPaymentRedirectUrlOrThrow: jest.fn(),
isPaymentDataRequired: jest.fn(),
getStorefrontJwtToken: jest.fn(),
getSiteLink: jest.fn(),
};

const createBuyNowCart = jest.fn(() => Promise.resolve(getCart()));
Expand Down
Loading

0 comments on commit 060d1b0

Please sign in to comment.