@commercetools/connect-payments-sdk 0.27.1 → 0.28.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.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,16 @@
1
1
  # @commercetools/connect-payments-sdk
2
2
 
3
+ ## 0.28.0
4
+
5
+ ### Minor Changes
6
+ - 9e2f639: chore(deps): upgrade dependencies to latest stable versions, including security patches
7
+
8
+ ## 0.27.2
9
+
10
+ ### Patch Changes
11
+
12
+ - d66f007: fix(payments): correct retry mechanism and add exponential backoff to payment updates
13
+
3
14
  ## 0.27.1
4
15
 
5
16
  ### Patch Changes
@@ -19,6 +19,17 @@ export declare class DefaultPaymentService implements PaymentService {
19
19
  findPaymentsByInterfaceId(opts: FindPaymentsByInterfaceId): Promise<Payment[]>;
20
20
  createPayment(draft: PaymentDraft): Promise<Payment>;
21
21
  updatePayment(opts: UpdatePayment): Promise<Payment>;
22
+ /**
23
+ * Calculates exponential backoff delay with jitter
24
+ * @param attempt - Current attempt number (0-based)
25
+ * @returns Delay in milliseconds
26
+ */
27
+ private calculateExponentialBackoff;
28
+ /**
29
+ * Sleep for a specified duration
30
+ * @param ms - Duration in milliseconds
31
+ */
32
+ private sleep;
22
33
  private consolidateUpdateActions;
23
34
  private populateSetInterfaceIdAction;
24
35
  private populateChangeTransactionInteractionId;
@@ -2,6 +2,7 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.DefaultPaymentService = void 0;
4
4
  const ct_api_error_1 = require("../errors/ct-api.error");
5
+ const node_crypto_1 = require("node:crypto");
5
6
  /**
6
7
  * This is the default implementation of the PaymentService interface.
7
8
  */
@@ -24,40 +25,60 @@ class DefaultPaymentService {
24
25
  }
25
26
  async updatePayment(opts) {
26
27
  const maxRetries = 3;
27
- let err;
28
- for (let retries = 0; retries < maxRetries; retries++) {
28
+ let lastError;
29
+ for (let attempt = 0; attempt < maxRetries; attempt++) {
29
30
  const payment = await this.getPayment({ id: opts.id });
30
31
  const actions = this.consolidateUpdateActions(payment, opts);
31
- this.logger.info({ paymentId: payment.id, paymentVersion: payment.version, actions, retries }, 'Updating payment with actions');
32
+ this.logger.info({ paymentId: payment.id, paymentVersion: payment.version, actions, attempt }, 'Updating payment with actions');
32
33
  if (actions.length === 0) {
33
- this.logger.info({ paymentId: payment.id, paymentVersion: payment.version, retries }, 'Update payment skipped, no actions to perform');
34
+ this.logger.info({ paymentId: payment.id, paymentVersion: payment.version, attempt }, 'Update payment skipped, no actions to perform');
34
35
  return payment;
35
36
  }
36
37
  try {
37
- const updatedPayment = await this.ctAPI.payment.updatePayment({
38
+ return await this.ctAPI.payment.updatePayment({
38
39
  resource: {
39
40
  id: payment.id,
40
41
  version: payment.version,
41
42
  },
42
43
  actions,
43
44
  });
44
- return updatedPayment;
45
45
  }
46
46
  catch (e) {
47
- err = e;
48
- if (e instanceof ct_api_error_1.CommercetoolsAPIError &&
47
+ lastError = e;
48
+ const isRetryableError = e instanceof ct_api_error_1.CommercetoolsAPIError &&
49
49
  (e.httpErrorStatus === 409 ||
50
- (e.httpErrorStatus === 400 && e.message.includes('already used without setting a payment interface')))) {
51
- this.logger.warn({ paymentId: payment.id, paymentVersion: payment.version, retries, err }, 'Unable to update the payment, retrying');
52
- retries++;
53
- }
54
- else {
55
- this.logger.error({ paymentId: payment.id, paymentVersion: payment.version, retries, err }, 'Unable to update the payment, abort');
56
- throw e;
50
+ (e.httpErrorStatus === 400 && e.message.includes('already used without setting a payment interface')));
51
+ if (isRetryableError && attempt < maxRetries - 1) {
52
+ const delayMs = this.calculateExponentialBackoff(attempt);
53
+ this.logger.warn({ paymentId: payment.id, paymentVersion: payment.version, attempt, delayMs, err: e }, 'Unable to update the payment, retrying');
54
+ await this.sleep(delayMs);
55
+ continue;
57
56
  }
57
+ this.logger.error({ paymentId: payment.id, paymentVersion: payment.version, attempt, err: e }, 'Unable to update the payment, abort');
58
+ throw e;
58
59
  }
59
60
  }
60
- throw err;
61
+ throw lastError;
62
+ }
63
+ /**
64
+ * Calculates exponential backoff delay with jitter
65
+ * @param attempt - Current attempt number (0-based)
66
+ * @returns Delay in milliseconds
67
+ */
68
+ calculateExponentialBackoff(attempt) {
69
+ const baseDelayMs = 100;
70
+ const maxDelayMs = 2000;
71
+ const jitterMs = 100;
72
+ const exponentialDelay = baseDelayMs * Math.pow(2, attempt);
73
+ const jitter = (0, node_crypto_1.randomInt)(0, jitterMs);
74
+ return Math.min(exponentialDelay + jitter, maxDelayMs);
75
+ }
76
+ /**
77
+ * Sleep for a specified duration
78
+ * @param ms - Duration in milliseconds
79
+ */
80
+ sleep(ms) {
81
+ return new Promise((resolve) => setTimeout(resolve, ms));
61
82
  }
62
83
  consolidateUpdateActions(payment, updateInfo) {
63
84
  const actions = [];
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@commercetools/connect-payments-sdk",
3
- "version": "0.27.1",
3
+ "version": "0.28.0",
4
4
  "description": "Payment SDK for commercetools payment connectors",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -15,12 +15,12 @@
15
15
  ],
16
16
  "license": "ISC",
17
17
  "dependencies": {
18
- "@commercetools-backend/loggers": "24.5.0",
19
- "@commercetools/platform-sdk": "8.18.0",
20
- "@commercetools/ts-client": "3.4.1",
21
- "jsonwebtoken": "9.0.2",
18
+ "@commercetools-backend/loggers": "27.4.0",
19
+ "@commercetools/platform-sdk": "8.25.0",
20
+ "@commercetools/ts-client": "4.9.1",
21
+ "jsonwebtoken": "9.0.3",
22
22
  "jwks-rsa": "3.2.0",
23
- "lodash": "4.17.21",
23
+ "lodash": "4.18.1",
24
24
  "logform": "2.7.0"
25
25
  }
26
26
  }
@@ -0,0 +1,9 @@
1
+ {
2
+ "extends": "./tsconfig.json",
3
+ "compilerOptions": {
4
+ "module": "CommonJS",
5
+ "moduleResolution": "node10",
6
+ "types": ["jest"]
7
+ },
8
+ "include": ["src/**/*.ts"]
9
+ }