@commercetools/connect-payments-sdk 0.25.1 → 0.27.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 +12 -0
- package/dist/commercetools/index.d.ts +2 -1
- package/dist/commercetools/services/ct-cart.service.d.ts +1 -0
- package/dist/commercetools/services/ct-cart.service.js +8 -0
- package/dist/commercetools/services/ct-recurring-payment-job.service.d.ts +55 -0
- package/dist/commercetools/services/ct-recurring-payment-job.service.js +106 -0
- package/dist/commercetools/types/cart.type.d.ts +7 -0
- package/dist/commercetools/types/recurring-payment-job.type.d.ts +34 -0
- package/dist/commercetools/types/recurring-payment-job.type.js +2 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.js +9 -0
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,17 @@
|
|
|
1
1
|
# @commercetools/connect-payments-sdk
|
|
2
2
|
|
|
3
|
+
## 0.27.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- 9fe494b: feat(recurring-orders): added new recurring payment job service that allows connectors to create a recurring payment job instance in Checkout
|
|
8
|
+
|
|
9
|
+
## 0.26.0
|
|
10
|
+
|
|
11
|
+
### Minor Changes
|
|
12
|
+
|
|
13
|
+
- d6a10eb: feat(cart): added a new method to the cart service to check whether the cart is a recurring cart
|
|
14
|
+
|
|
3
15
|
## 0.25.1
|
|
4
16
|
|
|
5
17
|
### Patch Changes
|
|
@@ -5,8 +5,9 @@ export { AuthorizationService as CommercetoolsAuthorizationService } from './typ
|
|
|
5
5
|
export { OrderService as CommercetoolsOrderService } from './types/order.type';
|
|
6
6
|
export { PaymentMethodService as CommercetoolsPaymentMethodService } from './types/payment-method.type';
|
|
7
7
|
export { CustomTypeService as CommercetoolsCustomTypeService } from './types/custom-type.type';
|
|
8
|
+
export { RecurringPaymentJobService as CommercetoolsRecurringPaymentJobService, RecurringPaymentJobDraft, } from './types/recurring-payment-job.type';
|
|
8
9
|
export * as CommercetoolsPaymentMethodTypes from './types/payment-method.type';
|
|
9
10
|
export { CommercetoolsClient } from './types/api.type';
|
|
10
|
-
export { CustomFieldsDraft, Cart, Order, OrderPagedQueryResponse, Payment, PaymentDraft, PaymentMethodInfoDraft, Money, LineItem, CustomLineItem, Address, Transaction, TransactionType, TransactionState, ShippingInfo, PaymentMethod, PaymentMethodPagedQueryResponse, PaymentMethodToken, PaymentMethodStatus, Type, TypeDraft, TypePagedQueryResponse, LocalizedString, } from '@commercetools/platform-sdk';
|
|
11
|
+
export { CustomFields, CustomFieldsDraft, Cart, Order, OrderPagedQueryResponse, Payment, PaymentDraft, PaymentMethodInfoDraft, Money, LineItem, CustomLineItem, Address, Transaction, TransactionType, TransactionState, ShippingInfo, PaymentMethod, PaymentMethodPagedQueryResponse, PaymentMethodToken, PaymentMethodStatus, Type, TypeDraft, TypeUpdateAction, ProductTypeDraft, TypeAddFieldDefinitionAction, TypeRemoveFieldDefinitionAction, CustomerSetCustomFieldAction, CustomerSetCustomTypeAction, CustomerUpdateAction, TypePagedQueryResponse, LocalizedString, Customer, } from '@commercetools/platform-sdk';
|
|
11
12
|
export * as CurrencyConverters from './helpers/currency.converter';
|
|
12
13
|
export * as TaxRateConverter from './helpers/taxrate.converter';
|
|
@@ -28,6 +28,7 @@ export declare class DefaultCartService implements CartService {
|
|
|
28
28
|
*/
|
|
29
29
|
getNormalizedShipping(opts: GetNormalizedShipping): NormalizedShipping[];
|
|
30
30
|
addPayment(opts: AddPayment): Promise<Cart>;
|
|
31
|
+
isRecurringCart(cart: Cart): boolean;
|
|
31
32
|
private calculateTotalPaidAmount;
|
|
32
33
|
private calculatePaymentAmount;
|
|
33
34
|
private wasPaymentReverted;
|
|
@@ -170,6 +170,14 @@ class DefaultCartService {
|
|
|
170
170
|
}
|
|
171
171
|
throw err;
|
|
172
172
|
}
|
|
173
|
+
isRecurringCart(cart) {
|
|
174
|
+
if (!cart.customerId)
|
|
175
|
+
return false;
|
|
176
|
+
const cartOrigin = cart.origin === 'RecurringOrder';
|
|
177
|
+
const hasRecurringLineItems = cart.lineItems?.some((item) => item.recurrenceInfo) ?? false;
|
|
178
|
+
const hasRecurringCustomLineItems = cart.customLineItems?.some((item) => item.recurrenceInfo) ?? false;
|
|
179
|
+
return cartOrigin || hasRecurringLineItems || hasRecurringCustomLineItems;
|
|
180
|
+
}
|
|
173
181
|
async calculateTotalPaidAmount(cart) {
|
|
174
182
|
if (!cart.paymentInfo || cart.paymentInfo.payments.length === 0) {
|
|
175
183
|
return 0;
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { Logger } from '../..';
|
|
2
|
+
import { RecurringPaymentJob, RecurringPaymentJobDraft, RecurringPaymentJobService } from '../types/recurring-payment-job.type';
|
|
3
|
+
import { DefaultCartService } from './ct-cart.service';
|
|
4
|
+
/**
|
|
5
|
+
* Default implementation of the RecurringPaymentJobService interface.
|
|
6
|
+
*/
|
|
7
|
+
export declare class DefaultRecurringPaymentJobService implements RecurringPaymentJobService {
|
|
8
|
+
private ctCartService;
|
|
9
|
+
private checkoutUrl;
|
|
10
|
+
private projectKey;
|
|
11
|
+
private logger;
|
|
12
|
+
constructor(opts: {
|
|
13
|
+
ctCartService: DefaultCartService;
|
|
14
|
+
checkoutUrl: string;
|
|
15
|
+
projectKey: string;
|
|
16
|
+
logger: Logger;
|
|
17
|
+
});
|
|
18
|
+
/**
|
|
19
|
+
* Creates a recurring payment job only if applicable (i.e., when the cart is configured for recurring payments).
|
|
20
|
+
*
|
|
21
|
+
* This method abstracts the business logic of determining whether a recurring payment job should be created.
|
|
22
|
+
* The caller doesn't need to validate the cart - the method handles it internally.
|
|
23
|
+
*
|
|
24
|
+
* The method performs the following operations:
|
|
25
|
+
* 1. Retrieves the cart associated with the origin payment
|
|
26
|
+
* 2. Checks if the cart is configured for recurring payments
|
|
27
|
+
* 3. If yes, creates the recurring payment job via the checkout API
|
|
28
|
+
* 4. If no, returns null without creating anything
|
|
29
|
+
*
|
|
30
|
+
* @param draft - The draft object containing the origin payment and payment method references
|
|
31
|
+
* @returns The created recurring payment job if the cart supports recurring payments,
|
|
32
|
+
* or null if it doesn't or if an error occurs
|
|
33
|
+
*
|
|
34
|
+
* @example
|
|
35
|
+
* ```typescript
|
|
36
|
+
* // Caller doesn't need to check if cart is recurring - method handles it
|
|
37
|
+
* const job = await service.createRecurringPaymentJobIfApplicable({
|
|
38
|
+
* originPayment: { id: 'payment-123', typeId: 'payment' },
|
|
39
|
+
* paymentMethod: { id: 'method-456', typeId: 'payment-method' }
|
|
40
|
+
* });
|
|
41
|
+
*
|
|
42
|
+
* if (job) {
|
|
43
|
+
* // Job was created because cart is recurring
|
|
44
|
+
* } else {
|
|
45
|
+
* // Cart is not recurring or an error occurred
|
|
46
|
+
* }
|
|
47
|
+
* ```
|
|
48
|
+
*/
|
|
49
|
+
createRecurringPaymentJobIfApplicable(draft: RecurringPaymentJobDraft): Promise<RecurringPaymentJob | null>;
|
|
50
|
+
/**
|
|
51
|
+
* Internal method that performs the HTTP request to create a recurring payment job.
|
|
52
|
+
*/
|
|
53
|
+
private internalCreateRecurringPaymentJob;
|
|
54
|
+
private safeParseErrorResponse;
|
|
55
|
+
}
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.DefaultRecurringPaymentJobService = void 0;
|
|
4
|
+
const errorx_1 = require("../../errorx/errorx");
|
|
5
|
+
/**
|
|
6
|
+
* Default implementation of the RecurringPaymentJobService interface.
|
|
7
|
+
*/
|
|
8
|
+
class DefaultRecurringPaymentJobService {
|
|
9
|
+
ctCartService;
|
|
10
|
+
checkoutUrl;
|
|
11
|
+
projectKey;
|
|
12
|
+
logger;
|
|
13
|
+
constructor(opts) {
|
|
14
|
+
this.ctCartService = opts.ctCartService;
|
|
15
|
+
this.checkoutUrl = opts.checkoutUrl;
|
|
16
|
+
this.projectKey = opts.projectKey;
|
|
17
|
+
this.logger = opts.logger;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Creates a recurring payment job only if applicable (i.e., when the cart is configured for recurring payments).
|
|
21
|
+
*
|
|
22
|
+
* This method abstracts the business logic of determining whether a recurring payment job should be created.
|
|
23
|
+
* The caller doesn't need to validate the cart - the method handles it internally.
|
|
24
|
+
*
|
|
25
|
+
* The method performs the following operations:
|
|
26
|
+
* 1. Retrieves the cart associated with the origin payment
|
|
27
|
+
* 2. Checks if the cart is configured for recurring payments
|
|
28
|
+
* 3. If yes, creates the recurring payment job via the checkout API
|
|
29
|
+
* 4. If no, returns null without creating anything
|
|
30
|
+
*
|
|
31
|
+
* @param draft - The draft object containing the origin payment and payment method references
|
|
32
|
+
* @returns The created recurring payment job if the cart supports recurring payments,
|
|
33
|
+
* or null if it doesn't or if an error occurs
|
|
34
|
+
*
|
|
35
|
+
* @example
|
|
36
|
+
* ```typescript
|
|
37
|
+
* // Caller doesn't need to check if cart is recurring - method handles it
|
|
38
|
+
* const job = await service.createRecurringPaymentJobIfApplicable({
|
|
39
|
+
* originPayment: { id: 'payment-123', typeId: 'payment' },
|
|
40
|
+
* paymentMethod: { id: 'method-456', typeId: 'payment-method' }
|
|
41
|
+
* });
|
|
42
|
+
*
|
|
43
|
+
* if (job) {
|
|
44
|
+
* // Job was created because cart is recurring
|
|
45
|
+
* } else {
|
|
46
|
+
* // Cart is not recurring or an error occurred
|
|
47
|
+
* }
|
|
48
|
+
* ```
|
|
49
|
+
*/
|
|
50
|
+
async createRecurringPaymentJobIfApplicable(draft) {
|
|
51
|
+
try {
|
|
52
|
+
const cart = await this.ctCartService.getCartByPaymentId({ paymentId: draft.originPayment.id });
|
|
53
|
+
if (!this.ctCartService.isRecurringCart(cart)) {
|
|
54
|
+
this.logger.info({ originPaymentId: draft.originPayment.id }, 'Cart is not recurring. Skipping recurring payment job creation');
|
|
55
|
+
return null;
|
|
56
|
+
}
|
|
57
|
+
this.logger.info({ draft }, 'Creating new recurring payment job');
|
|
58
|
+
const recurringPaymentJob = await this.internalCreateRecurringPaymentJob(draft);
|
|
59
|
+
this.logger.info({ recurringPaymentJobId: recurringPaymentJob.id }, 'Created new recurring payment job');
|
|
60
|
+
return recurringPaymentJob;
|
|
61
|
+
}
|
|
62
|
+
catch (error) {
|
|
63
|
+
this.logger.error({ error, draft }, 'Error creating recurring payment job');
|
|
64
|
+
return null;
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* Internal method that performs the HTTP request to create a recurring payment job.
|
|
69
|
+
*/
|
|
70
|
+
async internalCreateRecurringPaymentJob(draft) {
|
|
71
|
+
const url = `${this.checkoutUrl}/${this.projectKey}/recurring-payment-jobs`;
|
|
72
|
+
const payload = {
|
|
73
|
+
...draft,
|
|
74
|
+
status: {
|
|
75
|
+
state: 'Initial',
|
|
76
|
+
},
|
|
77
|
+
};
|
|
78
|
+
const response = await fetch(url, {
|
|
79
|
+
method: 'POST',
|
|
80
|
+
headers: {
|
|
81
|
+
'Content-Type': 'application/json',
|
|
82
|
+
},
|
|
83
|
+
body: JSON.stringify(payload),
|
|
84
|
+
});
|
|
85
|
+
if (!response.ok) {
|
|
86
|
+
const errorBody = await this.safeParseErrorResponse(response);
|
|
87
|
+
throw new errorx_1.ErrorGeneral('Could not create recurring payment job', {
|
|
88
|
+
privateFields: {
|
|
89
|
+
status: response.status,
|
|
90
|
+
statusText: response.statusText,
|
|
91
|
+
errorBody,
|
|
92
|
+
},
|
|
93
|
+
});
|
|
94
|
+
}
|
|
95
|
+
return (await response.json());
|
|
96
|
+
}
|
|
97
|
+
async safeParseErrorResponse(response) {
|
|
98
|
+
try {
|
|
99
|
+
return await response.json();
|
|
100
|
+
}
|
|
101
|
+
catch {
|
|
102
|
+
return response.statusText;
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
exports.DefaultRecurringPaymentJobService = DefaultRecurringPaymentJobService;
|
|
@@ -55,4 +55,11 @@ export interface CartService {
|
|
|
55
55
|
*/
|
|
56
56
|
getPlannedPaymentAmount(opts: GetPaymentAmount): Promise<PaymentAmount>;
|
|
57
57
|
addPayment(opts: AddPayment): Promise<Cart>;
|
|
58
|
+
/**
|
|
59
|
+
* Checks if the given cart contains items configured for recurring orders.
|
|
60
|
+
*
|
|
61
|
+
* @param cart - The cart to check
|
|
62
|
+
* @returns true if the cart contains recurring items, false otherwise
|
|
63
|
+
*/
|
|
64
|
+
isRecurringCart(cart: Cart): boolean;
|
|
58
65
|
}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
export type RecurringPaymentJobDraft = {
|
|
2
|
+
originPayment: {
|
|
3
|
+
id: string;
|
|
4
|
+
typeId: string;
|
|
5
|
+
};
|
|
6
|
+
paymentMethod: {
|
|
7
|
+
id: string;
|
|
8
|
+
typeId: string;
|
|
9
|
+
};
|
|
10
|
+
};
|
|
11
|
+
export type RecurringPaymentJob = {
|
|
12
|
+
id: string;
|
|
13
|
+
version: number;
|
|
14
|
+
createdAt: string;
|
|
15
|
+
lastModifiedAt: string;
|
|
16
|
+
originPayment?: {
|
|
17
|
+
id: string;
|
|
18
|
+
typeId: string;
|
|
19
|
+
};
|
|
20
|
+
paymentMethod?: {
|
|
21
|
+
id: string;
|
|
22
|
+
typeId: string;
|
|
23
|
+
};
|
|
24
|
+
status: {
|
|
25
|
+
state: string;
|
|
26
|
+
};
|
|
27
|
+
};
|
|
28
|
+
export interface RecurringPaymentJobService {
|
|
29
|
+
/**
|
|
30
|
+
* Ensures a recurring payment job is created if the payment's cart is configured for recurring payments.
|
|
31
|
+
* Returns null if the cart is not configured for recurring payments or if an error occurs.
|
|
32
|
+
*/
|
|
33
|
+
createRecurringPaymentJobIfApplicable(draft: RecurringPaymentJobDraft): Promise<RecurringPaymentJob | null>;
|
|
34
|
+
}
|
package/dist/index.d.ts
CHANGED
|
@@ -5,6 +5,7 @@ import { DefaultCartService } from './commercetools/services/ct-cart.service';
|
|
|
5
5
|
import { DefaultOrderService } from './commercetools/services/ct-order.service';
|
|
6
6
|
import { DefaultPaymentService } from './commercetools/services/ct-payment.service';
|
|
7
7
|
import { DefaultPaymentMethodService } from './commercetools/services/ct-payment-method.service';
|
|
8
|
+
import { DefaultRecurringPaymentJobService } from './commercetools/services/ct-recurring-payment-job.service';
|
|
8
9
|
import { DefaultCustomTypeService } from './commercetools/services/ct-custom-type.service';
|
|
9
10
|
import { Logger } from './logger';
|
|
10
11
|
export * from './api';
|
|
@@ -17,6 +18,7 @@ export declare const setupPaymentSDK: (opts: {
|
|
|
17
18
|
authUrl: string;
|
|
18
19
|
apiUrl: string;
|
|
19
20
|
sessionUrl: string;
|
|
21
|
+
checkoutUrl: string;
|
|
20
22
|
jwksUrl: string;
|
|
21
23
|
clientId: string;
|
|
22
24
|
clientSecret: string;
|
|
@@ -33,6 +35,7 @@ export declare const setupPaymentSDK: (opts: {
|
|
|
33
35
|
ctPaymentMethodService: DefaultPaymentMethodService;
|
|
34
36
|
ctCustomTypeService: DefaultCustomTypeService;
|
|
35
37
|
ctAuthorizationService: DefaultAuthorizationService;
|
|
38
|
+
ctRecurringPaymentJobService: DefaultRecurringPaymentJobService;
|
|
36
39
|
contextProvider: RequestContextProvider;
|
|
37
40
|
sessionHeaderAuthHookFn: SessionHeaderAuthenticationHook;
|
|
38
41
|
sessionQueryParamAuthHookFn: SessionQueryParamAuthenticationHook;
|
package/dist/index.js
CHANGED
|
@@ -23,6 +23,7 @@ const ct_order_service_1 = require("./commercetools/services/ct-order.service");
|
|
|
23
23
|
const ct_payment_service_1 = require("./commercetools/services/ct-payment.service");
|
|
24
24
|
const ct_payment_method_service_1 = require("./commercetools/services/ct-payment-method.service");
|
|
25
25
|
const ct_session_service_1 = require("./commercetools/services/ct-session.service");
|
|
26
|
+
const ct_recurring_payment_job_service_1 = require("./commercetools/services/ct-recurring-payment-job.service");
|
|
26
27
|
const ct_custom_type_service_1 = require("./commercetools/services/ct-custom-type.service");
|
|
27
28
|
const base_decorator_1 = require("./fetch/decorators/base.decorator");
|
|
28
29
|
const monitoring_decorator_1 = require("./fetch/decorators/monitoring.decorator");
|
|
@@ -69,6 +70,12 @@ const setupPaymentSDK = (opts) => {
|
|
|
69
70
|
const ctPaymentService = new ct_payment_service_1.DefaultPaymentService({ ctAPI, logger });
|
|
70
71
|
const ctPaymentMethodService = new ct_payment_method_service_1.DefaultPaymentMethodService({ ctAPI, logger });
|
|
71
72
|
const ctCustomTypeService = new ct_custom_type_service_1.DefaultCustomTypeService({ ctAPI, logger });
|
|
73
|
+
const ctRecurringPaymentJobService = new ct_recurring_payment_job_service_1.DefaultRecurringPaymentJobService({
|
|
74
|
+
ctCartService,
|
|
75
|
+
checkoutUrl: opts.checkoutUrl,
|
|
76
|
+
projectKey: opts.projectKey,
|
|
77
|
+
logger,
|
|
78
|
+
});
|
|
72
79
|
const oauth2Service = new security_1.DefaultOauth2Service({ logger });
|
|
73
80
|
const jwtService = new security_1.DefaultJWTService({
|
|
74
81
|
jwksUrl: opts.jwksUrl,
|
|
@@ -128,6 +135,7 @@ const setupPaymentSDK = (opts) => {
|
|
|
128
135
|
apiUrl: opts.apiUrl,
|
|
129
136
|
authUrl: opts.authUrl,
|
|
130
137
|
sessionUrl: opts.sessionUrl,
|
|
138
|
+
checkoutUrl: opts.checkoutUrl,
|
|
131
139
|
jwksUrl: opts.jwksUrl,
|
|
132
140
|
jwtIssuer: opts.jwtIssuer,
|
|
133
141
|
clientId: opts.clientId,
|
|
@@ -140,6 +148,7 @@ const setupPaymentSDK = (opts) => {
|
|
|
140
148
|
ctPaymentMethodService,
|
|
141
149
|
ctCustomTypeService,
|
|
142
150
|
ctAuthorizationService,
|
|
151
|
+
ctRecurringPaymentJobService,
|
|
143
152
|
contextProvider,
|
|
144
153
|
sessionHeaderAuthHookFn,
|
|
145
154
|
sessionQueryParamAuthHookFn,
|