Skip to content

Commit

Permalink
feat: add Merchant Name label on payment sheet (#18663)
Browse files Browse the repository at this point in the history
CXSPA-6508
  • Loading branch information
FollowTheFlo authored Mar 25, 2024
1 parent e78964f commit 281d005
Show file tree
Hide file tree
Showing 7 changed files with 150 additions and 99 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,7 @@ describe('ApplePayService', () => {
'getQuickBuyLocationContext',
'getQuickBuyProviderConfig',
'getQuickBuyDeliveryInfo',
'getMerchantName',
]);

applePaySessionFactoryMock = jasmine.createSpyObj(
Expand Down Expand Up @@ -197,6 +198,7 @@ describe('ApplePayService', () => {

describe('observable callbacks', () => {
let config: ApplePayObservableConfig;
const merchantNameMock = 'Nakano';
beforeEach(() => {
(
applePayObservableFactoryMock.initApplePayEventsHandler as jasmine.Spy
Expand All @@ -209,6 +211,9 @@ describe('ApplePayService', () => {
type: OpfQuickBuyDeliveryType.SHIPPING,
})
);
opfQuickBuyServiceMock.getMerchantName.and.returnValue(
of(merchantNameMock)
);
});

it('should handle validateMerchant change', () => {
Expand Down Expand Up @@ -309,7 +314,7 @@ describe('ApplePayService', () => {

expect(paymentMethodChangeResult.newTotal).toEqual({
amount: mockProduct.price?.value?.toString(),
label: mockProduct.name,
label: merchantNameMock,
});
});

Expand Down Expand Up @@ -345,7 +350,7 @@ describe('ApplePayService', () => {
.subscribe((actural) => (shippingMethodChangeResult = actural));
expect(shippingMethodChangeResult.newTotal).toEqual({
amount: mockCart.totalPrice?.value?.toString(),
label: mockProduct.name,
label: merchantNameMock,
});
});

Expand Down Expand Up @@ -665,6 +670,7 @@ describe('ApplePayService', () => {

it('should handle errors during Apple Pay session start', () => {
service = TestBed.inject(ApplePayService);
const merchantNameMock = 'Nakano';
opfQuickBuyServiceMock.getQuickBuyDeliveryInfo.and.returnValue(
of({
type: OpfQuickBuyDeliveryType.SHIPPING,
Expand All @@ -680,6 +686,10 @@ describe('ApplePayService', () => {
throwError('Error')
);

opfQuickBuyServiceMock.getMerchantName.and.returnValue(
of(merchantNameMock)
);

service
.start({ product: mockProduct, quantity: 1, countryCode: 'us' })
.subscribe({
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
/// <reference types="@types/applepayjs" />
import { Injectable, inject } from '@angular/core';
import { Address, Product, WindowRef } from '@spartacus/core';
import { Observable, of, throwError } from 'rxjs';
import { Observable, forkJoin, of, throwError } from 'rxjs';
import {
catchError,
finalize,
Expand All @@ -27,11 +27,11 @@ import {
ApplePayShippingType,
ApplePayTransactionInput,
OpfPaymentFacade,
OpfQuickBuyDeliveryInfo,
OpfQuickBuyDeliveryType,
OpfQuickBuyLocation,
PaymentMethod,
QuickBuyTransactionDetails,
defaultMerchantName,
} from '@spartacus/opf/base/root';

import { Cart, DeliveryMode } from '@spartacus/cart/base/root';
Expand Down Expand Up @@ -61,7 +61,7 @@ export class ApplePayService {
quantity: 0,
addressIds: [],
total: {
label: '',
label: defaultMerchantName,
amount: '',
currency: '',
},
Expand Down Expand Up @@ -185,33 +185,35 @@ export class ApplePayService {
countryCode,
};

return this.opfQuickBuyService
.getQuickBuyDeliveryInfo(
return forkJoin({
deliveryInfo: this.opfQuickBuyService.getQuickBuyDeliveryInfo(
this.transactionDetails.context as OpfQuickBuyLocation
)
.pipe(
switchMap((deliveryInfo: OpfQuickBuyDeliveryInfo) => {
this.transactionDetails.deliveryInfo = deliveryInfo;
if (deliveryInfo.type === OpfQuickBuyDeliveryType.PICKUP) {
// Don't display shipping contact form on payment sheet
initialRequest.requiredShippingContactFields = [];
initialRequest.shippingType = ApplePayShippingType.STORE_PICKUP;

return this.transactionDetails.context ===
OpfQuickBuyLocation.PRODUCT
? this.opfPickupInStoreHandlerService.getSingleProductDeliveryInfo()
: of(undefined);
}
return of(undefined);
}),
map((opfQuickBuyDeliveryInfo) => {
if (!opfQuickBuyDeliveryInfo) {
return initialRequest;
}
this.transactionDetails.deliveryInfo = opfQuickBuyDeliveryInfo;
),
merchantName: this.opfQuickBuyService.getMerchantName(),
}).pipe(
switchMap(({ deliveryInfo, merchantName }) => {
this.transactionDetails.total.label = merchantName;
initialRequest.total.label = merchantName;
this.transactionDetails.deliveryInfo = deliveryInfo;
if (deliveryInfo.type === OpfQuickBuyDeliveryType.PICKUP) {
// Don't display shipping contact form on payment sheet
initialRequest.requiredShippingContactFields = [];
initialRequest.shippingType = ApplePayShippingType.STORE_PICKUP;

return this.transactionDetails.context === OpfQuickBuyLocation.PRODUCT
? this.opfPickupInStoreHandlerService.getSingleProductDeliveryInfo()
: of(undefined);
}
return of(undefined);
}),
map((opfQuickBuyDeliveryInfo) => {
if (!opfQuickBuyDeliveryInfo) {
return initialRequest;
})
);
}
this.transactionDetails.deliveryInfo = opfQuickBuyDeliveryInfo;
return initialRequest;
})
);
}

protected handleSingleProductTransaction(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import { OpfQuickBuyService } from '../opf-quick-buy.service';
import { OpfGooglePayService } from './google-pay.service';

describe('OpfGooglePayService', () => {
const mockMerchantName = 'mockMerchantName';
let service: OpfGooglePayService;
let mockResourceLoaderService: jasmine.SpyObj<OpfResourceLoaderService>;
let mockItemCounterService: jasmine.SpyObj<ItemCounterService>;
Expand Down Expand Up @@ -69,6 +70,7 @@ describe('OpfGooglePayService', () => {
'getQuickBuyLocationContext',
'getQuickBuyProviderConfig',
'getQuickBuyDeliveryInfo',
'getMerchantName',
]);

const googlePayApiMock = {
Expand Down Expand Up @@ -495,6 +497,8 @@ describe('OpfGooglePayService', () => {
of(OpfQuickBuyLocation.PRODUCT)
);

mockQuickBuyService.getMerchantName.and.returnValue(of(mockMerchantName));

service.initTransaction();

expect(service['transactionDetails'].context).toBe(
Expand All @@ -518,6 +522,8 @@ describe('OpfGooglePayService', () => {
of(OpfQuickBuyLocation.CART)
);

mockQuickBuyService.getMerchantName.and.returnValue(of(mockMerchantName));

service.initTransaction();

expect(service['transactionDetails'].context).toBe(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,12 @@ import {
ActiveConfiguration,
OpfPaymentFacade,
OpfProviderType,
OpfQuickBuyDeliveryInfo,
OpfQuickBuyDeliveryType,
OpfQuickBuyLocation,
OpfResourceLoaderService,
PaymentMethod,
QuickBuyTransactionDetails,
defaultMerchantName,
} from '@spartacus/opf/base/root';
import {
CurrentProductService,
Expand Down Expand Up @@ -72,7 +72,7 @@ export class OpfGooglePayService {
// @ts-ignore
merchantInfo: {
// merchantId: 'spartacusStorefront',
merchantName: 'Spartacus Storefront',
merchantName: defaultMerchantName,
},
shippingOptionRequired: true,
shippingAddressRequired: true,
Expand Down Expand Up @@ -116,7 +116,8 @@ export class OpfGooglePayService {
}

protected setGooglePaymentRequestConfig(
deliveryType: OpfQuickBuyDeliveryType
deliveryType: OpfQuickBuyDeliveryType,
merchantName: string
) {
if (deliveryType === OpfQuickBuyDeliveryType.PICKUP) {
this.googlePaymentClientOptions = {
Expand All @@ -139,7 +140,7 @@ export class OpfGooglePayService {
};
this.googlePaymentRequest = this.initialGooglePaymentRequest;
}

this.googlePaymentRequest.merchantInfo.merchantName = merchantName;
this.updateGooglePaymentClient();
}

Expand Down Expand Up @@ -261,79 +262,82 @@ export class OpfGooglePayService {

handleSingleProductTransaction(): Observable<Product | boolean | null> {
this.transactionDetails.context = OpfQuickBuyLocation.PRODUCT;
return this.opfQuickBuyService
.getQuickBuyDeliveryInfo(this.transactionDetails.context)
.pipe(
switchMap((deliveryInfo: OpfQuickBuyDeliveryInfo) => {
this.transactionDetails.deliveryInfo = deliveryInfo;
this.setGooglePaymentRequestConfig(deliveryInfo.type);

return this.currentProductService.getProduct().pipe(
take(1),
switchMap((product: Product | null) => {
const count = this.itemCounterService.getCounter();
this.transactionDetails.product = product as Product;
this.transactionDetails.quantity = count;
return this.opfCartHandlerService
.addProductToCart(
product?.code || '',
count,
this.transactionDetails.deliveryInfo?.pickupDetails?.name
)
.pipe(
tap(() => {
this.setDeliveryMode(
undefined,
this.transactionDetails.deliveryInfo?.type
);
this.updateTransactionInfo({
totalPrice: this.estimateTotalPrice(
product?.price?.value
),
currencyCode:
product?.price?.currencyIso ||
this.initialTransactionInfo.currencyCode,
totalPriceStatus:
this.initialTransactionInfo.totalPriceStatus,
});
})
);
})
);
})
);
}

handleActiveCartTransaction(): Observable<Cart> {
this.transactionDetails.context = OpfQuickBuyLocation.CART;

return this.opfQuickBuyService
.getQuickBuyDeliveryInfo(this.transactionDetails.context)
.pipe(
switchMap((deliveryInfo: OpfQuickBuyDeliveryInfo) => {
this.transactionDetails.deliveryInfo = deliveryInfo;
this.setGooglePaymentRequestConfig(deliveryInfo.type);

return this.setDeliveryMode(undefined, deliveryInfo.type).pipe(
switchMap(() =>
this.opfCartHandlerService.getCurrentCart().pipe(
take(1),
tap((cart: Cart) => {
this.transactionDetails.cart = cart;
return forkJoin({
deliveryInfo: this.opfQuickBuyService.getQuickBuyDeliveryInfo(
this.transactionDetails.context as OpfQuickBuyLocation
),
merchantName: this.opfQuickBuyService.getMerchantName(),
}).pipe(
switchMap(({ deliveryInfo, merchantName }) => {
this.transactionDetails.deliveryInfo = deliveryInfo;
this.setGooglePaymentRequestConfig(deliveryInfo.type, merchantName);
return this.currentProductService.getProduct().pipe(
take(1),
switchMap((product: Product | null) => {
const count = this.itemCounterService.getCounter();
this.transactionDetails.product = product as Product;
this.transactionDetails.quantity = count;
return this.opfCartHandlerService
.addProductToCart(
product?.code || '',
count,
this.transactionDetails.deliveryInfo?.pickupDetails?.name
)
.pipe(
tap(() => {
this.setDeliveryMode(
undefined,
this.transactionDetails.deliveryInfo?.type
);
this.updateTransactionInfo({
totalPrice: `${cart.totalPrice?.value}`,
totalPrice: this.estimateTotalPrice(product?.price?.value),
currencyCode:
cart.totalPrice?.currencyIso ||
product?.price?.currencyIso ||
this.initialTransactionInfo.currencyCode,
totalPriceStatus:
this.initialTransactionInfo.totalPriceStatus,
});
})
)
);
})
);
})
);
}

handleActiveCartTransaction(): Observable<Cart> {
this.transactionDetails.context = OpfQuickBuyLocation.CART;

return forkJoin({
deliveryInfo: this.opfQuickBuyService.getQuickBuyDeliveryInfo(
this.transactionDetails.context as OpfQuickBuyLocation
),
merchantName: this.opfQuickBuyService.getMerchantName(),
}).pipe(
switchMap(({ deliveryInfo, merchantName }) => {
this.transactionDetails.deliveryInfo = deliveryInfo;
this.setGooglePaymentRequestConfig(deliveryInfo.type, merchantName);

return this.setDeliveryMode(undefined, deliveryInfo.type).pipe(
switchMap(() =>
this.opfCartHandlerService.getCurrentCart().pipe(
take(1),
tap((cart: Cart) => {
this.transactionDetails.cart = cart;
this.updateTransactionInfo({
totalPrice: `${cart.totalPrice?.value}`,
currencyCode:
cart.totalPrice?.currencyIso ||
this.initialTransactionInfo.currencyCode,
totalPriceStatus:
this.initialTransactionInfo.totalPriceStatus,
});
})
)
);
})
);
)
);
})
);
}

initTransaction(): void {
Expand Down
Loading

0 comments on commit 281d005

Please sign in to comment.