@commercetools/connect-payments-sdk 0.26.0 → 0.27.1
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 +1 -0
- package/dist/commercetools/services/ct-recurring-payment-job.service.d.ts +63 -0
- package/dist/commercetools/services/ct-recurring-payment-job.service.js +135 -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 +10 -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.1
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- 7bfd391: Fix issue calling the recurring payment jobs API
|
|
8
|
+
|
|
9
|
+
## 0.27.0
|
|
10
|
+
|
|
11
|
+
### Minor Changes
|
|
12
|
+
|
|
13
|
+
- 9fe494b: feat(recurring-orders): added new recurring payment job service that allows connectors to create a recurring payment job instance in Checkout
|
|
14
|
+
|
|
3
15
|
## 0.26.0
|
|
4
16
|
|
|
5
17
|
### Minor Changes
|
|
@@ -5,6 +5,7 @@ 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
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';
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import { Logger } from '../..';
|
|
2
|
+
import { AuthorizationService } from '../types/authorization.type';
|
|
3
|
+
import { RecurringPaymentJob, RecurringPaymentJobDraft, RecurringPaymentJobService } from '../types/recurring-payment-job.type';
|
|
4
|
+
import { DefaultCartService } from './ct-cart.service';
|
|
5
|
+
/**
|
|
6
|
+
* Default implementation of the RecurringPaymentJobService interface.
|
|
7
|
+
*/
|
|
8
|
+
export declare class DefaultRecurringPaymentJobService implements RecurringPaymentJobService {
|
|
9
|
+
private authorizationService;
|
|
10
|
+
private ctCartService;
|
|
11
|
+
private checkoutUrl;
|
|
12
|
+
private projectKey;
|
|
13
|
+
private logger;
|
|
14
|
+
private token;
|
|
15
|
+
constructor(opts: {
|
|
16
|
+
authorizationService: AuthorizationService;
|
|
17
|
+
ctCartService: DefaultCartService;
|
|
18
|
+
checkoutUrl: string;
|
|
19
|
+
projectKey: string;
|
|
20
|
+
logger: Logger;
|
|
21
|
+
});
|
|
22
|
+
/**
|
|
23
|
+
* Creates a recurring payment job only if applicable (i.e., when the cart is configured for recurring payments).
|
|
24
|
+
*
|
|
25
|
+
* This method abstracts the business logic of determining whether a recurring payment job should be created.
|
|
26
|
+
* The caller doesn't need to validate the cart - the method handles it internally.
|
|
27
|
+
*
|
|
28
|
+
* The method performs the following operations:
|
|
29
|
+
* 1. Retrieves the cart associated with the origin payment
|
|
30
|
+
* 2. Checks if the cart is configured for recurring payments
|
|
31
|
+
* 3. If yes, creates the recurring payment job via the checkout API
|
|
32
|
+
* 4. If no, returns null without creating anything
|
|
33
|
+
*
|
|
34
|
+
* @param draft - The draft object containing the origin payment and payment method references
|
|
35
|
+
* @returns The created recurring payment job if the cart supports recurring payments,
|
|
36
|
+
* or null if it doesn't or if an error occurs
|
|
37
|
+
*
|
|
38
|
+
* @example
|
|
39
|
+
* ```typescript
|
|
40
|
+
* // Caller doesn't need to check if cart is recurring - method handles it
|
|
41
|
+
* const job = await service.createRecurringPaymentJobIfApplicable({
|
|
42
|
+
* originPayment: { id: 'payment-123', typeId: 'payment' },
|
|
43
|
+
* paymentMethod: { id: 'method-456', typeId: 'payment-method' }
|
|
44
|
+
* });
|
|
45
|
+
*
|
|
46
|
+
* if (job) {
|
|
47
|
+
* // Job was created because cart is recurring
|
|
48
|
+
* } else {
|
|
49
|
+
* // Cart is not recurring or an error occurred
|
|
50
|
+
* }
|
|
51
|
+
* ```
|
|
52
|
+
*/
|
|
53
|
+
createRecurringPaymentJobIfApplicable(draft: RecurringPaymentJobDraft): Promise<RecurringPaymentJob | null>;
|
|
54
|
+
/**
|
|
55
|
+
* Internal method that performs the HTTP request to create a recurring payment job.
|
|
56
|
+
*/
|
|
57
|
+
private internalCreateRecurringPaymentJob;
|
|
58
|
+
/**
|
|
59
|
+
* Performs a fetch request with automatic token refresh on 401/403 errors.
|
|
60
|
+
*/
|
|
61
|
+
private fetchWithTokenRetry;
|
|
62
|
+
private safeParseErrorResponse;
|
|
63
|
+
}
|
|
@@ -0,0 +1,135 @@
|
|
|
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
|
+
authorizationService;
|
|
10
|
+
ctCartService;
|
|
11
|
+
checkoutUrl;
|
|
12
|
+
projectKey;
|
|
13
|
+
logger;
|
|
14
|
+
token;
|
|
15
|
+
constructor(opts) {
|
|
16
|
+
this.authorizationService = opts.authorizationService;
|
|
17
|
+
this.ctCartService = opts.ctCartService;
|
|
18
|
+
this.checkoutUrl = opts.checkoutUrl;
|
|
19
|
+
this.projectKey = opts.projectKey;
|
|
20
|
+
this.logger = opts.logger;
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Creates a recurring payment job only if applicable (i.e., when the cart is configured for recurring payments).
|
|
24
|
+
*
|
|
25
|
+
* This method abstracts the business logic of determining whether a recurring payment job should be created.
|
|
26
|
+
* The caller doesn't need to validate the cart - the method handles it internally.
|
|
27
|
+
*
|
|
28
|
+
* The method performs the following operations:
|
|
29
|
+
* 1. Retrieves the cart associated with the origin payment
|
|
30
|
+
* 2. Checks if the cart is configured for recurring payments
|
|
31
|
+
* 3. If yes, creates the recurring payment job via the checkout API
|
|
32
|
+
* 4. If no, returns null without creating anything
|
|
33
|
+
*
|
|
34
|
+
* @param draft - The draft object containing the origin payment and payment method references
|
|
35
|
+
* @returns The created recurring payment job if the cart supports recurring payments,
|
|
36
|
+
* or null if it doesn't or if an error occurs
|
|
37
|
+
*
|
|
38
|
+
* @example
|
|
39
|
+
* ```typescript
|
|
40
|
+
* // Caller doesn't need to check if cart is recurring - method handles it
|
|
41
|
+
* const job = await service.createRecurringPaymentJobIfApplicable({
|
|
42
|
+
* originPayment: { id: 'payment-123', typeId: 'payment' },
|
|
43
|
+
* paymentMethod: { id: 'method-456', typeId: 'payment-method' }
|
|
44
|
+
* });
|
|
45
|
+
*
|
|
46
|
+
* if (job) {
|
|
47
|
+
* // Job was created because cart is recurring
|
|
48
|
+
* } else {
|
|
49
|
+
* // Cart is not recurring or an error occurred
|
|
50
|
+
* }
|
|
51
|
+
* ```
|
|
52
|
+
*/
|
|
53
|
+
async createRecurringPaymentJobIfApplicable(draft) {
|
|
54
|
+
try {
|
|
55
|
+
const cart = await this.ctCartService.getCartByPaymentId({ paymentId: draft.originPayment.id });
|
|
56
|
+
if (!this.ctCartService.isRecurringCart(cart)) {
|
|
57
|
+
this.logger.info({ originPaymentId: draft.originPayment.id }, 'Cart is not recurring. Skipping recurring payment job creation');
|
|
58
|
+
return null;
|
|
59
|
+
}
|
|
60
|
+
this.logger.info({ draft }, 'Creating new recurring payment job');
|
|
61
|
+
const recurringPaymentJob = await this.internalCreateRecurringPaymentJob(draft);
|
|
62
|
+
this.logger.info({ recurringPaymentJobId: recurringPaymentJob.id }, 'Created new recurring payment job');
|
|
63
|
+
return recurringPaymentJob;
|
|
64
|
+
}
|
|
65
|
+
catch (error) {
|
|
66
|
+
this.logger.error({ error, draft }, 'Error creating recurring payment job');
|
|
67
|
+
return null;
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* Internal method that performs the HTTP request to create a recurring payment job.
|
|
72
|
+
*/
|
|
73
|
+
async internalCreateRecurringPaymentJob(draft) {
|
|
74
|
+
const url = `${this.checkoutUrl}/${this.projectKey}/recurring-payment-jobs`;
|
|
75
|
+
const payload = {
|
|
76
|
+
...draft,
|
|
77
|
+
status: {
|
|
78
|
+
state: 'Initial',
|
|
79
|
+
},
|
|
80
|
+
};
|
|
81
|
+
const response = await this.fetchWithTokenRetry(url, {
|
|
82
|
+
method: 'POST',
|
|
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
|
+
/**
|
|
98
|
+
* Performs a fetch request with automatic token refresh on 401/403 errors.
|
|
99
|
+
*/
|
|
100
|
+
async fetchWithTokenRetry(url, options) {
|
|
101
|
+
if (!this.token) {
|
|
102
|
+
this.token = await this.authorizationService.getAccessToken();
|
|
103
|
+
}
|
|
104
|
+
let response = await fetch(url, {
|
|
105
|
+
...options,
|
|
106
|
+
headers: {
|
|
107
|
+
'Content-Type': 'application/json',
|
|
108
|
+
Authorization: `Bearer ${this.token.access_token}`,
|
|
109
|
+
...options.headers,
|
|
110
|
+
},
|
|
111
|
+
});
|
|
112
|
+
// If commercetools oauth token is expired, get a new one and retry once
|
|
113
|
+
if (response.status === 401 || response.status === 403) {
|
|
114
|
+
this.token = await this.authorizationService.getAccessToken();
|
|
115
|
+
response = await fetch(url, {
|
|
116
|
+
...options,
|
|
117
|
+
headers: {
|
|
118
|
+
'Content-Type': 'application/json',
|
|
119
|
+
Authorization: `Bearer ${this.token.access_token}`,
|
|
120
|
+
...options.headers,
|
|
121
|
+
},
|
|
122
|
+
});
|
|
123
|
+
}
|
|
124
|
+
return response;
|
|
125
|
+
}
|
|
126
|
+
async safeParseErrorResponse(response) {
|
|
127
|
+
try {
|
|
128
|
+
return await response.json();
|
|
129
|
+
}
|
|
130
|
+
catch {
|
|
131
|
+
return response.statusText;
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
exports.DefaultRecurringPaymentJobService = DefaultRecurringPaymentJobService;
|
|
@@ -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,13 @@ 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
|
+
authorizationService: ctAuthorizationService,
|
|
75
|
+
ctCartService,
|
|
76
|
+
checkoutUrl: opts.checkoutUrl,
|
|
77
|
+
projectKey: opts.projectKey,
|
|
78
|
+
logger,
|
|
79
|
+
});
|
|
72
80
|
const oauth2Service = new security_1.DefaultOauth2Service({ logger });
|
|
73
81
|
const jwtService = new security_1.DefaultJWTService({
|
|
74
82
|
jwksUrl: opts.jwksUrl,
|
|
@@ -128,6 +136,7 @@ const setupPaymentSDK = (opts) => {
|
|
|
128
136
|
apiUrl: opts.apiUrl,
|
|
129
137
|
authUrl: opts.authUrl,
|
|
130
138
|
sessionUrl: opts.sessionUrl,
|
|
139
|
+
checkoutUrl: opts.checkoutUrl,
|
|
131
140
|
jwksUrl: opts.jwksUrl,
|
|
132
141
|
jwtIssuer: opts.jwtIssuer,
|
|
133
142
|
clientId: opts.clientId,
|
|
@@ -140,6 +149,7 @@ const setupPaymentSDK = (opts) => {
|
|
|
140
149
|
ctPaymentMethodService,
|
|
141
150
|
ctCustomTypeService,
|
|
142
151
|
ctAuthorizationService,
|
|
152
|
+
ctRecurringPaymentJobService,
|
|
143
153
|
contextProvider,
|
|
144
154
|
sessionHeaderAuthHookFn,
|
|
145
155
|
sessionQueryParamAuthHookFn,
|