Skip to content

Commit

Permalink
feat: Add hosted-fields payment logic Pattern1 (#17584)
Browse files Browse the repository at this point in the history
CXSPA-3717
  • Loading branch information
FollowTheFlo authored Jul 7, 2023
1 parent aa6f36b commit 20a3f6d
Show file tree
Hide file tree
Showing 51 changed files with 835 additions and 69 deletions.
7 changes: 7 additions & 0 deletions integration-libs/opf/base/assets/translations/en/opf.i18n.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,12 @@
* SPDX-License-Identifier: Apache-2.0
*/

/*
* SPDX-FileCopyrightText: 2023 SAP Spartacus team <[email protected]>
*
* SPDX-License-Identifier: Apache-2.0
*/

export const opf = {
opf: {
payment: {
Expand All @@ -17,6 +23,7 @@ export const opf = {
invalidCreditCard: 'Invalid credit card. Please review card details.',
unknown:
'Unknown error occurred while fetching payment. Please contact support',
cardReportedLost: 'Card is reported lost.',
},
},
},
Expand Down
12 changes: 12 additions & 0 deletions integration-libs/opf/base/core/connectors/converters.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
/*
* SPDX-FileCopyrightText: 2023 SAP Spartacus team <[email protected]>
*
* SPDX-License-Identifier: Apache-2.0
*/

import { InjectionToken } from '@angular/core';
import { Converter } from '@spartacus/core';

export const OTP_NORMALIZER = new InjectionToken<
Converter<any, string | undefined>
>('OtpNormalizer');
2 changes: 2 additions & 0 deletions integration-libs/opf/base/core/connectors/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,5 @@ export * from './opf-order.adapter';
export * from './opf-order.connector';
export * from './opf-payment.adapter';
export * from './opf-payment.connector';
export * from './otp.adapter';
export * from './otp.connector';
12 changes: 12 additions & 0 deletions integration-libs/opf/base/core/connectors/opf-payment.adapter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@
import {
OpfPaymentVerificationPayload,
OpfPaymentVerificationResponse,
SubmitRequest,
SubmitResponse,
} from '@spartacus/opf/base/root';
import { Observable } from 'rxjs';

Expand All @@ -19,4 +21,14 @@ export abstract class OpfPaymentAdapter {
paymentSessionId: string,
payload: OpfPaymentVerificationPayload
): Observable<OpfPaymentVerificationResponse>;

/**
* Abstract method used to submit payment for hosted-fields pattern
*/

abstract submitPayment(
submitRequest: SubmitRequest,
otpKey: string,
paymentSessionId: string
): Observable<SubmitResponse>;
}
10 changes: 10 additions & 0 deletions integration-libs/opf/base/core/connectors/opf-payment.connector.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ import { Injectable } from '@angular/core';
import {
OpfPaymentVerificationPayload,
OpfPaymentVerificationResponse,
SubmitRequest,
SubmitResponse,
} from '@spartacus/opf/base/root';

import { Observable } from 'rxjs';
Expand All @@ -23,4 +25,12 @@ export class OpfPaymentConnector {
): Observable<OpfPaymentVerificationResponse> {
return this.adapter.verifyPayment(paymentSessionId, payload);
}

public submitPayment(
submitRequest: SubmitRequest,
otpKey: string,
paymentSessionId: string
): Observable<SubmitResponse> {
return this.adapter.submitPayment(submitRequest, otpKey, paymentSessionId);
}
}
21 changes: 18 additions & 3 deletions integration-libs/opf/base/core/facade/facade-providers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,22 +5,37 @@
*/

import { Provider } from '@angular/core';
import { OpfOrderFacade, OpfPaymentFacade } from '@spartacus/opf/base/root';
import {
OpfGlobalFunctionsFacade,
OpfOrderFacade,
OpfOtpFacade,
OpfPaymentFacade,
} from '@spartacus/opf/base/root';

import { OpfGlobalFunctionsService } from './opf-global-functions.service';
import { OpfOrderService } from './opf-order.service';
import { OpfOtpService } from './opf-otp.service';
import { OpfPaymentService } from './opf-payment.service';

export const facadeProviders: Provider[] = [
OpfPaymentService,
OpfOrderService,

OpfOtpService,
OpfGlobalFunctionsService,
{
provide: OpfPaymentFacade,
useExisting: OpfPaymentService,
},

{
provide: OpfOrderFacade,
useExisting: OpfOrderService,
},
{
provide: OpfOtpFacade,
useExisting: OpfOtpService,
},
{
provide: OpfGlobalFunctionsFacade,
useExisting: OpfGlobalFunctionsService,
},
];
2 changes: 2 additions & 0 deletions integration-libs/opf/base/core/facade/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,7 @@
* SPDX-License-Identifier: Apache-2.0
*/

export * from './opf-global-functions.service';
export * from './opf-order.service';
export * from './opf-otp.service';
export * from './opf-payment.service';
133 changes: 133 additions & 0 deletions integration-libs/opf/base/core/facade/opf-global-functions.service.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,133 @@
/*
* SPDX-FileCopyrightText: 2023 SAP Spartacus team <[email protected]>
*
* SPDX-License-Identifier: Apache-2.0
*/

import {
ComponentRef,
Injectable,
NgZone,
ViewContainerRef,
} from '@angular/core';
import { WindowRef } from '@spartacus/core';
import {
GlobalOpfPaymentMethods,
KeyValuePair,
MerchantCallback,
OpfGlobalFunctionsFacade,
OpfPaymentFacade,
PaymentMethod,
} from '@spartacus/opf/base/root';
import { LAUNCH_CALLER, LaunchDialogService } from '@spartacus/storefront';
import { Observable } from 'rxjs';
import { finalize } from 'rxjs/operators';

@Injectable()
export class OpfGlobalFunctionsService implements OpfGlobalFunctionsFacade {
protected _isGlobalServiceInit = false;

constructor(
protected winRef: WindowRef,
private ngZone: NgZone,
protected opfPaymentFacade: OpfPaymentFacade,
protected launchDialogService: LaunchDialogService
) {}

registerGlobalFunctions(
paymentSessionId: string,
vcr?: ViewContainerRef
): void {
this.registerSubmit(paymentSessionId, vcr);
this._isGlobalServiceInit = true;
}

removeGlobalFunctions(): void {
if (!this._isGlobalServiceInit) {
return;
}
const window = this.winRef.nativeWindow as any;
if (window?.Opf) {
window.Opf = undefined;
}
this._isGlobalServiceInit = false;
}

protected getGlobalFunctionContainer(): GlobalOpfPaymentMethods {
const window = this.winRef.nativeWindow as any;
if (!window.Opf?.payments) {
window.Opf = window?.Opf ?? {};
window.Opf.payments = {};
}
return window.Opf.payments;
}

protected registerSubmit(
paymentSessionId: string,
vcr?: ViewContainerRef
): void {
this.getGlobalFunctionContainer().submit = ({
cartId,
additionalData,
submitSuccess = (): void => {
// this is intentional
},
submitPending = (): void => {
// this is intentional
},
submitFailure = (): void => {
// this is intentional
},
paymentMethod,
}: {
cartId: string;
additionalData: Array<KeyValuePair>;
submitSuccess: MerchantCallback;
submitPending: MerchantCallback;
submitFailure: MerchantCallback;
paymentMethod: PaymentMethod;
}): Promise<boolean> => {
return this.ngZone.run(() => {
let overlayedSpinner: void | Observable<ComponentRef<any> | undefined>;
if (vcr) {
overlayedSpinner = this.launchDialogService.launch(
LAUNCH_CALLER.PLACE_ORDER_SPINNER,
vcr
);
}
const callbackArray: [
MerchantCallback,
MerchantCallback,
MerchantCallback
] = [submitSuccess, submitPending, submitFailure];

return this.opfPaymentFacade
.submitPayment({
additionalData,
paymentSessionId,
cartId,
callbackArray,
paymentMethod,
returnPath: undefined,
})
.pipe(
finalize(() => {
if (overlayedSpinner) {
overlayedSpinner
.subscribe((component) => {
this.launchDialogService.clear(
LAUNCH_CALLER.PLACE_ORDER_SPINNER
);
if (component) {
component.destroy();
}
})
.unsubscribe();
}
})
)
.toPromise();
});
};
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

import { Injectable } from '@angular/core';
import { Command, CommandService, QueryService } from '@spartacus/core';
import { OpfOtpFacade } from '@spartacus/opf/checkout/root';
import { OpfOtpFacade } from '@spartacus/opf/base/root';
import { Observable } from 'rxjs';
import { OtpConnector } from '../connectors/otp.connector';

Expand Down
Loading

0 comments on commit 20a3f6d

Please sign in to comment.