@fat-zebra/sdk 1.5.12 → 1.5.14-beta.5

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 (38) hide show
  1. package/.jest/setup-logmethod-mock.js +8 -0
  2. package/README.dev.md +8 -13
  3. package/dist/hpp/hpp.d.ts +1 -1
  4. package/dist/hpp/hpp.js +7 -7
  5. package/dist/logging/instrument.d.ts +7 -0
  6. package/dist/logging/instrument.js +40 -0
  7. package/dist/logging/logMethod.d.ts +7 -0
  8. package/dist/logging/logMethod.js +46 -0
  9. package/dist/main.js +26 -4
  10. package/dist/new_sca/index.js +2 -2
  11. package/dist/react/useFatZebra.js +11 -1
  12. package/dist/sca/index.js +2 -2
  13. package/dist/sca/scenarios/enrollment.js +2 -2
  14. package/dist/sca/scenarios/validation.js +3 -3
  15. package/dist/shared/envs/local.d.ts +4 -2
  16. package/dist/shared/envs/local.js +4 -2
  17. package/dist/shared/envs/production.d.ts +3 -1
  18. package/dist/shared/envs/production.js +3 -1
  19. package/dist/shared/envs/sandbox.d.ts +3 -1
  20. package/dist/shared/envs/sandbox.js +3 -1
  21. package/dist/shared/envs/staging.d.ts +3 -1
  22. package/dist/shared/envs/staging.js +3 -1
  23. package/dist/shared/new_gateway/new-api-gateway-client.js +2 -2
  24. package/dist/shared/types.d.ts +2 -2
  25. package/dist/shared/types.js +1 -1
  26. package/package.json +11 -14
  27. package/.github/dependabot.yml +0 -13
  28. package/.github/workflows/ci.yml +0 -223
  29. package/.github/workflows/non-prod-ci.yml +0 -124
  30. package/.husky/commit-msg +0 -1
  31. package/.husky/prepare-commit-msg +0 -1
  32. package/CODEOWNERS +0 -1
  33. package/commitizen.png +0 -0
  34. package/commitlint.config.cjs +0 -3
  35. package/dist/decorators.d.ts +0 -1
  36. package/dist/decorators.js +0 -35
  37. /package/dist/{logger-context.d.ts → logging/logger-context.d.ts} +0 -0
  38. /package/dist/{logger-context.js → logging/logger-context.js} +0 -0
@@ -0,0 +1,8 @@
1
+ jest.mock("../src/logging/logMethod", () => {
2
+ const logMethod = () => {
3
+ // returns a decorator that leaves the method untouched
4
+ return (_target, _propertyKey, descriptor) => descriptor;
5
+ };
6
+
7
+ return { __esModule: true, logMethod };
8
+ });
package/README.dev.md CHANGED
@@ -103,13 +103,15 @@ Releases are based on tags. There are two types of releases:
103
103
  - Production
104
104
  - Beta
105
105
 
106
- To perform a production release:
106
+ To perform a production release:
107
107
 
108
108
  ```shell
109
109
  git tag -a v1.5.10 -m "Production Release: 1.5.10"
110
110
  git push origin v1.5.10
111
111
  ```
112
112
 
113
+ **NOTE:** Production releases will only work when on the `main` branch
114
+
113
115
  To perform a beta release
114
116
 
115
117
  ```shell
@@ -117,7 +119,7 @@ git tag -a v1.5.10-beta.0 -m "Beta: 1.5.10-beta.0"
117
119
  git push origin v1.5.10-beta.0
118
120
  ```
119
121
 
120
- ### CDN
122
+ ### CDN
121
123
 
122
124
  ## Staging
123
125
 
@@ -125,7 +127,7 @@ Staging is released automatically for each branch (on push)
125
127
 
126
128
  ## Sandbox
127
129
 
128
- Sandbox deployment will trigger on the main branch and when pushing through a tag with beta in it.
130
+ Sandbox deployment will trigger when pushing through a tag with beta in it.
129
131
 
130
132
  Running this on main will trigger sandbox deployment (as well as npm beta release):
131
133
 
@@ -137,9 +139,10 @@ git push origin v1.5.10-beta.0
137
139
  Additionally, the pipeline will trigger a cypress integration spec on sandbox which will run here: https://github.com/fatzebra/gazelle/actions
138
140
  Ensure this pipeline is green before deploying to production and then post a link of the outcome
139
141
 
140
- ## Production
142
+ ## Production
143
+
144
+ Production deployment will _ONLY_ trigger on the main branch and when pushing through a tag WITHOUT beta in it.
141
145
 
142
- Sandbox deployment will trigger on the main branch and when pushing through a tag WITHOUT beta in it.
143
146
  Running this on main will trigger production deployment:
144
147
 
145
148
  ```shell
@@ -151,12 +154,4 @@ git push origin v1.5.10
151
154
 
152
155
  The pipeline will upload a version to override the existing deployment, but also a version of the build to a folder in s3.
153
156
 
154
- ## Commitizen
155
-
156
- We use Husky and Commitizen to keep our commit history consistent, readable, and meaningful. Husky runs Git hooks automatically. This will in turn run commitizen. Commitizen enforces a standard commit message format based on Conventional Commits
157
- . This ensures every commit clearly communicates its purpose, making it easier to track changes, generate changelogs, and automate releases.
158
-
159
- Follow the commitizen wizard to correctly format the commit message.
160
-
161
- ![commitizen wizard](readme.png)
162
157
 
package/dist/hpp/hpp.d.ts CHANGED
@@ -50,7 +50,7 @@ declare class Hpp {
50
50
  private headlessLoaded;
51
51
  private headlessPreviouslyLoaded;
52
52
  private iframeLoaded;
53
- private newThreedsFlow;
53
+ private threeDSecureEnabled;
54
54
  constructor(config: HppModuleConfig);
55
55
  setListenersAndEmitReady(): void;
56
56
  load(config: HppLoadParams): void;
package/dist/hpp/hpp.js CHANGED
@@ -10,8 +10,8 @@ import { emit, on } from '../shared/event-manager';
10
10
  import { PostMessageClient } from '../shared/post-message-client';
11
11
  import { BridgeEvent, PublicEvent, } from '../shared/types';
12
12
  import * as util from '../shared/util';
13
- import { logMethod } from "../decorators";
14
- import { setTransactionReference } from "../logger-context";
13
+ import { logMethod } from "../logging/logMethod";
14
+ import { setTransactionReference } from "../logging/logger-context";
15
15
  import newSca from "../new_sca";
16
16
  const HPP_DEFAULT_OPTIONS = {
17
17
  enableSca: false,
@@ -20,7 +20,7 @@ const HPP_DEFAULT_OPTIONS = {
20
20
  };
21
21
  class Hpp {
22
22
  constructor(config) {
23
- this.newThreedsFlow = false;
23
+ this.threeDSecureEnabled = false;
24
24
  this.paymentIntent = config.paymentIntent;
25
25
  this.customer = config.customer;
26
26
  this.username = config.username;
@@ -131,7 +131,7 @@ class Hpp {
131
131
  if (this.hppOptions.tokenizeOnly)
132
132
  return;
133
133
  if (this.hppOptions.enableSca) {
134
- if (this.newThreedsFlow) {
134
+ if (this.threeDSecureEnabled) {
135
135
  this.newSca.setup({ card_token: data.token, paymentIntent: this.paymentIntent }).then((data) => {
136
136
  console.log("result:", data);
137
137
  // continue with 3DS flow
@@ -197,8 +197,8 @@ class Hpp {
197
197
  data: data,
198
198
  });
199
199
  };
200
- handlers[BridgeEvent.NEW_THREEDS_ENABLED] = (data) => {
201
- this.newThreedsFlow = typeof data === "boolean" ? data : false;
200
+ handlers[BridgeEvent.THREE_D_SECURE_ENABLED] = (data) => {
201
+ this.threeDSecureEnabled = typeof data === "boolean" ? data : false;
202
202
  };
203
203
  this.postMessageClient.setEventListeners(handlers);
204
204
  }
@@ -234,6 +234,6 @@ class Hpp {
234
234
  }
235
235
  }
236
236
  __decorate([
237
- logMethod
237
+ logMethod()
238
238
  ], Hpp.prototype, "createPurchase", null);
239
239
  export { Hpp, HPP_DEFAULT_OPTIONS, };
@@ -0,0 +1,7 @@
1
+ type LogOptions = {
2
+ endpoint?: string;
3
+ mapArgs?: (args: unknown[]) => unknown;
4
+ enabled?: () => boolean;
5
+ };
6
+ export declare function instrumentFunction<A extends any[], R>(methodName: string, fn: (...args: A) => R, opts?: LogOptions): (...args: A) => R;
7
+ export {};
@@ -0,0 +1,40 @@
1
+ import axios from "axios";
2
+ import { getLoggerUsername, getTransactionReference } from "./logger-context";
3
+ function defaultEndpoint() {
4
+ return `${process.env.PAYNOW_BASE_URL}/log_sdk`;
5
+ }
6
+ function sendLog(endpoint, payload) {
7
+ try {
8
+ if (typeof navigator !== "undefined" && navigator.sendBeacon) {
9
+ const ok = navigator.sendBeacon(endpoint, JSON.stringify(payload));
10
+ if (!ok)
11
+ void axios.post(endpoint, payload);
12
+ }
13
+ else {
14
+ // fallback for non-browser or older environments
15
+ void axios.post(endpoint, payload);
16
+ }
17
+ }
18
+ catch (error) {
19
+ console.warn("SDK logging failed:", error);
20
+ }
21
+ }
22
+ export function instrumentFunction(methodName, fn, opts = {}) {
23
+ var _a, _b, _c;
24
+ const endpoint = (_a = opts.endpoint) !== null && _a !== void 0 ? _a : defaultEndpoint();
25
+ const enabled = (_b = opts.enabled) !== null && _b !== void 0 ? _b : (() => true);
26
+ const mapArgs = (_c = opts.mapArgs) !== null && _c !== void 0 ? _c : ((a) => a);
27
+ return function instrumented(...args) {
28
+ if (enabled()) {
29
+ const payload = {
30
+ username: getLoggerUsername(),
31
+ reference: getTransactionReference(),
32
+ method: methodName,
33
+ arguments: mapArgs(args),
34
+ timestamp: new Date().toISOString(),
35
+ };
36
+ sendLog(endpoint, payload);
37
+ }
38
+ return fn.apply(this, args);
39
+ };
40
+ }
@@ -0,0 +1,7 @@
1
+ type LogOptions = {
2
+ endpoint?: string;
3
+ mapArgs?: (args: unknown[]) => unknown;
4
+ enabled?: () => boolean;
5
+ };
6
+ export declare function logMethod(opts?: LogOptions): (target: any, propertyKey: string, descriptor: PropertyDescriptor) => PropertyDescriptor;
7
+ export {};
@@ -0,0 +1,46 @@
1
+ // src/logging/logMethod.ts
2
+ import { instrumentFunction } from "./instrument";
3
+ // This function can be used to decorate class methods to gain observability into:
4
+ // - when they were called,
5
+ // - which arguments they were called with,
6
+ // - and (optionally) where to send that telemetry.
7
+ //
8
+ // Usage:
9
+ // // Capture all args (with the default `mapArgs` behaviour applied) - i.e. all arguments will be passed through.
10
+ // @logMethod()
11
+ //
12
+ // // Provide a custom endpoint
13
+ // @logMethod({ endpoint: "/telemetry/sdk/methods" })
14
+ //
15
+ // // Enable/disable dynamically (useful for env / feature flags)
16
+ // @logMethod({ enabled: () => process.env.NODE_ENV !== "test" })
17
+ //
18
+ // @logMethod({
19
+ // mapArgs: (args) => {
20
+ // const [opts, ...rest] = args;
21
+ // return [
22
+ // opts && typeof opts === "object" ? { ...(opts as any), card_holder: "John Smith" } : opts,
23
+ // ...rest,
24
+ // ];
25
+ // },
26
+ // })
27
+ //
28
+ // Notes:
29
+ // - The default `mapArgs` will shallow-clone any object arguments and add `{ js_sdk: true }`.
30
+ // - Only methods can be decorated; decorating non-functions will log an error.
31
+ // Decorator factory
32
+ export function logMethod(opts = {}) {
33
+ return function (target, propertyKey, descriptor) {
34
+ var _a;
35
+ const original = descriptor.value;
36
+ if (typeof original !== "function") {
37
+ console.error(`@logMethod can only decorate methods (${propertyKey})`);
38
+ }
39
+ descriptor.value = instrumentFunction(propertyKey, original, Object.assign(Object.assign({}, opts), { mapArgs: (_a = opts.mapArgs) !== null && _a !== void 0 ? _a : ((args) => args.map((a) => {
40
+ if (!a || typeof a !== "object")
41
+ return a;
42
+ return Object.assign(Object.assign({}, a), { js_sdk: true });
43
+ })) }));
44
+ return descriptor;
45
+ };
46
+ }
package/dist/main.js CHANGED
@@ -1,3 +1,9 @@
1
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
2
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
3
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
4
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
5
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
6
+ };
1
7
  var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
2
8
  function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
3
9
  return new (P || (P = Promise))(function (resolve, reject) {
@@ -19,7 +25,8 @@ import { Hpp } from './hpp';
19
25
  import ClickToPay from './click_to_pay';
20
26
  import { validateApplePayLoadParams } from "./validation/validators/apple-pay-load-params-button-validator";
21
27
  import { ApplePay } from "./applepay";
22
- import { setLoggerUsername } from "./logger-context";
28
+ import { setLoggerUsername } from "./logging/logger-context";
29
+ import { logMethod } from "./logging/logMethod";
23
30
  export default class FatZebra {
24
31
  constructor(config) {
25
32
  setLoggerUsername(config.username);
@@ -64,8 +71,8 @@ export default class FatZebra {
64
71
  postMessageClient.setEventListeners(handlers);
65
72
  }
66
73
  verifyCard(params) {
67
- var _a;
68
74
  return __awaiter(this, void 0, void 0, function* () {
75
+ var _a;
69
76
  const valid = validateVerifyCardParams(params);
70
77
  if (!valid) {
71
78
  emit(PublicEvent.VALIDATION_ERROR, {
@@ -79,14 +86,14 @@ export default class FatZebra {
79
86
  const headless = bridge.load(process.env.PAYNOW_BRIDGE_URL);
80
87
  const card = params.paymentMethod.data;
81
88
  this.cardDidTokenize(headless, (data) => __awaiter(this, void 0, void 0, function* () {
82
- var _b;
89
+ var _a;
83
90
  const bin = card.number.substr(0, 6);
84
91
  this.sca.run({
85
92
  cardToken: data.token,
86
93
  customer: params.customer,
87
94
  paymentIntent: params.paymentIntent,
88
95
  bin,
89
- challengeWindowSize: (_b = params.options) === null || _b === void 0 ? void 0 : _b.challengeWindowSize,
96
+ challengeWindowSize: (_a = params.options) === null || _a === void 0 ? void 0 : _a.challengeWindowSize,
90
97
  });
91
98
  }));
92
99
  this.tokenizeCard(card, headless);
@@ -173,4 +180,19 @@ export default class FatZebra {
173
180
  onOnce(event, callback);
174
181
  }
175
182
  }
183
+ __decorate([
184
+ logMethod({
185
+ mapArgs: (args) => {
186
+ var _a;
187
+ const params = args[0];
188
+ return [
189
+ {
190
+ merchant_username: window.MerchantUsername,
191
+ payment_intent: params === null || params === void 0 ? void 0 : params.paymentIntent,
192
+ payment_method: (_a = params === null || params === void 0 ? void 0 : params.paymentMethod) === null || _a === void 0 ? void 0 : _a.type,
193
+ },
194
+ ];
195
+ },
196
+ })
197
+ ], FatZebra.prototype, "verifyCard", null);
176
198
  export { FatZebra, };
@@ -17,8 +17,8 @@ class newSca {
17
17
  environment
18
18
  });
19
19
  }
20
- setup({ card_token, paymentIntent }) {
21
- return __awaiter(this, void 0, void 0, function* () {
20
+ setup(_a) {
21
+ return __awaiter(this, arguments, void 0, function* ({ card_token, paymentIntent }) {
22
22
  const result = yield this.gatewayClient.setup({ card_token, paymentIntent });
23
23
  return result;
24
24
  });
@@ -1,10 +1,12 @@
1
- import { useMemo } from "react";
1
+ import { useEffect, useMemo } from "react";
2
2
  import * as FatZebra from "../shared/types";
3
3
  import { generatePaymentURL } from "./paymentUrl";
4
4
  import Sca from "../sca";
5
5
  import GatewayClient from "../shared/api-gateway-client";
6
6
  import { generateVerifyURL } from "./verifyUrl";
7
7
  import useMessage from "./useMessage";
8
+ import { instrumentFunction } from "../logging/instrument";
9
+ const logUseFatZebra = instrumentFunction("useFatZebra", (meta) => meta, { mapArgs: ([meta]) => [meta] });
8
10
  const useFatZebra = ({ config, handlers, cardToken }) => {
9
11
  const { options, accessToken, paymentIntent, username } = config;
10
12
  const sca = useMemo(() => {
@@ -21,6 +23,14 @@ const useFatZebra = ({ config, handlers, cardToken }) => {
21
23
  handlers,
22
24
  sca
23
25
  });
26
+ useEffect(() => {
27
+ logUseFatZebra({
28
+ environment: config.environment,
29
+ reference: config.paymentIntent.payment.reference,
30
+ username: config.username,
31
+ react_sdk: true
32
+ });
33
+ }, [config.environment, cardToken]);
24
34
  const payment = paymentIntent.payment;
25
35
  const verifyUrl = generateVerifyURL(Object.assign({ token: cardToken, verification: paymentIntent.verification, merchant: username }, options), config.environment);
26
36
  const paymentUrl = generatePaymentURL(Object.assign({ merchant: username, reference: payment.reference, amount: payment.amount, currency: payment.currency, hash: paymentIntent.verification }, options), config.environment);
package/dist/sca/index.js CHANGED
@@ -90,8 +90,8 @@ class Sca {
90
90
  this._cardinal.setup(cardinalJwt);
91
91
  });
92
92
  }
93
- perform3DS({ sessionID }) {
94
- return __awaiter(this, void 0, void 0, function* () {
93
+ perform3DS(_a) {
94
+ return __awaiter(this, arguments, void 0, function* ({ sessionID }) {
95
95
  this.sessionId = sessionID;
96
96
  // Register handler. Called after OTP is entered on challenge prompt.
97
97
  this._cardinal.onPaymentValidated((data, error) => __awaiter(this, void 0, void 0, function* () {
@@ -21,7 +21,7 @@ const enrollmentScenarios = [
21
21
  veresEnrolled: VEResEnrolled.BYPASSED,
22
22
  pares: null,
23
23
  outcome: {
24
- success: false,
24
+ success: false, // no liability shift
25
25
  authenticationType: 'bypass',
26
26
  errorCode: ScaErrorCode.BYPASSED_AUTHENTICATION
27
27
  },
@@ -34,7 +34,7 @@ const enrollmentScenarios = [
34
34
  veresEnrolled: VEResEnrolled.UNABLE,
35
35
  pares: null,
36
36
  outcome: {
37
- success: false,
37
+ success: false, // no liability shift
38
38
  errorCode: ScaErrorCode.AUTHENTICATION_NOT_AVAILABLE_ON_LOOKUP
39
39
  }
40
40
  },
@@ -34,7 +34,7 @@ const validationScenarios = [
34
34
  pares: PARes.CANCELED,
35
35
  outcome: {
36
36
  authenticationType: 'challenge',
37
- success: false,
37
+ success: false, // no liability shift
38
38
  errorCode: ScaErrorCode.UNSUCCESSFUL_STEPUP_AUTHENTICATION
39
39
  }
40
40
  },
@@ -47,7 +47,7 @@ const validationScenarios = [
47
47
  pares: PARes.NOT_COMPLETED,
48
48
  outcome: {
49
49
  authenticationType: 'challenge',
50
- success: false,
50
+ success: false, // no liability shift
51
51
  errorCode: ScaErrorCode.UNAVAILABLE_STEPUP_AUTHENTICATION
52
52
  }
53
53
  },
@@ -126,7 +126,7 @@ const validationScenarios = [
126
126
  pares: null,
127
127
  outcome: {
128
128
  authenticationType: 'challenge',
129
- success: false,
129
+ success: false, // no liability shift
130
130
  errorCode: ScaErrorCode.UNSUCCESSFUL_STEPUP_AUTHENTICATION
131
131
  }
132
132
  },
@@ -1,5 +1,7 @@
1
- declare const bridgeUrl = "https://paynow.test";
1
+ declare const bridgeUrl = "https://paynow.test/sdk/bridge";
2
2
  declare const apiUrl = "https://api.test/sdk";
3
3
  declare const payNowUrl = "https://paynow.test";
4
4
  declare const songbirdUrl = "https://songbirdstag.cardinalcommerce.com/edge/v1/songbird.js";
5
- export { bridgeUrl, apiUrl, payNowUrl, songbirdUrl };
5
+ declare const cybersourceUrl = "https://centinelapistag.cardinalcommerce.com";
6
+ declare const returnCybersourceUrl = "https://paynow.test/return";
7
+ export { bridgeUrl, apiUrl, payNowUrl, songbirdUrl, cybersourceUrl, returnCybersourceUrl };
@@ -1,5 +1,7 @@
1
- const bridgeUrl = "https://paynow.test";
1
+ const bridgeUrl = "https://paynow.test/sdk/bridge";
2
2
  const apiUrl = "https://api.test/sdk";
3
3
  const payNowUrl = "https://paynow.test";
4
4
  const songbirdUrl = "https://songbirdstag.cardinalcommerce.com/edge/v1/songbird.js";
5
- export { bridgeUrl, apiUrl, payNowUrl, songbirdUrl };
5
+ const cybersourceUrl = "https://centinelapistag.cardinalcommerce.com";
6
+ const returnCybersourceUrl = "https://paynow.test/return";
7
+ export { bridgeUrl, apiUrl, payNowUrl, songbirdUrl, cybersourceUrl, returnCybersourceUrl };
@@ -2,4 +2,6 @@ declare const bridgeUrl = "https://paynow.pmnts.io/sdk/bridge";
2
2
  declare const apiUrl = "https://gateway.pmnts.io/sdk";
3
3
  declare const payNowUrl = "https://paynow.pmnts.io";
4
4
  declare const songbirdUrl = "https://songbird.cardinalcommerce.com/edge/v1/songbird.js";
5
- export { bridgeUrl, apiUrl, payNowUrl, songbirdUrl };
5
+ declare const cybersourceUrl = "https://centinelapi.cardinalcommerce.com";
6
+ declare const returnCybersourceUrl = "https://paynow.pmnts.io/return";
7
+ export { bridgeUrl, apiUrl, payNowUrl, songbirdUrl, cybersourceUrl, returnCybersourceUrl };
@@ -2,4 +2,6 @@ const bridgeUrl = "https://paynow.pmnts.io/sdk/bridge";
2
2
  const apiUrl = "https://gateway.pmnts.io/sdk";
3
3
  const payNowUrl = "https://paynow.pmnts.io";
4
4
  const songbirdUrl = "https://songbird.cardinalcommerce.com/edge/v1/songbird.js";
5
- export { bridgeUrl, apiUrl, payNowUrl, songbirdUrl };
5
+ const cybersourceUrl = "https://centinelapi.cardinalcommerce.com";
6
+ const returnCybersourceUrl = "https://paynow.pmnts.io/return";
7
+ export { bridgeUrl, apiUrl, payNowUrl, songbirdUrl, cybersourceUrl, returnCybersourceUrl };
@@ -2,4 +2,6 @@ declare const bridgeUrl = "https://paynow.pmnts-sandbox.io/sdk/bridge";
2
2
  declare const apiUrl = "https://gateway.pmnts-sandbox.io/sdk";
3
3
  declare const payNowUrl = "https://paynow.pmnts-sandbox.io";
4
4
  declare const songbirdUrl = "https://songbirdstag.cardinalcommerce.com/edge/v1/songbird.js";
5
- export { bridgeUrl, apiUrl, payNowUrl, songbirdUrl };
5
+ declare const cybersourceUrl = "https://centinelapistag.cardinalcommerce.com";
6
+ declare const returnCybersourceUrl = "https://paynow.pmnts-sandbox.io/return";
7
+ export { bridgeUrl, apiUrl, payNowUrl, songbirdUrl, cybersourceUrl, returnCybersourceUrl };
@@ -2,4 +2,6 @@ const bridgeUrl = "https://paynow.pmnts-sandbox.io/sdk/bridge";
2
2
  const apiUrl = "https://gateway.pmnts-sandbox.io/sdk";
3
3
  const payNowUrl = "https://paynow.pmnts-sandbox.io";
4
4
  const songbirdUrl = "https://songbirdstag.cardinalcommerce.com/edge/v1/songbird.js";
5
- export { bridgeUrl, apiUrl, payNowUrl, songbirdUrl };
5
+ const cybersourceUrl = "https://centinelapistag.cardinalcommerce.com";
6
+ const returnCybersourceUrl = "https://paynow.pmnts-sandbox.io/return";
7
+ export { bridgeUrl, apiUrl, payNowUrl, songbirdUrl, cybersourceUrl, returnCybersourceUrl };
@@ -2,4 +2,6 @@ declare const bridgeUrl = "https://paynow.pmnts-staging.io/sdk/bridge";
2
2
  declare const apiUrl = "https://gateway.pmnts-staging.io/sdk";
3
3
  declare const payNowUrl = "https://paynow.pmnts-staging.io";
4
4
  declare const songbirdUrl = "https://songbirdstag.cardinalcommerce.com/edge/v1/songbird.js";
5
- export { bridgeUrl, apiUrl, payNowUrl, songbirdUrl };
5
+ declare const cybersourceUrl = "https://centinelapistag.cardinalcommerce.com";
6
+ declare const returnCybersourceUrl = "https://paynow.pmnts-staging.io/return";
7
+ export { bridgeUrl, apiUrl, payNowUrl, songbirdUrl, cybersourceUrl, returnCybersourceUrl };
@@ -2,4 +2,6 @@ const bridgeUrl = "https://paynow.pmnts-staging.io/sdk/bridge";
2
2
  const apiUrl = "https://gateway.pmnts-staging.io/sdk";
3
3
  const payNowUrl = "https://paynow.pmnts-staging.io";
4
4
  const songbirdUrl = "https://songbirdstag.cardinalcommerce.com/edge/v1/songbird.js";
5
- export { bridgeUrl, apiUrl, payNowUrl, songbirdUrl };
5
+ const cybersourceUrl = "https://centinelapistag.cardinalcommerce.com";
6
+ const returnCybersourceUrl = "https://paynow.pmnts-staging.io/return";
7
+ export { bridgeUrl, apiUrl, payNowUrl, songbirdUrl, cybersourceUrl, returnCybersourceUrl };
@@ -33,8 +33,8 @@ class NewGatewayClient {
33
33
  }
34
34
  /**************** SCA/3DS2 /****************/
35
35
  //
36
- setup({ card_token, paymentIntent }) {
37
- return __awaiter(this, void 0, void 0, function* () {
36
+ setup(_a) {
37
+ return __awaiter(this, arguments, void 0, function* ({ card_token, paymentIntent }) {
38
38
  return this.client.post("/three_d_secure/setup", Object.assign(Object.assign({ merchant_username: this.username, card_token }, paymentIntent.payment), { verification: paymentIntent.verification }));
39
39
  });
40
40
  }
@@ -33,8 +33,8 @@ declare enum BridgeEvent {
33
33
  FORM_VALIDATION_SUCCESS = "fzi.form_validation_success",
34
34
  BIN_LOOKUP = "fzi.bin_lookup",
35
35
  CLICK_TO_PAY_TOKENIZATION = "fzi.c2p.tc_res",
36
- NEW_THREEDS_ENABLED = "fzi.new_threeds_enabled",
37
- READY = "fzi.ready"
36
+ READY = "fzi.ready",
37
+ THREE_D_SECURE_ENABLED = "fzi.three_d_secure_enabled"
38
38
  }
39
39
  declare enum PaymentMethodType {
40
40
  CARD = "card",
@@ -34,8 +34,8 @@ var BridgeEvent;
34
34
  BridgeEvent["FORM_VALIDATION_SUCCESS"] = "fzi.form_validation_success";
35
35
  BridgeEvent["BIN_LOOKUP"] = "fzi.bin_lookup";
36
36
  BridgeEvent["CLICK_TO_PAY_TOKENIZATION"] = "fzi.c2p.tc_res";
37
- BridgeEvent["NEW_THREEDS_ENABLED"] = "fzi.new_threeds_enabled";
38
37
  BridgeEvent["READY"] = "fzi.ready";
38
+ BridgeEvent["THREE_D_SECURE_ENABLED"] = "fzi.three_d_secure_enabled";
39
39
  })(BridgeEvent || (BridgeEvent = {}));
40
40
  var PaymentMethodType;
41
41
  (function (PaymentMethodType) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fat-zebra/sdk",
3
- "version": "1.5.12",
3
+ "version": "1.5.14-beta.5",
4
4
  "description": "",
5
5
  "main": "index.js",
6
6
  "scripts": {
@@ -18,8 +18,6 @@
18
18
  "author": "",
19
19
  "license": "ISC",
20
20
  "devDependencies": {
21
- "@commitlint/cli": "^19.8.1",
22
- "@commitlint/config-conventional": "^19.8.1",
23
21
  "@testing-library/dom": "^10.4.0",
24
22
  "@testing-library/react": "^16.0.0",
25
23
  "@testing-library/user-event": "^14.5.2",
@@ -30,41 +28,40 @@
30
28
  "@types/jsdom": "^21.1.1",
31
29
  "@types/react": "^19.1.16",
32
30
  "@types/react-dom": "^19.1.9",
33
- "audit-ci": "^6.6.1",
34
- "commitizen": "^4.3.1",
35
- "cz-conventional-changelog": "^3.3.0",
31
+ "audit-ci": "^7.1.0",
36
32
  "dotenv": "^16.0.1",
37
33
  "esbuild": "^0.25.10",
38
34
  "husky": "^9.1.7",
39
35
  "jest": "^30.2.0",
40
36
  "jest-environment-jsdom": "^30.2.0",
41
37
  "jest-localstorage-mock": "^2.4.22",
38
+ "jest-util": "^30.2.0",
42
39
  "jsdom": "^26.1.0",
43
- "jsonwebtoken": "^9.0.0",
40
+ "jsonwebtoken": "^9.0.1",
44
41
  "nock": "^13.0.1",
45
42
  "react": "^19.1.1",
46
43
  "react-dom": "^19.1.1",
47
- "ts-jest": "^29.1.1",
44
+ "ts-jest": "^29.4.6",
48
45
  "ts-loader": "^9.4.4",
49
46
  "ts-node": "^10.9.2",
50
47
  "typescript": "^5.1.6"
51
48
  },
49
+ "overrides": {
50
+ "test-exclude": "^7.0.1",
51
+ "minimatch": "^10.2.2"
52
+ },
52
53
  "dependencies": {
53
54
  "ajv": "^8.17.1",
54
55
  "ajv-formats": "^3.0.1",
55
56
  "ajv-keywords": "^5.1.0",
56
- "axios": "^1.12.0",
57
+ "axios": "1.13.5",
57
58
  "custom-event-polyfill": "^1.0.7",
59
+ "glob": "^13.0.6",
58
60
  "ts-polyfill": "^3.8.2",
59
61
  "url-template": "^3.1.0"
60
62
  },
61
63
  "peerDependencies": {
62
64
  "react": ">= 16",
63
65
  "react-dom": ">= 16"
64
- },
65
- "config": {
66
- "commitizen": {
67
- "path": "./node_modules/cz-conventional-changelog"
68
- }
69
66
  }
70
67
  }
@@ -1,13 +0,0 @@
1
- version: 2
2
- registries:
3
- cloudsmith_npm:
4
- type: npm-registry
5
- url: https://npm.cloudsmith.io/fat-zebra/npm
6
- token: ${{ secrets.CLOUDSMITH_NPM_PASSWORD }}
7
- updates:
8
- - package-ecosystem: npm
9
- directories:
10
- - .
11
- schedule:
12
- interval: weekly
13
- registries: '*'
@@ -1,223 +0,0 @@
1
- name: CI
2
-
3
- env:
4
- AWS_REGION: ap-southeast-2
5
- SBOX_UPLOAD_PATH: s3://sandbox-pmnts-resources/sdk/v1/
6
- PROD_UPLOAD_PATH: s3://pmnts-resources/sdk/v1/
7
- SBOX_CLOUDFRONT_ID: "E5G12OAJDKLBT"
8
- PROD_CLOUDFRONT_ID: "E3348QX8Q2J4OV"
9
- on:
10
- push:
11
- branches: ['main']
12
- tags:
13
- - 'v*.*.*' # prod tags e.g. v1.5.8
14
- - 'v*.*.*-beta.*' # beta tags e.g. v1.5.8-beta.0
15
-
16
- jobs:
17
- checks:
18
- name: Security & Type checks
19
- runs-on: ubuntu-latest
20
- env:
21
- NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
22
- steps:
23
- - uses: actions/checkout@v4
24
- - uses: actions/setup-node@v4
25
- with: { node-version: '20.x', cache: 'npm' }
26
- - run: npm ci
27
- - run: npx --yes audit-ci --high
28
- - run: npx tsc --noEmit
29
- - run: npx tsc -p tsconfig.package.json --noEmit
30
- - run: yarn test
31
-
32
- # --- BUILD JOBS ----------------------------------------------------
33
-
34
- build-sandbox:
35
- needs: checks
36
- if: github.ref_type == 'tag' && contains(github.ref_name, '-beta.')
37
- runs-on: ubuntu-latest
38
- env:
39
- NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
40
- GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
41
- NPM_CLOUDSMITH_REPO_PWD: ${{ secrets.CLOUDSMITH_API_KEY }}
42
- steps:
43
- - uses: actions/checkout@v4
44
- - uses: fatzebra/gh-workflows/build_npm@main
45
- - name: Build (sandbox)
46
- run: npm run build:sandbox
47
- - uses: actions/upload-artifact@v4
48
- with:
49
- name: sdk-dist-sandbox
50
- path: |
51
- dist/sandbox/*.js
52
- dist/sandbox/*.css
53
- if-no-files-found: error
54
-
55
- build-production:
56
- needs: checks
57
- if: github.ref_type == 'tag' && !contains(github.ref_name, '-beta.')
58
- runs-on: ubuntu-latest
59
- env:
60
- NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
61
- GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
62
- NPM_CLOUDSMITH_REPO_PWD: ${{ secrets.CLOUDSMITH_API_KEY }}
63
- steps:
64
- - uses: actions/checkout@v4
65
- - uses: fatzebra/gh-workflows/build_npm@main
66
- - name: Build (production)
67
- run: npm run build:production
68
- - uses: actions/upload-artifact@v4
69
- with:
70
- name: sdk-dist-production
71
- path: |
72
- dist/production/*.js
73
- dist/production/*.css
74
- if-no-files-found: error
75
-
76
- # --- DEPLOY JOBS ----------------------------------------------------
77
- deploy-sandbox:
78
- if: github.ref_type == 'tag' && contains(github.ref_name, '-beta.')
79
- needs:
80
- - build-sandbox
81
- runs-on: ubuntu-latest
82
- permissions:
83
- id-token: write
84
- contents: read
85
-
86
- steps:
87
- - uses: actions/download-artifact@v4
88
- with:
89
- name: sdk-dist-sandbox
90
- path: dist/sandbox/
91
- - uses: fatzebra/gh-workflows/aws_login@main
92
- with:
93
- platform: fz
94
- environment: sbox
95
- role_name: AppDeploy
96
- - run: aws s3 sync --delete --content-type 'application/javascript' --exclude '*' --include '*.js' dist/sandbox/ "${SBOX_UPLOAD_PATH}"
97
- - run: aws s3 sync --delete --content-type 'text/css' --exclude '*' --include '*.css' dist/sandbox/ "${SBOX_UPLOAD_PATH}"
98
- - name: Invalidate CloudFront cache
99
- shell: bash
100
- run: |
101
- invalidation_id=$(aws cloudfront create-invalidation \
102
- --distribution-id "${SBOX_CLOUDFRONT_ID}" \
103
- --paths '/sdk/*' \
104
- --output text \
105
- --query 'Invalidation.Id')
106
- echo "Invalidation started: ${invalidation_id}"
107
- aws cloudfront wait invalidation-completed \
108
- --distribution-id "${SBOX_CLOUDFRONT_ID}" \
109
- --id "${invalidation_id}"
110
- echo "Invalidation completed."
111
-
112
- deploy-production:
113
- if: github.ref_type == 'tag' && !contains(github.ref_name, '-beta.')
114
- needs:
115
- - build-production
116
- runs-on: ubuntu-latest
117
- permissions:
118
- id-token: write
119
- contents: read
120
- steps:
121
- - uses: actions/download-artifact@v4
122
- with:
123
- name: sdk-dist-production
124
- path: dist/production
125
- - uses: fatzebra/gh-workflows/aws_login@main
126
- with:
127
- platform: fz
128
- environment: prod
129
- role_name: AppDeploy
130
- - run: aws s3 sync --delete --content-type 'application/javascript' --exclude '*' --include '*.js' dist/production/ "${PROD_UPLOAD_PATH}"
131
- - run: aws s3 sync --delete --content-type 'text/css' --exclude '*' --include '*.css' dist/production/ "${PROD_UPLOAD_PATH}"
132
- - name: Invalidate CloudFront cache
133
- shell: bash
134
- run: |
135
- invalidation_id=$(aws cloudfront create-invalidation \
136
- --distribution-id "${PROD_CLOUDFRONT_ID}" \
137
- --paths '/sdk/*' \
138
- --output text \
139
- --query 'Invalidation.Id')
140
- echo "Invalidation started: ${invalidation_id}"
141
- aws cloudfront wait invalidation-completed \
142
- --distribution-id "${PROD_CLOUDFRONT_ID}" \
143
- --id "${invalidation_id}"
144
- echo "Invalidation completed."
145
-
146
- notify-sandbox-dispatch:
147
- name: Notify (sandbox build)
148
- needs: deploy-sandbox
149
- if: github.ref_type == 'tag' && contains(github.ref_name, '-beta.')
150
- uses: fatzebra/gh-workflows/.github/workflows/send_build_created.yml@main
151
- with:
152
- destination_repository: fatzebra/gazelle
153
- secrets: inherit
154
-
155
- # Publish to npm for beta tags and production tags
156
- publish-npm-beta:
157
- runs-on: ubuntu-latest
158
- if: startsWith(github.ref, 'refs/tags/') && contains(github.ref_name, '-beta.')
159
- env:
160
- TAG_NAME: ${{ github.ref_name }} # e.g. v1.5.10-beta.0
161
- NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
162
- steps:
163
- - uses: actions/checkout@v4
164
- with:
165
- fetch-depth: 0
166
-
167
- - uses: actions/setup-node@v4
168
- with:
169
- node-version: 20
170
- registry-url: 'https://registry.npmjs.org' # writes .npmrc using NPM_TOKEN
171
-
172
- - name: Show tag name
173
- run: echo "Publishing for tag $TAG_NAME"
174
-
175
- # make package.json version match the git tag (strip leading "v" if present)
176
- - name: Sync package.json version to git tag
177
- run: |
178
- VERSION="${TAG_NAME#v}"
179
- npm version --no-git-tag-version "$VERSION"
180
-
181
- - name: Install deps
182
- run: npm ci
183
-
184
- - name: Run package build
185
- run: npm run build:package
186
-
187
- - name: Publish (beta dist-tag)
188
- run: npm publish --access public --tag beta
189
-
190
-
191
- # --- NPM publish for production tags (vX.Y.Z) ---
192
- publish-npm-latest:
193
- if: startsWith(github.ref, 'refs/tags/') && !contains(github.ref_name, '-beta.')
194
- runs-on: ubuntu-latest
195
- env:
196
- TAG_NAME: ${{ github.ref_name }}
197
- NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
198
- steps:
199
- - uses: actions/checkout@v4
200
- with:
201
- fetch-depth: 0
202
-
203
- - uses: actions/setup-node@v4
204
- with:
205
- node-version: 20
206
- registry-url: 'https://registry.npmjs.org'
207
-
208
- - name: Tag Name
209
- run: echo "Publishing for tag $TAG_NAME"
210
-
211
- - name: Sync package.json version to git tag
212
- run: |
213
- VERSION="${TAG_NAME#v}"
214
- npm version --no-git-tag-version "$VERSION"
215
-
216
- - name: Install deps
217
- run: npm ci
218
-
219
- - name: Run package build
220
- run: npm run build:package
221
-
222
- - name: Publish (latest dist-tag)
223
- run: npm publish --access public --tag latest
@@ -1,124 +0,0 @@
1
- name: Non Prod CI
2
-
3
- env:
4
- AWS_REGION: ap-southeast-2
5
- TEST_UPLOAD_PATH: s3://test-cdn-pmnts-origin/sdk/v1/
6
- TEST_CLOUDFRONT_ID: "E1MCI9BNDVLHEU"
7
- on:
8
- push:
9
- branches-ignore:
10
- - main
11
- tags:
12
- - 'v*.*.*-beta.*'
13
-
14
- jobs:
15
- checks:
16
- name: Security & Type checks
17
- runs-on: ubuntu-latest
18
- env:
19
- NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
20
- steps:
21
- - uses: actions/checkout@v4
22
- - uses: actions/setup-node@v4
23
- with: { node-version: '20.x', cache: 'npm' }
24
- - run: npm ci
25
- - run: npx --yes audit-ci --high
26
- - run: npx tsc --noEmit
27
- - run: npx tsc -p tsconfig.package.json --noEmit
28
- - run: yarn test
29
-
30
- # --- BUILD JOBS ----------------------------------------------------
31
-
32
- build-staging:
33
- needs: checks
34
- if: github.ref_type == 'branch' && github.ref_name != 'main'
35
- runs-on: ubuntu-latest
36
- env:
37
- NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
38
- GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
39
- NPM_CLOUDSMITH_REPO_PWD: ${{ secrets.CLOUDSMITH_API_KEY }}
40
- steps:
41
- - uses: actions/checkout@v4
42
- - uses: fatzebra/gh-workflows/build_npm@main
43
- - name: Build (staging)
44
- run: npm run build:staging
45
- - uses: actions/upload-artifact@v4
46
- with:
47
- name: sdk-dist-staging
48
- path: |
49
- dist/staging/*.js
50
- dist/staging/*.css
51
- if-no-files-found: error
52
-
53
- # --- DEPLOY JOBS ----------------------------------------------------
54
-
55
- deploy-staging:
56
- if: github.ref_type == 'branch' && github.ref_name != 'main'
57
- needs:
58
- - build-staging
59
- runs-on: ubuntu-latest
60
- permissions:
61
- id-token: write
62
- contents: read
63
- steps:
64
- - uses: actions/download-artifact@v4
65
- with:
66
- name: sdk-dist-staging
67
- path: dist/staging/
68
- - uses: fatzebra/gh-workflows/aws_login@main
69
- with:
70
- platform: fz
71
- environment: test
72
- role_name: AppDeploy
73
-
74
- - run: aws s3 sync --delete --content-type 'application/javascript' --exclude '*' --include '*.js' dist/staging/ "${TEST_UPLOAD_PATH}"
75
- - run: aws s3 sync --delete --content-type 'text/css' --exclude '*' --include '*.css' dist/staging/ "${TEST_UPLOAD_PATH}"
76
-
77
- - name: Invalidate CloudFront cache
78
- shell: bash
79
- run: |
80
- invalidation_id=$(aws cloudfront create-invalidation \
81
- --distribution-id "${TEST_CLOUDFRONT_ID}" \
82
- --paths '/sdk/*' \
83
- --output text \
84
- --query 'Invalidation.Id')
85
- echo "Invalidation started: ${invalidation_id}"
86
- aws cloudfront wait invalidation-completed \
87
- --distribution-id "${TEST_CLOUDFRONT_ID}" \
88
- --id "${invalidation_id}"
89
- echo "Invalidation completed."
90
-
91
- # Publish to npm for beta tags and production tags
92
- publish-npm-beta:
93
- runs-on: ubuntu-latest
94
- if: startsWith(github.ref, 'refs/tags/') && contains(github.ref_name, '-beta.')
95
- env:
96
- TAG_NAME: ${{ github.ref_name }} # e.g. v1.5.10-beta.0
97
- NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
98
- steps:
99
- - uses: actions/checkout@v4
100
- with:
101
- fetch-depth: 0
102
-
103
- - uses: actions/setup-node@v4
104
- with:
105
- node-version: 20
106
- registry-url: 'https://registry.npmjs.org' # writes .npmrc using NPM_TOKEN
107
-
108
- - name: Show tag name
109
- run: echo "Publishing for tag $TAG_NAME"
110
-
111
- # make package.json version match the git tag (strip leading "v" if present)
112
- - name: Sync package.json version to git tag
113
- run: |
114
- VERSION="${TAG_NAME#v}"
115
- npm version --no-git-tag-version "$VERSION"
116
-
117
- - name: Install deps
118
- run: npm ci
119
-
120
- - name: Run package build
121
- run: npm run build:package
122
-
123
- - name: Publish (beta dist-tag)
124
- run: npm publish --access public --tag beta
package/.husky/commit-msg DELETED
@@ -1 +0,0 @@
1
- npx --no -- commitlint --edit "$1"
@@ -1 +0,0 @@
1
- exec < /dev/tty && npx cz --hook || true
package/CODEOWNERS DELETED
@@ -1 +0,0 @@
1
- * @fatzebra/cx
package/commitizen.png DELETED
Binary file
@@ -1,3 +0,0 @@
1
- module.exports = {
2
- extends: ['@commitlint/config-conventional'],
3
- };
@@ -1 +0,0 @@
1
- export declare function logMethod(target: any, propertyKey: string, descriptor: PropertyDescriptor): PropertyDescriptor;
@@ -1,35 +0,0 @@
1
- var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
2
- function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
3
- return new (P || (P = Promise))(function (resolve, reject) {
4
- function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
5
- function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
6
- function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
7
- step((generator = generator.apply(thisArg, _arguments || [])).next());
8
- });
9
- };
10
- import axios from 'axios';
11
- import { getLoggerUsername, getTransactionReference } from "./logger-context";
12
- export function logMethod(target, propertyKey, descriptor) {
13
- const originalMethod = descriptor.value;
14
- const LOGGING_ENDPOINT = `${process.env.PAYNOW_BASE_URL}/log_sdk`;
15
- descriptor.value = function (...args) {
16
- return __awaiter(this, void 0, void 0, function* () {
17
- try {
18
- const username = getLoggerUsername();
19
- const reference = getTransactionReference();
20
- axios.post(LOGGING_ENDPOINT, {
21
- username,
22
- reference,
23
- method: propertyKey,
24
- arguments: args,
25
- timestamp: new Date().toISOString(),
26
- });
27
- }
28
- catch (error) {
29
- console.warn('Logging failed for sdk:', error);
30
- }
31
- return originalMethod.apply(this, args);
32
- });
33
- };
34
- return descriptor;
35
- }