@rkfl/transact-server 2.1.0-alpha.2 → 2.1.0-alpha.4
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/README.md +346 -346
- package/dist/index.js +1 -1
- package/dist/payouts/constants.d.ts +7 -0
- package/dist/payouts/fiat.d.ts +13 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,347 +1,347 @@
|
|
|
1
|
-
# Rocketfuel SDK (Node.js)
|
|
2
|
-
|
|
3
|
-
A secure and minimal Node.js SDK to interact with Rocketfuel payment APIs. (This SDK is for Node.js server-side usage.)
|
|
4
|
-
|
|
5
|
-
## Installation
|
|
6
|
-
|
|
7
|
-
```bash
|
|
8
|
-
npm i @rkfl/transact-server
|
|
9
|
-
```
|
|
10
|
-
## Documentation
|
|
11
|
-
Click here for more detailed [Documentation](https://docs.rocketfuel.inc/plug-ins-and-sdks/javascript-js/rocketfuel-sdk-nodejs)
|
|
12
|
-
## Usage
|
|
13
|
-
|
|
14
|
-
### Create order
|
|
15
|
-
|
|
16
|
-
```ts
|
|
17
|
-
import { Rocketfuel } from '@rocketfuel/plugin';
|
|
18
|
-
|
|
19
|
-
const client = new Rocketfuel({
|
|
20
|
-
clientId: 'YOUR_ID',
|
|
21
|
-
clientSecret: 'YOUR_SECRET',
|
|
22
|
-
merchantId: 'YOUR_MERCHANT_ID',
|
|
23
|
-
domain: 'production' // or 'sandbox'
|
|
24
|
-
});
|
|
25
|
-
|
|
26
|
-
const orderData = {
|
|
27
|
-
amount: "10",
|
|
28
|
-
currency: "USD",
|
|
29
|
-
cart: [
|
|
30
|
-
{
|
|
31
|
-
id: "iphone_14_pro_max",
|
|
32
|
-
name: "iPhone 14 Pro Max",
|
|
33
|
-
price: "10",
|
|
34
|
-
quantity: 1
|
|
35
|
-
}
|
|
36
|
-
],
|
|
37
|
-
customerInfo: {
|
|
38
|
-
name: "John Doe",
|
|
39
|
-
email: "john.doe@example.com"
|
|
40
|
-
},
|
|
41
|
-
customParameter: {
|
|
42
|
-
returnMethod: "GET",
|
|
43
|
-
params: [
|
|
44
|
-
{
|
|
45
|
-
name: "submerchant",
|
|
46
|
-
value: "mobilesale"
|
|
47
|
-
}
|
|
48
|
-
]
|
|
49
|
-
},
|
|
50
|
-
merchant_id: '14ec584d-53af-476d-aacd-2b7f025cf21b'
|
|
51
|
-
};
|
|
52
|
-
|
|
53
|
-
const result = await client.createOrder(orderData);
|
|
54
|
-
|
|
55
|
-
```
|
|
56
|
-
|
|
57
|
-
### Transaction Lookup
|
|
58
|
-
To check or confirm the transaction status using order id or Rocketfuel provided transaction id
|
|
59
|
-
|
|
60
|
-
```
|
|
61
|
-
|
|
62
|
-
async function checkTransaction(txId) {
|
|
63
|
-
try {
|
|
64
|
-
const result = await client.transactionLookup(txId, 'ORDERID');
|
|
65
|
-
console.log('Transaction Details:', result);
|
|
66
|
-
// Process the transaction details as needed
|
|
67
|
-
} catch (error) {
|
|
68
|
-
console.error('Error fetching transaction details:', error.message);
|
|
69
|
-
}
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
// Example call:
|
|
73
|
-
checkTransaction('12345ABC');
|
|
74
|
-
```
|
|
75
|
-
|
|
76
|
-
### Webook Verification
|
|
77
|
-
Use this function to verify that a webhook is valid and trusted before processing its contents. It prevents spoofed requests, data tampering, and unauthorized events.
|
|
78
|
-
This function returns true if the signature is valid, otherwise false.
|
|
79
|
-
|
|
80
|
-
```ts
|
|
81
|
-
function handleWebhook(req, res) {
|
|
82
|
-
const isValid = client.verifyWebhookSignature(req.body);
|
|
83
|
-
|
|
84
|
-
if (!isValid) {
|
|
85
|
-
console.warn('Webhook signature verification failed');
|
|
86
|
-
return res.status(403).send('Invalid signature');
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
const payload = JSON.parse(req.body.data.data);
|
|
90
|
-
console.log('Verified Webhook Payload:', payload);
|
|
91
|
-
|
|
92
|
-
// Process your payload
|
|
93
|
-
res.status(200).send('Webhook received');
|
|
94
|
-
}
|
|
95
|
-
```
|
|
96
|
-
|
|
97
|
-
## Payouts SDK (Fiat, Crypto & Admin)
|
|
98
|
-
|
|
99
|
-
The payouts SDK lets you invite payees, manage KYC, allocate/administer balances, and send fiat or crypto payouts using a single high-level client.
|
|
100
|
-
|
|
101
|
-
### Payout client setup
|
|
102
|
-
|
|
103
|
-
```ts
|
|
104
|
-
import { RocketfuelPayouts } from '@rkfl/transact-server';
|
|
105
|
-
|
|
106
|
-
const payouts = new RocketfuelPayouts({
|
|
107
|
-
clientId: 'YOUR_ID',
|
|
108
|
-
clientSecret: 'YOUR_SECRET',
|
|
109
|
-
merchantId: 'YOUR_MERCHANT_ID',
|
|
110
|
-
environment: 'sandbox', // 'production' | 'qa' | 'preprod' | 'sandbox'
|
|
111
|
-
});
|
|
112
|
-
```
|
|
113
|
-
|
|
114
|
-
The `RocketfuelPayouts` client exposes three scoped clients:
|
|
115
|
-
|
|
116
|
-
- **Fiat payouts**: `payouts.fiat`
|
|
117
|
-
- **Crypto payouts**: `payouts.crypto`
|
|
118
|
-
- **Admin operations**: `payouts.admin`
|
|
119
|
-
|
|
120
|
-
### Fiat payouts (bank payouts)
|
|
121
|
-
|
|
122
|
-
```ts
|
|
123
|
-
// Get bank configuration for a payee
|
|
124
|
-
const bankConfig = await payouts.fiat.getBankConfiguration({
|
|
125
|
-
payeeId: 'payee-id',
|
|
126
|
-
country: 'US',
|
|
127
|
-
currency: 'USD',
|
|
128
|
-
});
|
|
129
|
-
|
|
130
|
-
// Save/update bank details
|
|
131
|
-
await payouts.fiat.saveBankDetails('payee-id', {
|
|
132
|
-
currency: 'USD',
|
|
133
|
-
country: 'US',
|
|
134
|
-
// ...bank fields as required by bankConfig
|
|
135
|
-
});
|
|
136
|
-
|
|
137
|
-
// Get transfer fee quote
|
|
138
|
-
const feeQuote = await payouts.fiat.getTransferFee(
|
|
139
|
-
{ payeeId: 'payee-id', country: 'US', currency: 'USD' },
|
|
140
|
-
{
|
|
141
|
-
amount: '100.00',
|
|
142
|
-
currency: 'USD',
|
|
143
|
-
country: 'US',
|
|
144
|
-
},
|
|
145
|
-
);
|
|
146
|
-
|
|
147
|
-
// Send a fiat transfer
|
|
148
|
-
const transferResult = await payouts.fiat.transfer(
|
|
149
|
-
{ payeeId: 'payee-id', country: 'US', currency: 'USD' },
|
|
150
|
-
{
|
|
151
|
-
amount: '100.00',
|
|
152
|
-
currency: 'USD',
|
|
153
|
-
country: 'US',
|
|
154
|
-
// ...bank detail reference / additional payload
|
|
155
|
-
},
|
|
156
|
-
);
|
|
157
|
-
|
|
158
|
-
// Check transfer status (fiat or generic payout)
|
|
159
|
-
const status = await payouts.fiat.getTransferStatus('order-id', 'payee-id');
|
|
160
|
-
```
|
|
161
|
-
|
|
162
|
-
### Crypto payouts
|
|
163
|
-
|
|
164
|
-
```ts
|
|
165
|
-
// Get payout currencies available for a payee
|
|
166
|
-
const currencies = await payouts.crypto.getCurrencies('payee-id');
|
|
167
|
-
|
|
168
|
-
// Optionally check address risk/compliance
|
|
169
|
-
await payouts.crypto.checkAddress({
|
|
170
|
-
address: '0x...',
|
|
171
|
-
chain: 'ETH',
|
|
172
|
-
// ...other KYT fields
|
|
173
|
-
});
|
|
174
|
-
|
|
175
|
-
// Get crypto transfer fee quote
|
|
176
|
-
const cryptoFee = await payouts.crypto.getTransferFee('payee-id', {
|
|
177
|
-
amount: '10',
|
|
178
|
-
currency: 'ETH',
|
|
179
|
-
chain: 'ETH',
|
|
180
|
-
});
|
|
181
|
-
|
|
182
|
-
// Prepare/validate transfer
|
|
183
|
-
const check = await payouts.crypto.checkTransfer('payee-id', {
|
|
184
|
-
amount: '10',
|
|
185
|
-
currency: 'ETH',
|
|
186
|
-
chain: 'ETH',
|
|
187
|
-
toAddress: '0x...',
|
|
188
|
-
});
|
|
189
|
-
|
|
190
|
-
// Execute crypto transfer
|
|
191
|
-
const tx = await payouts.crypto.transfer('payee-id', {
|
|
192
|
-
amount: '10',
|
|
193
|
-
currency: 'ETH',
|
|
194
|
-
chain: 'ETH',
|
|
195
|
-
toAddress: '0x...',
|
|
196
|
-
});
|
|
197
|
-
|
|
198
|
-
// Check transfer status (crypto or generic payout)
|
|
199
|
-
const cryptoStatus = await payouts.crypto.getTransferStatus('order-id', 'payee-id');
|
|
200
|
-
```
|
|
201
|
-
|
|
202
|
-
### Payout admin operations
|
|
203
|
-
|
|
204
|
-
```ts
|
|
205
|
-
// Invite a new payee
|
|
206
|
-
const newPayee = await payouts.admin.invitePayee({
|
|
207
|
-
email: 'user@example.com',
|
|
208
|
-
// ...other payee fields
|
|
209
|
-
});
|
|
210
|
-
|
|
211
|
-
// Submit KYC for a payee
|
|
212
|
-
await payouts.admin.submitPayeeKyc({
|
|
213
|
-
payeeId: newPayee.id,
|
|
214
|
-
// ...KYC payload
|
|
215
|
-
});
|
|
216
|
-
|
|
217
|
-
// Get a payee's internal balance
|
|
218
|
-
const payeeBalance = await payouts.admin.getPayeeBalance('payee-id');
|
|
219
|
-
|
|
220
|
-
// Get overall payout admin balance and running balance
|
|
221
|
-
const adminBalance = await payouts.admin.getBalance();
|
|
222
|
-
const runningBalance = await payouts.admin.getRunningBalance();
|
|
223
|
-
|
|
224
|
-
// Create an allocation transfer
|
|
225
|
-
const allocation = await payouts.admin.createTransferAllocation({
|
|
226
|
-
payeeId: 'payee-id',
|
|
227
|
-
amount: '100.00',
|
|
228
|
-
currency: 'USD',
|
|
229
|
-
// ...other allocation fields
|
|
230
|
-
});
|
|
231
|
-
|
|
232
|
-
// Confirm / allocate a transfer
|
|
233
|
-
await payouts.admin.allocateTransfer(allocation.id, {
|
|
234
|
-
action: 'CONFIRM', // or other allocation actions supported by backend
|
|
235
|
-
});
|
|
236
|
-
```
|
|
237
|
-
|
|
238
|
-
### Payout webhook verification & events
|
|
239
|
-
|
|
240
|
-
Use the payout webhook helper to validate webhook signatures and use typed event names:
|
|
241
|
-
|
|
242
|
-
```ts
|
|
243
|
-
import {
|
|
244
|
-
PayoutWebhookVerifier,
|
|
245
|
-
PAYOUT_WEBHOOK_EVENT_TYPE,
|
|
246
|
-
PAYOUT_WEBHOOK_EVENTS,
|
|
247
|
-
} from '@rkfl/transact-server';
|
|
248
|
-
|
|
249
|
-
function handlePayoutWebhook(req, res) {
|
|
250
|
-
const isValid = PayoutWebhookVerifier.verify(req.body);
|
|
251
|
-
|
|
252
|
-
if (!isValid) {
|
|
253
|
-
console.warn('Payout webhook signature verification failed');
|
|
254
|
-
return res.status(403).send('Invalid signature');
|
|
255
|
-
}
|
|
256
|
-
|
|
257
|
-
// Top-level event metadata
|
|
258
|
-
const { event, notificationType, timestamp } = req.body;
|
|
259
|
-
|
|
260
|
-
// Canonical payload string signed by Rocketfuel
|
|
261
|
-
const payload = JSON.parse(req.body.data);
|
|
262
|
-
|
|
263
|
-
if (event === PAYOUT_WEBHOOK_EVENTS.PayoutStatusChange) {
|
|
264
|
-
// handle payout status change
|
|
265
|
-
}
|
|
266
|
-
|
|
267
|
-
return res.status(200).send('OK');
|
|
268
|
-
}
|
|
269
|
-
```
|
|
270
|
-
|
|
271
|
-
## 📦 NPM Commands Documentation
|
|
272
|
-
### 1. npm:login
|
|
273
|
-
|
|
274
|
-
Logs you into your npm account from the terminal.
|
|
275
|
-
You’ll be prompted for your npm username, password, and email.
|
|
276
|
-
```
|
|
277
|
-
npm run npm:login
|
|
278
|
-
```
|
|
279
|
-
Use this before your first publish or if you’re logged out.
|
|
280
|
-
|
|
281
|
-
### 2. npm:publish
|
|
282
|
-
Publishes the current package to npm with public access.
|
|
283
|
-
The package name and version must be unique on npm.
|
|
284
|
-
```
|
|
285
|
-
npm run npm:publish
|
|
286
|
-
```
|
|
287
|
-
|
|
288
|
-
### 3. npm:patch
|
|
289
|
-
Increments the patch version (last digit) in package.json by +1.
|
|
290
|
-
Used for bug fixes or small improvements.
|
|
291
|
-
```
|
|
292
|
-
npm run npm:patch
|
|
293
|
-
```
|
|
294
|
-
Example Version Change:
|
|
295
|
-
```
|
|
296
|
-
1.0.9 → 1.0.10
|
|
297
|
-
1.0.10 → 1.0.11
|
|
298
|
-
```
|
|
299
|
-
### 4. npm:minor
|
|
300
|
-
Increments the minor version (middle digit) by +1 and resets patch to 0.
|
|
301
|
-
Used for adding new features without breaking compatibility.
|
|
302
|
-
```
|
|
303
|
-
npm run npm:minor
|
|
304
|
-
```
|
|
305
|
-
Example Version Change:
|
|
306
|
-
```
|
|
307
|
-
1.0.5 → 1.1.0
|
|
308
|
-
1.2.7 → 1.3.0
|
|
309
|
-
```
|
|
310
|
-
### 5. npm:major
|
|
311
|
-
Increments the major version (first digit) by +1 and resets minor and patch to 0.
|
|
312
|
-
Used for breaking changes or major redesigns.
|
|
313
|
-
```
|
|
314
|
-
npm run npm:major
|
|
315
|
-
```
|
|
316
|
-
Example Version Change:
|
|
317
|
-
```
|
|
318
|
-
1.4.8 → 2.0.0
|
|
319
|
-
2.1.3 → 3.0.0
|
|
320
|
-
```
|
|
321
|
-
## 🚀 Recommended Workflow
|
|
322
|
-
### Login once:
|
|
323
|
-
```
|
|
324
|
-
npm run npm:login
|
|
325
|
-
```
|
|
326
|
-
Make changes to your code.
|
|
327
|
-
|
|
328
|
-
### Bump version:
|
|
329
|
-
```
|
|
330
|
-
npm run npm:patch
|
|
331
|
-
```
|
|
332
|
-
Minor:
|
|
333
|
-
|
|
334
|
-
```
|
|
335
|
-
npm run npm:minor
|
|
336
|
-
```
|
|
337
|
-
Major:
|
|
338
|
-
```
|
|
339
|
-
npm run npm:major
|
|
340
|
-
```
|
|
341
|
-
|
|
342
|
-
### Publish:
|
|
343
|
-
```
|
|
344
|
-
npm run npm:publish
|
|
345
|
-
```
|
|
346
|
-
## 📄 License
|
|
1
|
+
# Rocketfuel SDK (Node.js)
|
|
2
|
+
|
|
3
|
+
A secure and minimal Node.js SDK to interact with Rocketfuel payment APIs. (This SDK is for Node.js server-side usage.)
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm i @rkfl/transact-server
|
|
9
|
+
```
|
|
10
|
+
## Documentation
|
|
11
|
+
Click here for more detailed [Documentation](https://docs.rocketfuel.inc/plug-ins-and-sdks/javascript-js/rocketfuel-sdk-nodejs)
|
|
12
|
+
## Usage
|
|
13
|
+
|
|
14
|
+
### Create order
|
|
15
|
+
|
|
16
|
+
```ts
|
|
17
|
+
import { Rocketfuel } from '@rocketfuel/plugin';
|
|
18
|
+
|
|
19
|
+
const client = new Rocketfuel({
|
|
20
|
+
clientId: 'YOUR_ID',
|
|
21
|
+
clientSecret: 'YOUR_SECRET',
|
|
22
|
+
merchantId: 'YOUR_MERCHANT_ID',
|
|
23
|
+
domain: 'production' // or 'sandbox'
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
const orderData = {
|
|
27
|
+
amount: "10",
|
|
28
|
+
currency: "USD",
|
|
29
|
+
cart: [
|
|
30
|
+
{
|
|
31
|
+
id: "iphone_14_pro_max",
|
|
32
|
+
name: "iPhone 14 Pro Max",
|
|
33
|
+
price: "10",
|
|
34
|
+
quantity: 1
|
|
35
|
+
}
|
|
36
|
+
],
|
|
37
|
+
customerInfo: {
|
|
38
|
+
name: "John Doe",
|
|
39
|
+
email: "john.doe@example.com"
|
|
40
|
+
},
|
|
41
|
+
customParameter: {
|
|
42
|
+
returnMethod: "GET",
|
|
43
|
+
params: [
|
|
44
|
+
{
|
|
45
|
+
name: "submerchant",
|
|
46
|
+
value: "mobilesale"
|
|
47
|
+
}
|
|
48
|
+
]
|
|
49
|
+
},
|
|
50
|
+
merchant_id: '14ec584d-53af-476d-aacd-2b7f025cf21b'
|
|
51
|
+
};
|
|
52
|
+
|
|
53
|
+
const result = await client.createOrder(orderData);
|
|
54
|
+
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
### Transaction Lookup
|
|
58
|
+
To check or confirm the transaction status using order id or Rocketfuel provided transaction id
|
|
59
|
+
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
async function checkTransaction(txId) {
|
|
63
|
+
try {
|
|
64
|
+
const result = await client.transactionLookup(txId, 'ORDERID');
|
|
65
|
+
console.log('Transaction Details:', result);
|
|
66
|
+
// Process the transaction details as needed
|
|
67
|
+
} catch (error) {
|
|
68
|
+
console.error('Error fetching transaction details:', error.message);
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
// Example call:
|
|
73
|
+
checkTransaction('12345ABC');
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
### Webook Verification
|
|
77
|
+
Use this function to verify that a webhook is valid and trusted before processing its contents. It prevents spoofed requests, data tampering, and unauthorized events.
|
|
78
|
+
This function returns true if the signature is valid, otherwise false.
|
|
79
|
+
|
|
80
|
+
```ts
|
|
81
|
+
function handleWebhook(req, res) {
|
|
82
|
+
const isValid = client.verifyWebhookSignature(req.body);
|
|
83
|
+
|
|
84
|
+
if (!isValid) {
|
|
85
|
+
console.warn('Webhook signature verification failed');
|
|
86
|
+
return res.status(403).send('Invalid signature');
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
const payload = JSON.parse(req.body.data.data);
|
|
90
|
+
console.log('Verified Webhook Payload:', payload);
|
|
91
|
+
|
|
92
|
+
// Process your payload
|
|
93
|
+
res.status(200).send('Webhook received');
|
|
94
|
+
}
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
## Payouts SDK (Fiat, Crypto & Admin)
|
|
98
|
+
|
|
99
|
+
The payouts SDK lets you invite payees, manage KYC, allocate/administer balances, and send fiat or crypto payouts using a single high-level client.
|
|
100
|
+
|
|
101
|
+
### Payout client setup
|
|
102
|
+
|
|
103
|
+
```ts
|
|
104
|
+
import { RocketfuelPayouts } from '@rkfl/transact-server';
|
|
105
|
+
|
|
106
|
+
const payouts = new RocketfuelPayouts({
|
|
107
|
+
clientId: 'YOUR_ID',
|
|
108
|
+
clientSecret: 'YOUR_SECRET',
|
|
109
|
+
merchantId: 'YOUR_MERCHANT_ID',
|
|
110
|
+
environment: 'sandbox', // 'production' | 'qa' | 'preprod' | 'sandbox'
|
|
111
|
+
});
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
The `RocketfuelPayouts` client exposes three scoped clients:
|
|
115
|
+
|
|
116
|
+
- **Fiat payouts**: `payouts.fiat`
|
|
117
|
+
- **Crypto payouts**: `payouts.crypto`
|
|
118
|
+
- **Admin operations**: `payouts.admin`
|
|
119
|
+
|
|
120
|
+
### Fiat payouts (bank payouts)
|
|
121
|
+
|
|
122
|
+
```ts
|
|
123
|
+
// Get bank configuration for a payee
|
|
124
|
+
const bankConfig = await payouts.fiat.getBankConfiguration({
|
|
125
|
+
payeeId: 'payee-id',
|
|
126
|
+
country: 'US',
|
|
127
|
+
currency: 'USD',
|
|
128
|
+
});
|
|
129
|
+
|
|
130
|
+
// Save/update bank details
|
|
131
|
+
await payouts.fiat.saveBankDetails('payee-id', {
|
|
132
|
+
currency: 'USD',
|
|
133
|
+
country: 'US',
|
|
134
|
+
// ...bank fields as required by bankConfig
|
|
135
|
+
});
|
|
136
|
+
|
|
137
|
+
// Get transfer fee quote
|
|
138
|
+
const feeQuote = await payouts.fiat.getTransferFee(
|
|
139
|
+
{ payeeId: 'payee-id', country: 'US', currency: 'USD' },
|
|
140
|
+
{
|
|
141
|
+
amount: '100.00',
|
|
142
|
+
currency: 'USD',
|
|
143
|
+
country: 'US',
|
|
144
|
+
},
|
|
145
|
+
);
|
|
146
|
+
|
|
147
|
+
// Send a fiat transfer
|
|
148
|
+
const transferResult = await payouts.fiat.transfer(
|
|
149
|
+
{ payeeId: 'payee-id', country: 'US', currency: 'USD' },
|
|
150
|
+
{
|
|
151
|
+
amount: '100.00',
|
|
152
|
+
currency: 'USD',
|
|
153
|
+
country: 'US',
|
|
154
|
+
// ...bank detail reference / additional payload
|
|
155
|
+
},
|
|
156
|
+
);
|
|
157
|
+
|
|
158
|
+
// Check transfer status (fiat or generic payout)
|
|
159
|
+
const status = await payouts.fiat.getTransferStatus('order-id', 'payee-id');
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
### Crypto payouts
|
|
163
|
+
|
|
164
|
+
```ts
|
|
165
|
+
// Get payout currencies available for a payee
|
|
166
|
+
const currencies = await payouts.crypto.getCurrencies('payee-id');
|
|
167
|
+
|
|
168
|
+
// Optionally check address risk/compliance
|
|
169
|
+
await payouts.crypto.checkAddress({
|
|
170
|
+
address: '0x...',
|
|
171
|
+
chain: 'ETH',
|
|
172
|
+
// ...other KYT fields
|
|
173
|
+
});
|
|
174
|
+
|
|
175
|
+
// Get crypto transfer fee quote
|
|
176
|
+
const cryptoFee = await payouts.crypto.getTransferFee('payee-id', {
|
|
177
|
+
amount: '10',
|
|
178
|
+
currency: 'ETH',
|
|
179
|
+
chain: 'ETH',
|
|
180
|
+
});
|
|
181
|
+
|
|
182
|
+
// Prepare/validate transfer
|
|
183
|
+
const check = await payouts.crypto.checkTransfer('payee-id', {
|
|
184
|
+
amount: '10',
|
|
185
|
+
currency: 'ETH',
|
|
186
|
+
chain: 'ETH',
|
|
187
|
+
toAddress: '0x...',
|
|
188
|
+
});
|
|
189
|
+
|
|
190
|
+
// Execute crypto transfer
|
|
191
|
+
const tx = await payouts.crypto.transfer('payee-id', {
|
|
192
|
+
amount: '10',
|
|
193
|
+
currency: 'ETH',
|
|
194
|
+
chain: 'ETH',
|
|
195
|
+
toAddress: '0x...',
|
|
196
|
+
});
|
|
197
|
+
|
|
198
|
+
// Check transfer status (crypto or generic payout)
|
|
199
|
+
const cryptoStatus = await payouts.crypto.getTransferStatus('order-id', 'payee-id');
|
|
200
|
+
```
|
|
201
|
+
|
|
202
|
+
### Payout admin operations
|
|
203
|
+
|
|
204
|
+
```ts
|
|
205
|
+
// Invite a new payee
|
|
206
|
+
const newPayee = await payouts.admin.invitePayee({
|
|
207
|
+
email: 'user@example.com',
|
|
208
|
+
// ...other payee fields
|
|
209
|
+
});
|
|
210
|
+
|
|
211
|
+
// Submit KYC for a payee
|
|
212
|
+
await payouts.admin.submitPayeeKyc({
|
|
213
|
+
payeeId: newPayee.id,
|
|
214
|
+
// ...KYC payload
|
|
215
|
+
});
|
|
216
|
+
|
|
217
|
+
// Get a payee's internal balance
|
|
218
|
+
const payeeBalance = await payouts.admin.getPayeeBalance('payee-id');
|
|
219
|
+
|
|
220
|
+
// Get overall payout admin balance and running balance
|
|
221
|
+
const adminBalance = await payouts.admin.getBalance();
|
|
222
|
+
const runningBalance = await payouts.admin.getRunningBalance();
|
|
223
|
+
|
|
224
|
+
// Create an allocation transfer
|
|
225
|
+
const allocation = await payouts.admin.createTransferAllocation({
|
|
226
|
+
payeeId: 'payee-id',
|
|
227
|
+
amount: '100.00',
|
|
228
|
+
currency: 'USD',
|
|
229
|
+
// ...other allocation fields
|
|
230
|
+
});
|
|
231
|
+
|
|
232
|
+
// Confirm / allocate a transfer
|
|
233
|
+
await payouts.admin.allocateTransfer(allocation.id, {
|
|
234
|
+
action: 'CONFIRM', // or other allocation actions supported by backend
|
|
235
|
+
});
|
|
236
|
+
```
|
|
237
|
+
|
|
238
|
+
### Payout webhook verification & events
|
|
239
|
+
|
|
240
|
+
Use the payout webhook helper to validate webhook signatures and use typed event names:
|
|
241
|
+
|
|
242
|
+
```ts
|
|
243
|
+
import {
|
|
244
|
+
PayoutWebhookVerifier,
|
|
245
|
+
PAYOUT_WEBHOOK_EVENT_TYPE,
|
|
246
|
+
PAYOUT_WEBHOOK_EVENTS,
|
|
247
|
+
} from '@rkfl/transact-server';
|
|
248
|
+
|
|
249
|
+
function handlePayoutWebhook(req, res) {
|
|
250
|
+
const isValid = PayoutWebhookVerifier.verify(req.body);
|
|
251
|
+
|
|
252
|
+
if (!isValid) {
|
|
253
|
+
console.warn('Payout webhook signature verification failed');
|
|
254
|
+
return res.status(403).send('Invalid signature');
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
// Top-level event metadata
|
|
258
|
+
const { event, notificationType, timestamp } = req.body;
|
|
259
|
+
|
|
260
|
+
// Canonical payload string signed by Rocketfuel
|
|
261
|
+
const payload = JSON.parse(req.body.data);
|
|
262
|
+
|
|
263
|
+
if (event === PAYOUT_WEBHOOK_EVENTS.PayoutStatusChange) {
|
|
264
|
+
// handle payout status change
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
return res.status(200).send('OK');
|
|
268
|
+
}
|
|
269
|
+
```
|
|
270
|
+
|
|
271
|
+
## 📦 NPM Commands Documentation
|
|
272
|
+
### 1. npm:login
|
|
273
|
+
|
|
274
|
+
Logs you into your npm account from the terminal.
|
|
275
|
+
You’ll be prompted for your npm username, password, and email.
|
|
276
|
+
```
|
|
277
|
+
npm run npm:login
|
|
278
|
+
```
|
|
279
|
+
Use this before your first publish or if you’re logged out.
|
|
280
|
+
|
|
281
|
+
### 2. npm:publish
|
|
282
|
+
Publishes the current package to npm with public access.
|
|
283
|
+
The package name and version must be unique on npm.
|
|
284
|
+
```
|
|
285
|
+
npm run npm:publish
|
|
286
|
+
```
|
|
287
|
+
|
|
288
|
+
### 3. npm:patch
|
|
289
|
+
Increments the patch version (last digit) in package.json by +1.
|
|
290
|
+
Used for bug fixes or small improvements.
|
|
291
|
+
```
|
|
292
|
+
npm run npm:patch
|
|
293
|
+
```
|
|
294
|
+
Example Version Change:
|
|
295
|
+
```
|
|
296
|
+
1.0.9 → 1.0.10
|
|
297
|
+
1.0.10 → 1.0.11
|
|
298
|
+
```
|
|
299
|
+
### 4. npm:minor
|
|
300
|
+
Increments the minor version (middle digit) by +1 and resets patch to 0.
|
|
301
|
+
Used for adding new features without breaking compatibility.
|
|
302
|
+
```
|
|
303
|
+
npm run npm:minor
|
|
304
|
+
```
|
|
305
|
+
Example Version Change:
|
|
306
|
+
```
|
|
307
|
+
1.0.5 → 1.1.0
|
|
308
|
+
1.2.7 → 1.3.0
|
|
309
|
+
```
|
|
310
|
+
### 5. npm:major
|
|
311
|
+
Increments the major version (first digit) by +1 and resets minor and patch to 0.
|
|
312
|
+
Used for breaking changes or major redesigns.
|
|
313
|
+
```
|
|
314
|
+
npm run npm:major
|
|
315
|
+
```
|
|
316
|
+
Example Version Change:
|
|
317
|
+
```
|
|
318
|
+
1.4.8 → 2.0.0
|
|
319
|
+
2.1.3 → 3.0.0
|
|
320
|
+
```
|
|
321
|
+
## 🚀 Recommended Workflow
|
|
322
|
+
### Login once:
|
|
323
|
+
```
|
|
324
|
+
npm run npm:login
|
|
325
|
+
```
|
|
326
|
+
Make changes to your code.
|
|
327
|
+
|
|
328
|
+
### Bump version:
|
|
329
|
+
```
|
|
330
|
+
npm run npm:patch
|
|
331
|
+
```
|
|
332
|
+
Minor:
|
|
333
|
+
|
|
334
|
+
```
|
|
335
|
+
npm run npm:minor
|
|
336
|
+
```
|
|
337
|
+
Major:
|
|
338
|
+
```
|
|
339
|
+
npm run npm:major
|
|
340
|
+
```
|
|
341
|
+
|
|
342
|
+
### Publish:
|
|
343
|
+
```
|
|
344
|
+
npm run npm:publish
|
|
345
|
+
```
|
|
346
|
+
## 📄 License
|
|
347
347
|
MIT License © RocketFuel Blockchain, Inc.
|
package/dist/index.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import e from"crypto-js";import*as t from"crypto";const s={production:"https://app.rocketfuel.inc/api",qa:"https://qa-app.rfdemo.co/api",preprod:"https://preprod-app.rocketdemo.net/api",sandbox:"https://app-sandbox.rocketfuel.inc/api"};class a{#e;#t;#s;#a;#r=null;#n=null;constructor({clientId:e,clientSecret:t,merchantId:a,environment:r}){this.#e=e,this.#t=t,this.#s=a,this.#a=s[r||"production"]}#i(){const t=JSON.stringify({merchantId:this.#s,totop:""});return e.AES.encrypt(t,this.#t).toString()}#o(){const e={"Content-Type":"application/json"};return this.#r&&(e.Authorization=`Bearer ${this.#r}`),e}async#c(){const e={clientId:this.#e,encryptedPayload:this.#i()},t=await fetch(`${this.#a}/auth/generate-auth-token`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(e)});if(!t.ok)throw new Error(`Auth failed: ${t.status}`);const s=await t.json(),a=s?.result;if(!a?.access)throw new Error("Token missing in response");this.#r=a.access,this.#n=a.refresh}async#h(e,t,s=!0){const a=await fetch(e,t);if((401===a.status||403===a.status)&&s){await this.#c();const s={...t,headers:this.#o()};return this.#h(e,s,!1)}if(!a.ok){const e=new Error(a.statusText);throw e.status=a.status,e}return a.json()}async createOrder(e){this.#r||await this.#c();const t=await this.#h(`${this.#a}/hosted-page`,{method:"POST",headers:this.#o(),body:JSON.stringify(e)});return{uuid:t?.result?.uuid}}async transactionLookup(e,t="ORDERID"){this.#r||await this.#c();const s=await this.#h(`${this.#a}/purchase/transactionLookup`,{method:"POST",headers:this.#o(),body:JSON.stringify({txId:e,type:t})});return s?.result}async verifyAgeVerification(e){this.#r||await this.#c();const t=await this.#h(`${this.#a}/merchant/audit/${e}`,{method:"GET",headers:this.#o()});return t?.result}verifyWebhookSignature(e){try{const{data:{data:s},signature:a}=e,r=t.createVerify("RSA-SHA256");return r.update(s),r.verify("-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA2e4stIYooUrKHVQmwztC\n/l0YktX6uz4bE1iDtA2qu4OaXx+IKkwBWa0hO2mzv6dAoawyzxa2jmN01vrpMkMj\nrB+Dxmoq7tRvRTx1hXzZWaKuv37BAYosOIKjom8S8axM1j6zPkX1zpMLE8ys3dUX\nFN5Dl/kBfeCTwGRV4PZjP4a+QwgFRzZVVfnpcRI/O6zhfkdlRah8MrAPWYSoGBpG\nCPiAjUeHO/4JA5zZ6IdfZuy/DKxbcOlt9H+z14iJwB7eVUByoeCE+Bkw+QE4msKs\naIn4xl9GBoyfDZKajTzL50W/oeoE1UcuvVfaULZ9DWnHOy6idCFH1WbYDxYYIWLi\nAQIDAQAB\n-----END PUBLIC KEY-----",a,"base64")}catch(e){return console.error("Signature verification failed:",e),!1}}}const r={production:"https://app.rocketfuel.inc/api",qa:"https://qa-app.rfdemo.co/api",preprod:"https://preprod-app.rocketdemo.net/api",sandbox:"https://app-sandbox.rocketfuel.inc/api"};class n{clientId;clientSecret;merchantId;domain;accessToken=null;refreshToken=null;constructor({clientId:e,clientSecret:t,merchantId:s,environment:a}){this.clientId=e,this.clientSecret=t,this.merchantId=s,this.domain=r[a||"production"]}getAuthPayload(){const t=JSON.stringify({merchantId:this.merchantId,totop:""});return e.AES.encrypt(t,this.clientSecret).toString()}getHeaders(){const e={"Content-Type":"application/json"};return this.accessToken&&(e.Authorization=`Bearer ${this.accessToken}`),e}async getAccessToken(){const e={clientId:this.clientId,encryptedPayload:this.getAuthPayload()},t=await fetch(`${this.domain}/auth/generate-auth-token`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(e)});if(!t.ok)throw new Error(`Auth failed: ${t.status}`);const s=await t.json(),a=s?.result;if(!a?.access)throw new Error("Token missing in response");this.accessToken=a.access,this.refreshToken=a.refresh}async requestWithRetry(e,t,s=!0){const a=await fetch(e,t);if((401===a.status||403===a.status)&&s){await this.getAccessToken();const s={...t,headers:this.getHeaders()};return this.requestWithRetry(e,s,!1)}if(!a.ok){const e=new Error(a.statusText);throw e.status=a.status,e}return a.json()}}class i extends n{constructor(e){super(e)}async getBankConfiguration(e){this.accessToken||await this.getAccessToken();const t=new URLSearchParams({payeeId:e.payeeId,currency:e.currency,country:e.country}),s=`${this.domain}/payout/fiat/bank-configuration?${t.toString()}`,a=await this.requestWithRetry(s,{method:"GET",headers:this.getHeaders()}),r=new URLSearchParams({payeeId:e.payeeId}),n=`${this.domain}/payout/fiat/personal-field-values?${r.toString()}`,i=await this.requestWithRetry(n,{method:"GET",headers:this.getHeaders()}),o=a?.result??a,c=i?.result?.fields;if(c&&o){const e=Object.keys(c),t={};return Object.keys(o).forEach(s=>{t[s]=o[s].map(t=>(e.indexOf(t.name)>-1&&(t.acceptedValues=c[t.name]),t))}),console.debug("fetched personal field values and appended it"),t}return console.debug("no personal field values found"),o}async getStatus(e){this.accessToken||await this.getAccessToken();const t=new URLSearchParams({payeeId:e.payeeId,country:e.country,currency:e.currency}),s=`${this.domain}/payout/services?${t.toString()}`,a=await this.requestWithRetry(s,{method:"GET",headers:this.getHeaders()});return a?.result??a}async shouldShowExternalPayeeForm(){this.accessToken||await this.getAccessToken();const e=`${this.domain}/payout/user/create/external/check`,t=await this.requestWithRetry(e,{method:"GET",headers:this.getHeaders()});return t?.result??t}async createPayeeUserExternal(e){this.accessToken||await this.getAccessToken();const t=`${this.domain}/payout/user/create/external`,s=await this.requestWithRetry(t,{method:"POST",headers:this.getHeaders(),body:JSON.stringify(e)});return s?.result??s}async getCountries(e){this.accessToken||await this.getAccessToken();const t=new URLSearchParams;e.payeeId&&t.set("payeeId",e.payeeId),e.currency&&t.set("currency",e.currency);const s=`${this.domain}/payout/fiat/country${t.toString()?`?${t.toString()}`:""}`,a=await this.requestWithRetry(s,{method:"GET",headers:this.getHeaders()});return a?.result??a}async getCurrencies(e){this.accessToken||await this.getAccessToken();const t=new URLSearchParams({payeeId:e.payeeId});e.country&&t.set("country",e.country);const s=`${this.domain}/payout/fiat/currency?${t.toString()}`,a=await this.requestWithRetry(s,{method:"GET",headers:this.getHeaders()});return a?.result??a}async saveBankDetails(e,t){this.accessToken||await this.getAccessToken();const s=new URLSearchParams({payeeId:e,currency:t.currency,country:t.country}),a=`${this.domain}/payout/fiat/bank-configuration?${s.toString()}`,r=await this.requestWithRetry(a,{method:"POST",headers:this.getHeaders(),body:JSON.stringify(t)});return r?.result??r}async deleteBankDetails(e){this.accessToken||await this.getAccessToken();const t=new URLSearchParams({payeeId:e.payeeId}),s=`${this.domain}/payout/fiat/bank/${encodeURIComponent(e.bankId)}?${t.toString()}`,a=await this.requestWithRetry(s,{method:"DELETE",headers:this.getHeaders()});return a?.result??a}async listBankDetails(e){this.accessToken||await this.getAccessToken();const t=new URLSearchParams({payeeId:e.payeeId}),s=`${this.domain}/payout/fiat/bank-detail?${t.toString()}`,a=await this.requestWithRetry(s,{method:"GET",headers:this.getHeaders()});return a?.result??a}async getTransferFee(e,t){this.accessToken||await this.getAccessToken();const s=new URLSearchParams({payeeId:e.payeeId,country:e.country,currency:e.currency}),a=`${this.domain}/payout/fiat/fees?${s.toString()}`,r=await this.requestWithRetry(a,{method:"POST",headers:this.getHeaders(),body:JSON.stringify(t)});return r?.result??r}async transfer(e,t){this.accessToken||await this.getAccessToken();const s=new URLSearchParams({payeeId:e.payeeId,country:e.country,currency:e.currency}),a=`${this.domain}/payout/fiat/transfer?${s.toString()}`,r=await this.requestWithRetry(a,{method:"POST",headers:this.getHeaders(),body:JSON.stringify(t)});return r?.result??r}async getTransferStatus(e,t){this.accessToken||await this.getAccessToken();const s=new URLSearchParams({payeeId:t}),a=`${this.domain}/payout/order/${encodeURIComponent(e)}?${s.toString()}`,r=await this.requestWithRetry(a,{method:"GET",headers:this.getHeaders()});return r?.result??r}async getPaymentMethods(e){this.accessToken||await this.getAccessToken();const t=new URLSearchParams({amount:e.amount});e.payeeId&&t.set("payeeId",e.payeeId),e.country&&t.set("country",e.country),e.currency&&t.set("currency",e.currency);const s=`${this.domain}/payout/fiat/payment-methods?${t.toString()}`,a=await this.requestWithRetry(s,{method:"GET",headers:this.getHeaders()});return a?.result??a}async getFileUploadUrl(e){this.accessToken||await this.getAccessToken();const t=new URLSearchParams({contentType:e.contentType});e.payeeId&&t.set("payeeId",e.payeeId);const s=`${this.domain}/payout/files/upload-url?${t.toString()}`,a=await this.requestWithRetry(s,{method:"GET",headers:this.getHeaders()});return a?.result??a}async getComplianceStatus(e){this.accessToken||await this.getAccessToken();const t=new URLSearchParams({country:e.country,service:e.service});e.destinationRecordId&&t.set("destinationRecordId",e.destinationRecordId),e.payeeId&&t.set("payeeId",e.payeeId);const s=`${this.domain}/payout/compliance-status?${t.toString()}`,a=await this.requestWithRetry(s,{method:"GET",headers:this.getHeaders()});return a?.result??a}}class o extends n{constructor(e){super(e)}async getCurrencies(e){this.accessToken||await this.getAccessToken();const t=`${this.domain}/payout/currencies?payeeId=${encodeURIComponent(e)}`,s=await this.requestWithRetry(t,{method:"GET",headers:this.getHeaders()});return s?.result}async checkAddress(e){this.accessToken||await this.getAccessToken();return await this.requestWithRetry(`${this.domain}/payout/know-your-address`,{method:"POST",headers:this.getHeaders(),body:JSON.stringify(e)})}async getTransferFee(e,t){this.accessToken||await this.getAccessToken();const s=`${this.domain}/payout/fee?payeeId=${encodeURIComponent(e)}`,a=await this.requestWithRetry(s,{method:"POST",headers:this.getHeaders(),body:JSON.stringify(t)});return a?.result}async checkTransfer(e,t){this.accessToken||await this.getAccessToken();const s=`${this.domain}/payout/withdraw-check?payeeId=${encodeURIComponent(e)}`,a=await this.requestWithRetry(s,{method:"POST",headers:this.getHeaders(),body:JSON.stringify(t)});return a?.result}async transfer(e,t){this.accessToken||await this.getAccessToken();const s=`${this.domain}/payout/withdraw?payeeId=${encodeURIComponent(e)}`,a=await this.requestWithRetry(s,{method:"POST",headers:this.getHeaders(),body:JSON.stringify(t)});return a?.result}async getTransferStatus(e,t){this.accessToken||await this.getAccessToken();const s=new URLSearchParams({payeeId:t}),a=`${this.domain}/payout/order/${encodeURIComponent(e)}?${s.toString()}`,r=await this.requestWithRetry(a,{method:"GET",headers:this.getHeaders()});return r?.result??r}}class c extends n{constructor(e){super(e)}async invitePayee(e){this.accessToken||await this.getAccessToken();const t=await this.requestWithRetry(`${this.domain}/payout/external/payee`,{method:"POST",headers:this.getHeaders(),body:JSON.stringify(e)});return t?.result}async submitPayeeKyc(e){this.accessToken||await this.getAccessToken();const t=await this.requestWithRetry(`${this.domain}/compliance/kyc`,{method:"POST",headers:this.getHeaders(),body:JSON.stringify(e)});return t?.result}async getPayeeBalance(e){this.accessToken||await this.getAccessToken();const t=await this.requestWithRetry(`${this.domain}/payout-admin/payee/${encodeURIComponent(e)}/balance`,{method:"GET",headers:this.getHeaders()});return t?.result}async getBalance(){this.accessToken||await this.getAccessToken();return await this.requestWithRetry(`${this.domain}/payout-admin/balance`,{method:"GET",headers:this.getHeaders()})}async getRunningBalance(){this.accessToken||await this.getAccessToken();return await this.requestWithRetry(`${this.domain}/payout-admin/running-balance`,{method:"GET",headers:this.getHeaders()})}async createTransferAllocation(e){this.accessToken||await this.getAccessToken();const t=await this.requestWithRetry(`${this.domain}/payout-admin/transfer`,{method:"POST",headers:this.getHeaders(),body:JSON.stringify(e)});return t?.result??t}async allocateTransfer(e,t){this.accessToken||await this.getAccessToken();const s=`${this.domain}/payout-admin/transfer/${encodeURIComponent(e)}/allocate`,a=await this.requestWithRetry(s,{method:"POST",headers:this.getHeaders(),body:JSON.stringify(t)});return a?.result??a}}class h{static verify(e){try{const{data:s,signature:a}=e||{};if(!s||!a)return!1;const r=t.createVerify("RSA-SHA256");return r.update(s),r.verify("-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA2e4stIYooUrKHVQmwztC\n/l0YktX6uz4bE1iDtA2qu4OaXx+IKkwBWa0hO2mzv6dAoawyzxa2jmN01vrpMkMj\nrB+Dxmoq7tRvRTx1hXzZWaKuv37BAYosOIKjom8S8axM1j6zPkX1zpMLE8ys3dUX\nFN5Dl/kBfeCTwGRV4PZjP4a+QwgFRzZVVfnpcRI/O6zhfkdlRah8MrAPWYSoGBpG\nCPiAjUeHO/4JA5zZ6IdfZuy/DKxbcOlt9H+z14iJwB7eVUByoeCE+Bkw+QE4msKs\naIn4xl9GBoyfDZKajTzL50W/oeoE1UcuvVfaULZ9DWnHOy6idCFH1WbYDxYYIWLi\nAQIDAQAB\n-----END PUBLIC KEY-----",a,"base64")}catch(e){return console.error("Payout signature verification failed:",e),!1}}}const d="PAYOUT",u={PayeeAdded:"PayeeAdded",PayeeKycStarted:"PayeeKycStarted",PayeeKycStatusChange:"PayeeKycStatusChange",PayeeFundAllocated:"PayeeFundAllocated",PayoutStarted:"PayoutStarted",PayoutStatusChange:"PayoutStatusChange"};class y{fiat;crypto;admin;constructor(e){this.fiat=new i(e),this.crypto=new o(e),this.admin=new c(e)}}export{u as PAYOUT_WEBHOOK_EVENTS,d as PAYOUT_WEBHOOK_EVENT_TYPE,h as PayoutWebhookVerifier,a as Rocketfuel,y as RocketfuelPayouts};
|
|
1
|
+
import e from"crypto-js";import*as t from"crypto";const s={production:"https://app.rocketfuel.inc/api",qa:"https://qa-app.rfdemo.co/api",preprod:"https://preprod-app.rocketdemo.net/api",sandbox:"https://app-sandbox.rocketfuel.inc/api"};class a{#e;#t;#s;#a;#r=null;#n=null;constructor({clientId:e,clientSecret:t,merchantId:a,environment:r}){this.#e=e,this.#t=t,this.#s=a,this.#a=s[r||"production"]}#i(){const t=JSON.stringify({merchantId:this.#s,totop:""});return e.AES.encrypt(t,this.#t).toString()}#o(){const e={"Content-Type":"application/json"};return this.#r&&(e.Authorization=`Bearer ${this.#r}`),e}async#c(){const e={clientId:this.#e,encryptedPayload:this.#i()},t=await fetch(`${this.#a}/auth/generate-auth-token`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(e)});if(!t.ok)throw new Error(`Auth failed: ${t.status}`);const s=await t.json(),a=s?.result;if(!a?.access)throw new Error("Token missing in response");this.#r=a.access,this.#n=a.refresh}async#h(e,t,s=!0){const a=await fetch(e,t);if((401===a.status||403===a.status)&&s){await this.#c();const s={...t,headers:this.#o()};return this.#h(e,s,!1)}if(!a.ok){const e=new Error(a.statusText);throw e.status=a.status,e}return a.json()}async createOrder(e){this.#r||await this.#c();const t=await this.#h(`${this.#a}/hosted-page`,{method:"POST",headers:this.#o(),body:JSON.stringify(e)});return{uuid:t?.result?.uuid}}async transactionLookup(e,t="ORDERID"){this.#r||await this.#c();const s=await this.#h(`${this.#a}/purchase/transactionLookup`,{method:"POST",headers:this.#o(),body:JSON.stringify({txId:e,type:t})});return s?.result}async verifyAgeVerification(e){this.#r||await this.#c();const t=await this.#h(`${this.#a}/merchant/audit/${e}`,{method:"GET",headers:this.#o()});return t?.result}verifyWebhookSignature(e){try{const{data:{data:s},signature:a}=e,r=t.createVerify("RSA-SHA256");return r.update(s),r.verify("-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA2e4stIYooUrKHVQmwztC\n/l0YktX6uz4bE1iDtA2qu4OaXx+IKkwBWa0hO2mzv6dAoawyzxa2jmN01vrpMkMj\nrB+Dxmoq7tRvRTx1hXzZWaKuv37BAYosOIKjom8S8axM1j6zPkX1zpMLE8ys3dUX\nFN5Dl/kBfeCTwGRV4PZjP4a+QwgFRzZVVfnpcRI/O6zhfkdlRah8MrAPWYSoGBpG\nCPiAjUeHO/4JA5zZ6IdfZuy/DKxbcOlt9H+z14iJwB7eVUByoeCE+Bkw+QE4msKs\naIn4xl9GBoyfDZKajTzL50W/oeoE1UcuvVfaULZ9DWnHOy6idCFH1WbYDxYYIWLi\nAQIDAQAB\n-----END PUBLIC KEY-----",a,"base64")}catch(e){return console.error("Signature verification failed:",e),!1}}}const r={production:"https://app.rocketfuel.inc/api",qa:"https://qa-app.rfdemo.co/api",preprod:"https://preprod-app.rocketdemo.net/api",sandbox:"https://app-sandbox.rocketfuel.inc/api"};class n{clientId;clientSecret;merchantId;domain;accessToken=null;refreshToken=null;constructor({clientId:e,clientSecret:t,merchantId:s,environment:a}){this.clientId=e,this.clientSecret=t,this.merchantId=s,this.domain=r[a||"production"]}getAuthPayload(){const t=JSON.stringify({merchantId:this.merchantId,totop:""});return e.AES.encrypt(t,this.clientSecret).toString()}getHeaders(){const e={"Content-Type":"application/json"};return this.accessToken&&(e.Authorization=`Bearer ${this.accessToken}`),e}async getAccessToken(){const e={clientId:this.clientId,encryptedPayload:this.getAuthPayload()},t=await fetch(`${this.domain}/auth/generate-auth-token`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(e)});if(!t.ok)throw new Error(`Auth failed: ${t.status}`);const s=await t.json(),a=s?.result;if(!a?.access)throw new Error("Token missing in response");this.accessToken=a.access,this.refreshToken=a.refresh}async requestWithRetry(e,t,s=!0){const a=await fetch(e,t);if((401===a.status||403===a.status)&&s){await this.getAccessToken();const s={...t,headers:this.getHeaders()};return this.requestWithRetry(e,s,!1)}if(!a.ok){const e=new Error(a.statusText);throw e.status=a.status,e}return a.json()}}class i extends n{constructor(e){super(e)}async getBankConfiguration(e){this.accessToken||await this.getAccessToken();const t=new URLSearchParams({payeeId:e.payeeId,currency:e.currency,country:e.country}),s=`${this.domain}/payout/fiat/bank-configuration?${t.toString()}`,a=await this.requestWithRetry(s,{method:"GET",headers:this.getHeaders()}),r=new URLSearchParams({payeeId:e.payeeId}),n=`${this.domain}/payout/fiat/personal-field-values?${r.toString()}`,i=await this.requestWithRetry(n,{method:"GET",headers:this.getHeaders()}),o=a?.result??a,c=i?.result?.fields;if(c&&o){const e=Object.keys(c),t={};return Object.keys(o).forEach(s=>{t[s]=o[s].map(t=>(e.indexOf(t.name)>-1&&(t.acceptedValues=c[t.name]),t))}),console.debug("fetched personal field values and appended it"),t}return console.debug("no personal field values found"),o}async getStatus(e){this.accessToken||await this.getAccessToken();const t=new URLSearchParams({payeeId:e.payeeId,country:e.country,currency:e.currency}),s=`${this.domain}/payout/services?${t.toString()}`,a=await this.requestWithRetry(s,{method:"GET",headers:this.getHeaders()});return a?.result??a}async shouldShowExternalPayeeForm(){this.accessToken||await this.getAccessToken();const e=`${this.domain}/payout/user/create/external/check`,t=await this.requestWithRetry(e,{method:"GET",headers:this.getHeaders()});return t?.result??t}async createPayeeUserExternal(e){this.accessToken||await this.getAccessToken();const t=`${this.domain}/payout/user/create/external`,s=await this.requestWithRetry(t,{method:"POST",headers:this.getHeaders(),body:JSON.stringify(e)});return s?.result??s}async getPublicCountries(){const e=`${this.domain}/payout/countries`,t=await this.requestWithRetry(e,{method:"GET",headers:this.getHeaders()});return t?.result??t}async getCountries(e){this.accessToken||await this.getAccessToken();const t=new URLSearchParams;e.payeeId&&t.set("payeeId",e.payeeId),e.currency&&t.set("currency",e.currency);const s=`${this.domain}/payout/fiat/country${t.toString()?`?${t.toString()}`:""}`,a=await this.requestWithRetry(s,{method:"GET",headers:this.getHeaders()});return a?.result??a}async getCurrencies(e){this.accessToken||await this.getAccessToken();const t=new URLSearchParams({payeeId:e.payeeId});e.country&&t.set("country",e.country);const s=`${this.domain}/payout/fiat/currency?${t.toString()}`,a=await this.requestWithRetry(s,{method:"GET",headers:this.getHeaders()});return a?.result??a}async saveBankDetails(e,t){this.accessToken||await this.getAccessToken();const s=new URLSearchParams({payeeId:e,currency:t.currency,country:t.country}),a=`${this.domain}/payout/fiat/bank-configuration?${s.toString()}`,r=await this.requestWithRetry(a,{method:"POST",headers:this.getHeaders(),body:JSON.stringify(t)});return r?.result??r}async deleteBankDetails(e){this.accessToken||await this.getAccessToken();const t=new URLSearchParams({payeeId:e.payeeId}),s=`${this.domain}/payout/fiat/bank/${encodeURIComponent(e.bankId)}?${t.toString()}`,a=await this.requestWithRetry(s,{method:"DELETE",headers:this.getHeaders()});return a?.result??a}async listBankDetails(e){this.accessToken||await this.getAccessToken();const t=new URLSearchParams({payeeId:e.payeeId}),s=`${this.domain}/payout/fiat/bank-detail?${t.toString()}`,a=await this.requestWithRetry(s,{method:"GET",headers:this.getHeaders()});return a?.result??a}async getTransferFee(e,t){this.accessToken||await this.getAccessToken();const s=new URLSearchParams({payeeId:e.payeeId,country:e.country,currency:e.currency}),a=`${this.domain}/payout/fiat/fees?${s.toString()}`,r=await this.requestWithRetry(a,{method:"POST",headers:this.getHeaders(),body:JSON.stringify(t)});return r?.result??r}async transfer(e,t){this.accessToken||await this.getAccessToken();const s=new URLSearchParams({payeeId:e.payeeId,country:e.country,currency:e.currency}),a=`${this.domain}/payout/fiat/transfer?${s.toString()}`,r=await this.requestWithRetry(a,{method:"POST",headers:this.getHeaders(),body:JSON.stringify(t)});return r?.result??r}async getTransferStatus(e,t){this.accessToken||await this.getAccessToken();const s=new URLSearchParams({payeeId:t}),a=`${this.domain}/payout/order/${encodeURIComponent(e)}?${s.toString()}`,r=await this.requestWithRetry(a,{method:"GET",headers:this.getHeaders()});return r?.result??r}async getPaymentMethods(e){this.accessToken||await this.getAccessToken();const t=new URLSearchParams({amount:e.amount});e.payeeId&&t.set("payeeId",e.payeeId),e.country&&t.set("country",e.country),e.currency&&t.set("currency",e.currency);const s=`${this.domain}/payout/fiat/payment-methods?${t.toString()}`,a=await this.requestWithRetry(s,{method:"GET",headers:this.getHeaders()});return a?.result??a}async getFileUploadUrl(e){this.accessToken||await this.getAccessToken();const t=new URLSearchParams({contentType:e.contentType});e.payeeId&&t.set("payeeId",e.payeeId);const s=`${this.domain}/payout/files/upload-url?${t.toString()}`,a=await this.requestWithRetry(s,{method:"GET",headers:this.getHeaders()});return a?.result??a}async getComplianceStatus(e){this.accessToken||await this.getAccessToken();const t=new URLSearchParams({country:e.country,service:e.service});e.destinationRecordId&&t.set("destinationRecordId",e.destinationRecordId),e.payeeId&&t.set("payeeId",e.payeeId);const s=`${this.domain}/payout/compliance-status?${t.toString()}`,a=await this.requestWithRetry(s,{method:"GET",headers:this.getHeaders()});return a?.result??a}}class o extends n{constructor(e){super(e)}async getCurrencies(e){this.accessToken||await this.getAccessToken();const t=`${this.domain}/payout/currencies?payeeId=${encodeURIComponent(e)}`,s=await this.requestWithRetry(t,{method:"GET",headers:this.getHeaders()});return s?.result}async checkAddress(e){this.accessToken||await this.getAccessToken();return await this.requestWithRetry(`${this.domain}/payout/know-your-address`,{method:"POST",headers:this.getHeaders(),body:JSON.stringify(e)})}async getTransferFee(e,t){this.accessToken||await this.getAccessToken();const s=`${this.domain}/payout/fee?payeeId=${encodeURIComponent(e)}`,a=await this.requestWithRetry(s,{method:"POST",headers:this.getHeaders(),body:JSON.stringify(t)});return a?.result}async checkTransfer(e,t){this.accessToken||await this.getAccessToken();const s=`${this.domain}/payout/withdraw-check?payeeId=${encodeURIComponent(e)}`,a=await this.requestWithRetry(s,{method:"POST",headers:this.getHeaders(),body:JSON.stringify(t)});return a?.result}async transfer(e,t){this.accessToken||await this.getAccessToken();const s=`${this.domain}/payout/withdraw?payeeId=${encodeURIComponent(e)}`,a=await this.requestWithRetry(s,{method:"POST",headers:this.getHeaders(),body:JSON.stringify(t)});return a?.result}async getTransferStatus(e,t){this.accessToken||await this.getAccessToken();const s=new URLSearchParams({payeeId:t}),a=`${this.domain}/payout/order/${encodeURIComponent(e)}?${s.toString()}`,r=await this.requestWithRetry(a,{method:"GET",headers:this.getHeaders()});return r?.result??r}}class c extends n{constructor(e){super(e)}async invitePayee(e){this.accessToken||await this.getAccessToken();const t=await this.requestWithRetry(`${this.domain}/payout/external/payee`,{method:"POST",headers:this.getHeaders(),body:JSON.stringify(e)});return t?.result}async submitPayeeKyc(e){this.accessToken||await this.getAccessToken();const t=await this.requestWithRetry(`${this.domain}/compliance/kyc`,{method:"POST",headers:this.getHeaders(),body:JSON.stringify(e)});return t?.result}async getPayeeBalance(e){this.accessToken||await this.getAccessToken();const t=await this.requestWithRetry(`${this.domain}/payout-admin/payee/${encodeURIComponent(e)}/balance`,{method:"GET",headers:this.getHeaders()});return t?.result}async getBalance(){this.accessToken||await this.getAccessToken();return await this.requestWithRetry(`${this.domain}/payout-admin/balance`,{method:"GET",headers:this.getHeaders()})}async getRunningBalance(){this.accessToken||await this.getAccessToken();return await this.requestWithRetry(`${this.domain}/payout-admin/running-balance`,{method:"GET",headers:this.getHeaders()})}async createTransferAllocation(e){this.accessToken||await this.getAccessToken();const t=await this.requestWithRetry(`${this.domain}/payout-admin/transfer`,{method:"POST",headers:this.getHeaders(),body:JSON.stringify(e)});return t?.result??t}async allocateTransfer(e,t){this.accessToken||await this.getAccessToken();const s=`${this.domain}/payout-admin/transfer/${encodeURIComponent(e)}/allocate`,a=await this.requestWithRetry(s,{method:"POST",headers:this.getHeaders(),body:JSON.stringify(t)});return a?.result??a}}class h{static verify(e){try{const{data:s,signature:a}=e||{};if(!s||!a)return!1;const r=t.createVerify("RSA-SHA256");return r.update(s),r.verify("-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA2e4stIYooUrKHVQmwztC\n/l0YktX6uz4bE1iDtA2qu4OaXx+IKkwBWa0hO2mzv6dAoawyzxa2jmN01vrpMkMj\nrB+Dxmoq7tRvRTx1hXzZWaKuv37BAYosOIKjom8S8axM1j6zPkX1zpMLE8ys3dUX\nFN5Dl/kBfeCTwGRV4PZjP4a+QwgFRzZVVfnpcRI/O6zhfkdlRah8MrAPWYSoGBpG\nCPiAjUeHO/4JA5zZ6IdfZuy/DKxbcOlt9H+z14iJwB7eVUByoeCE+Bkw+QE4msKs\naIn4xl9GBoyfDZKajTzL50W/oeoE1UcuvVfaULZ9DWnHOy6idCFH1WbYDxYYIWLi\nAQIDAQAB\n-----END PUBLIC KEY-----",a,"base64")}catch(e){return console.error("Payout signature verification failed:",e),!1}}}const d="PAYOUT",u={PayeeAdded:"PayeeAdded",PayeeKycStarted:"PayeeKycStarted",PayeeKycStatusChange:"PayeeKycStatusChange",PayeeFundAllocated:"PayeeFundAllocated",PayoutStarted:"PayoutStarted",PayoutStatusChange:"PayoutStatusChange"};class y{fiat;crypto;admin;constructor(e){this.fiat=new i(e),this.crypto=new o(e),this.admin=new c(e)}}export{u as PAYOUT_WEBHOOK_EVENTS,d as PAYOUT_WEBHOOK_EVENT_TYPE,h as PayoutWebhookVerifier,a as Rocketfuel,y as RocketfuelPayouts};
|
|
2
2
|
//# sourceMappingURL=index.js.map
|
|
@@ -141,8 +141,15 @@ export interface ComplianceStatusQuery {
|
|
|
141
141
|
export interface CreatePayeeUserExternalPayload {
|
|
142
142
|
fName: string;
|
|
143
143
|
lName: string;
|
|
144
|
+
email: string;
|
|
144
145
|
country: string;
|
|
145
146
|
}
|
|
146
147
|
export interface ShouldShowExternalPayeeFormResponse {
|
|
147
148
|
showForm: boolean;
|
|
148
149
|
}
|
|
150
|
+
export interface Country {
|
|
151
|
+
id: number;
|
|
152
|
+
name: string;
|
|
153
|
+
iso2: string;
|
|
154
|
+
iso3: string;
|
|
155
|
+
}
|
package/dist/payouts/fiat.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { type BankConfigurationQuery, type FiatCountryQuery, type FiatCurrencyQuery, type FiatStatusQuery, type SaveBankDetailsPayload, type DeleteBankDetailsParams, type ListBankDetailsQuery, type FiatTransferFeeQuery, type FiatTransferFeePayload, type FiatTransferQuery, type FiatTransferPayload, type FiatPaymentMethodsQuery, type FileUploadUrlQuery, type ComplianceStatusQuery, type CreatePayeeUserExternalPayload, type ShouldShowExternalPayeeFormResponse } from './constants';
|
|
1
|
+
import { type BankConfigurationQuery, type FiatCountryQuery, type FiatCurrencyQuery, type FiatStatusQuery, type SaveBankDetailsPayload, type DeleteBankDetailsParams, type ListBankDetailsQuery, type FiatTransferFeeQuery, type FiatTransferFeePayload, type FiatTransferQuery, type FiatTransferPayload, type FiatPaymentMethodsQuery, type FileUploadUrlQuery, type ComplianceStatusQuery, type CreatePayeeUserExternalPayload, type ShouldShowExternalPayeeFormResponse, type Country } from './constants';
|
|
2
2
|
import { PayoutBase, type PayoutClientConfig } from './core';
|
|
3
3
|
export declare class FiatPayoutClient extends PayoutBase {
|
|
4
4
|
constructor(config: PayoutClientConfig);
|
|
@@ -23,8 +23,20 @@ export declare class FiatPayoutClient extends PayoutBase {
|
|
|
23
23
|
/**
|
|
24
24
|
* Create an external payee user.
|
|
25
25
|
* Maps to: POST /api/payout/user/create/external
|
|
26
|
+
*
|
|
27
|
+
* Required fields:
|
|
28
|
+
* - fName: string (first name)
|
|
29
|
+
* - lName: string (last name)
|
|
30
|
+
* - email: string (valid email address)
|
|
31
|
+
* - country: string (ISO3 code, 3 uppercase letters)
|
|
26
32
|
*/
|
|
27
33
|
createPayeeUserExternal(payload: CreatePayeeUserExternalPayload): Promise<any>;
|
|
34
|
+
/**
|
|
35
|
+
* Get public list of all countries with id, name, iso2, and iso3 codes.
|
|
36
|
+
* This is a public endpoint that does not require authentication.
|
|
37
|
+
* Maps to: GET /api/payout/countries
|
|
38
|
+
*/
|
|
39
|
+
getPublicCountries(): Promise<Country[]>;
|
|
28
40
|
/**
|
|
29
41
|
* Get list of supported payout countries.
|
|
30
42
|
* Maps to: GET /api/payout/fiat/country?[payeeId={payeeId}][¤cy={currency}]
|