Skip to content

Commit

Permalink
wrap show around native promise to make await-able
Browse files Browse the repository at this point in the history
  • Loading branch information
siddy2181 committed Dec 18, 2024
1 parent ba7fd0d commit e62dde1
Show file tree
Hide file tree
Showing 4 changed files with 88 additions and 57 deletions.
1 change: 1 addition & 0 deletions __sdk__.js
Original file line number Diff line number Diff line change
Expand Up @@ -95,5 +95,6 @@ module.exports = {
},
"three-domain-secure": {
entry: "./src/three-domain-secure/interface",
globals,
},
};
125 changes: 73 additions & 52 deletions src/three-domain-secure/component.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,8 @@ import type {
responseBody,
MerchantPayloadData,
SdkConfig,
threeDSResponse,
ThreeDSResponse,
HeliosResponse,

Check failure on line 19 in src/three-domain-secure/component.jsx

View workflow job for this annotation

GitHub Actions / main

'HeliosResponse' is defined but never used
TDSProps,
Update3DSTokenResponse,

Check failure on line 21 in src/three-domain-secure/component.jsx

View workflow job for this annotation

GitHub Actions / main

'Update3DSTokenResponse' is defined but never used
} from "./types";
Expand Down Expand Up @@ -63,7 +64,7 @@ const parseMerchantPayload = ({

export interface ThreeDomainSecureComponentInterface {
isEligible(payload: MerchantPayloadData): Promise<boolean>;
show(): Promise<threeDSResponse>;
show(): Promise<ThreeDSResponse>;
}

export class ThreeDomainSecureComponent {
Expand Down Expand Up @@ -131,63 +132,83 @@ export class ThreeDomainSecureComponent {
}
}

async show(): Promise<threeDSResponse> {
async show(): Promise<ThreeDSResponse> {

Check failure on line 135 in src/three-domain-secure/component.jsx

View workflow job for this annotation

GitHub Actions / main

Async method 'show' has no 'await' expression
if (!this.threeDSIframe) {
throw new ValidationError(`Ineligible for three domain secure`);
return Promise.reject(
new ValidationError(`Ineligible for three domain secure`)
);
}
const promise = new ZalgoPromise();
const cancelThreeDS = () => {
return ZalgoPromise.try(() => {
this.logger.warn("3DS Cancelled");
}).then(() => {
// eslint-disable-next-line no-use-before-define
// eslint-disable-next-line compat/compat
return new Promise((resolve, reject) => {
let authenticationState,
liabilityShift = "false";
const cancelThreeDS = () => {
return ZalgoPromise.try(() => {
this.logger.warn("3DS Cancelled");
}).then(() => {
resolve({
authenticationState: "cancelled",
liabilityShift: "false",
nonce: this.fastlaneNonce,
});
// eslint-disable-next-line no-use-before-define
instance.close();
});
};

const instance = this.threeDSIframe({
payerActionUrl: this.authenticationURL,
onSuccess: async (res) => {
const { reference_id, liability_shift, success } = res;
let enrichedNonce;
// Helios returns a boolen parameter: "success"
// It will be true for all cases where liability is shifted to merchant
// and false for downstream failures and errors
authenticationState = success ? "success" : "errored";
liabilityShift = liability_shift ? liability_shift : "false";

// call BT mutation to update fastlaneNonce with 3ds data
// reference_id will be available for all usecases(success/failure)
if (reference_id) {
const gqlResponse = await this.updateNonceWith3dsData(reference_id);
const { data, errors } = gqlResponse;
if (data) {
enrichedNonce =
data.updateTokenizedCreditCardWithExternalThreeDSecure
.paymentMethod.id;
} else if (errors) {
this.logger.warn("Errors returned when updating nonce", errors);
}
}

// Resolve the parent promise with enriched nonce if available
// else, return the original nonce that the merchant sent
resolve({
authenticationState,
liabilityShift,
nonce: enrichedNonce || this.fastlaneNonce,
});
},
onCancel: cancelThreeDS,
onError: (err) => {
instance.close();
reject(
new Error(
`Error with obtaining 3DS auth response: ${JSON.stringify(err)}`
)
);
},
});

// Render the iframe
instance.render("body").catch(() => {
instance.close();
});
};
// $FlowFixMe
const instance = await this.threeDSIframe({
payerActionUrl: this.authenticationURL,
onSuccess: async (res) => {
const { reference_id, authentication_status, liability_shift } = res;
let enrichedNonce, response;

if (reference_id) {
// $FlowFixMe ZalgoPromise not recognized
response = await this.updateNonceWith3dsData(reference_id);
}
// $FlowIssue
const { data, errors } = response;
if (data) {
enrichedNonce =
data?.updateTokenizedCreditCardWithExternalThreeDSecure
.paymentMethod.id;
} else if (errors) {
return promise.resolve({
authenticationStatus: authentication_status,
liabilityShift: liability_shift,
nonce: enrichedNonce,
});
}
},
onCancel: cancelThreeDS,
onError: (err) => {
return ZalgoPromise.reject(
new Error(
`Error with obtaining 3DS auth response, ${JSON.stringify(err)}`
)
);
},
});

return instance
.render("body")
.then(() => promise)
.finally(instance.close);
}

updateNonceWith3dsData(
threeDSRefID: string
): ZalgoPromise<Update3DSTokenResponse> {
updateNonceWith3dsData(threeDSRefID: string): Promise<any> {

Check failure on line 210 in src/three-domain-secure/component.jsx

View workflow job for this annotation

GitHub Actions / main

Unexpected use of weak type "any"
// $FlowFixMe Zalgopromise not recognized
return this.graphQLClient.request({
headers: {
"Braintree-Version": "2023-09-28",
Expand Down
16 changes: 12 additions & 4 deletions src/three-domain-secure/types.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
/* @flow */
/* eslint-disable no-restricted-globals, promise/no-native */
import { ZalgoPromise } from "@krakenjs/zalgo-promise/src";
import { type ZoidComponent } from "@krakenjs/zoid/src";

export type MerchantPayloadData = {|
Expand Down Expand Up @@ -70,27 +71,34 @@ export type SdkConfig = {|
clientID: string,
|};

export type threeDSResponse = {|
export type ThreeDSResponse = {|
liabilityShift: string,
authenticationStatus: string,
authenticationState: string,
nonce?: string,
|};

export type HeliosResponse = {|
liability_shift?: string,
reference_id?: string,
success: boolean,
|};

export type TDSResult = {||};

export type TDSProps = {|
xcomponent?: string,
payerActionUrl: string,
onSuccess: (data: threeDSResponse) => void,
onSuccess: (data: HeliosResponse) => Promise,
onError: (mixed) => void,
onCancel: (mixed) => ZalgoPromise,
sdkMeta?: string,
content?: void | {|
windowMessage?: string,
continueMessage?: string,
cancelMessage?: string,
interrogativeMessage?: string,
|},
nonce: string,
nonce?: string,
|};

export type UrlProps = {|
Expand Down
3 changes: 2 additions & 1 deletion src/three-domain-secure/utils.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,8 @@ export function getFastlaneThreeDS(): TDSComponent {
return (
<Overlay
context={context}
close={close}
// $FlowFixMe
close={props.onCancel || close}
focus={focus}
event={event}
frame={frame}
Expand Down

0 comments on commit e62dde1

Please sign in to comment.