fintoc 1.1.2 → 1.2.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.
Files changed (188) hide show
  1. package/README.md +75 -296
  2. package/build/main/index.d.ts +3 -0
  3. package/build/main/index.js +13 -2
  4. package/build/main/interfaces/client/constructorOptions.d.ts +1 -0
  5. package/build/main/interfaces/client/index.js +6 -2
  6. package/build/main/interfaces/client/requestOptions.d.ts +1 -0
  7. package/build/main/interfaces/mixins/index.js +6 -2
  8. package/build/main/interfaces/paginator/index.js +6 -2
  9. package/build/main/interfaces/paginator/paginationOptions.d.ts +1 -0
  10. package/build/main/lib/client.d.ts +6 -1
  11. package/build/main/lib/client.js +50 -24
  12. package/build/main/lib/core.d.ts +18 -2
  13. package/build/main/lib/core.js +23 -6
  14. package/build/main/lib/errors.d.ts +2 -0
  15. package/build/main/lib/errors.js +5 -2
  16. package/build/main/lib/jws.d.ts +25 -0
  17. package/build/main/lib/jws.js +130 -0
  18. package/build/main/lib/managers/accountsManager.d.ts +4 -0
  19. package/build/main/lib/managers/accountsManager.js +7 -2
  20. package/build/main/lib/managers/index.js +6 -2
  21. package/build/main/lib/managers/invoicesManager.js +2 -2
  22. package/build/main/lib/managers/linksManager.js +2 -2
  23. package/build/main/lib/managers/movementsManager.js +2 -2
  24. package/build/main/lib/managers/paymentIntentsManager.js +2 -2
  25. package/build/main/lib/managers/refreshIntentsManager.js +2 -2
  26. package/build/main/lib/managers/subscriptionsManager.js +2 -2
  27. package/build/main/lib/managers/taxReturnsManager.js +2 -2
  28. package/build/main/lib/managers/v2/accountNumbersManager.d.ts +6 -0
  29. package/build/main/lib/managers/v2/accountNumbersManager.js +10 -0
  30. package/build/main/lib/managers/v2/accountsManager.d.ts +6 -0
  31. package/build/main/lib/managers/v2/accountsManager.js +10 -0
  32. package/build/main/lib/managers/v2/index.d.ts +4 -0
  33. package/build/main/lib/managers/v2/index.js +21 -0
  34. package/build/main/lib/managers/v2/simulateManager.d.ts +8 -0
  35. package/build/main/lib/managers/v2/simulateManager.js +15 -0
  36. package/build/main/lib/managers/v2/transfersManager.d.ts +6 -0
  37. package/build/main/lib/managers/v2/transfersManager.js +10 -0
  38. package/build/main/lib/managers/webhookEndpointsManager.js +2 -2
  39. package/build/main/lib/mixins/index.js +6 -2
  40. package/build/main/lib/mixins/managerMixin.d.ts +21 -6
  41. package/build/main/lib/mixins/managerMixin.js +35 -19
  42. package/build/main/lib/mixins/resourceMixin.js +10 -11
  43. package/build/main/lib/paginator.d.ts +1 -1
  44. package/build/main/lib/paginator.js +16 -13
  45. package/build/main/lib/resourceHandlers.d.ts +1 -1
  46. package/build/main/lib/resourceHandlers.js +15 -14
  47. package/build/main/lib/resources/account.d.ts +4 -0
  48. package/build/main/lib/resources/account.js +7 -2
  49. package/build/main/lib/resources/link.d.ts +20 -0
  50. package/build/main/lib/resources/link.js +31 -6
  51. package/build/main/lib/resources/v2/account.d.ts +3 -0
  52. package/build/main/lib/resources/v2/account.js +8 -0
  53. package/build/main/lib/resources/v2/accountNumber.d.ts +3 -0
  54. package/build/main/lib/resources/v2/accountNumber.js +8 -0
  55. package/build/main/lib/resources/v2/index.d.ts +3 -0
  56. package/build/main/lib/resources/v2/index.js +20 -0
  57. package/build/main/lib/resources/v2/transfer.d.ts +3 -0
  58. package/build/main/lib/resources/v2/transfer.js +8 -0
  59. package/build/main/lib/utils.d.ts +3 -3
  60. package/build/main/lib/utils.js +36 -23
  61. package/build/main/lib/version.js +1 -1
  62. package/build/main/lib/webhook.d.ts +17 -0
  63. package/build/main/lib/webhook.js +109 -0
  64. package/build/main/spec/client/creationFunctionality.spec.js +11 -11
  65. package/build/main/spec/client/requestFunctionality.spec.js +36 -11
  66. package/build/main/spec/core.spec.js +2 -2
  67. package/build/main/spec/integration.spec.d.ts +1 -0
  68. package/build/main/spec/integration.spec.js +587 -0
  69. package/build/main/spec/jws.spec.d.ts +1 -0
  70. package/build/main/spec/jws.spec.js +185 -0
  71. package/build/main/spec/managers/linkManagers.spec.js +5 -5
  72. package/build/main/spec/mixins/managerMixin/creation.spec.js +9 -9
  73. package/build/main/spec/mixins/managerMixin/handlers.spec.js +10 -14
  74. package/build/main/spec/mixins/managerMixin/methods.spec.js +10 -10
  75. package/build/main/spec/mixins/managerMixin/mocks/complexMockManager.d.ts +1 -1
  76. package/build/main/spec/mixins/managerMixin/mocks/complexMockManager.js +4 -4
  77. package/build/main/spec/mixins/managerMixin/mocks/emptyMockManager.js +2 -2
  78. package/build/main/spec/mixins/resourceMixin/creation.spec.js +6 -6
  79. package/build/main/spec/mixins/resourceMixin/methods.spec.js +7 -7
  80. package/build/main/spec/mixins/resourceMixin/serialization.spec.js +5 -5
  81. package/build/main/spec/mocks/client/axiosInstance.js +6 -5
  82. package/build/main/spec/mocks/client/response.d.ts +3 -0
  83. package/build/main/spec/mocks/client/response.js +8 -3
  84. package/build/main/spec/mocks/initializers.d.ts +1 -1
  85. package/build/main/spec/mocks/initializers.js +4 -5
  86. package/build/main/spec/paginator/paginate.spec.js +7 -7
  87. package/build/main/spec/paginator/parseLink.spec.js +13 -13
  88. package/build/main/spec/paginator/parseLinkHeaders.spec.js +8 -8
  89. package/build/main/spec/paginator/request.spec.js +10 -8
  90. package/build/main/spec/resources/account.spec.js +2 -2
  91. package/build/main/spec/resources/link.spec.js +6 -6
  92. package/build/main/spec/shared/utils.js +3 -4
  93. package/build/main/spec/utils/canRaiseHTTPError.spec.js +4 -4
  94. package/build/main/spec/utils/getErrorClass.spec.js +5 -5
  95. package/build/main/spec/utils/getResourceClass.spec.js +13 -13
  96. package/build/main/spec/utils/isISODate.spec.js +5 -5
  97. package/build/main/spec/utils/objetize.spec.js +14 -14
  98. package/build/main/spec/utils/objetizeGenerator.spec.js +6 -6
  99. package/build/main/spec/utils/serialize.spec.js +14 -14
  100. package/build/main/spec/utils/shared/getGenerator.js +2 -3
  101. package/build/main/spec/utils/singularize.spec.js +7 -7
  102. package/build/main/spec/utils/snakeToPascal.spec.js +7 -7
  103. package/build/main/spec/webhook.spec.d.ts +1 -0
  104. package/build/main/spec/webhook.spec.js +120 -0
  105. package/build/main/types/genericFunction.d.ts +1 -1
  106. package/build/main/types/index.js +6 -2
  107. package/build/main/types/resourceArguments.d.ts +1 -1
  108. package/build/module/index.d.ts +3 -0
  109. package/build/module/index.js +4 -1
  110. package/build/module/interfaces/client/constructorOptions.d.ts +1 -0
  111. package/build/module/interfaces/client/requestOptions.d.ts +1 -0
  112. package/build/module/interfaces/paginator/paginationOptions.d.ts +1 -0
  113. package/build/module/lib/client.d.ts +6 -1
  114. package/build/module/lib/client.js +41 -14
  115. package/build/module/lib/core.d.ts +18 -2
  116. package/build/module/lib/core.js +35 -8
  117. package/build/module/lib/errors.d.ts +2 -0
  118. package/build/module/lib/errors.js +3 -1
  119. package/build/module/lib/jws.d.ts +25 -0
  120. package/build/module/lib/jws.js +94 -0
  121. package/build/module/lib/managers/accountsManager.d.ts +4 -0
  122. package/build/module/lib/managers/accountsManager.js +8 -2
  123. package/build/module/lib/managers/invoicesManager.js +2 -2
  124. package/build/module/lib/managers/linksManager.js +2 -2
  125. package/build/module/lib/managers/movementsManager.js +2 -2
  126. package/build/module/lib/managers/paymentIntentsManager.js +2 -2
  127. package/build/module/lib/managers/refreshIntentsManager.js +2 -2
  128. package/build/module/lib/managers/subscriptionsManager.js +2 -2
  129. package/build/module/lib/managers/taxReturnsManager.js +2 -2
  130. package/build/module/lib/managers/v2/accountNumbersManager.d.ts +6 -0
  131. package/build/module/lib/managers/v2/accountNumbersManager.js +6 -0
  132. package/build/module/lib/managers/v2/accountsManager.d.ts +6 -0
  133. package/build/module/lib/managers/v2/accountsManager.js +6 -0
  134. package/build/module/lib/managers/v2/index.d.ts +4 -0
  135. package/build/module/lib/managers/v2/index.js +5 -0
  136. package/build/module/lib/managers/v2/simulateManager.d.ts +8 -0
  137. package/build/module/lib/managers/v2/simulateManager.js +11 -0
  138. package/build/module/lib/managers/v2/transfersManager.d.ts +6 -0
  139. package/build/module/lib/managers/v2/transfersManager.js +6 -0
  140. package/build/module/lib/managers/webhookEndpointsManager.js +2 -2
  141. package/build/module/lib/mixins/managerMixin.d.ts +21 -6
  142. package/build/module/lib/mixins/managerMixin.js +32 -16
  143. package/build/module/lib/mixins/resourceMixin.js +2 -3
  144. package/build/module/lib/paginator.d.ts +1 -1
  145. package/build/module/lib/paginator.js +12 -8
  146. package/build/module/lib/resourceHandlers.d.ts +1 -1
  147. package/build/module/lib/resourceHandlers.js +5 -3
  148. package/build/module/lib/resources/account.d.ts +4 -0
  149. package/build/module/lib/resources/account.js +7 -2
  150. package/build/module/lib/resources/link.d.ts +20 -0
  151. package/build/module/lib/resources/link.js +31 -6
  152. package/build/module/lib/resources/v2/account.d.ts +3 -0
  153. package/build/module/lib/resources/v2/account.js +4 -0
  154. package/build/module/lib/resources/v2/accountNumber.d.ts +3 -0
  155. package/build/module/lib/resources/v2/accountNumber.js +4 -0
  156. package/build/module/lib/resources/v2/index.d.ts +3 -0
  157. package/build/module/lib/resources/v2/index.js +4 -0
  158. package/build/module/lib/resources/v2/transfer.d.ts +3 -0
  159. package/build/module/lib/resources/v2/transfer.js +4 -0
  160. package/build/module/lib/utils.d.ts +3 -3
  161. package/build/module/lib/utils.js +1 -1
  162. package/build/module/lib/version.js +1 -1
  163. package/build/module/lib/webhook.d.ts +17 -0
  164. package/build/module/lib/webhook.js +72 -0
  165. package/build/module/spec/client/creationFunctionality.spec.js +6 -6
  166. package/build/module/spec/client/requestFunctionality.spec.js +26 -1
  167. package/build/module/spec/integration.spec.d.ts +1 -0
  168. package/build/module/spec/integration.spec.js +582 -0
  169. package/build/module/spec/jws.spec.d.ts +1 -0
  170. package/build/module/spec/jws.spec.js +147 -0
  171. package/build/module/spec/mixins/managerMixin/handlers.spec.js +6 -10
  172. package/build/module/spec/mixins/managerMixin/methods.spec.js +1 -1
  173. package/build/module/spec/mixins/managerMixin/mocks/complexMockManager.d.ts +1 -1
  174. package/build/module/spec/mixins/managerMixin/mocks/complexMockManager.js +4 -4
  175. package/build/module/spec/mixins/managerMixin/mocks/emptyMockManager.js +2 -2
  176. package/build/module/spec/mocks/client/axiosInstance.js +4 -3
  177. package/build/module/spec/mocks/client/response.d.ts +3 -0
  178. package/build/module/spec/mocks/client/response.js +9 -3
  179. package/build/module/spec/mocks/initializers.d.ts +1 -1
  180. package/build/module/spec/paginator/paginate.spec.js +2 -2
  181. package/build/module/spec/paginator/request.spec.js +6 -4
  182. package/build/module/spec/utils/objetizeGenerator.spec.js +1 -1
  183. package/build/module/spec/utils/shared/getGenerator.js +1 -1
  184. package/build/module/spec/webhook.spec.d.ts +1 -0
  185. package/build/module/spec/webhook.spec.js +115 -0
  186. package/build/module/types/genericFunction.d.ts +1 -1
  187. package/build/module/types/resourceArguments.d.ts +1 -1
  188. package/package.json +7 -7
package/README.md CHANGED
@@ -20,13 +20,20 @@
20
20
  </a>
21
21
  </p>
22
22
 
23
- ## Why?
24
-
25
- You can think of [Fintoc API](https://fintoc.com/docs) as a piscola.
26
- And the key ingredient to a properly made piscola are the ice cubes.
27
- Sure, you can still have a [piscola without ice cubes](https://curl.haxx.se/).
28
- But hey… that’s not enjoyable -- why would you do that?
29
- Do yourself a favor: go grab some ice cubes by installing this refreshing library.
23
+ ## Table of Contents
24
+ - [Installation](#installation)
25
+ - [Usage](#usage)
26
+ - [Quickstart](#quickstart)
27
+ - [Calling endpoints](#calling-endpoints)
28
+ - [list](#list)
29
+ - [get](#get)
30
+ - [create](#create)
31
+ - [update](#update)
32
+ - [delete](#delete)
33
+ - [Webhook Signature Validation](#webhook-signature-validation)
34
+ - [Idempotency Keys](#idempotency-keys)
35
+ - [Serialization](#serialization)
36
+ - [Acknowledgements](#acknowledgements)
30
37
 
31
38
  ## Installation
32
39
 
@@ -48,32 +55,42 @@ The idea behind this SDK is to stick to the API design as much as possible, so t
48
55
 
49
56
  ### Quickstart
50
57
 
51
- To be able to use this SDK, you first need to have a [Fintoc](https://app.fintoc.com/login) account. You will need to get your secret API key from the dashboard to be able to use the SDK. Once you have your API key, all you need to do is initialize a `Fintoc` object with it and you're ready to start enjoying Fintoc!
58
+ To be able to use this SDK, you first need to get your secret API Key from the [Fintoc Dashboard](https://dashboard.fintoc.com/login). Once you have your API key, all you need to do is initialize a `Fintoc` object with it and you're ready to start enjoying Fintoc!
52
59
 
53
60
  ```javascript
54
61
  import { Fintoc } from 'fintoc';
55
62
 
56
63
  const fintocClient = new Fintoc('your_api_key');
64
+
65
+ // List all succeeded payment intents since the beginning of 2025
66
+ const paymentIntents = await fintocClient.paymentIntents.list({ since: '2025-01-01' });
67
+ for await (const pi of paymentIntents) {
68
+ console.log(pi.created_at, pi.amount, pi.status);
69
+ }
70
+
71
+ // Get a specific payment intent
72
+ const paymentIntent = await fintocClient.paymentIntents.get('pi_12312312');
73
+ console.log(paymentIntent.created_at, paymentIntent.amount, paymentIntent.status);
57
74
  ```
58
75
 
59
- Now you can start using the SDK!
76
+ ### Calling endpoints
60
77
 
61
- ### Managers
78
+ The SDK provides direct access to Fintoc API resources following the API structure. Simply use the resource name and follow it by the appropriate action you want.
62
79
 
63
- To make the usage of the SDK feel natural, resources are managed by **managers** (_wow_). These **managers** correspond to objects with some methods that allow you to get the resources that you want. Each manager is _attached_ to another resource, following the API structure. For example, the `Fintoc` object has `links` and `webhookEndpoints` managers, while `Link` objects have an `accounts` manager (we will see more examples soon). Notice that **not every manager has all of the methods**, as they correspond to the API capabilities. The methods of the managers are the following (we will use the `webhookEndpoints` manager as an example):
80
+ Notice that **not every resource has all of the methods**, as they correspond to the API capabilities.
64
81
 
65
- #### `all`
82
+ #### `list`
66
83
 
67
- You can use the `all` method of the managers as follows:
84
+ You can use the `list` method to list all the instances of the resource:
68
85
 
69
86
  ```javascript
70
- const webhookEndpoints = await fintocClient.webhookEndpoints.all();
87
+ const webhookEndpoints = await fintocClient.webhookEndpoints.list();
71
88
  ```
72
89
 
73
- The `all` method of the managers returns **an async generator** with all the instances of the resource. This method can also receive an `options` object! The arguments that can be passed are the arguments that the API receives for that specific resource! For example, the `Movement` resource can be filtered using `since` and `until`, so if you wanted to get a range of `movements` from an `account`, all you need to do is to pass the parameters to the method!
90
+ The `list` method returns an **async generator** with all the instances of the resource. This method can also receive the arguments that the API receives for that specific resource. For example, the `PaymentIntent` resource can be filtered using `since` and `until`, so if you wanted to get a range of `payment intents`, all you need to do is to pass the parameters to the method:
74
91
 
75
92
  ```javascript
76
- const movements = await account.movements.all({
93
+ const paymentIntents = await fintocClient.paymentIntents.list({
77
94
  since: '2019-07-24',
78
95
  until: '2021-05-12',
79
96
  });
@@ -82,42 +99,35 @@ const movements = await account.movements.all({
82
99
  Notice that, in order to iterate over the async generator, you need to `await` the generator itself **and then** each of the instances:
83
100
 
84
101
  ```javascript
85
- const movements = await account.movements.all();
86
-
87
- for await (const movement of movements) {
88
- console.log(movement.id);
89
- }
90
- ```
91
-
92
- Or you can abbreviate it a bit:
102
+ const paymentIntents = await fintocClient.paymentIntents.list({
103
+ since: '2019-07-24',
104
+ until: '2021-05-12',
105
+ });
93
106
 
94
- ```javascript
95
- for await (const movement of await account.movements.all()) {
96
- console.log(movement.id);
107
+ for await (const paymentIntent of paymentIntents) {
108
+ console.log(paymentIntent.id);
97
109
  }
98
110
  ```
99
111
 
100
112
  You can also pass the `lazy: false` parameter to the method to force the SDK to return a list of all the instances of the resource instead of the generator. **Beware**: this could take **very long**, depending on the amount of instances that exist of said resource:
101
113
 
102
114
  ```javascript
103
- const webhookEndpoints = await fintocClient.webhookEndpoints.all({ lazy: false });
115
+ const paymentIntents = await fintocClient.paymentIntents.list({ lazy: false });
104
116
 
105
- Array.isArray(webhookEndpoints); // true
117
+ Array.isArray(paymentIntents); // true
106
118
  ```
107
119
 
108
120
  #### `get`
109
121
 
110
- You can use the `get` method of the managers as follows:
122
+ You can use the `get` method to get a specific instance of the resource:
111
123
 
112
124
  ```javascript
113
- const webhookEndpoint = await fintocClient.webhookEndpoints.get('we_8anqVLlBC8ROodem');
125
+ const paymentIntent = await fintocClient.paymentIntents.get('pi_8anqVLlBC8ROodem');
114
126
  ```
115
127
 
116
- The `get` method of the managers returns an existing instance of the resource using its identifier to find it.
117
-
118
128
  #### `create`
119
129
 
120
- You can use the `create` method of the managers as follows:
130
+ You can use the `create` method to create an instance of the resource:
121
131
 
122
132
  ```javascript
123
133
  const webhookEndpoint = await fintocClient.webhookEndpoints.create({
@@ -131,7 +141,7 @@ The `create` method of the managers creates and returns a new instance of the re
131
141
 
132
142
  #### `update`
133
143
 
134
- You can use the `update` method of the managers as follows:
144
+ You can use the `update` method to update an instance of the resource:
135
145
 
136
146
  ```javascript
137
147
  const webhookEndpoint = await fintocClient.webhookEndpoints.update(
@@ -145,32 +155,9 @@ const webhookEndpoint = await fintocClient.webhookEndpoints.update(
145
155
 
146
156
  The `update` method of the managers updates and returns an existing instance of the resource using its identifier to find it. The first parameter of the method corresponds to the identifier being used to find the existing instance of the resource. The attributes to be modified are passed as an `options` object, and correspond to the parameters specified by the API documentation for the update action of said resource.
147
157
 
148
- Notice that using the manager to update an instance of a resource is equivalent (in terms of outcome) to calling the `update` directly on the object itself:
149
-
150
-
151
- ```javascript
152
- // Using the manager
153
- const webhookEndpoint = await fintocClient.webhookEndpoints.update(
154
- 'we_8anqVLlBC8ROodem',
155
- {
156
- enabled_events: ['account.refresh_intent.succeeded'],
157
- disabled: true,
158
- },
159
- );
160
-
161
- // Using the object
162
- const webhookEndpoint = await fintocClient.webhookEndpoints.get('we_8anqVLlBC8ROodem');
163
- webhookEndpoint.update({
164
- enabled_events: ['account.refresh_intent.succeeded'],
165
- disabled: true,
166
- });
167
- ```
168
-
169
- When using the SDK, you will probably almost always want to use the object directly to update, just because it is way less verbose if you already have the object itself. Also, using the `update` method from the manager first needs to `get` the resource and then updates it, so it translates to 2 API calls. If you already have the object to update, using the `update` method directly from the object just updates it, so it translates to just 1 API call.
170
-
171
158
  #### `delete`
172
159
 
173
- You can use the `delete` method of the managers as follows:
160
+ You can use the `delete` method to delete an instance of the resource:
174
161
 
175
162
  ```javascript
176
163
  const deletedIdentifier = await fintocClient.webhookEndpoints.delete('we_8anqVLlBC8ROodem');
@@ -178,254 +165,46 @@ const deletedIdentifier = await fintocClient.webhookEndpoints.delete('we_8anqVLl
178
165
 
179
166
  The `delete` method of the managers deletes an existing instance of the resource using its identifier to find it and returns the identifier.
180
167
 
181
- Notice that using the manager to delete an instance of a resource is equivalent (in terms of outcome) to calling the `delete` directly on the object itself:
182
-
183
-
184
- ```javascript
185
- // Using the manager
186
- const deletedIdentifier = await fintocClient.webhookEndpoints.delete('we_8anqVLlBC8ROodem');
187
-
188
- // Using the object
189
- const webhookEndpoint = await fintocClient.webhookEndpoints.get('we_8anqVLlBC8ROodem');
190
- const deletedIdentifier = await webhookEndpoint.delete();
191
- ```
192
-
193
- When using the SDK, you will probably almost always want to use the object directly to delete, just because it is way less verbose if you already have the object itself. Also, using the `delete` method from the manager first needs to `get` the resource and then deletes it, so it translates to 2 API calls. If you already have the object to delete, using the `delete` method directly from the object just deletes it, so it translates to just 1 API call.
194
-
195
- ### The shape of the SDK
196
-
197
- For complete information about the API, head to [the docs](https://fintoc.com/docs). You will notice that the shape of the SDK is very similar to the shape of the API. Let's start with the `Fintoc` object.
198
-
199
- #### The `Fintoc` object
200
-
201
- To create a `Fintoc` object, instantiate it using your secret API key:
202
-
203
- ```javascript
204
- import { Fintoc } from 'fintoc';
205
-
206
- const fintocClient = new Fintoc('your_api_key');
207
- ```
208
-
209
- This gives us access to a bunch of operations already. The object created using this _snippet_ contains three [managers](#managers): `links`, `paymentIntents` and `webhookEndpoints`.
210
-
211
- #### The `webhookEndpoints` manager
212
-
213
- Available methods: `all`, `get`, `create`, `update`, `delete`.
214
-
215
- From the Fintoc client, you can manage your webhook endpoints swiftly! Start by creating a new Webhook Endpoint!
216
-
217
- ```javascript
218
- const webhookEndpoint = await fintocClient.webhookEndpoints.create({
219
- url: 'https://webhook.site/58gfb429-c33c-20c7-584b-d5ew3y3202a0',
220
- enabled_events: ['account.refresh_intent.succeeded'],
221
- disabled: true,
222
- });
223
-
224
- console.log(webhookEndpoint.id); // we_8anqVLlBC8ROodem
225
- ```
226
-
227
- You can update this webhook endpoint any time you want! Just run the following command:
228
-
229
- ```javascript
230
- const webhookEndpoint = await fintocClient.webhookEndpoints.update(
231
- 'we_8anqVLlBC8ROodem',
232
- {
233
- enabled_events: ['link.credentials_changed'],
234
- description: 'Fantasting webhook endpoint',
235
- },
236
- );
237
-
238
- console.log(webhookEndpoint.status); // disabled
239
- ```
240
-
241
- Maybe you no longer want this webhook endpoint. Let's delete it!
242
-
243
- ```javascript
244
- fintocClient.webhookEndpoints.delete('we_8anqVLlBC8ROodem');
245
- ```
246
-
247
- Now, let's list every webhook endpoint we have:
248
-
249
- ```javascript
250
- for await (const webhookEndpoint of await fintocClient.webhookEndpoints.all()) {
251
- console.log(webhookEndpoint.id);
252
- }
253
- ```
254
-
255
- If you see a webhook endpoint you want to use, just use the `get` method!
256
-
257
- ```javascript
258
- const webhookEndpoint = await fintocClient.webhookEndpoints.get('we_8anqVLlBC8ROodem');
259
-
260
- console.log(webhookEndpoint.id); // we_8anqVLlBC8ROodem
261
- ```
262
-
263
- #### The `paymentIntents` manager
264
-
265
- Available methods: `all`, `get`, `create`.
168
+ ### Webhook Signature Validation
266
169
 
267
- Payment intents allow you to start a payment using Fintoc! Start by creating a new payment intent:
170
+ To ensure the authenticity of incoming webhooks from Fintoc, you should always validate the signature. The SDK provides a `WebhookSignature` class to verify the `Fintoc-Signature` header
268
171
 
269
172
  ```javascript
270
- const paymentIntent = await fintocClient.paymentIntents.create({
271
- currency: 'CLP',
272
- amount: 5990,
273
- recipient_account: {
274
- holder_id: '111111111',
275
- number: '123123123',
276
- type: 'checking_account',
277
- institution_id: 'cl_banco_de_chile',
278
- },
279
- });
280
-
281
- console.log(paymentIntent.id); // pi_BO381oEATXonG6bj
282
- console.log(paymentIntent.widget_token); // pi_BO381oEATXonG6bj_sec_a4xK32BanKWYn
173
+ WebhookSignature.verifyHeader(
174
+ req.body,
175
+ req.headers['fintoc-signature'],
176
+ 'your_webhook_secret'
177
+ )
283
178
  ```
284
179
 
285
- Notice that the success of this payment intent will be notified through a Webhook. Now, let's list every payment intent we have:
180
+ The `verifyHeader` method takes the following parameters:
181
+ - `payload`: The raw request body as a string
182
+ - `header`: The Fintoc-Signature header value
183
+ - `secret`: Your webhook secret key (found in your Fintoc dashboard)
184
+ - `tolerance`: Number of seconds to tolerate when checking timestamp (default: 300)
286
185
 
287
- ```javascript
288
- for await (const paymentIntent of await fintocClient.paymentIntents.all()) {
289
- console.log(paymentIntent.id);
290
- }
291
- ```
186
+ If the signature is invalid or the timestamp is outside the tolerance window, a `WebhookSignatureError` will be raised with a descriptive message.
292
187
 
293
- If you see a payment intent you want to use, just use the `get` method!
294
188
 
295
- ```javascript
296
- const paymentIntent = fintocClient.paymentIntents.get('pi_BO381oEATXonG6bj')
189
+ For a complete example of handling webhooks, see [examples/webhook.js](examples/webhook.js).
297
190
 
298
- console.log(paymentIntent.id) // pi_BO381oEATXonG6bj
299
- console.log(paymentIntent.status) // succeeded
300
- ```
191
+ ### Idempotency Keys
301
192
 
302
- #### The `links` manager
303
-
304
- Available methods: `all`, `get`, `update`, `delete`.
305
-
306
- Links are probably the most importat resource. Let's list them!
307
-
308
- ```javascript
309
- console.log((await fintocClient.links.all({ lazy: false })).length); // 3
310
-
311
- for await (const link of await fintocClient.links.all()) {
312
- console.log(link.id);
313
- }
314
- ```
315
-
316
- Links are a bit different than the rest of the resources, because their identifier is not really their `id`, but their `link_token`. This means that, in order to `get`, `update` or `delete` a link, you need to pass the `link_token`, not the `link_id`!
193
+ You can provide an [Idempotency Key](https://docs.fintoc.com/reference/idempotent-requests) using the `idempotency_key` argument. For example:
317
194
 
318
195
  ```javascript
319
- const link = await fintocClient.links.get('link_Y75EXAKiIVj7w489_token_NCqjwRVoTX3cmnx8pnbpqd11');
320
- ```
321
-
322
- Notice that the Link objects generated from the `all` method will won't be able to execute `update` or `delete` operations, while any Link object generated from `get` or `update` will have permission to `update` or `delete` (given that the link token is necessary to `get` or `update` in the first place).
323
-
324
- The Link resource has a lot of **managers**!
325
-
326
- ```javascript
327
- const invoices = await link.invoices.all(); // Invoices
328
- const taxReturns = await link.taxReturns.all(); // Tax Returns
329
- const subscriptions = await link.subscriptions.all(); // Subscriptions
330
- const refreshIntents = await link.refreshIntents.all(); // Refresh Intents
331
- const accounts = await link.accounts.all(); // Accounts
332
- ```
333
-
334
- #### The `invoices` manager
335
-
336
- Available methods: `all`.
337
-
338
- Once you have a Link, you can use the `invoices` manager to get all the invoices associated to a link!
339
-
340
- ```javascript
341
- for await (const invoice of await link.invoices.all()) {
342
- console.log(invoice.id);
343
- }
344
- ```
345
-
346
- #### The `taxReturns` manager
347
-
348
- Available methods: `all`, `get`.
349
-
350
- Once you have a Link, you can use the `taxReturns` manager to get all the tax returns associated to a link!
351
-
352
- ```javascript
353
- for await (const taxReturn of await link.taxReturns.all()) {
354
- console.log(taxReturn.id);
355
- }
356
- ```
357
-
358
- #### The `subscriptions` manager
359
-
360
- Available methods: `all`, `get`.
361
-
362
- Once you have a Link, you can use the `subscriptions` manager to get all the subscriptions associated to a link!
363
-
364
- ```javascript
365
- for await (const subscription of await link.subscriptions.all()) {
366
- console.log(subscription.id);
367
- }
368
- ```
369
-
370
- #### The `refreshIntents` manager
371
-
372
- Available methods: `all`, `get`, `create`.
373
-
374
- Refresh intents allow you to control how an account gets refreshed on Fintoc! Once you have a Link, you can use the `refreshIntents` manager to create a new refresh intent:
375
-
376
- ```javascript
377
- const refreshIntent = await link.refreshIntents.create();
378
-
379
- console.log(refreshIntent.id); // ri_5A94DVCJ7xNM3MEo
380
- ```
381
-
382
- Notice that the success of this refresh intent will be notified through a Webhook. Now, let's list every refresh intent we have:
383
-
384
- ```javascript
385
- for await (const refreshIntent of await link.refreshIntents.all()) {
386
- console.log(refreshIntent.id);
387
- }
388
- ```
389
-
390
- If you see a refresh intent you want to use, just use the `get` method!
391
-
392
- ```javascript
393
- const refreshIntent = await link.refreshIntents.get('ri_5A94DVCJ7xNM3MEo');
394
-
395
- console.log(refreshIntent.id); // ri_5A94DVCJ7xNM3MEo
396
- console.log(refreshIntent.status); // succeeded
397
- ```
398
-
399
- #### The `accounts` manager
400
-
401
- Available methods: `all`, `get`.
402
-
403
- Once you have a Link, you can use the `accounts` manager to get all the accounts associated to a link!
404
-
405
- ```javascript
406
- for await (const account of await link.accounts.all()) {
407
- console.log(account.id);
408
- }
409
- ```
410
-
411
- Notice that accounts also have a `movements` manager, to get all of the movements of an account:
412
-
413
- ```javascript
414
- const account = (await link.accounts.all({ lazy: false }))[0];
415
-
416
- const movements = await account.movements.all({ lazy: false });
417
- ```
418
-
419
- #### The `movements` manager
420
-
421
- Available methods: `all`, `get`.
422
-
423
- Once you have an Account, you can use the `movements` manager to get all the movements associated to that account!
424
-
425
- ```javascript
426
- for await (const movement of await account.movements.all()) {
427
- console.log(movement.id);
428
- }
196
+ const transfer = await fintoc.v2.transfers.create({
197
+ idempotency_key: '12345678',
198
+ amount: 54123,
199
+ currency: 'mxn',
200
+ account_id: 'acc_12345678',
201
+ counterparty: {
202
+ account_number: '012969100000000026',
203
+ },
204
+ metadata: {
205
+ customer_id: '19385014'
206
+ }
207
+ });
429
208
  ```
430
209
 
431
210
  ### Serialization
@@ -433,7 +212,7 @@ for await (const movement of await account.movements.all()) {
433
212
  Any resource of the SDK can be serialized! To get the serialized resource, just call the `serialize` method!
434
213
 
435
214
  ```javascript
436
- const account = (await link.accounts.all({ lazy: false }))[0];
215
+ const account = (await link.accounts.list({ lazy: false }))[0];
437
216
 
438
217
  const serialization = account.serialize();
439
218
  ```
@@ -1 +1,4 @@
1
1
  export * from './lib/core';
2
+ export { WebhookSignature } from './lib/webhook';
3
+ export { WebhookSignatureError } from './lib/errors';
4
+ export { JWSSignature } from './lib/jws';
@@ -1,7 +1,11 @@
1
1
  "use strict";
2
2
  var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
3
  if (k2 === undefined) k2 = k;
4
- Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[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);
5
9
  }) : (function(o, m, k, k2) {
6
10
  if (k2 === undefined) k2 = k;
7
11
  o[k2] = m[k];
@@ -10,5 +14,12 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
10
14
  for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
11
15
  };
12
16
  Object.defineProperty(exports, "__esModule", { value: true });
17
+ exports.JWSSignature = exports.WebhookSignatureError = exports.WebhookSignature = void 0;
13
18
  __exportStar(require("./lib/core"), exports);
14
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvaW5kZXgudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7O0FBQUEsNkNBQTJCIn0=
19
+ var webhook_1 = require("./lib/webhook");
20
+ Object.defineProperty(exports, "WebhookSignature", { enumerable: true, get: function () { return webhook_1.WebhookSignature; } });
21
+ var errors_1 = require("./lib/errors");
22
+ Object.defineProperty(exports, "WebhookSignatureError", { enumerable: true, get: function () { return errors_1.WebhookSignatureError; } });
23
+ var jws_1 = require("./lib/jws");
24
+ Object.defineProperty(exports, "JWSSignature", { enumerable: true, get: function () { return jws_1.JWSSignature; } });
25
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvaW5kZXgudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7Ozs7Ozs7QUFBQSw2Q0FBMkI7QUFDM0IseUNBQWlEO0FBQXhDLDJHQUFBLGdCQUFnQixPQUFBO0FBQ3pCLHVDQUFxRDtBQUE1QywrR0FBQSxxQkFBcUIsT0FBQTtBQUM5QixpQ0FBeUM7QUFBaEMsbUdBQUEsWUFBWSxPQUFBIn0=
@@ -3,4 +3,5 @@ export interface IConstructorOptions {
3
3
  apiKey: string;
4
4
  userAgent: string;
5
5
  params?: Record<string, string>;
6
+ jwsPrivateKey?: string | Buffer;
6
7
  }
@@ -1,7 +1,11 @@
1
1
  "use strict";
2
2
  var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
3
  if (k2 === undefined) k2 = k;
4
- Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[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);
5
9
  }) : (function(o, m, k, k2) {
6
10
  if (k2 === undefined) k2 = k;
7
11
  o[k2] = m[k];
@@ -11,4 +15,4 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
11
15
  };
12
16
  Object.defineProperty(exports, "__esModule", { value: true });
13
17
  __exportStar(require("./constructorOptions"), exports);
14
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9zcmMvaW50ZXJmYWNlcy9jbGllbnQvaW5kZXgudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7O0FBQUEsdURBQXFDIn0=
18
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9zcmMvaW50ZXJmYWNlcy9jbGllbnQvaW5kZXgudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7Ozs7OztBQUFBLHVEQUFxQyJ9
@@ -5,4 +5,5 @@ export interface IRequestOptions {
5
5
  method?: Method;
6
6
  params?: Record<string, any>;
7
7
  json?: Record<string, string>;
8
+ idempotencyKey?: string;
8
9
  }
@@ -1,7 +1,11 @@
1
1
  "use strict";
2
2
  var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
3
  if (k2 === undefined) k2 = k;
4
- Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[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);
5
9
  }) : (function(o, m, k, k2) {
6
10
  if (k2 === undefined) k2 = k;
7
11
  o[k2] = m[k];
@@ -13,4 +17,4 @@ Object.defineProperty(exports, "__esModule", { value: true });
13
17
  __exportStar(require("./managerMixinConstructor"), exports);
14
18
  __exportStar(require("./resourceMixin"), exports);
15
19
  __exportStar(require("./resourceMixinConstructor"), exports);
16
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9zcmMvaW50ZXJmYWNlcy9taXhpbnMvaW5kZXgudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7O0FBQUEsNERBQTBDO0FBQzFDLGtEQUFnQztBQUNoQyw2REFBMkMifQ==
20
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9zcmMvaW50ZXJmYWNlcy9taXhpbnMvaW5kZXgudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7Ozs7OztBQUFBLDREQUEwQztBQUMxQyxrREFBZ0M7QUFDaEMsNkRBQTJDIn0=
@@ -1,7 +1,11 @@
1
1
  "use strict";
2
2
  var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
3
  if (k2 === undefined) k2 = k;
4
- Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[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);
5
9
  }) : (function(o, m, k, k2) {
6
10
  if (k2 === undefined) k2 = k;
7
11
  o[k2] = m[k];
@@ -11,4 +15,4 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
11
15
  };
12
16
  Object.defineProperty(exports, "__esModule", { value: true });
13
17
  __exportStar(require("./paginationOptions"), exports);
14
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9zcmMvaW50ZXJmYWNlcy9wYWdpbmF0b3IvaW5kZXgudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7O0FBQUEsc0RBQW9DIn0=
18
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9zcmMvaW50ZXJmYWNlcy9wYWdpbmF0b3IvaW5kZXgudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7Ozs7OztBQUFBLHNEQUFvQyJ9
@@ -2,5 +2,6 @@ import { AxiosInstance } from 'axios';
2
2
  export interface IPaginationOptions {
3
3
  client: AxiosInstance;
4
4
  path: string;
5
+ headers: Record<string, string>;
5
6
  params?: Record<string, string>;
6
7
  }
@@ -1,17 +1,20 @@
1
1
  import { IConstructorOptions } from '../interfaces/client';
2
2
  import { IExtendOptions } from '../interfaces/client/extensionOptions';
3
3
  import { IRequestOptions } from '../interfaces/client/requestOptions';
4
+ import { JWSSignature } from './jws';
4
5
  export declare class Client {
5
6
  #private;
6
7
  baseUrl: string;
7
8
  apiKey: string;
8
9
  userAgent: string;
9
10
  params: Record<string, any>;
11
+ jws?: JWSSignature;
10
12
  constructor(options: IConstructorOptions);
11
13
  private get client();
12
- get headers(): {
14
+ get staticHeaders(): {
13
15
  Authorization: string;
14
16
  'User-Agent': string;
17
+ 'Content-Type': string;
15
18
  };
16
19
  request(options: IRequestOptions & {
17
20
  paginated: false;
@@ -21,4 +24,6 @@ export declare class Client {
21
24
  }): Promise<AsyncGenerator<Record<string, string>, void, unknown>>;
22
25
  request(options: IRequestOptions): Promise<Record<string, string>>;
23
26
  extend(extension?: IExtendOptions): Client;
27
+ private buildHeaders;
28
+ private buildJWSHeaders;
24
29
  }