@fat-zebra/sdk 1.4.14 → 1.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (172) hide show
  1. package/.idea/fatzebra-js.iml +12 -0
  2. package/.idea/modules.xml +8 -0
  3. package/.idea/vcs.xml +6 -0
  4. package/CHANGELOG.md +13 -0
  5. package/README.dev.md +1 -14
  6. package/build-styles.js +12 -0
  7. package/dist/click_to_pay/index.d.ts +1 -1
  8. package/dist/click_to_pay/index.js +45 -1
  9. package/dist/fatzebra.css +91 -0
  10. package/dist/hpp/hpp.js +1 -3
  11. package/dist/local/fatzebra.js +18266 -0
  12. package/dist/local/fatzebra.js.map +1 -1
  13. package/dist/main.d.ts +2 -2
  14. package/dist/main.js +7 -21
  15. package/dist/react/VerifyCard.d.ts +2 -2
  16. package/dist/react/VerifyCard.js +4 -4
  17. package/dist/react/VerifyExistingCard.d.ts +10 -0
  18. package/dist/react/VerifyExistingCard.js +12 -0
  19. package/dist/react/index.d.ts +2 -1
  20. package/dist/react/index.js +2 -1
  21. package/dist/react/useFatZebra.d.ts +4 -2
  22. package/dist/react/useFatZebra.js +7 -7
  23. package/dist/react/verifyUrl.d.ts +8 -0
  24. package/dist/react/verifyUrl.js +22 -0
  25. package/dist/sca/cardinal.d.ts +11 -10
  26. package/dist/sca/cardinal.js +29 -8
  27. package/dist/sca/index.d.ts +3 -0
  28. package/dist/sca/index.js +53 -48
  29. package/dist/sca/types.d.ts +2 -2
  30. package/dist/shared/api-gateway-client.d.ts +4 -10
  31. package/dist/shared/api-gateway-client.js +12 -38
  32. package/dist/shared/env.d.ts +4 -0
  33. package/dist/shared/env.js +4 -0
  34. package/dist/shared/event-manager.d.ts +3 -1
  35. package/dist/shared/event-manager.js +7 -1
  36. package/dist/shared/post-message-client.d.ts +1 -0
  37. package/dist/shared/post-message-client.js +8 -13
  38. package/dist/shared/types.d.ts +8 -20
  39. package/dist/shared/types.js +4 -15
  40. package/dist/staging/fatzebra.css +91 -0
  41. package/dist/staging/fatzebra.js +18265 -0
  42. package/dist/staging/fatzebra.js.map +1 -0
  43. package/dist/staging/index.html +247 -0
  44. package/dist/validation/schemas/hpp-options.json +45 -93
  45. package/package.json +6 -7
  46. package/dist/production/fatzebra.js.LICENSE.txt +0 -1
  47. package/dist/src/applepay/applepay.js +0 -198
  48. package/dist/src/applepay/applepay.js.map +0 -1
  49. package/dist/src/applepay/clients/apple-pay-client.js +0 -66
  50. package/dist/src/applepay/clients/apple-pay-client.js.map +0 -1
  51. package/dist/src/applepay/clients/paynow-client.js +0 -96
  52. package/dist/src/applepay/clients/paynow-client.js.map +0 -1
  53. package/dist/src/applepay/index.js +0 -6
  54. package/dist/src/applepay/index.js.map +0 -1
  55. package/dist/src/click_to_pay/index.js +0 -88
  56. package/dist/src/click_to_pay/index.js.map +0 -1
  57. package/dist/src/click_to_pay/types.js +0 -3
  58. package/dist/src/click_to_pay/types.js.map +0 -1
  59. package/dist/src/hpp/hpp.js +0 -230
  60. package/dist/src/hpp/hpp.js.map +0 -1
  61. package/dist/src/hpp/hpp.test.js +0 -135
  62. package/dist/src/hpp/hpp.test.js.map +0 -1
  63. package/dist/src/hpp/index.js +0 -6
  64. package/dist/src/hpp/index.js.map +0 -1
  65. package/dist/src/index.js +0 -14
  66. package/dist/src/index.js.map +0 -1
  67. package/dist/src/main.js +0 -243
  68. package/dist/src/main.js.map +0 -1
  69. package/dist/src/main.test.js +0 -236
  70. package/dist/src/main.test.js.map +0 -1
  71. package/dist/src/paypal/paypal-button.js +0 -311
  72. package/dist/src/paypal/paypal-button.js.map +0 -1
  73. package/dist/src/paypal/paypal-button.test.js +0 -41
  74. package/dist/src/paypal/paypal-button.test.js.map +0 -1
  75. package/dist/src/paypal/paypal-checkout.js +0 -111
  76. package/dist/src/paypal/paypal-checkout.js.map +0 -1
  77. package/dist/src/paypal/paypal-checkout.test.js +0 -167
  78. package/dist/src/paypal/paypal-checkout.test.js.map +0 -1
  79. package/dist/src/paypal/types.js +0 -9
  80. package/dist/src/paypal/types.js.map +0 -1
  81. package/dist/src/paypal/validation.js +0 -73
  82. package/dist/src/paypal/validation.js.map +0 -1
  83. package/dist/src/react/VerifyCard.js +0 -29
  84. package/dist/src/react/VerifyCard.js.map +0 -1
  85. package/dist/src/react/index.js +0 -11
  86. package/dist/src/react/index.js.map +0 -1
  87. package/dist/src/react/submitForm.js +0 -13
  88. package/dist/src/react/submitForm.js.map +0 -1
  89. package/dist/src/react/url.js +0 -60
  90. package/dist/src/react/url.js.map +0 -1
  91. package/dist/src/react/url.test.js +0 -88
  92. package/dist/src/react/url.test.js.map +0 -1
  93. package/dist/src/react/useFatZebra.js +0 -119
  94. package/dist/src/react/useFatZebra.js.map +0 -1
  95. package/dist/src/sca/cardinal.js +0 -110
  96. package/dist/src/sca/cardinal.js.map +0 -1
  97. package/dist/src/sca/eci-mappings.js +0 -63
  98. package/dist/src/sca/eci-mappings.js.map +0 -1
  99. package/dist/src/sca/eci-mappings.test.js +0 -31
  100. package/dist/src/sca/eci-mappings.test.js.map +0 -1
  101. package/dist/src/sca/index.js +0 -363
  102. package/dist/src/sca/index.js.map +0 -1
  103. package/dist/src/sca/index.test.js +0 -620
  104. package/dist/src/sca/index.test.js.map +0 -1
  105. package/dist/src/sca/scenarios/enrollment.js +0 -161
  106. package/dist/src/sca/scenarios/enrollment.js.map +0 -1
  107. package/dist/src/sca/scenarios/index.js +0 -8
  108. package/dist/src/sca/scenarios/index.js.map +0 -1
  109. package/dist/src/sca/scenarios/validation.js +0 -139
  110. package/dist/src/sca/scenarios/validation.js.map +0 -1
  111. package/dist/src/sca/types.js +0 -57
  112. package/dist/src/sca/types.js.map +0 -1
  113. package/dist/src/shared/api-gateway-client.js +0 -184
  114. package/dist/src/shared/api-gateway-client.js.map +0 -1
  115. package/dist/src/shared/bridge-client.js +0 -24
  116. package/dist/src/shared/bridge-client.js.map +0 -1
  117. package/dist/src/shared/constants.js +0 -19
  118. package/dist/src/shared/constants.js.map +0 -1
  119. package/dist/src/shared/env.development.js +0 -12
  120. package/dist/src/shared/env.development.js.map +0 -1
  121. package/dist/src/shared/env.js +0 -46
  122. package/dist/src/shared/env.js.map +0 -1
  123. package/dist/src/shared/envs/local.js +0 -12
  124. package/dist/src/shared/envs/local.js.map +0 -1
  125. package/dist/src/shared/envs/production.js +0 -12
  126. package/dist/src/shared/envs/production.js.map +0 -1
  127. package/dist/src/shared/envs/sandbox.js +0 -12
  128. package/dist/src/shared/envs/sandbox.js.map +0 -1
  129. package/dist/src/shared/envs/staging.js +0 -12
  130. package/dist/src/shared/envs/staging.js.map +0 -1
  131. package/dist/src/shared/event-manager.js +0 -14
  132. package/dist/src/shared/event-manager.js.map +0 -1
  133. package/dist/src/shared/post-message-client.js +0 -107
  134. package/dist/src/shared/post-message-client.js.map +0 -1
  135. package/dist/src/shared/post-message-client.test.js +0 -58
  136. package/dist/src/shared/post-message-client.test.js.map +0 -1
  137. package/dist/src/shared/types.js +0 -47
  138. package/dist/src/shared/types.js.map +0 -1
  139. package/dist/src/shared/types.test.js +0 -55
  140. package/dist/src/shared/types.test.js.map +0 -1
  141. package/dist/src/shared/util.js +0 -96
  142. package/dist/src/shared/util.js.map +0 -1
  143. package/dist/src/shared/util.test.js +0 -148
  144. package/dist/src/shared/util.test.js.map +0 -1
  145. package/dist/src/validation/index.js +0 -12
  146. package/dist/src/validation/index.js.map +0 -1
  147. package/dist/src/validation/schemas/click-to-pay/load-params.json +0 -34
  148. package/dist/src/validation/schemas/click-to-pay/options.json +0 -23
  149. package/dist/src/validation/schemas/click-to-pay/payment-intent.json +0 -42
  150. package/dist/src/validation/schemas/customer.json +0 -38
  151. package/dist/src/validation/schemas/hpp-load-params.json +0 -40
  152. package/dist/src/validation/schemas/hpp-options.json +0 -48
  153. package/dist/src/validation/schemas/payment-intent.json +0 -48
  154. package/dist/src/validation/schemas/payment-method.json +0 -83
  155. package/dist/src/validation/schemas/verify-card-options.json +0 -15
  156. package/dist/src/validation/schemas/verify-card-params.json +0 -24
  157. package/dist/src/validation/validation-helper.js +0 -10
  158. package/dist/src/validation/validation-helper.js.map +0 -1
  159. package/dist/src/validation/validation-helper.test.js +0 -34
  160. package/dist/src/validation/validation-helper.test.js.map +0 -1
  161. package/dist/src/validation/validators/click-to-pay-load-params-validator.js +0 -19
  162. package/dist/src/validation/validators/click-to-pay-load-params-validator.js.map +0 -1
  163. package/dist/src/validation/validators/hpp-load-params-validator.js +0 -21
  164. package/dist/src/validation/validators/hpp-load-params-validator.js.map +0 -1
  165. package/dist/src/validation/validators/hpp-load-params-validator.test.js +0 -56
  166. package/dist/src/validation/validators/hpp-load-params-validator.test.js.map +0 -1
  167. package/dist/src/validation/validators/verify-card-params-validator.js +0 -23
  168. package/dist/src/validation/validators/verify-card-params-validator.js.map +0 -1
  169. package/dist/tests/helpers/api-gateway-mock.js +0 -37
  170. package/dist/tests/helpers/api-gateway-mock.js.map +0 -1
  171. /package/dist/react/{url.d.ts → paymentUrl.d.ts} +0 -0
  172. /package/dist/react/{url.js → paymentUrl.js} +0 -0
package/dist/main.d.ts CHANGED
@@ -1,6 +1,5 @@
1
1
  import { Customer, PaymentIntent, PaymentMethod, PublicEvent } from './shared/types';
2
2
  import { HppLoadParams } from './hpp';
3
- import { PayPalConfig } from './paypal/types';
4
3
  import { ChallengeWindowSize } from './sca/types';
5
4
  import { HppClickToPayParams } from './click_to_pay/types';
6
5
  export interface FZConfig {
@@ -34,7 +33,8 @@ export default class FatZebra {
34
33
  renderPaymentsPage(params: HppLoadParams): void;
35
34
  renderClickToPay(params: HppClickToPayParams): void;
36
35
  checkout(): void;
37
- setupPayPal(config: PayPalConfig): void;
38
36
  on(event: PublicEvent, callback: (e: any) => void): void;
37
+ off(event: PublicEvent, callback: (e: any) => void): void;
38
+ onOnce(event: PublicEvent, callback: (e: any) => void): void;
39
39
  }
40
40
  export { type HppLoadParams, FatZebra, };
package/dist/main.js CHANGED
@@ -11,19 +11,17 @@ import Sca from './sca';
11
11
  import { PostMessageClient, } from './shared/post-message-client';
12
12
  import { BridgeEvent, PaymentMethodType, PublicEvent, } from './shared/types';
13
13
  import { LocalStorageAccessTokenKey } from './shared/constants';
14
- import { emit, on } from './shared/event-manager';
14
+ import { emit, on, off, onOnce } from './shared/event-manager';
15
15
  import * as bridge from './shared/bridge-client';
16
16
  import { validateHppLoadParams, validateVerifyCardParams, toHumanizedErrors, validateClickToPayLoadParams, } from './validation';
17
17
  import GatewayClient from './shared/api-gateway-client';
18
18
  import { Hpp } from './hpp';
19
- import { PayPalCheckout } from './paypal/paypal-checkout';
20
19
  import ClickToPay from './click_to_pay';
21
20
  export default class FatZebra {
22
21
  constructor(config) {
23
22
  this.fzConfig = config;
24
23
  window.MerchantUsername = config.username;
25
24
  this.gatewayClient = new GatewayClient({
26
- accessToken: window.localStorage.getItem(LocalStorageAccessTokenKey),
27
25
  username: config.username,
28
26
  environment: process.env.API_ENV,
29
27
  });
@@ -141,26 +139,14 @@ export default class FatZebra {
141
139
  checkout() {
142
140
  window.HPP.purchase();
143
141
  }
144
- setupPayPal(config) {
145
- const paypalCheckout = new PayPalCheckout({
146
- currency: config.currency,
147
- payment: config.payment,
148
- containerId: config.containerId,
149
- style: config.style
150
- });
151
- paypalCheckout.load()
152
- .then(function () {
153
- paypalCheckout.render();
154
- })
155
- .catch(function (error) {
156
- emit(PublicEvent.PAYPAL_ERROR, {
157
- errors: [error].flat(),
158
- data: null
159
- });
160
- });
161
- }
162
142
  on(event, callback) {
163
143
  on(event, callback);
164
144
  }
145
+ off(event, callback) {
146
+ off(event, callback);
147
+ }
148
+ onOnce(event, callback) {
149
+ onOnce(event, callback);
150
+ }
165
151
  }
166
152
  export { FatZebra, };
@@ -5,5 +5,5 @@ type FrameProps = {
5
5
  config: FatZebra.PaymentConfig;
6
6
  iframeProps?: HTMLProps<HTMLIFrameElement>;
7
7
  };
8
- declare const Frame: ({ handlers, config, iframeProps }: FrameProps) => React.JSX.Element;
9
- export default Frame;
8
+ declare const VerifyCard: ({ handlers, config, iframeProps }: FrameProps) => React.JSX.Element;
9
+ export default VerifyCard;
@@ -1,11 +1,11 @@
1
1
  import React from "react";
2
2
  import useFatZebra from "./useFatZebra";
3
- const Frame = ({ handlers, config, iframeProps }) => {
4
- const { url } = useFatZebra({
3
+ const VerifyCard = ({ handlers, config, iframeProps }) => {
4
+ const { paymentUrl } = useFatZebra({
5
5
  config,
6
6
  handlers: handlers,
7
7
  });
8
8
  return (React.createElement("div", null,
9
- React.createElement("iframe", Object.assign({ src: url, title: "verification-form" }, iframeProps))));
9
+ React.createElement("iframe", Object.assign({ src: paymentUrl, "data-test-id": "verify-card", title: "verification-form" }, iframeProps))));
10
10
  };
11
- export default Frame;
11
+ export default VerifyCard;
@@ -0,0 +1,10 @@
1
+ import React, { HTMLProps } from "react";
2
+ import * as FatZebra from "../shared/types";
3
+ type FrameProps = {
4
+ handlers: FatZebra.Handlers;
5
+ config: FatZebra.PaymentConfig;
6
+ iframeProps?: HTMLProps<HTMLIFrameElement>;
7
+ cardToken: string;
8
+ };
9
+ declare const VerifyExistingCard: ({ handlers, cardToken, config, iframeProps }: FrameProps) => React.JSX.Element;
10
+ export default VerifyExistingCard;
@@ -0,0 +1,12 @@
1
+ import React from "react";
2
+ import useFatZebra from "./useFatZebra";
3
+ const VerifyExistingCard = ({ handlers, cardToken, config, iframeProps }) => {
4
+ const { verifyUrl } = useFatZebra({
5
+ config,
6
+ cardToken,
7
+ handlers: handlers,
8
+ });
9
+ return (React.createElement("div", null,
10
+ React.createElement("iframe", Object.assign({ src: verifyUrl, "data-test-id": "verify-existing-card", title: "verification-form" }, iframeProps))));
11
+ };
12
+ export default VerifyExistingCard;
@@ -1,3 +1,4 @@
1
1
  import VerifyCard from "./VerifyCard";
2
+ import VerifyExistingCard from "./VerifyExistingCard";
2
3
  import submitForm from "./submitForm";
3
- export { VerifyCard, submitForm };
4
+ export { VerifyCard, VerifyExistingCard, submitForm };
@@ -1,3 +1,4 @@
1
1
  import VerifyCard from "./VerifyCard";
2
+ import VerifyExistingCard from "./VerifyExistingCard";
2
3
  import submitForm from "./submitForm";
3
- export { VerifyCard, submitForm };
4
+ export { VerifyCard, VerifyExistingCard, submitForm };
@@ -2,8 +2,10 @@ import * as FatZebra from "../shared/types";
2
2
  type UseFatZebraProps = {
3
3
  handlers: FatZebra.Handlers;
4
4
  config: FatZebra.PaymentConfig;
5
+ cardToken?: string;
5
6
  };
6
- declare const useFatZebra: ({ config, handlers }: UseFatZebraProps) => {
7
- url: string;
7
+ declare const useFatZebra: ({ config, handlers, cardToken }: UseFatZebraProps) => {
8
+ paymentUrl: string;
9
+ verifyUrl: string;
8
10
  };
9
11
  export default useFatZebra;
@@ -1,9 +1,10 @@
1
1
  import { useEffect, useMemo } from "react";
2
2
  import * as FatZebra from "../shared/types";
3
- import { generatePaymentURL } from "./url";
3
+ import { generatePaymentURL } from "./paymentUrl";
4
4
  import Sca from "../sca";
5
5
  import GatewayClient from "../shared/api-gateway-client";
6
- const useFatZebra = ({ config, handlers }) => {
6
+ import { generateVerifyURL } from "./verifyUrl";
7
+ const useFatZebra = ({ config, handlers, cardToken }) => {
7
8
  const { options, accessToken, paymentIntent, username } = config;
8
9
  const sca = useMemo(() => {
9
10
  const gatewayClient = new GatewayClient({ accessToken, username, environment: config.environment });
@@ -31,9 +32,7 @@ const useFatZebra = ({ config, handlers }) => {
31
32
  else {
32
33
  emit(FatZebra.PublicEvent.TOKENIZATION_SUCCESS, {
33
34
  message: "Card tokenization success.",
34
- data: {
35
- token: data.token,
36
- },
35
+ data
37
36
  });
38
37
  }
39
38
  if (options.sca_enabled) {
@@ -72,7 +71,8 @@ const useFatZebra = ({ config, handlers }) => {
72
71
  };
73
72
  }, []);
74
73
  const payment = paymentIntent.payment;
75
- const url = generatePaymentURL(Object.assign({ merchant: username, reference: payment.reference, amount: payment.amount, currency: payment.currency, hash: paymentIntent.verification }, options), config.environment);
76
- return { url };
74
+ const verifyUrl = generateVerifyURL(Object.assign({ token: cardToken, verification: paymentIntent.verification, merchant: username }, options), config.environment);
75
+ const paymentUrl = generatePaymentURL(Object.assign({ merchant: username, reference: payment.reference, amount: payment.amount, currency: payment.currency, hash: paymentIntent.verification }, options), config.environment);
76
+ return { paymentUrl, verifyUrl };
77
77
  };
78
78
  export default useFatZebra;
@@ -0,0 +1,8 @@
1
+ import { Environment } from "../shared/env";
2
+ type RequiredURLValues = {
3
+ token: string;
4
+ verification: string;
5
+ merchant: string;
6
+ };
7
+ declare const generateVerifyURL: (values: RequiredURLValues, environment?: Environment) => string;
8
+ export { generateVerifyURL };
@@ -0,0 +1,22 @@
1
+ import { parseTemplate } from 'url-template';
2
+ import env, { Environment } from "../shared/env";
3
+ const generateVerifyURL = (values, environment) => {
4
+ const queryParts = [
5
+ "hide_button",
6
+ "iframe",
7
+ "verification",
8
+ "username",
9
+ "cardToken"
10
+ ];
11
+ const environmentConfig = env[environment || Environment.sandbox];
12
+ const urlTemplate = parseTemplate(`${environmentConfig.payNowUrl}/sdk/v3/verify{?${queryParts.join(",")}}`);
13
+ const url = urlTemplate.expand({
14
+ cardToken: values.token,
15
+ verification: values.verification,
16
+ username: values.merchant,
17
+ iframe: true,
18
+ hide_button: true
19
+ });
20
+ return url;
21
+ };
22
+ export { generateVerifyURL };
@@ -1,10 +1,3 @@
1
- interface CardinalConfig {
2
- timeout?: number;
3
- maxRequestRetries?: number;
4
- logging?: {
5
- level: 'on' | 'off' | 'verbose';
6
- };
7
- }
8
1
  interface CardinalSetupCompleteResponseData {
9
2
  sessionId: string;
10
3
  modules: {
@@ -16,12 +9,20 @@ interface PaymentValidatedDTO {
16
9
  processorTransactionId: string;
17
10
  jwt: string;
18
11
  }
12
+ export declare const defaultConfig: {
13
+ timeout: number;
14
+ maxRequestRetries: number;
15
+ logging: {
16
+ level: string;
17
+ };
18
+ };
19
19
  export default class CardinalManager {
20
- private cardinal;
21
- constructor(config?: CardinalConfig);
20
+ private retries;
21
+ constructor(retries?: Array<number>);
22
+ configure(retryCount?: number, lastError?: string): Promise<any>;
22
23
  setup(jwt: any): void;
23
24
  onPaymentValidated(handler: (data: PaymentValidatedDTO, error: string) => void): void;
24
- onPaymentSetupComplete(): Promise<CardinalSetupCompleteResponseData>;
25
+ onPaymentSetupComplete(callback: (data: CardinalSetupCompleteResponseData) => void): void;
25
26
  processBin(bin: string): Promise<any>;
26
27
  continue(acsUrl: string, pareq: string, transactionId: string): void;
27
28
  }
@@ -17,7 +17,7 @@ var CardinalPaymentEvent;
17
17
  CardinalPaymentEvent["SETUP_COMPLETE"] = "payments.setupComplete";
18
18
  CardinalPaymentEvent["VALIDATED"] = "payments.validated";
19
19
  })(CardinalPaymentEvent || (CardinalPaymentEvent = {}));
20
- const defaultConfig = {
20
+ export const defaultConfig = {
21
21
  timeout: 8000,
22
22
  maxRequestRetries: 3,
23
23
  logging: {
@@ -25,14 +25,36 @@ const defaultConfig = {
25
25
  }
26
26
  };
27
27
  export default class CardinalManager {
28
- constructor(config) {
29
- window.Cardinal.configure((config ? config : defaultConfig));
28
+ constructor(retries) {
29
+ this.retries = retries || [10, 100, 1000, 5000, 10000];
30
+ }
31
+ // https://www.bayanbennett.com/posts/retrying-and-exponential-backoff-with-promises/
32
+ // Attempts 5 times to setup Cardinal.
33
+ // 10ms, 100ms, 1s, 5s, 10s.
34
+ // Cardinal may take a while to load, for example if the user is on a slow connection (train in a tunnel, for example)
35
+ configure(retryCount, lastError) {
36
+ return __awaiter(this, void 0, void 0, function* () {
37
+ retryCount || (retryCount = 1);
38
+ const delayMs = this.retries[retryCount - 1];
39
+ const delay = (delayMs) => new Promise(resolve => setTimeout(resolve, delayMs));
40
+ if (retryCount > 5)
41
+ throw new Error(lastError);
42
+ try {
43
+ console.log("Attempting to load Cardinal", { retryCount, delay: delayMs });
44
+ window.Cardinal.configure(defaultConfig);
45
+ }
46
+ catch (error) {
47
+ yield delay(delayMs);
48
+ yield this.configure(retryCount + 1, error);
49
+ }
50
+ });
30
51
  }
31
52
  setup(jwt) {
32
53
  window.Cardinal.setup(CardinalWorkflow.INIT, { jwt });
33
54
  }
34
55
  onPaymentValidated(handler) {
35
56
  window.Cardinal.on('payments.validated', (data, jwt) => {
57
+ window.Cardinal.off('payments.validated');
36
58
  if (data.ErrorDescription.toLowerCase() === 'success') {
37
59
  handler({
38
60
  processorTransactionId: data.Payment.ProcessorTransactionId,
@@ -44,11 +66,10 @@ export default class CardinalManager {
44
66
  }
45
67
  });
46
68
  }
47
- onPaymentSetupComplete() {
48
- return new Promise((resolve, reject) => {
49
- window.Cardinal.on(CardinalPaymentEvent.SETUP_COMPLETE, (data) => {
50
- resolve(data);
51
- });
69
+ onPaymentSetupComplete(callback) {
70
+ window.Cardinal.on(CardinalPaymentEvent.SETUP_COMPLETE, (data) => {
71
+ window.Cardinal.off(CardinalPaymentEvent.SETUP_COMPLETE);
72
+ callback(data);
52
73
  });
53
74
  }
54
75
  processBin(bin) {
@@ -36,6 +36,9 @@ declare class Sca {
36
36
  reportFailure(message: string, data?: any): void;
37
37
  reportSuccess(message: string, data: any): void;
38
38
  run(config: ScaRunProps): Promise<void>;
39
+ perform3DS({ sessionID }: {
40
+ sessionID: string;
41
+ }): Promise<void>;
39
42
  createCardinalJWT(): Promise<string>;
40
43
  check3DSEnrollment(): Promise<void>;
41
44
  customerProperties(customer: Customer): CustomerSnakeCase;
package/dist/sca/index.js CHANGED
@@ -64,6 +64,7 @@ class Sca {
64
64
  try {
65
65
  if (!this._cardinal) {
66
66
  this._cardinal = new CardinalManager();
67
+ yield this._cardinal.configure();
67
68
  }
68
69
  }
69
70
  catch (error) {
@@ -85,53 +86,57 @@ class Sca {
85
86
  this.reportFailure('FatZebra.3DS: JWT creation failed.');
86
87
  return;
87
88
  }
88
- // Init cardinal
89
- this._cardinal.setup(cardinalJwt);
90
- if (!this.sessionId) {
91
- const paymentsSetupCompleteResponse = yield this._cardinal.onPaymentSetupComplete();
89
+ this._cardinal.onPaymentSetupComplete((paymentsSetupCompleteResponse) => __awaiter(this, void 0, void 0, function* () {
92
90
  this.sessionId = paymentsSetupCompleteResponse.sessionId;
93
- // Register handler. Called after OTP is entered on challenge prompt.
94
- this._cardinal.onPaymentValidated((data, error) => __awaiter(this, void 0, void 0, function* () {
95
- var _a;
96
- if (typeof error == 'string') {
97
- this.reportFailure(`FatZebra.3DS: Validation failed. ${error}.`);
98
- return;
99
- }
100
- const decodeSCASessionResponse = (yield this.gatewayClient.decodeSCASession({
101
- token: data.jwt
102
- })).data;
103
- if (data.processorTransactionId !== decodeSCASessionResponse.processor_transaction_id) {
104
- this.reportFailure("FatZebra.3DS: Validation failed. Invalid process transaction id.");
105
- }
106
- let validateSCAResponse;
107
- try {
108
- const requestParams = {
109
- amount: this.paymentIntent.payment.amount,
110
- authentication_transaction_id: this.enrollmentResult.authentication_transaction_id,
111
- card_token: this.cardToken,
112
- currency: this.paymentIntent.payment.currency,
113
- pareq: this.enrollmentResult.pareq,
114
- reference: this.paymentIntent.payment.reference,
115
- };
116
- validateSCAResponse = (yield this.gatewayClient.validateSCA(requestParams)).data;
117
- }
118
- catch (errorResponse) {
119
- this.reportFailure('FatZebra.3DS: Validation failed. Server error.');
120
- return;
121
- }
122
- const threedsData = threedsResponseData(validateSCAResponse);
123
- const scenario = getValidationResult(validateSCAResponse);
124
- if (scenario.outcome.success) {
125
- this.reportSuccess(`FatZebra.3DS: 3DS success - ${scenario.description}.`, threedsData);
126
- }
127
- else {
128
- const failureMessage = [scenario.description, (_a = scenario.outcome) === null || _a === void 0 ? void 0 : _a.errorCode].filter(Boolean).join(' - ');
129
- this.reportFailure(`FatZebra.3DS: 3DS error - ${failureMessage}`, {
130
- errorCode: scenario.outcome.errorCode,
131
- });
132
- }
133
- }));
134
- }
91
+ this.perform3DS({ sessionID: paymentsSetupCompleteResponse.sessionId });
92
+ }));
93
+ this._cardinal.setup(cardinalJwt);
94
+ });
95
+ }
96
+ perform3DS({ sessionID }) {
97
+ return __awaiter(this, void 0, void 0, function* () {
98
+ this.sessionId = sessionID;
99
+ // Register handler. Called after OTP is entered on challenge prompt.
100
+ this._cardinal.onPaymentValidated((data, error) => __awaiter(this, void 0, void 0, function* () {
101
+ var _a;
102
+ if (typeof error == 'string') {
103
+ this.reportFailure(`FatZebra.3DS: Validation failed. ${error}.`);
104
+ return;
105
+ }
106
+ const decodeSCASessionResponse = (yield this.gatewayClient.decodeSCASession({
107
+ token: data.jwt
108
+ })).data;
109
+ if (data.processorTransactionId !== decodeSCASessionResponse.processor_transaction_id) {
110
+ this.reportFailure("FatZebra.3DS: Validation failed. Invalid process transaction id.");
111
+ }
112
+ let validateSCAResponse;
113
+ try {
114
+ const requestParams = {
115
+ amount: this.paymentIntent.payment.amount,
116
+ authentication_transaction_id: this.enrollmentResult.authentication_transaction_id,
117
+ card_token: this.cardToken,
118
+ currency: this.paymentIntent.payment.currency,
119
+ pareq: this.enrollmentResult.pareq,
120
+ reference: this.paymentIntent.payment.reference,
121
+ };
122
+ validateSCAResponse = (yield this.gatewayClient.validateSCA(requestParams)).data;
123
+ }
124
+ catch (errorResponse) {
125
+ this.reportFailure('FatZebra.3DS: Validation failed. Server error.');
126
+ return;
127
+ }
128
+ const threedsData = threedsResponseData(validateSCAResponse);
129
+ const scenario = getValidationResult(validateSCAResponse);
130
+ if (scenario.outcome.success) {
131
+ this.reportSuccess(`FatZebra.3DS: 3DS success - ${scenario.description}.`, threedsData);
132
+ }
133
+ else {
134
+ const failureMessage = [scenario.description, (_a = scenario.outcome) === null || _a === void 0 ? void 0 : _a.errorCode].filter(Boolean).join(' - ');
135
+ this.reportFailure(`FatZebra.3DS: 3DS error - ${failureMessage}`, {
136
+ errorCode: scenario.outcome.errorCode,
137
+ });
138
+ }
139
+ }));
135
140
  // Cardinal processs BIN using directory server. This determines the 3DS version used.
136
141
  try {
137
142
  yield this._cardinal.processBin(this.bin);
@@ -225,8 +230,8 @@ const threedsResponseData = (response) => {
225
230
  sli: toFzSli(response.eci),
226
231
  xid: response.xid,
227
232
  ver: response.enrolled,
228
- directory_server_txn_id: response.directory_server_txn_id,
229
- threeds_version: response.version,
233
+ directoryServerTxnId: response.directory_server_txn_id,
234
+ threedsVersion: response.version,
230
235
  };
231
236
  };
232
237
  const getEnrollmentResult = (enrollment) => {
@@ -28,8 +28,8 @@ interface ThreedsData {
28
28
  sli: string;
29
29
  xid: string;
30
30
  ver: string;
31
- directory_server_txn_id: string;
32
- threeds_version: string;
31
+ directoryServerTxnId: string;
32
+ threedsVersion: string;
33
33
  }
34
34
  interface EnrollSCARequest {
35
35
  amount: number;
@@ -1,27 +1,21 @@
1
1
  import { AxiosResponse, AxiosInstance } from "axios";
2
2
  import { Environment } from "../shared/env";
3
3
  import * as sca from "../sca/types";
4
- import * as paypal from "../paypal/types";
5
4
  export type GatewayClientProps = {
6
- accessToken: string;
7
5
  username: string;
8
6
  environment?: Environment;
7
+ accessToken?: string;
9
8
  };
10
9
  declare class GatewayClient {
11
- client: AxiosInstance | null;
10
+ username: string;
12
11
  environment?: Environment;
13
- constructor({ accessToken, username, environment }: GatewayClientProps);
12
+ client: AxiosInstance;
13
+ constructor({ username, environment, accessToken }: GatewayClientProps);
14
14
  /**************** SCA/3DS2 /****************/
15
15
  createSCASession(data: sca.CreateSCASessionRequest): Promise<AxiosResponse>;
16
16
  decodeSCASession(data: sca.DecodeSCASessionRequest): Promise<AxiosResponse>;
17
17
  enrolSCA(data: sca.EnrollSCARequest): Promise<AxiosResponse>;
18
18
  validateSCA(data: sca.ValidateSCARequest): Promise<AxiosResponse>;
19
19
  getCard(data: sca.GetCardRequest): Promise<AxiosResponse>;
20
- /**************** PayPal /****************/
21
- createPayPalOrder(data: paypal.CreatePayPalOrderRequest): Promise<AxiosResponse>;
22
- capturePayPalOrder(data: paypal.CapturePayPalOrderRequest): Promise<AxiosResponse>;
23
- authorizePayPalOrder(data: paypal.AuthorizePayPalOrderRequest): Promise<AxiosResponse>;
24
- createPayPalBillingAgreement(data: paypal.CreatePayPalBillingAgreementRequest): Promise<AxiosResponse>;
25
- approvePayPalBillingAgreement(data: paypal.ApprovePayPalBillingAgreementRequest): Promise<AxiosResponse>;
26
20
  }
27
21
  export default GatewayClient;
@@ -7,18 +7,19 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
7
7
  step((generator = generator.apply(thisArg, _arguments || [])).next());
8
8
  });
9
9
  };
10
- import { RequestHeaderSdkVersion, RequestHeaderMerchantUsername, RequestTimeout, LongRequestTimeout, } from "./constants";
10
+ import { RequestHeaderSdkVersion, RequestHeaderMerchantUsername, RequestTimeout, LocalStorageAccessTokenKey, } from "./constants";
11
11
  import axios from "axios";
12
12
  import { getSdkVersionNumber } from "./util";
13
13
  import env, { Environment } from "../shared/env";
14
14
  class GatewayClient {
15
- constructor({ accessToken, username, environment }) {
15
+ constructor({ username, environment, accessToken }) {
16
+ this.username = username;
16
17
  this.environment = environment || Environment.sandbox;
17
18
  const headers = {};
18
19
  headers["Authorization"] = `Bearer ${accessToken}`;
19
20
  headers[RequestHeaderSdkVersion] = getSdkVersionNumber();
20
- headers[RequestHeaderMerchantUsername] = username;
21
- this.client = axios.create({
21
+ headers[RequestHeaderMerchantUsername] = this.username;
22
+ const client = axios.create({
22
23
  baseURL: env[this.environment].apiUrl,
23
24
  timeout: RequestTimeout,
24
25
  headers,
@@ -30,6 +31,13 @@ class GatewayClient {
30
31
  },
31
32
  ],
32
33
  });
34
+ client.interceptors.request.use(function (config) {
35
+ const localStorageAccessToken = window.localStorage.getItem(LocalStorageAccessTokenKey);
36
+ config.headers["Authorization"] = `Bearer ${accessToken || localStorageAccessToken}`;
37
+ // Do something before request is sent
38
+ return config;
39
+ });
40
+ this.client = client;
33
41
  }
34
42
  /**************** SCA/3DS2 /****************/
35
43
  createSCASession(data) {
@@ -68,39 +76,5 @@ class GatewayClient {
68
76
  return this.client.get(`/credit_cards/${data.card_token}`);
69
77
  });
70
78
  }
71
- /**************** PayPal /****************/
72
- createPayPalOrder(data) {
73
- return __awaiter(this, void 0, void 0, function* () {
74
- return this.client.post("/paypal/orders", data, {
75
- timeout: LongRequestTimeout,
76
- });
77
- });
78
- }
79
- capturePayPalOrder(data) {
80
- return __awaiter(this, void 0, void 0, function* () {
81
- return this.client.post(`/paypal/orders/${data.id}/capture`, null, {
82
- timeout: LongRequestTimeout,
83
- });
84
- });
85
- }
86
- authorizePayPalOrder(data) {
87
- return __awaiter(this, void 0, void 0, function* () {
88
- return this.client.post(`/paypal/orders/${data.id}/authorize`, null, {
89
- timeout: LongRequestTimeout,
90
- });
91
- });
92
- }
93
- createPayPalBillingAgreement(data) {
94
- return __awaiter(this, void 0, void 0, function* () {
95
- return this.client.post("/paypal/billing_agreements", data, {
96
- timeout: LongRequestTimeout,
97
- });
98
- });
99
- }
100
- approvePayPalBillingAgreement(data) {
101
- return __awaiter(this, void 0, void 0, function* () {
102
- return this.client.post(`/paypal/billing_agreements/${data.id}/approve`, null, { timeout: LongRequestTimeout });
103
- });
104
- }
105
79
  }
106
80
  export default GatewayClient;
@@ -4,12 +4,16 @@ import * as sandbox from "./envs/sandbox";
4
4
  import * as production from "./envs/production";
5
5
  export declare enum Environment {
6
6
  local = "local",
7
+ test = "test",
8
+ development = "development",
7
9
  staging = "staging",
8
10
  sandbox = "sandbox",
9
11
  production = "production"
10
12
  }
11
13
  declare const env: {
14
+ test: typeof local;
12
15
  local: typeof local;
16
+ development: typeof local;
13
17
  staging: typeof staging;
14
18
  sandbox: typeof sandbox;
15
19
  production: typeof production;
@@ -5,12 +5,16 @@ import * as production from "./envs/production";
5
5
  export var Environment;
6
6
  (function (Environment) {
7
7
  Environment["local"] = "local";
8
+ Environment["test"] = "test";
9
+ Environment["development"] = "development";
8
10
  Environment["staging"] = "staging";
9
11
  Environment["sandbox"] = "sandbox";
10
12
  Environment["production"] = "production";
11
13
  })(Environment || (Environment = {}));
12
14
  const env = {
15
+ [Environment.test]: local,
13
16
  [Environment.local]: local,
17
+ [Environment.development]: local,
14
18
  [Environment.staging]: staging,
15
19
  [Environment.sandbox]: sandbox,
16
20
  [Environment.production]: production,
@@ -24,6 +24,8 @@ interface ErrorEventDetail {
24
24
  data: any;
25
25
  }
26
26
  declare const emit: (event: PublicEvent, data: SuccessEventDetail | ErrorEventDetail, target?: HTMLElement | Window) => void;
27
+ declare const off: (event: PublicEvent, callback: (e: any) => void, target?: HTMLElement | Window) => void;
28
+ declare const onOnce: (event: PublicEvent, callback: (e: any) => void, target?: HTMLElement | Window) => void;
27
29
  declare const on: (event: PublicEvent, callback: (e: any) => void, target?: HTMLElement | Window) => void;
28
- export { emit, on };
30
+ export { emit, on, onOnce, off };
29
31
  export type { EventData, SuccessEventDetail, ErrorEventDetail };
@@ -1,7 +1,13 @@
1
1
  const emit = (event, data, target = window) => {
2
2
  target.dispatchEvent(new CustomEvent(event, { detail: data }));
3
3
  };
4
+ const off = (event, callback, target = window) => {
5
+ target.removeEventListener(event, callback);
6
+ };
7
+ const onOnce = (event, callback, target = window) => {
8
+ target.addEventListener(event, callback, { once: true });
9
+ };
4
10
  const on = (event, callback, target = window) => {
5
11
  target.addEventListener(event, callback);
6
12
  };
7
- export { emit, on };
13
+ export { emit, on, onOnce, off };
@@ -39,6 +39,7 @@ declare class PostMessageClient {
39
39
  private channel;
40
40
  private fzEnv;
41
41
  private target;
42
+ private domain;
42
43
  constructor(config: PostMessageClientConfig);
43
44
  setEventListeners(handlers: EventHandlers): void;
44
45
  setEventListenersLegacy(handlers: EventHandlers): void;