@commercetools/connect-payments-sdk 0.13.1 → 0.15.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,17 @@
1
1
  # @commercetools/connect-payments-sdk
2
2
 
3
+ ## 0.15.0
4
+
5
+ ### Minor Changes
6
+
7
+ - 36738ad: subtract gift card planned amount from cart amount to compute required payment amount
8
+
9
+ ## 0.14.0
10
+
11
+ ### Minor Changes
12
+
13
+ - 012a346: Add currency conversion utility functions
14
+
3
15
  ## 0.13.1
4
16
 
5
17
  ### Patch Changes
@@ -0,0 +1,9 @@
1
+ import { Money, RequestContextData } from '../..';
2
+ export declare function getGiftCardPlannedAmountFromContext(context: RequestContextData): Money | undefined;
3
+ export declare function getCtSessionIdFromContext(context: RequestContextData): string | undefined;
4
+ export declare function getCartIdFromContext(context: RequestContextData): string | undefined;
5
+ export declare function getAllowedPaymentMethodsFromContext(context: RequestContextData): string[] | undefined;
6
+ export declare function getPaymentInterfaceFromContext(context: RequestContextData): string | undefined;
7
+ export declare function getProcessorUrlFromContext(context: RequestContextData): string | undefined;
8
+ export declare function getMerchantReturnUrlFromContext(context: RequestContextData): string | undefined;
9
+ export declare function getFutureOrderNumberFromContext(context: RequestContextData): string | undefined;
@@ -0,0 +1,59 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getGiftCardPlannedAmountFromContext = getGiftCardPlannedAmountFromContext;
4
+ exports.getCtSessionIdFromContext = getCtSessionIdFromContext;
5
+ exports.getCartIdFromContext = getCartIdFromContext;
6
+ exports.getAllowedPaymentMethodsFromContext = getAllowedPaymentMethodsFromContext;
7
+ exports.getPaymentInterfaceFromContext = getPaymentInterfaceFromContext;
8
+ exports.getProcessorUrlFromContext = getProcessorUrlFromContext;
9
+ exports.getMerchantReturnUrlFromContext = getMerchantReturnUrlFromContext;
10
+ exports.getFutureOrderNumberFromContext = getFutureOrderNumberFromContext;
11
+ const __1 = require("../..");
12
+ function getGiftCardPlannedAmountFromContext(context) {
13
+ const authentication = context.authentication;
14
+ if (authentication && authentication instanceof __1.SessionAuthentication) {
15
+ return authentication?.getPrincipal().giftCardPlannedAmount;
16
+ }
17
+ }
18
+ function getCtSessionIdFromContext(context) {
19
+ const authentication = context.authentication;
20
+ if (authentication && authentication instanceof __1.SessionAuthentication) {
21
+ return authentication?.getCredentials();
22
+ }
23
+ }
24
+ function getCartIdFromContext(context) {
25
+ const authentication = context.authentication;
26
+ if (authentication && authentication instanceof __1.SessionAuthentication) {
27
+ return authentication?.getPrincipal().cartId;
28
+ }
29
+ }
30
+ function getAllowedPaymentMethodsFromContext(context) {
31
+ const authentication = context.authentication;
32
+ if (authentication && authentication instanceof __1.SessionAuthentication) {
33
+ return authentication?.getPrincipal().allowedPaymentMethods;
34
+ }
35
+ }
36
+ function getPaymentInterfaceFromContext(context) {
37
+ const authentication = context.authentication;
38
+ if (authentication && authentication instanceof __1.SessionAuthentication) {
39
+ return authentication?.getPrincipal().paymentInterface;
40
+ }
41
+ }
42
+ function getProcessorUrlFromContext(context) {
43
+ const authentication = context.authentication;
44
+ if (authentication && authentication instanceof __1.SessionAuthentication) {
45
+ return authentication?.getPrincipal().processorUrl;
46
+ }
47
+ }
48
+ function getMerchantReturnUrlFromContext(context) {
49
+ const authentication = context.authentication;
50
+ if (authentication && authentication instanceof __1.SessionAuthentication) {
51
+ return authentication?.getPrincipal().merchantReturnUrl;
52
+ }
53
+ }
54
+ function getFutureOrderNumberFromContext(context) {
55
+ const authentication = context.authentication;
56
+ if (authentication && authentication instanceof __1.SessionAuthentication) {
57
+ return authentication?.getPrincipal().futureOrderNumber;
58
+ }
59
+ }
@@ -1,4 +1,5 @@
1
1
  export * from './context/request-context.provider';
2
+ export * from './context/request-context.helper';
2
3
  export * from './context/types/request-context.type';
3
4
  export * from './handlers/config.handler';
4
5
  export * from './handlers/status.handler';
package/dist/api/index.js CHANGED
@@ -15,6 +15,7 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
15
15
  };
16
16
  Object.defineProperty(exports, "__esModule", { value: true });
17
17
  __exportStar(require("./context/request-context.provider"), exports);
18
+ __exportStar(require("./context/request-context.helper"), exports);
18
19
  __exportStar(require("./context/types/request-context.type"), exports);
19
20
  __exportStar(require("./handlers/config.handler"), exports);
20
21
  __exportStar(require("./handlers/status.handler"), exports);
@@ -0,0 +1,52 @@
1
+ /**
2
+ * Applies the fraction digit to the given amount.
3
+ * Positive fraction digit moves the decimal to the right, negative to the left. (i.e. adding or removing zeros from either end)
4
+ *
5
+ * @example (10, -2) => 0.1
6
+ * @example (10, -1) => 1
7
+ * @example (10, 0) => 10
8
+ * @example (10, 1) => 100
9
+ * @example (10, 2) => 1000
10
+ * @example (12345, -3) => 12,345
11
+ * @example (12345, -2) => 123,45
12
+ * @example (12345, -1) => 1234,5
13
+ * @example (12345, 0) => 12345
14
+ * @example (12345, 1) => 123450
15
+ * @example (12345, 2) => 1234500
16
+ * @example (12345, 3) => 12345000
17
+ *
18
+ * @throws an Error if the given fraction digit (either via mapping or directly) is not a integer value
19
+ */
20
+ declare const convert: (amount: number, fractionDigit: number) => number;
21
+ type ConvertWithMappingOptions = {
22
+ /**
23
+ * A mapping where the key is the ISO 4217 currency code value and the value is the fraction digit (integer value) to apply.
24
+ */
25
+ mapping: Map<string, number>;
26
+ /**
27
+ * The amount to apply the fraction digit to
28
+ */
29
+ amount: number;
30
+ /**
31
+ * The currency code that belongs to this amount. This is used to lookup the value in the mapping to see if it needs to be overruled
32
+ */
33
+ currencyCode: string;
34
+ /**
35
+ * The fraction digit
36
+ */
37
+ fractionDigit?: number;
38
+ };
39
+ /**
40
+ * Applies the given fraction digit to the amount with the possibility to overrule the fraction digit via the supplied mapping.
41
+ *
42
+ * @param options The options to use with converting
43
+ *
44
+ * @function convert for more information how the fractionDigit is applied
45
+ *
46
+ * @returns The original value if neither the overruling fraction digit is found or no fraction digit is given, otherwise returns the converted value based on either the overruling fraction digit or fraction digit
47
+ *
48
+ * @throws an Error if the given fraction digit (either via mapping or directly) is not a integer value
49
+ */
50
+ declare const convertWithMapping: (options: ConvertWithMappingOptions) => number;
51
+ export { convert, convertWithMapping };
52
+ export type { ConvertWithMappingOptions };
@@ -0,0 +1,57 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.convertWithMapping = exports.convert = void 0;
4
+ const validateFractionDigit = (fractionDigit) => {
5
+ if (!Number.isInteger(fractionDigit)) {
6
+ throw new Error(`The given fraction digit of "${fractionDigit}" is not a integer. Fraction digit must be an integer value.`);
7
+ }
8
+ };
9
+ /**
10
+ * Applies the fraction digit to the given amount.
11
+ * Positive fraction digit moves the decimal to the right, negative to the left. (i.e. adding or removing zeros from either end)
12
+ *
13
+ * @example (10, -2) => 0.1
14
+ * @example (10, -1) => 1
15
+ * @example (10, 0) => 10
16
+ * @example (10, 1) => 100
17
+ * @example (10, 2) => 1000
18
+ * @example (12345, -3) => 12,345
19
+ * @example (12345, -2) => 123,45
20
+ * @example (12345, -1) => 1234,5
21
+ * @example (12345, 0) => 12345
22
+ * @example (12345, 1) => 123450
23
+ * @example (12345, 2) => 1234500
24
+ * @example (12345, 3) => 12345000
25
+ *
26
+ * @throws an Error if the given fraction digit (either via mapping or directly) is not a integer value
27
+ */
28
+ const convert = (amount, fractionDigit) => {
29
+ validateFractionDigit(fractionDigit);
30
+ return amount * (1 * Math.pow(10, fractionDigit));
31
+ };
32
+ exports.convert = convert;
33
+ /**
34
+ * Applies the given fraction digit to the amount with the possibility to overrule the fraction digit via the supplied mapping.
35
+ *
36
+ * @param options The options to use with converting
37
+ *
38
+ * @function convert for more information how the fractionDigit is applied
39
+ *
40
+ * @returns The original value if neither the overruling fraction digit is found or no fraction digit is given, otherwise returns the converted value based on either the overruling fraction digit or fraction digit
41
+ *
42
+ * @throws an Error if the given fraction digit (either via mapping or directly) is not a integer value
43
+ */
44
+ const convertWithMapping = (options) => {
45
+ const { amount, currencyCode, mapping, fractionDigit: fractionDigits } = options;
46
+ const overrulingFractionDigits = mapping.get(currencyCode);
47
+ if (overrulingFractionDigits) {
48
+ validateFractionDigit(overrulingFractionDigits);
49
+ return convert(amount, overrulingFractionDigits);
50
+ }
51
+ if (fractionDigits) {
52
+ validateFractionDigit(fractionDigits);
53
+ return convert(amount, fractionDigits);
54
+ }
55
+ return amount;
56
+ };
57
+ exports.convertWithMapping = convertWithMapping;
@@ -5,3 +5,4 @@ export { AuthorizationService as CommercetoolsAuthorizationService } from './typ
5
5
  export { OrderService as CommercetoolsOrderService } from './types/order.type';
6
6
  export { CommercetoolsClient } from './types/api.type';
7
7
  export { Cart, Order, OrderPagedQueryResponse, Payment, PaymentDraft, Money, LineItem, CustomLineItem, Address, Transaction, TransactionType, TransactionState, ShippingInfo, } from '@commercetools/platform-sdk';
8
+ export * as CurrencyConverters from './helpers/currency.converter';
@@ -1,2 +1,37 @@
1
1
  "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
2
35
  Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.CurrencyConverters = void 0;
37
+ exports.CurrencyConverters = __importStar(require("./helpers/currency.converter"));
@@ -8,6 +8,7 @@ import { PaymentAmount } from '../types/payment.type';
8
8
  export declare class DefaultCartService implements CartService {
9
9
  private ctAPI;
10
10
  private logger;
11
+ private contextProvider;
11
12
  constructor(opts: CartServiceOptions);
12
13
  getCartByPaymentId(opts: GetCartByPaymentIdRequest): Promise<Cart>;
13
14
  getCart(opts: GetCart): Promise<Cart>;
@@ -9,9 +9,11 @@ const ct_api_error_1 = require("../errors/ct-api.error");
9
9
  class DefaultCartService {
10
10
  ctAPI;
11
11
  logger;
12
+ contextProvider;
12
13
  constructor(opts) {
13
14
  this.ctAPI = opts.ctAPI;
14
15
  this.logger = opts.logger;
16
+ this.contextProvider = opts.contextProvider;
15
17
  }
16
18
  async getCartByPaymentId(opts) {
17
19
  const queryPredicate = `paymentInfo(payments(id = "${opts.paymentId}"))`;
@@ -31,18 +33,21 @@ class DefaultCartService {
31
33
  return await this.ctAPI.cart.getCartById(opts.id);
32
34
  }
33
35
  async getPaymentAmount(opts) {
36
+ const giftCardPlannedAmount = (0, __1.getGiftCardPlannedAmountFromContext)(this.contextProvider.getContextData());
34
37
  const paidAmount = await this.calculateTotalPaidAmount(opts.cart);
35
38
  let cartAmount;
36
39
  if (opts.cart.taxedPrice) {
37
40
  cartAmount = {
38
41
  currencyCode: opts.cart.taxedPrice.totalGross.currencyCode,
39
42
  centAmount: opts.cart.taxedPrice.totalGross.centAmount,
43
+ fractionDigits: opts.cart.taxedPrice.totalGross.fractionDigits,
40
44
  };
41
45
  }
42
46
  else {
43
47
  cartAmount = {
44
48
  currencyCode: opts.cart.totalPrice.currencyCode,
45
49
  centAmount: opts.cart.totalPrice.centAmount,
50
+ fractionDigits: opts.cart.totalPrice.fractionDigits,
46
51
  };
47
52
  }
48
53
  if (paidAmount >= cartAmount.centAmount) {
@@ -54,12 +59,17 @@ class DefaultCartService {
54
59
  },
55
60
  });
56
61
  }
57
- else {
58
- return {
59
- currencyCode: cartAmount.currencyCode,
60
- centAmount: cartAmount.centAmount - paidAmount,
61
- };
62
- }
62
+ const currentAmountToPay = giftCardPlannedAmount && giftCardPlannedAmount.currencyCode === cartAmount.currencyCode
63
+ ? cartAmount.centAmount - giftCardPlannedAmount.centAmount
64
+ : cartAmount.centAmount;
65
+ this.logger.info({
66
+ currentAmountToPay,
67
+ }, 'current amount to pay after gift card amount deduction');
68
+ return {
69
+ currencyCode: cartAmount.currencyCode,
70
+ centAmount: currentAmountToPay - paidAmount,
71
+ fractionDigits: cartAmount.fractionDigits,
72
+ };
63
73
  }
64
74
  /**
65
75
  * Get only one shipping address from the cart. If the cart has multiple shipping addresses, it returns the first one.
@@ -1,3 +1,4 @@
1
+ import { Money } from '@commercetools/platform-sdk';
1
2
  import { Logger } from '../..';
2
3
  import { AuthorizationService, CommercetoolsToken } from '../types/authorization.type';
3
4
  import { Session, SessionService } from '../types/session.type';
@@ -20,5 +21,6 @@ export declare class DefaultSessionService implements SessionService {
20
21
  getPaymentInterfaceFromSession(session: Session): string | undefined;
21
22
  getMerchantReturnUrlFromSession(session: Session): string | undefined;
22
23
  getFutureOrderNumberFromSession(session: Session): string | undefined;
24
+ getGiftCardPlannedAmountFromSession(session: Session): Money | undefined;
23
25
  private getSession;
24
26
  }
@@ -75,6 +75,9 @@ class DefaultSessionService {
75
75
  getFutureOrderNumberFromSession(session) {
76
76
  return session.metadata?.futureOrderNumber;
77
77
  }
78
+ getGiftCardPlannedAmountFromSession(session) {
79
+ return session.metadata?.giftCardPlannedAmount;
80
+ }
78
81
  async getSession(sessionId) {
79
82
  return await fetch(`${this.sessionUrl}/${this.projectKey}/sessions/${sessionId}`, {
80
83
  method: 'GET',
@@ -2,6 +2,7 @@ import { Address, Cart, ShippingInfo } from '@commercetools/platform-sdk';
2
2
  import { Logger } from '../../logger';
3
3
  import { AddPayment, CommercetoolsAPI } from './api.type';
4
4
  import { PaymentAmount } from './payment.type';
5
+ import { ContextProvider, RequestContextData } from '../../api';
5
6
  export type GetCart = {
6
7
  id: string;
7
8
  version?: number;
@@ -29,6 +30,7 @@ export type ShippingAmounts = {
29
30
  export type CartServiceOptions = {
30
31
  ctAPI: CommercetoolsAPI;
31
32
  logger: Logger;
33
+ contextProvider: ContextProvider<RequestContextData>;
32
34
  };
33
35
  export type GetCartByPaymentIdRequest = {
34
36
  paymentId: string;
@@ -4,6 +4,7 @@ import { Logger } from '../../logger';
4
4
  export type PaymentAmount = {
5
5
  centAmount: number;
6
6
  currencyCode: string;
7
+ fractionDigits: number;
7
8
  };
8
9
  export type PaymentServiceOptions = {
9
10
  ctAPI: CommercetoolsAPI;
@@ -1,3 +1,4 @@
1
+ import { Money } from '@commercetools/platform-sdk';
1
2
  export type Session = {
2
3
  id: string;
3
4
  version: number;
@@ -29,4 +30,5 @@ export interface SessionService {
29
30
  getPaymentInterfaceFromSession(session: Session): string | undefined;
30
31
  getMerchantReturnUrlFromSession(session: Session): string | undefined;
31
32
  getFutureOrderNumberFromSession(session: Session): string | undefined;
33
+ getGiftCardPlannedAmountFromSession(session: Session): Money | undefined;
32
34
  }
package/dist/index.js CHANGED
@@ -48,9 +48,6 @@ const setupPaymentSDK = (opts) => {
48
48
  contextProvider,
49
49
  logger,
50
50
  });
51
- const ctCartService = new ct_cart_service_1.DefaultCartService({ ctAPI, logger });
52
- const ctOrderService = new ct_order_service_1.DefaultOrderService({ ctAPI, logger });
53
- const ctPaymentService = new ct_payment_service_1.DefaultPaymentService({ ctAPI, logger });
54
51
  const ctAuthorizationService = new ct_authorization_service_1.DefaultAuthorizationService({
55
52
  authUrl: opts.authUrl,
56
53
  clientId: opts.clientId,
@@ -64,6 +61,9 @@ const setupPaymentSDK = (opts) => {
64
61
  projectKey: opts.projectKey,
65
62
  logger,
66
63
  });
64
+ const ctCartService = new ct_cart_service_1.DefaultCartService({ ctAPI, logger, contextProvider });
65
+ const ctOrderService = new ct_order_service_1.DefaultOrderService({ ctAPI, logger });
66
+ const ctPaymentService = new ct_payment_service_1.DefaultPaymentService({ ctAPI, logger });
67
67
  const oauth2Service = new security_1.DefaultOauth2Service({ logger });
68
68
  const jwtService = new security_1.DefaultJWTService({
69
69
  jwksUrl: opts.jwksUrl,
@@ -21,6 +21,7 @@ class SessionHeaderAuthenticationManager {
21
21
  paymentInterface: this.sessionService.getPaymentInterfaceFromSession(session),
22
22
  merchantReturnUrl: this.sessionService.getMerchantReturnUrlFromSession(session),
23
23
  futureOrderNumber: this.sessionService.getFutureOrderNumberFromSession(session),
24
+ giftCardPlannedAmount: this.sessionService.getGiftCardPlannedAmountFromSession(session),
24
25
  });
25
26
  }
26
27
  catch (e) {
@@ -1,3 +1,4 @@
1
+ import { Money } from '@commercetools/platform-sdk';
1
2
  export interface AuthenticationManager {
2
3
  authenticate(authentication: Authentication): Promise<Authentication> | Authentication;
3
4
  }
@@ -22,6 +23,7 @@ export type SessionPrincipal = {
22
23
  paymentInterface?: string;
23
24
  merchantReturnUrl?: string;
24
25
  futureOrderNumber?: string;
26
+ giftCardPlannedAmount?: Money;
25
27
  };
26
28
  export type Oauth2Principal = {
27
29
  clientId: string;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@commercetools/connect-payments-sdk",
3
- "version": "0.13.1",
3
+ "version": "0.15.0",
4
4
  "description": "Payment SDK for commercetools payment connectors",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -15,8 +15,8 @@
15
15
  ],
16
16
  "license": "ISC",
17
17
  "dependencies": {
18
- "@commercetools-backend/loggers": "22.37.0",
19
- "@commercetools/platform-sdk": "7.23.0",
18
+ "@commercetools-backend/loggers": "22.38.1",
19
+ "@commercetools/platform-sdk": "8.0.0",
20
20
  "@commercetools/sdk-client-v2": "2.5.0",
21
21
  "jsonwebtoken": "9.0.2",
22
22
  "jwks-rsa": "3.1.0",