recurrente-js 1.0.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.
@@ -0,0 +1,71 @@
1
+ import { PaymentIntentSucceeded, PaymentIntentFailed, SubscriptionCreate, SubscriptionPastDue, SubscriptionPaused, SubscriptionCancel, RecurrenteWebhookEvent } from '../types/globals';
2
+ /**
3
+ * A handler function type definition.
4
+ * @template T The type of the webhook event.
5
+ */
6
+ type WebhookHandler<T> = (event: T) => void;
7
+ /**
8
+ * Mapping of event types to corresponding event interfaces.
9
+ */
10
+ interface EventTypeMapping {
11
+ 'payment_intent.succeeded': PaymentIntentSucceeded;
12
+ 'payment_intent.failed': PaymentIntentFailed;
13
+ 'subscription.create': SubscriptionCreate;
14
+ 'subscription.past_due': SubscriptionPastDue;
15
+ 'subscription.paused': SubscriptionPaused;
16
+ 'subscription.cancel': SubscriptionCancel;
17
+ }
18
+ /**
19
+ * Verifies the Svix webhook signature and parses the event.
20
+ *
21
+ * @param payload - The raw request body as a string.
22
+ * @param headers - The request headers.
23
+ * @returns The verified and parsed event.
24
+ * @throws {Error} If the signature verification fails.
25
+ */
26
+ declare function verifySvixSignature(payload: string, headers: Record<string, string | string[] | undefined>): RecurrenteWebhookEvent;
27
+ /**
28
+ * Registers a custom webhook handler for a specific event type.
29
+ *
30
+ * @template T The type of the webhook event.
31
+ * @param {keyof EventTypeMapping} eventType - The type of the event (e.g., 'payment_intent.succeeded').
32
+ * @param {WebhookHandler<EventTypeMapping[T]>} handler - The custom handler function to register for this event type.
33
+ *
34
+ * @example
35
+ * registerWebhookHandler('payment_intent.succeeded', (event) => {
36
+ * console.log(`Payment succeeded for: ${event.customer.email}`);
37
+ * // Custom logic for a successful payment
38
+ * });
39
+ */
40
+ declare function registerWebhookHandler<T extends keyof EventTypeMapping>(eventType: T, handler: WebhookHandler<EventTypeMapping[T]>): void;
41
+ /**
42
+ * Handles a verified webhook event by dispatching it to the appropriate registered or default handler.
43
+ *
44
+ * **Important Note:** Before calling this function, you must verify the webhook signature using `verifySvixSignature`
45
+ * to ensure the event is authentic and has not been tampered with.
46
+ *
47
+ * @param {RecurrenteWebhookEvent} event - The verified webhook event object sent by Recurrente.
48
+ *
49
+ * @example
50
+ * app.post('/webhook', (req, res) => {
51
+ * try {
52
+ * const payload = req.body;
53
+ * const headers = req.headers;
54
+ *
55
+ * // Verify the signature and obtain the event
56
+ * const event = verifySvixSignature(payload, headers);
57
+ *
58
+ * // Handle the verified event
59
+ * handleWebhookEvent(event);
60
+ *
61
+ * res.status(200).send('Webhook processed');
62
+ * } catch (error) {
63
+ * console.error('Error processing webhook:', error);
64
+ * res.status(400).send('Invalid webhook signature');
65
+ * }
66
+ * });
67
+ *
68
+ * @throws {Error} If no handler is found for the event type.
69
+ */
70
+ declare function handleWebhookEvent(event: RecurrenteWebhookEvent): void;
71
+ export { handleWebhookEvent, verifySvixSignature, registerWebhookHandler };
@@ -0,0 +1,122 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.handleWebhookEvent = handleWebhookEvent;
7
+ exports.verifySvixSignature = verifySvixSignature;
8
+ exports.registerWebhookHandler = registerWebhookHandler;
9
+ const svix_1 = require("svix");
10
+ const conversion_1 = require("../utils/conversion");
11
+ const dotenv_1 = __importDefault(require("dotenv"));
12
+ // Load environment variables from .env file if they are not already set
13
+ dotenv_1.default.config();
14
+ /**
15
+ * A record to store the user-registered webhook handlers.
16
+ * Each event type is mapped to its corresponding handler function.
17
+ */
18
+ const userHandlers = {
19
+ 'payment_intent.succeeded': (event) => {
20
+ console.log('Default PaymentIntentSucceeded Handler:', event);
21
+ },
22
+ 'payment_intent.failed': (event) => {
23
+ console.log('Default PaymentIntentFailed Handler:', event);
24
+ },
25
+ 'subscription.create': (event) => {
26
+ console.log('Default SubscriptionCreate Handler:', event);
27
+ },
28
+ 'subscription.past_due': (event) => {
29
+ console.log('Default SubscriptionPastDue Handler:', event);
30
+ },
31
+ 'subscription.paused': (event) => {
32
+ console.log('Default SubscriptionPaused Handler:', event);
33
+ },
34
+ 'subscription.cancel': (event) => {
35
+ console.log('Default SubscriptionCancel Handler:', event);
36
+ },
37
+ };
38
+ /**
39
+ * Verifies the Svix webhook signature and parses the event.
40
+ *
41
+ * @param payload - The raw request body as a string.
42
+ * @param headers - The request headers.
43
+ * @returns The verified and parsed event.
44
+ * @throws {Error} If the signature verification fails.
45
+ */
46
+ function verifySvixSignature(payload, headers) {
47
+ const signingSecret = process.env.RECURRENTE_SVIX_SIGNING_SECRET;
48
+ if (!signingSecret) {
49
+ throw new Error('Missing signing secret');
50
+ }
51
+ const svixHeaders = {
52
+ 'svix-id': headers['svix-id'],
53
+ 'svix-timestamp': headers['svix-timestamp'],
54
+ 'svix-signature': headers['svix-signature'],
55
+ };
56
+ const svix = new svix_1.Webhook(signingSecret);
57
+ try {
58
+ // Verify the signature and parse the event
59
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
60
+ const event = svix.verify(payload, svixHeaders);
61
+ // Convert snake_case keys to camelCase
62
+ const camelCasedEvent = (0, conversion_1.toCamelCase)(event);
63
+ return camelCasedEvent;
64
+ }
65
+ catch (error) {
66
+ throw new Error('Invalid webhook signature');
67
+ }
68
+ }
69
+ /**
70
+ * Registers a custom webhook handler for a specific event type.
71
+ *
72
+ * @template T The type of the webhook event.
73
+ * @param {keyof EventTypeMapping} eventType - The type of the event (e.g., 'payment_intent.succeeded').
74
+ * @param {WebhookHandler<EventTypeMapping[T]>} handler - The custom handler function to register for this event type.
75
+ *
76
+ * @example
77
+ * registerWebhookHandler('payment_intent.succeeded', (event) => {
78
+ * console.log(`Payment succeeded for: ${event.customer.email}`);
79
+ * // Custom logic for a successful payment
80
+ * });
81
+ */
82
+ function registerWebhookHandler(eventType, handler) {
83
+ userHandlers[eventType] = handler;
84
+ }
85
+ /**
86
+ * Handles a verified webhook event by dispatching it to the appropriate registered or default handler.
87
+ *
88
+ * **Important Note:** Before calling this function, you must verify the webhook signature using `verifySvixSignature`
89
+ * to ensure the event is authentic and has not been tampered with.
90
+ *
91
+ * @param {RecurrenteWebhookEvent} event - The verified webhook event object sent by Recurrente.
92
+ *
93
+ * @example
94
+ * app.post('/webhook', (req, res) => {
95
+ * try {
96
+ * const payload = req.body;
97
+ * const headers = req.headers;
98
+ *
99
+ * // Verify the signature and obtain the event
100
+ * const event = verifySvixSignature(payload, headers);
101
+ *
102
+ * // Handle the verified event
103
+ * handleWebhookEvent(event);
104
+ *
105
+ * res.status(200).send('Webhook processed');
106
+ * } catch (error) {
107
+ * console.error('Error processing webhook:', error);
108
+ * res.status(400).send('Invalid webhook signature');
109
+ * }
110
+ * });
111
+ *
112
+ * @throws {Error} If no handler is found for the event type.
113
+ */
114
+ function handleWebhookEvent(event) {
115
+ const handler = userHandlers[event.eventType];
116
+ if (handler) {
117
+ handler(event);
118
+ }
119
+ else {
120
+ throw new Error(`No handler registered for event type: ${event.eventType}`);
121
+ }
122
+ }
@@ -0,0 +1,131 @@
1
+ import { ProductSubscription, CreateSubscriptionResponse, SubscriptionStatusResponse, CreateProductRequest, CreateProductResponse, GetProductResponse, GetAllProductsResponse, UpdateProductRequest } from '../types/globals';
2
+ /**
3
+ * Recurrente API utility for managing product subscriptions, cancellations, and product deletions.
4
+ *
5
+ * The `recurrente` object provides methods to create, cancel, retrieve, and delete subscriptions and products,
6
+ * making it easy to integrate Recurrente's payment services into your project.
7
+ *
8
+ * @namespace recurrente
9
+ * @property {Function} test - Test endpoint.
10
+ * @property {Function} createProduct - Creates a new product with a one-time payment.
11
+ * @property {Function} getProduct - Retrieves details of a specific product by its ID.
12
+ * @property {Function} getAllProducts - Retrieves a paginated list of all products.
13
+ * @property {Function} updateProduct - Updates an existing product by its ID.
14
+ * @property {Function} deleteProduct - Deletes a product by its ID.
15
+ * @property {Function} createSubscription - Creates a new subscription for a product.
16
+ * @property {Function} cancelSubscription - Cancels an existing subscription by its ID.
17
+ * @property {Function} getSubscription - Retrieves details of a specific subscription by its ID.
18
+ */
19
+ declare const recurrente: {
20
+ /**
21
+ * Makes a GET request to the '/test' endpoint.
22
+ *
23
+ * **FOR DEVELOPMENT PURPOSES ONLY TO TEST**
24
+ *
25
+ * This method is included for testing internal API functionality.
26
+ *
27
+ * @function
28
+ * @memberof recurrente
29
+ * @returns {Promise<{message: string}>} A message indicating the success or failure of the request.
30
+ * @throws {ErrorResponse} Throws an error if the request fails.
31
+ */
32
+ test: () => Promise<{
33
+ message: string;
34
+ }>;
35
+ /**
36
+ * Creates a new product with a one-time payment.
37
+ *
38
+ * This function takes the product data, converts it to snake_case,
39
+ * and sends it to the API to create a one-time payment product.
40
+ * It returns the created product's details.
41
+ *
42
+ * @function
43
+ * @memberof recurrente
44
+ * @see createProduct
45
+ * @param {CreateProductRequest} productData - The details of the product to create.
46
+ * @returns {Promise<CreateProductResponse>} A promise that resolves with the created product's details.
47
+ * @throws {ErrorResponse} Throws an error if the product creation fails.
48
+ */
49
+ createProduct: (productData: CreateProductRequest) => Promise<CreateProductResponse>;
50
+ /**
51
+ * Retrieves details of a specific product by its ID.
52
+ *
53
+ * This function fetches details of an existing product by making a GET request
54
+ * using the product ID.
55
+ *
56
+ * @function
57
+ * @memberof recurrente
58
+ * @see getProduct
59
+ * @param {string} productId - The ID of the product to retrieve.
60
+ * @returns {Promise<GetProductResponse>} The details of the product.
61
+ * @throws {ErrorResponse} Throws an error if the retrieval fails.
62
+ */
63
+ getProduct: (productId: string) => Promise<GetProductResponse>;
64
+ /**
65
+ * Retrieves a paginated list of all products.
66
+ *
67
+ * This function fetches a list of products from the API. By default, it retrieves
68
+ * the 10 most recent products, but pagination can be controlled using query parameters.
69
+ *
70
+ * @function
71
+ * @memberof recurrente
72
+ * @see getAllProducts
73
+ * @param {number} [page=1] - The page number to retrieve, defaults to the first page.
74
+ * @returns {Promise<GetAllProductsResponse>} A promise that resolves with an array of product details.
75
+ * @throws {ErrorResponse} Throws an error if the product retrieval fails.
76
+ */
77
+ getAllProducts: (page?: number) => Promise<GetAllProductsResponse>;
78
+ /**
79
+ * Updates an existing product by its ID.
80
+ *
81
+ * This function takes the product ID and an object containing the updated product details.
82
+ * It sends a PATCH request to the API to update the specified product. You can also
83
+ * modify product prices or delete them by passing the _destroy parameter in prices_attributes.
84
+ *
85
+ * @function
86
+ * @memberof recurrente
87
+ * @see updateProduct
88
+ * @param {string} productId - The ID of the product to update.
89
+ * @param {UpdateProductRequest} productData - The updated product details.
90
+ * @returns {Promise<GetProductResponse>} A promise that resolves with the updated product's details.
91
+ * @throws {ErrorResponse} Throws an error if the product update fails.
92
+ */
93
+ updateProduct: (productId: string, productData: UpdateProductRequest) => Promise<GetProductResponse>;
94
+ /**
95
+ * Deletes a product by its ID.
96
+ *
97
+ * @function
98
+ * @memberof recurrente
99
+ * @see deleteProduct
100
+ */
101
+ deleteProduct: (productId: string) => Promise<{
102
+ message: string;
103
+ }>;
104
+ /**
105
+ * Creates a new subscription for a product.
106
+ *
107
+ * @function
108
+ * @memberof recurrente
109
+ * @see createSubscription
110
+ */
111
+ createSubscription: (productData: ProductSubscription) => Promise<CreateSubscriptionResponse>;
112
+ /**
113
+ * Cancels an existing subscription by its ID.
114
+ *
115
+ * @function
116
+ * @memberof recurrente
117
+ * @see cancelSubscription
118
+ */
119
+ cancelSubscription: (subscriptionId: string) => Promise<{
120
+ message: string;
121
+ }>;
122
+ /**
123
+ * Retrieves details of a specific subscription by its ID.
124
+ *
125
+ * @function
126
+ * @memberof recurrente
127
+ * @see getSubscription
128
+ */
129
+ getSubscription: (subscriptionId: string) => Promise<SubscriptionStatusResponse>;
130
+ };
131
+ export default recurrente;
@@ -0,0 +1,355 @@
1
+ "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ var __importDefault = (this && this.__importDefault) || function (mod) {
12
+ return (mod && mod.__esModule) ? mod : { "default": mod };
13
+ };
14
+ Object.defineProperty(exports, "__esModule", { value: true });
15
+ const axios_1 = __importDefault(require("axios"));
16
+ const axiosInstance_1 = __importDefault(require("../config/axiosInstance"));
17
+ const conversion_1 = require("../utils/conversion");
18
+ /**
19
+ * Creates a new product with a one-time payment.
20
+ *
21
+ * This function takes the product data, converts it to snake_case,
22
+ * and sends it to the API to create a new one-time payment product.
23
+ * It returns the created product's details.
24
+ *
25
+ * @param {CreateProductRequest} productData - The product details for the one-time payment.
26
+ * @returns {Promise<CreateProductResponse>} The response containing product details.
27
+ * @throws {ErrorResponse} Throws an error if the product creation fails.
28
+ */
29
+ const createProduct = (productData) => __awaiter(void 0, void 0, void 0, function* () {
30
+ try {
31
+ const productDataInSnakeCase = (0, conversion_1.toSnakeCase)(productData);
32
+ const response = yield axiosInstance_1.default.post('/products/', productDataInSnakeCase);
33
+ return (0, conversion_1.toCamelCase)(response.data); // Return the created product's details
34
+ }
35
+ catch (error) {
36
+ // Handle errors via the centralized error handler
37
+ throw handleAxiosError(error);
38
+ }
39
+ });
40
+ /**
41
+ * Retrieves details of a specific product by its ID.
42
+ *
43
+ * This function fetches details of an existing product by making a GET request
44
+ * to the API using the provided product ID. It returns the product's details.
45
+ *
46
+ * @param {string} productId - The ID of the product to retrieve.
47
+ * @returns {Promise<GetProductResponse>} The response containing the product details.
48
+ * @throws {ErrorResponse} Throws an error if the product retrieval fails.
49
+ */
50
+ const getProduct = (productId) => __awaiter(void 0, void 0, void 0, function* () {
51
+ try {
52
+ const response = yield axiosInstance_1.default.get(`/products/${productId}`);
53
+ return (0, conversion_1.toCamelCase)(response.data);
54
+ }
55
+ catch (error) {
56
+ throw handleAxiosError(error); // Handle errors via the centralized error handler
57
+ }
58
+ });
59
+ /**
60
+ * Retrieves a list of all products.
61
+ *
62
+ * This function fetches a paginated list of products from the API.
63
+ * By default, it retrieves the 10 most recent products, but pagination
64
+ * can be controlled using query parameters.
65
+ *
66
+ * @param {number} [page=1] - The page number to retrieve, defaults to the first page.
67
+ * @returns {Promise<GetAllProductsResponse>} The response containing an array of product details.
68
+ * @throws {ErrorResponse} Throws an error if the product retrieval fails.
69
+ */
70
+ const getAllProducts = (...args_1) => __awaiter(void 0, [...args_1], void 0, function* (page = 1) {
71
+ try {
72
+ const response = yield axiosInstance_1.default.get(`/products?page=${page}`);
73
+ return (0, conversion_1.toCamelCase)(response.data);
74
+ }
75
+ catch (error) {
76
+ throw handleAxiosError(error); // Handle errors via the centralized error handler
77
+ }
78
+ });
79
+ /**
80
+ * Updates an existing product by its ID.
81
+ *
82
+ * This function takes the product ID and an object containing the updated product details.
83
+ * It sends a PATCH request to the API to update the specified product. You can also
84
+ * modify product prices or delete them by passing the _destroy parameter in prices_attributes.
85
+ *
86
+ * @param {string} productId - The ID of the product to update.
87
+ * @param {UpdateProductRequest} productData - The updated product details.
88
+ * @returns {Promise<GetProductResponse>} A promise that resolves with the updated product's details.
89
+ * @throws {ErrorResponse} Throws an error if the product update fails.
90
+ */
91
+ const updateProduct = (productId, productData) => __awaiter(void 0, void 0, void 0, function* () {
92
+ try {
93
+ const productDataInSnakeCase = (0, conversion_1.toSnakeCase)(productData);
94
+ const response = yield axiosInstance_1.default.patch(`/products/${productId}`, productDataInSnakeCase);
95
+ return (0, conversion_1.toCamelCase)(response.data); // Return the updated product's details
96
+ }
97
+ catch (error) {
98
+ throw handleAxiosError(error); // Handle errors via the centralized error handler
99
+ }
100
+ });
101
+ /**
102
+ * Creates a new subscription for a product.
103
+ *
104
+ * This function takes a product's subscription data, converts it to snake_case,
105
+ * and sends it to the API to create a new subscription. It returns the created
106
+ * subscription's details.
107
+ *
108
+ * @param {ProductSubscription} productData - The subscription details for the product.
109
+ * @returns {Promise<CreateSubscriptionResponse>} The response containing subscription details.
110
+ * @throws {ErrorResponse} Throws an error if the subscription creation fails.
111
+ */
112
+ const createSubscription = (productData) => __awaiter(void 0, void 0, void 0, function* () {
113
+ try {
114
+ const productDataInSnakeCase = (0, conversion_1.toSnakeCase)(productData);
115
+ const response = yield axiosInstance_1.default.post('/products/', productDataInSnakeCase);
116
+ return (0, conversion_1.toCamelCase)(response.data); // Return the success response only
117
+ }
118
+ catch (error) {
119
+ // Throw an error to handle it in a higher-level function or component
120
+ throw handleAxiosError(error);
121
+ }
122
+ });
123
+ /**
124
+ * Cancels an existing subscription by its ID.
125
+ *
126
+ * This function sends a request to cancel the subscription specified by the
127
+ * subscription ID. It returns a message indicating the success of the operation.
128
+ *
129
+ * @param {string} subscriptionId - The ID of the subscription to cancel.
130
+ * @returns {Promise<{message: string}>} A message indicating whether the subscription was canceled successfully.
131
+ * @throws {ErrorResponse} Throws an error if the cancellation fails.
132
+ */
133
+ const cancelSubscription = (subscriptionId) => __awaiter(void 0, void 0, void 0, function* () {
134
+ try {
135
+ const response = yield axiosInstance_1.default.delete(`/subscriptions/${subscriptionId}`);
136
+ return {
137
+ message: `Subscription canceled successfully. Status: ${response.status}`,
138
+ };
139
+ }
140
+ catch (error) {
141
+ throw handleAxiosError(error);
142
+ }
143
+ });
144
+ /**
145
+ * Deletes a product by its ID.
146
+ *
147
+ * This function deletes a product from the system using the product ID. It
148
+ * returns a message indicating whether the product was deleted successfully.
149
+ *
150
+ * @param {string} productId - The ID of the product to delete.
151
+ * @returns {Promise<{message: string}>} A message indicating whether the product was deleted successfully.
152
+ * @throws {ErrorResponse} Throws an error if the deletion fails.
153
+ */
154
+ const deleteProduct = (productId) => __awaiter(void 0, void 0, void 0, function* () {
155
+ try {
156
+ yield axiosInstance_1.default.delete(`/products/${productId}`);
157
+ return { message: 'Product deleted successfully' };
158
+ }
159
+ catch (error) {
160
+ throw handleAxiosError(error);
161
+ }
162
+ });
163
+ /**
164
+ * Retrieves details of a specific subscription by its ID.
165
+ *
166
+ * This function fetches details of an existing subscription by making a GET request
167
+ * using the subscription ID.
168
+ *
169
+ * @param {string} subscriptionId - The ID of the subscription to retrieve.
170
+ * @returns {Promise<SubscriptionStatusResponse>} The details of the subscription.
171
+ * @throws {ErrorResponse} Throws an error if the retrieval fails.
172
+ */
173
+ const getSubscription = (subscriptionId) => __awaiter(void 0, void 0, void 0, function* () {
174
+ try {
175
+ const response = yield axiosInstance_1.default.get(`/subscriptions/${subscriptionId}`);
176
+ return (0, conversion_1.toCamelCase)(response.data);
177
+ }
178
+ catch (error) {
179
+ throw handleAxiosError(error);
180
+ }
181
+ });
182
+ /**
183
+ * Centralized error handler for Axios requests.
184
+ *
185
+ * This function checks if the error is from Axios and extracts meaningful
186
+ * information from the response or throws a general error message if the error
187
+ * is not from Axios.
188
+ *
189
+ * @param {unknown} error - The error object caught during an API request.
190
+ * @returns {ErrorResponse} An object containing error details such as status and message.
191
+ */
192
+ function handleAxiosError(error) {
193
+ if (axios_1.default.isAxiosError(error)) {
194
+ if (error.response && error.response.data) {
195
+ return {
196
+ status: 'error',
197
+ message: error.response.data.message || 'An error occurred',
198
+ errors: error.response.data.errors || {},
199
+ };
200
+ }
201
+ return {
202
+ status: 'error',
203
+ message: error.message || 'Unknown Axios error occurred',
204
+ };
205
+ }
206
+ else {
207
+ return {
208
+ status: 'error',
209
+ message: 'An unknown error occurred',
210
+ };
211
+ }
212
+ }
213
+ /**
214
+ * Makes a GET request to the '/test' endpoint.
215
+ *
216
+ * This function is not exported and is intended for internal use.
217
+ *
218
+ * @returns {Promise<{message: string}>} A message indicating success or failure of the request.
219
+ * @throws {ErrorResponse} Throws an error if the request fails.
220
+ */
221
+ const test = () => __awaiter(void 0, void 0, void 0, function* () {
222
+ try {
223
+ const response = yield axiosInstance_1.default.get('/test');
224
+ return {
225
+ message: `Test request succeeded. Status: ${response.data.message}`,
226
+ };
227
+ }
228
+ catch (error) {
229
+ throw handleAxiosError(error);
230
+ }
231
+ });
232
+ /**
233
+ * Recurrente API utility for managing product subscriptions, cancellations, and product deletions.
234
+ *
235
+ * The `recurrente` object provides methods to create, cancel, retrieve, and delete subscriptions and products,
236
+ * making it easy to integrate Recurrente's payment services into your project.
237
+ *
238
+ * @namespace recurrente
239
+ * @property {Function} test - Test endpoint.
240
+ * @property {Function} createProduct - Creates a new product with a one-time payment.
241
+ * @property {Function} getProduct - Retrieves details of a specific product by its ID.
242
+ * @property {Function} getAllProducts - Retrieves a paginated list of all products.
243
+ * @property {Function} updateProduct - Updates an existing product by its ID.
244
+ * @property {Function} deleteProduct - Deletes a product by its ID.
245
+ * @property {Function} createSubscription - Creates a new subscription for a product.
246
+ * @property {Function} cancelSubscription - Cancels an existing subscription by its ID.
247
+ * @property {Function} getSubscription - Retrieves details of a specific subscription by its ID.
248
+ */
249
+ const recurrente = {
250
+ /**
251
+ * Makes a GET request to the '/test' endpoint.
252
+ *
253
+ * **FOR DEVELOPMENT PURPOSES ONLY TO TEST**
254
+ *
255
+ * This method is included for testing internal API functionality.
256
+ *
257
+ * @function
258
+ * @memberof recurrente
259
+ * @returns {Promise<{message: string}>} A message indicating the success or failure of the request.
260
+ * @throws {ErrorResponse} Throws an error if the request fails.
261
+ */
262
+ test,
263
+ /**
264
+ * Creates a new product with a one-time payment.
265
+ *
266
+ * This function takes the product data, converts it to snake_case,
267
+ * and sends it to the API to create a one-time payment product.
268
+ * It returns the created product's details.
269
+ *
270
+ * @function
271
+ * @memberof recurrente
272
+ * @see createProduct
273
+ * @param {CreateProductRequest} productData - The details of the product to create.
274
+ * @returns {Promise<CreateProductResponse>} A promise that resolves with the created product's details.
275
+ * @throws {ErrorResponse} Throws an error if the product creation fails.
276
+ */
277
+ createProduct,
278
+ /**
279
+ * Retrieves details of a specific product by its ID.
280
+ *
281
+ * This function fetches details of an existing product by making a GET request
282
+ * using the product ID.
283
+ *
284
+ * @function
285
+ * @memberof recurrente
286
+ * @see getProduct
287
+ * @param {string} productId - The ID of the product to retrieve.
288
+ * @returns {Promise<GetProductResponse>} The details of the product.
289
+ * @throws {ErrorResponse} Throws an error if the retrieval fails.
290
+ */
291
+ getProduct,
292
+ /**
293
+ * Retrieves a paginated list of all products.
294
+ *
295
+ * This function fetches a list of products from the API. By default, it retrieves
296
+ * the 10 most recent products, but pagination can be controlled using query parameters.
297
+ *
298
+ * @function
299
+ * @memberof recurrente
300
+ * @see getAllProducts
301
+ * @param {number} [page=1] - The page number to retrieve, defaults to the first page.
302
+ * @returns {Promise<GetAllProductsResponse>} A promise that resolves with an array of product details.
303
+ * @throws {ErrorResponse} Throws an error if the product retrieval fails.
304
+ */
305
+ getAllProducts,
306
+ /**
307
+ * Updates an existing product by its ID.
308
+ *
309
+ * This function takes the product ID and an object containing the updated product details.
310
+ * It sends a PATCH request to the API to update the specified product. You can also
311
+ * modify product prices or delete them by passing the _destroy parameter in prices_attributes.
312
+ *
313
+ * @function
314
+ * @memberof recurrente
315
+ * @see updateProduct
316
+ * @param {string} productId - The ID of the product to update.
317
+ * @param {UpdateProductRequest} productData - The updated product details.
318
+ * @returns {Promise<GetProductResponse>} A promise that resolves with the updated product's details.
319
+ * @throws {ErrorResponse} Throws an error if the product update fails.
320
+ */
321
+ updateProduct,
322
+ /**
323
+ * Deletes a product by its ID.
324
+ *
325
+ * @function
326
+ * @memberof recurrente
327
+ * @see deleteProduct
328
+ */
329
+ deleteProduct,
330
+ /**
331
+ * Creates a new subscription for a product.
332
+ *
333
+ * @function
334
+ * @memberof recurrente
335
+ * @see createSubscription
336
+ */
337
+ createSubscription,
338
+ /**
339
+ * Cancels an existing subscription by its ID.
340
+ *
341
+ * @function
342
+ * @memberof recurrente
343
+ * @see cancelSubscription
344
+ */
345
+ cancelSubscription,
346
+ /**
347
+ * Retrieves details of a specific subscription by its ID.
348
+ *
349
+ * @function
350
+ * @memberof recurrente
351
+ * @see getSubscription
352
+ */
353
+ getSubscription,
354
+ };
355
+ exports.default = recurrente;
@@ -0,0 +1,3 @@
1
+ import { AxiosInstance } from 'axios';
2
+ declare const client: AxiosInstance;
3
+ export default client;