@@ -15,7 +15,8 @@ import type {
15
15
responseBody ,
16
16
MerchantPayloadData ,
17
17
SdkConfig ,
18
- threeDSResponse ,
18
+ ThreeDSResponse ,
19
+ HeliosResponse ,
19
20
TDSProps ,
20
21
Update3DSTokenResponse ,
21
22
} from "./types" ;
@@ -63,7 +64,7 @@ const parseMerchantPayload = ({
63
64
64
65
export interface ThreeDomainSecureComponentInterface {
65
66
isEligible ( payload : MerchantPayloadData ) : Promise < boolean > ;
66
- show ( ) : Promise < threeDSResponse > ;
67
+ show ( ) : Promise < ThreeDSResponse > ;
67
68
}
68
69
69
70
export class ThreeDomainSecureComponent {
@@ -131,63 +132,83 @@ export class ThreeDomainSecureComponent {
131
132
}
132
133
}
133
134
134
- async show ( ) : Promise < threeDSResponse > {
135
+ async show ( ) : Promise < ThreeDSResponse > {
135
136
if ( ! this . threeDSIframe ) {
136
- throw new ValidationError ( `Ineligible for three domain secure` ) ;
137
+ return Promise . reject (
138
+ new ValidationError ( `Ineligible for three domain secure` )
139
+ ) ;
137
140
}
138
- const promise = new ZalgoPromise ( ) ;
139
- const cancelThreeDS = ( ) => {
140
- return ZalgoPromise . try ( ( ) => {
141
- this . logger . warn ( "3DS Cancelled" ) ;
142
- } ) . then ( ( ) => {
143
- // eslint-disable-next-line no-use-before-define
141
+ // eslint-disable-next-line compat/compat
142
+ return new Promise ( ( resolve , reject ) => {
143
+ let authenticationState ,
144
+ liabilityShift = "false" ;
145
+ const cancelThreeDS = ( ) => {
146
+ return ZalgoPromise . try ( ( ) => {
147
+ this . logger . warn ( "3DS Cancelled" ) ;
148
+ } ) . then ( ( ) => {
149
+ resolve ( {
150
+ authenticationState : "cancelled" ,
151
+ liabilityShift : "false" ,
152
+ nonce : this . fastlaneNonce ,
153
+ } ) ;
154
+ // eslint-disable-next-line no-use-before-define
155
+ instance . close ( ) ;
156
+ } ) ;
157
+ } ;
158
+
159
+ const instance = this . threeDSIframe ( {
160
+ payerActionUrl : this . authenticationURL ,
161
+ onSuccess : async ( res ) => {
162
+ const { reference_id, liability_shift, success } = res ;
163
+ let enrichedNonce ;
164
+ // Helios returns a boolen parameter: "success"
165
+ // It will be true for all cases where liability is shifted to merchant
166
+ // and false for downstream failures and errors
167
+ authenticationState = success ? "success" : "errored" ;
168
+ liabilityShift = liability_shift ? liability_shift : "false" ;
169
+
170
+ // call BT mutation to update fastlaneNonce with 3ds data
171
+ // reference_id will be available for all usecases(success/failure)
172
+ if ( reference_id ) {
173
+ const gqlResponse = await this . updateNonceWith3dsData ( reference_id ) ;
174
+ const { data, errors } = gqlResponse ;
175
+ if ( data ) {
176
+ enrichedNonce =
177
+ data . updateTokenizedCreditCardWithExternalThreeDSecure
178
+ . paymentMethod . id ;
179
+ } else if ( errors ) {
180
+ this . logger . warn ( "Errors returned when updating nonce" , errors ) ;
181
+ }
182
+ }
183
+
184
+ // Resolve the parent promise with enriched nonce if available
185
+ // else, return the original nonce that the merchant sent
186
+ resolve ( {
187
+ authenticationState,
188
+ liabilityShift,
189
+ nonce : enrichedNonce || this . fastlaneNonce ,
190
+ } ) ;
191
+ } ,
192
+ onCancel : cancelThreeDS ,
193
+ onError : ( err ) => {
194
+ instance . close ( ) ;
195
+ reject (
196
+ new Error (
197
+ `Error with obtaining 3DS auth response: ${ JSON . stringify ( err ) } `
198
+ )
199
+ ) ;
200
+ } ,
201
+ } ) ;
202
+
203
+ // Render the iframe
204
+ instance . render ( "body" ) . catch ( ( ) => {
144
205
instance . close ( ) ;
145
206
} ) ;
146
- } ;
147
- // $FlowFixMe
148
- const instance = await this . threeDSIframe ( {
149
- payerActionUrl : this . authenticationURL ,
150
- onSuccess : async ( res ) => {
151
- const { reference_id, authentication_status, liability_shift } = res ;
152
- let enrichedNonce , response ;
153
-
154
- if ( reference_id ) {
155
- // $FlowFixMe ZalgoPromise not recognized
156
- response = await this . updateNonceWith3dsData ( reference_id ) ;
157
- }
158
- // $FlowIssue
159
- const { data, errors } = response ;
160
- if ( data ) {
161
- enrichedNonce =
162
- data ?. updateTokenizedCreditCardWithExternalThreeDSecure
163
- . paymentMethod . id ;
164
- } else if ( errors ) {
165
- return promise . resolve ( {
166
- authenticationStatus : authentication_status ,
167
- liabilityShift : liability_shift ,
168
- nonce : enrichedNonce ,
169
- } ) ;
170
- }
171
- } ,
172
- onCancel : cancelThreeDS ,
173
- onError : ( err ) => {
174
- return ZalgoPromise . reject (
175
- new Error (
176
- `Error with obtaining 3DS auth response, ${ JSON . stringify ( err ) } `
177
- )
178
- ) ;
179
- } ,
180
207
} ) ;
181
-
182
- return instance
183
- . render ( "body" )
184
- . then ( ( ) => promise )
185
- . finally ( instance . close ) ;
186
208
}
187
209
188
- updateNonceWith3dsData (
189
- threeDSRefID : string
190
- ) : ZalgoPromise < Update3DSTokenResponse > {
210
+ updateNonceWith3dsData ( threeDSRefID : string ) : Promise < any > {
211
+ // $FlowFixMe Zalgopromise not recognized
191
212
return this . graphQLClient . request ( {
192
213
headers : {
193
214
"Braintree-Version" : "2023-09-28" ,
0 commit comments