@yosle/tropipayjs 0.2.1 → 0.2.2
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 +27 -0
- package/api/TropipayAPI.d.ts +31 -4
- package/index.d.ts +41 -104
- package/index.js +99 -81
- package/interfaces/index.d.ts +10 -35
- package/interfaces/paymentlink/index.d.ts +3 -1
- package/package.json +5 -2
- package/paymentcard/paymentcard.spec.d.ts +1 -0
- package/src/api/TropipayAPI.ts +129 -30
- package/src/depositAccount/depositAccounts.ts +5 -5
- package/src/index.ts +1 -0
- package/src/interfaces/index.ts +212 -264
- package/src/interfaces/paymentlink/index.d.ts +32 -33
- package/src/interfaces/paymentlink/index.ts +3 -1
- package/src/paymentcard/PaymentCard.ts +4 -4
- package/src/utils/TropipayUtils.ts +1 -40
- package/utils/TropipayUtils.d.ts +1 -14
- package/accounts/accounts.d.ts +0 -52
- package/src/accounts/accounts.ts +0 -86
package/README.md
CHANGED
|
@@ -133,6 +133,33 @@ console.log(paylink.shortUrl);
|
|
|
133
133
|
|
|
134
134
|
For more examples, please refer to the [Documentation](https://github.com/yosle/tropipayjs/blob/master/docs/)
|
|
135
135
|
|
|
136
|
+
### Refunding a Transaction
|
|
137
|
+
|
|
138
|
+
The library provides two methods for handling refunds with 2FA confirmation:
|
|
139
|
+
|
|
140
|
+
#### Request a Security Code (Production only)
|
|
141
|
+
|
|
142
|
+
In **Production** mode, you must first request a 2FA code via SMS:
|
|
143
|
+
|
|
144
|
+
```javascript
|
|
145
|
+
await tpp.requestSecurityCode();
|
|
146
|
+
// An SMS with the code will be sent to your phone
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
#### Refund a Movement
|
|
150
|
+
|
|
151
|
+
Once you have the security code (or in Development mode), you can refund a transaction:
|
|
152
|
+
|
|
153
|
+
```javascript
|
|
154
|
+
// Development mode — use the default test code
|
|
155
|
+
const result = await tpp.refundMovement("ORD-123456", 5000, "123456");
|
|
156
|
+
|
|
157
|
+
// Production mode — pass the code received via SMS
|
|
158
|
+
const result = await tpp.refundMovement("ORD-123456", 5000, "847291");
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
**Note:** The refund endpoint requires the `ALLOW_REFUND` scope and 2FA to be enabled on your Tropipay account. In Development mode the default 2FA code is `123456` unless you have configured the Authenticator app.
|
|
162
|
+
|
|
136
163
|
# Contributing
|
|
137
164
|
|
|
138
165
|
If you have a suggestion that would make this better, please fork the repo and create a pull request. You can also simply open an issue with the tag "enhancement". Don't forget to give the project a star! Thanks again!
|
package/api/TropipayAPI.d.ts
CHANGED
|
@@ -5,19 +5,17 @@
|
|
|
5
5
|
*
|
|
6
6
|
*/
|
|
7
7
|
import { Axios } from "axios";
|
|
8
|
-
import { TropipayConfig, AccountBalance, Country, PaymentLink, MediationPaymentCardConfig, LoginResponse } from "../interfaces";
|
|
8
|
+
import { TropipayConfig, AccountBalance, Country, PaymentLink, MediationPaymentCardConfig, LoginResponse, RefundResponse } from "../interfaces";
|
|
9
9
|
type ServerMode = "Development" | "Production";
|
|
10
10
|
import TropipayHooks from "../hooks/TropipayHooks";
|
|
11
11
|
import PaymentCard from "../paymentcard/PaymentCard";
|
|
12
12
|
import MediationPaymentCard from "../mediationPaymentCard/MediationPaymentCard";
|
|
13
13
|
import DepositAccounts from "../depositAccount/depositAccounts";
|
|
14
|
-
import Accounts from "../accounts/accounts";
|
|
15
14
|
export declare class Tropipay {
|
|
16
15
|
readonly clientId: string;
|
|
17
16
|
readonly clientSecret: string;
|
|
18
17
|
readonly scopes: String[];
|
|
19
18
|
request: Axios;
|
|
20
|
-
loginRequest: Axios;
|
|
21
19
|
static accessToken: string | null;
|
|
22
20
|
static refreshToken: string | null;
|
|
23
21
|
static expiresIn: number | null;
|
|
@@ -26,7 +24,6 @@ export declare class Tropipay {
|
|
|
26
24
|
paymentCards: PaymentCard;
|
|
27
25
|
depositAccounts: DepositAccounts;
|
|
28
26
|
mediationPaymentCard: MediationPaymentCard;
|
|
29
|
-
accounts: Accounts;
|
|
30
27
|
/**
|
|
31
28
|
* Initializes a new instance of the Tropipay class.
|
|
32
29
|
*
|
|
@@ -85,10 +82,39 @@ export declare class Tropipay {
|
|
|
85
82
|
* belonging or not to the TropiPay platform with the particularity
|
|
86
83
|
* that the payment will be held in custody or retained until it is
|
|
87
84
|
* released with the approval of the payer.
|
|
85
|
+
* @deprecated This method is no longer supported and may be removed in a future release.
|
|
88
86
|
* @see https://tpp.stoplight.io/docs/tropipay-api-doc/12a128ff971e4-creating-a-mediation-payment-card
|
|
89
87
|
* @param config Payload with the payment details
|
|
90
88
|
*/
|
|
91
89
|
createMediationPaymentCard(config: MediationPaymentCardConfig): Promise<PaymentLink>;
|
|
90
|
+
/**
|
|
91
|
+
* Refund a completed transaction.
|
|
92
|
+
* Requires 2FA enabled and ALLOW_REFUND permission on the Tropipay account.
|
|
93
|
+
*
|
|
94
|
+
* In Development mode, `securityCode` defaults to `"123456"` when omitted.
|
|
95
|
+
* In Production mode, you must first call `requestSecurityCode()` to receive
|
|
96
|
+
* the 2FA code via SMS, then pass it as the `securityCode` parameter.
|
|
97
|
+
*
|
|
98
|
+
* @see https://doc.tropipay.com/docs/api-reference/movements#refund-a-transaction
|
|
99
|
+
* @param orderCode Code of the order/transaction to refund (e.g. "ORD-123456")
|
|
100
|
+
* @param amount Amount to refund in cents (e.g. 5000 = 50.00 USD/EUR)
|
|
101
|
+
* @param securityCode 2FA confirmation code. Use "123456" in Development or
|
|
102
|
+
* the code received via SMS in Production (obtained via requestSecurityCode()).
|
|
103
|
+
*/
|
|
104
|
+
refundMovement(orderCode: string, amount: number, securityCode: string): Promise<RefundResponse>;
|
|
105
|
+
/**
|
|
106
|
+
* Request a 2FA security code to be sent via SMS for confirming sensitive
|
|
107
|
+
* operations like refunds.
|
|
108
|
+
*
|
|
109
|
+
* In Production mode, you must call this method first to trigger an SMS with
|
|
110
|
+
* the code, then use the received code when calling `refundMovement()`.
|
|
111
|
+
* In Development mode this is not required as the default code "123456"
|
|
112
|
+
* is used automatically.
|
|
113
|
+
*
|
|
114
|
+
* @see https://doc.tropipay.com/docs/api-reference/movements#refund-a-transaction
|
|
115
|
+
* @returns The API response confirming the code was sent
|
|
116
|
+
*/
|
|
117
|
+
requestSecurityCode(type?: "sms" | "email"): Promise<any>;
|
|
92
118
|
}
|
|
93
119
|
export declare class ClientSideUtils {
|
|
94
120
|
constructor(tropipayInstance: Tropipay);
|
|
@@ -102,5 +128,6 @@ export declare const Scopes: {
|
|
|
102
128
|
ALLOW_GET_BALANCE: string;
|
|
103
129
|
ALLOW_GET_MOVEMENT_LIST: string;
|
|
104
130
|
ALLOW_GET_CREDENTIAL: string;
|
|
131
|
+
ALLOW_REFUND: string;
|
|
105
132
|
};
|
|
106
133
|
export {};
|
package/index.d.ts
CHANGED
|
@@ -39,71 +39,36 @@ interface UserHookSubscribed extends UserHook {
|
|
|
39
39
|
createdAt: string;
|
|
40
40
|
updatedAt: string;
|
|
41
41
|
}
|
|
42
|
-
/**
|
|
43
|
-
* Interface for creating payment links/cards
|
|
44
|
-
* @see https://tpp.stoplight.io/docs/tropipay-api-doc/b3A6ODgyNTM3OQ-create-a-new-pay-link-charge
|
|
45
|
-
*/
|
|
46
42
|
interface PaymentLinkPayload {
|
|
47
|
-
/** Account ID where the funds will be received if compatible */
|
|
48
|
-
accountId?: number;
|
|
49
|
-
/** Reference code for the payment, preferred to be unique */
|
|
50
43
|
reference: string;
|
|
51
|
-
/** Short description of the payment */
|
|
52
44
|
concept: string;
|
|
53
|
-
/** Whether to mark this payment link as favorite */
|
|
54
45
|
favorite: boolean;
|
|
55
|
-
/** Amount to charge in the specified currency */
|
|
56
46
|
amount: number;
|
|
57
|
-
/** Currency code (EUR, USD, etc.) */
|
|
58
47
|
currency: string;
|
|
59
|
-
/** Detailed description of the payment */
|
|
60
48
|
description: string;
|
|
61
|
-
/** If true, the payment link can only be used once */
|
|
62
49
|
singleUse: boolean;
|
|
63
|
-
/** Reason ID for the payment */
|
|
64
50
|
reasonId: number;
|
|
65
|
-
/** Number of days until the payment link expires */
|
|
66
51
|
expirationDays: number;
|
|
67
|
-
/** Language code for the payment page (en, es, etc.) */
|
|
68
52
|
lang: string;
|
|
69
|
-
/** URL to redirect after successful payment */
|
|
70
53
|
urlSuccess: string;
|
|
71
|
-
/** URL to redirect after failed payment */
|
|
72
54
|
urlFailed: string;
|
|
73
|
-
/** Webhook URL for payment notifications */
|
|
74
55
|
urlNotification: string;
|
|
75
|
-
/** Date when the service will be provided (ISO format) */
|
|
76
56
|
serviceDate: string;
|
|
77
|
-
/** Client information for the payment */
|
|
78
57
|
client?: {
|
|
79
|
-
/** Client's first name */
|
|
80
58
|
name?: string;
|
|
81
|
-
/** Client's last name */
|
|
82
59
|
lastName?: string;
|
|
83
|
-
/** Client's address */
|
|
84
60
|
address?: string;
|
|
85
|
-
/** Client's phone number */
|
|
86
61
|
phone?: string;
|
|
87
|
-
/** Client's email address */
|
|
88
62
|
email?: string;
|
|
89
|
-
/** Client's country ID */
|
|
90
63
|
countryId?: number;
|
|
91
|
-
/** Client's country ISO code */
|
|
92
64
|
countryIso?: string;
|
|
93
|
-
/** Client's city */
|
|
94
65
|
city: string;
|
|
95
|
-
/** Client's postal code */
|
|
96
66
|
postCode: string;
|
|
97
|
-
/** Whether client accepted terms and conditions */
|
|
98
67
|
termsAndConditions: boolean;
|
|
99
68
|
} | null;
|
|
100
|
-
/** @deprecated If true, redirects directly to payment page */
|
|
101
69
|
directPayment: boolean;
|
|
102
|
-
/** List of allowed payment methods */
|
|
103
70
|
paymentMethods?: string[];
|
|
104
|
-
/** Base64 encoded image for the payment page */
|
|
105
71
|
imageBase?: string;
|
|
106
|
-
/** Whether to save the payment token for future use */
|
|
107
72
|
saveToken?: boolean;
|
|
108
73
|
}
|
|
109
74
|
interface PaymentLink extends PaymentLinkPayload {
|
|
@@ -203,6 +168,16 @@ type AccountDeposits = {
|
|
|
203
168
|
count: number;
|
|
204
169
|
rows: Deposit[];
|
|
205
170
|
};
|
|
171
|
+
type RefundResponse = {
|
|
172
|
+
id: number;
|
|
173
|
+
orderCode: string;
|
|
174
|
+
amount: number;
|
|
175
|
+
currency: string;
|
|
176
|
+
state: string;
|
|
177
|
+
type: string;
|
|
178
|
+
createdAt: string;
|
|
179
|
+
completedAt: string;
|
|
180
|
+
};
|
|
206
181
|
|
|
207
182
|
declare class TropipayHooks {
|
|
208
183
|
private tropipay;
|
|
@@ -354,58 +329,6 @@ declare class DepositAccounts {
|
|
|
354
329
|
delete(id: number): Promise<any>;
|
|
355
330
|
}
|
|
356
331
|
|
|
357
|
-
interface PaymentMethod {
|
|
358
|
-
slug: string;
|
|
359
|
-
name: string;
|
|
360
|
-
enabled: boolean;
|
|
361
|
-
allowedCurrencies: string[];
|
|
362
|
-
}
|
|
363
|
-
interface ServiceLimit {
|
|
364
|
-
value: number | null;
|
|
365
|
-
currency: string;
|
|
366
|
-
}
|
|
367
|
-
interface ServiceLimits {
|
|
368
|
-
min: ServiceLimit;
|
|
369
|
-
max: ServiceLimit;
|
|
370
|
-
}
|
|
371
|
-
interface Service {
|
|
372
|
-
slug: string;
|
|
373
|
-
enabled: boolean;
|
|
374
|
-
allowed_currencies: string[];
|
|
375
|
-
limits: ServiceLimits;
|
|
376
|
-
}
|
|
377
|
-
interface TropiCard {
|
|
378
|
-
}
|
|
379
|
-
interface Account {
|
|
380
|
-
id: number;
|
|
381
|
-
accountNumber: string;
|
|
382
|
-
userId: string;
|
|
383
|
-
alias: string;
|
|
384
|
-
balance: number;
|
|
385
|
-
pendingIn: number;
|
|
386
|
-
pendingOut: number;
|
|
387
|
-
state: number;
|
|
388
|
-
paymentEntityId: number;
|
|
389
|
-
currency: string;
|
|
390
|
-
type: number;
|
|
391
|
-
createdAt: string;
|
|
392
|
-
updatedAt: string;
|
|
393
|
-
isDefault: boolean;
|
|
394
|
-
groupId: number | null;
|
|
395
|
-
TropiCards: TropiCard[];
|
|
396
|
-
services: Service[];
|
|
397
|
-
paymentMethods: PaymentMethod[];
|
|
398
|
-
}
|
|
399
|
-
declare class Accounts {
|
|
400
|
-
private tropipay;
|
|
401
|
-
constructor(tropipayInstance: Tropipay);
|
|
402
|
-
/**
|
|
403
|
-
* List all accounts of the authenticated user
|
|
404
|
-
* @returns Array of Account objects
|
|
405
|
-
*/
|
|
406
|
-
list(): Promise<Account[]>;
|
|
407
|
-
}
|
|
408
|
-
|
|
409
332
|
/**
|
|
410
333
|
* Tropipayjs is a Typescript/Javascript library for the Tropipay API.
|
|
411
334
|
*
|
|
@@ -420,7 +343,6 @@ declare class Tropipay {
|
|
|
420
343
|
readonly clientSecret: string;
|
|
421
344
|
readonly scopes: String[];
|
|
422
345
|
request: Axios;
|
|
423
|
-
loginRequest: Axios;
|
|
424
346
|
static accessToken: string | null;
|
|
425
347
|
static refreshToken: string | null;
|
|
426
348
|
static expiresIn: number | null;
|
|
@@ -429,7 +351,6 @@ declare class Tropipay {
|
|
|
429
351
|
paymentCards: PaymentCard;
|
|
430
352
|
depositAccounts: DepositAccounts;
|
|
431
353
|
mediationPaymentCard: MediationPaymentCard;
|
|
432
|
-
accounts: Accounts;
|
|
433
354
|
/**
|
|
434
355
|
* Initializes a new instance of the Tropipay class.
|
|
435
356
|
*
|
|
@@ -488,10 +409,39 @@ declare class Tropipay {
|
|
|
488
409
|
* belonging or not to the TropiPay platform with the particularity
|
|
489
410
|
* that the payment will be held in custody or retained until it is
|
|
490
411
|
* released with the approval of the payer.
|
|
412
|
+
* @deprecated This method is no longer supported and may be removed in a future release.
|
|
491
413
|
* @see https://tpp.stoplight.io/docs/tropipay-api-doc/12a128ff971e4-creating-a-mediation-payment-card
|
|
492
414
|
* @param config Payload with the payment details
|
|
493
415
|
*/
|
|
494
416
|
createMediationPaymentCard(config: MediationPaymentCardConfig): Promise<PaymentLink>;
|
|
417
|
+
/**
|
|
418
|
+
* Refund a completed transaction.
|
|
419
|
+
* Requires 2FA enabled and ALLOW_REFUND permission on the Tropipay account.
|
|
420
|
+
*
|
|
421
|
+
* In Development mode, `securityCode` defaults to `"123456"` when omitted.
|
|
422
|
+
* In Production mode, you must first call `requestSecurityCode()` to receive
|
|
423
|
+
* the 2FA code via SMS, then pass it as the `securityCode` parameter.
|
|
424
|
+
*
|
|
425
|
+
* @see https://doc.tropipay.com/docs/api-reference/movements#refund-a-transaction
|
|
426
|
+
* @param orderCode Code of the order/transaction to refund (e.g. "ORD-123456")
|
|
427
|
+
* @param amount Amount to refund in cents (e.g. 5000 = 50.00 USD/EUR)
|
|
428
|
+
* @param securityCode 2FA confirmation code. Use "123456" in Development or
|
|
429
|
+
* the code received via SMS in Production (obtained via requestSecurityCode()).
|
|
430
|
+
*/
|
|
431
|
+
refundMovement(orderCode: string, amount: number, securityCode: string): Promise<RefundResponse>;
|
|
432
|
+
/**
|
|
433
|
+
* Request a 2FA security code to be sent via SMS for confirming sensitive
|
|
434
|
+
* operations like refunds.
|
|
435
|
+
*
|
|
436
|
+
* In Production mode, you must call this method first to trigger an SMS with
|
|
437
|
+
* the code, then use the received code when calling `refundMovement()`.
|
|
438
|
+
* In Development mode this is not required as the default code "123456"
|
|
439
|
+
* is used automatically.
|
|
440
|
+
*
|
|
441
|
+
* @see https://doc.tropipay.com/docs/api-reference/movements#refund-a-transaction
|
|
442
|
+
* @returns The API response confirming the code was sent
|
|
443
|
+
*/
|
|
444
|
+
requestSecurityCode(type?: "sms" | "email"): Promise<any>;
|
|
495
445
|
}
|
|
496
446
|
declare class ClientSideUtils {
|
|
497
447
|
constructor(tropipayInstance: Tropipay);
|
|
@@ -501,9 +451,7 @@ declare class ServerSideUtils {
|
|
|
501
451
|
private tropipay;
|
|
502
452
|
constructor(tropipayInstance: Tropipay);
|
|
503
453
|
/**
|
|
504
|
-
*
|
|
505
|
-
* @deprecated This method is deprecated and will be removed in future versions.
|
|
506
|
-
* Use the `verifySignatureV3` method from the `ServerSideUtils` class instead.
|
|
454
|
+
* Verify Topipay's signature on webhooks.
|
|
507
455
|
* @param credentials Credential object or Tropipay instance
|
|
508
456
|
* @param {String} originalCurrencyAmount
|
|
509
457
|
* @param bankOrderCode
|
|
@@ -542,19 +490,8 @@ declare class ServerSideUtils {
|
|
|
542
490
|
* @return {Promise<string>} the valid base64 image
|
|
543
491
|
*/
|
|
544
492
|
static isValidImage(base64Image: string): boolean;
|
|
545
|
-
/**
|
|
546
|
-
* Verify Topipay's signature on API V3 webhooks.
|
|
547
|
-
* @param {string} originalCurrencyAmount
|
|
548
|
-
* @param {string} bankOrderCode
|
|
549
|
-
* @param {string} signature signaturev3 field to be verified
|
|
550
|
-
* @returns {boolean}
|
|
551
|
-
*/
|
|
552
|
-
static verifySignatureV3(credentials: {
|
|
553
|
-
clientId: string;
|
|
554
|
-
clientSecret: string;
|
|
555
|
-
} | Tropipay, originalCurrencyAmount: string, bankOrderCode: string, signature: string): boolean;
|
|
556
493
|
}
|
|
557
494
|
|
|
558
495
|
declare const SERVER_MODE: ServerMode$1;
|
|
559
496
|
|
|
560
|
-
export { AccountBalance, AccountDeposits, ClientSideUtils, Country, Deposit, HookEventType, HookTargetType, LoginError, LoginResponse, MAX_IMAGE_SIZE_MB, MediationPaymentCardConfig, PaymentLink, PaymentLinkPayload, SERVER_MODE, ServerMode$1 as ServerMode, ServerSideUtils, Tropipay, TropipayConfig, TropipayCredentials, UserHook, UserHookSubscribed };
|
|
497
|
+
export { AccountBalance, AccountDeposits, ClientSideUtils, Country, Deposit, HookEventType, HookTargetType, LoginError, LoginResponse, MAX_IMAGE_SIZE_MB, MediationPaymentCardConfig, PaymentLink, PaymentLinkPayload, RefundResponse, SERVER_MODE, ServerMode$1 as ServerMode, ServerSideUtils, Tropipay, TropipayConfig, TropipayCredentials, UserHook, UserHookSubscribed };
|
package/index.js
CHANGED
|
@@ -220,7 +220,7 @@ class PaymentCard {
|
|
|
220
220
|
await this.tropipay.login();
|
|
221
221
|
}
|
|
222
222
|
try {
|
|
223
|
-
const paylink = await this.tropipay.request.post("/api/
|
|
223
|
+
const paylink = await this.tropipay.request.post("/api/v2/paymentcards", payload, {
|
|
224
224
|
headers: {
|
|
225
225
|
"Content-Type": "application/json",
|
|
226
226
|
Authorization: `Bearer ${Tropipay.accessToken}`,
|
|
@@ -243,7 +243,7 @@ class PaymentCard {
|
|
|
243
243
|
await this.tropipay.login();
|
|
244
244
|
}
|
|
245
245
|
try {
|
|
246
|
-
const paymentcards = await this.tropipay.request.get(`/api/
|
|
246
|
+
const paymentcards = await this.tropipay.request.get(`/api/v2/paymentcards`, {
|
|
247
247
|
headers: {
|
|
248
248
|
"Content-Type": "application/json",
|
|
249
249
|
Authorization: `Bearer ${Tropipay.accessToken}`,
|
|
@@ -268,7 +268,7 @@ class PaymentCard {
|
|
|
268
268
|
await this.tropipay.login();
|
|
269
269
|
}
|
|
270
270
|
try {
|
|
271
|
-
const paymentcard = await this.tropipay.request.get(`/api/
|
|
271
|
+
const paymentcard = await this.tropipay.request.get(`/api/v2/paymentcards/${id}`, {
|
|
272
272
|
headers: {
|
|
273
273
|
"Content-Type": "application/json",
|
|
274
274
|
Authorization: `Bearer ${Tropipay.accessToken}`,
|
|
@@ -294,7 +294,7 @@ class PaymentCard {
|
|
|
294
294
|
await this.tropipay.login();
|
|
295
295
|
}
|
|
296
296
|
try {
|
|
297
|
-
const paymentcard = await this.tropipay.request.delete(`/api/
|
|
297
|
+
const paymentcard = await this.tropipay.request.delete(`/api/v2/paymentcards/`, {
|
|
298
298
|
headers: {
|
|
299
299
|
"Content-Type": "application/json",
|
|
300
300
|
Authorization: `Bearer ${Tropipay.accessToken}`,
|
|
@@ -360,7 +360,7 @@ class DepositAccounts {
|
|
|
360
360
|
await this.tropipay.login();
|
|
361
361
|
}
|
|
362
362
|
try {
|
|
363
|
-
const deposit = await this.tropipay.request.get(`/api/
|
|
363
|
+
const deposit = await this.tropipay.request.get(`/api/v2/deposit_accounts`, {
|
|
364
364
|
headers: {
|
|
365
365
|
"Content-Type": "application/json",
|
|
366
366
|
Authorization: `Bearer ${Tropipay.accessToken}`,
|
|
@@ -383,7 +383,7 @@ class DepositAccounts {
|
|
|
383
383
|
await this.tropipay.login();
|
|
384
384
|
}
|
|
385
385
|
try {
|
|
386
|
-
const deposit = await this.tropipay.request.post("/api/
|
|
386
|
+
const deposit = await this.tropipay.request.post("/api/v2/deposit_accounts", depositAccountObj, {
|
|
387
387
|
headers: {
|
|
388
388
|
"Content-Type": "application/json",
|
|
389
389
|
Authorization: `Bearer ${Tropipay.accessToken}`,
|
|
@@ -407,7 +407,7 @@ class DepositAccounts {
|
|
|
407
407
|
await this.tropipay.login();
|
|
408
408
|
}
|
|
409
409
|
try {
|
|
410
|
-
const deposit = await this.tropipay.request.get(`/api/
|
|
410
|
+
const deposit = await this.tropipay.request.get(`/api/v2/deposit_accounts/${id}`, {
|
|
411
411
|
headers: {
|
|
412
412
|
"Content-Type": "application/json",
|
|
413
413
|
Authorization: `Bearer ${Tropipay.accessToken}`,
|
|
@@ -430,7 +430,7 @@ class DepositAccounts {
|
|
|
430
430
|
await this.tropipay.login();
|
|
431
431
|
}
|
|
432
432
|
try {
|
|
433
|
-
const deposit = await this.tropipay.request.put(`/api/
|
|
433
|
+
const deposit = await this.tropipay.request.put(`/api/v2/deposit_accounts/`, {
|
|
434
434
|
headers: {
|
|
435
435
|
"Content-Type": "application/json",
|
|
436
436
|
Authorization: `Bearer ${Tropipay.accessToken}`,
|
|
@@ -453,7 +453,7 @@ class DepositAccounts {
|
|
|
453
453
|
await this.tropipay.login();
|
|
454
454
|
}
|
|
455
455
|
try {
|
|
456
|
-
const deposit = await this.tropipay.request.delete(`/api/
|
|
456
|
+
const deposit = await this.tropipay.request.delete(`/api/v2/deposit_accounts/${id}`, {
|
|
457
457
|
headers: {
|
|
458
458
|
"Content-Type": "application/json",
|
|
459
459
|
Authorization: `Bearer ${Tropipay.accessToken}`,
|
|
@@ -468,35 +468,6 @@ class DepositAccounts {
|
|
|
468
468
|
}
|
|
469
469
|
}
|
|
470
470
|
|
|
471
|
-
class Accounts {
|
|
472
|
-
tropipay;
|
|
473
|
-
constructor(tropipayInstance) {
|
|
474
|
-
this.tropipay = tropipayInstance;
|
|
475
|
-
}
|
|
476
|
-
/**
|
|
477
|
-
* List all accounts of the authenticated user
|
|
478
|
-
* @returns Array of Account objects
|
|
479
|
-
*/
|
|
480
|
-
async list() {
|
|
481
|
-
if (!Tropipay.accessToken) {
|
|
482
|
-
await this.tropipay.login();
|
|
483
|
-
}
|
|
484
|
-
try {
|
|
485
|
-
const accounts = await this.tropipay.request.get(`/api/v3/accounts/`, {
|
|
486
|
-
headers: {
|
|
487
|
-
"Content-Type": "application/json",
|
|
488
|
-
Authorization: `Bearer ${Tropipay.accessToken}`,
|
|
489
|
-
Accept: "application/json",
|
|
490
|
-
},
|
|
491
|
-
});
|
|
492
|
-
return accounts.data;
|
|
493
|
-
}
|
|
494
|
-
catch (error) {
|
|
495
|
-
throw handleExceptions(error);
|
|
496
|
-
}
|
|
497
|
-
}
|
|
498
|
-
}
|
|
499
|
-
|
|
500
471
|
/**
|
|
501
472
|
* Tropipayjs is a Typescript/Javascript library for the Tropipay API.
|
|
502
473
|
*
|
|
@@ -508,7 +479,6 @@ class Tropipay {
|
|
|
508
479
|
clientSecret;
|
|
509
480
|
scopes;
|
|
510
481
|
request;
|
|
511
|
-
loginRequest;
|
|
512
482
|
static accessToken;
|
|
513
483
|
static refreshToken;
|
|
514
484
|
static expiresIn;
|
|
@@ -517,7 +487,6 @@ class Tropipay {
|
|
|
517
487
|
paymentCards;
|
|
518
488
|
depositAccounts;
|
|
519
489
|
mediationPaymentCard;
|
|
520
|
-
accounts;
|
|
521
490
|
/**
|
|
522
491
|
* Initializes a new instance of the Tropipay class.
|
|
523
492
|
*
|
|
@@ -536,6 +505,7 @@ class Tropipay {
|
|
|
536
505
|
"ALLOW_GET_BALANCE",
|
|
537
506
|
"ALLOW_GET_MOVEMENT_LIST",
|
|
538
507
|
"ALLOW_GET_CREDENTIAL",
|
|
508
|
+
"ALLOW_REFUND",
|
|
539
509
|
];
|
|
540
510
|
}
|
|
541
511
|
else {
|
|
@@ -549,7 +519,7 @@ class Tropipay {
|
|
|
549
519
|
this.serverMode = config.serverMode || "Development";
|
|
550
520
|
const tpp_env = this.serverMode === "Production"
|
|
551
521
|
? "https://www.tropipay.com"
|
|
552
|
-
: "https://
|
|
522
|
+
: "https://tropipay-dev.herokuapp.com";
|
|
553
523
|
this.request = axios__default["default"].create({
|
|
554
524
|
baseURL: config.customTropipayUrl || tpp_env,
|
|
555
525
|
headers: {
|
|
@@ -558,28 +528,21 @@ class Tropipay {
|
|
|
558
528
|
Authorization: `Bearer ${Tropipay.accessToken}`,
|
|
559
529
|
},
|
|
560
530
|
});
|
|
561
|
-
// Create a separate instance for login requests
|
|
562
|
-
this.loginRequest = axios__default["default"].create({
|
|
563
|
-
baseURL: config.customTropipayUrl || tpp_env,
|
|
564
|
-
headers: {
|
|
565
|
-
"Content-Type": "application/json",
|
|
566
|
-
Accept: "application/json",
|
|
567
|
-
},
|
|
568
|
-
});
|
|
569
531
|
// Add request interceptor for Token expired
|
|
570
532
|
this.request.interceptors.request.use(async (config) => {
|
|
571
|
-
const currentTimestamp = Math.floor(Date.now() / 1000);
|
|
533
|
+
const currentTimestamp = Math.floor(Date.now() / 1000); // Current time in seconds
|
|
572
534
|
if (Tropipay.expiresIn && Tropipay.expiresIn < currentTimestamp) {
|
|
573
|
-
|
|
535
|
+
// Token has expired, attempt to refresh it
|
|
574
536
|
try {
|
|
575
537
|
await this.login();
|
|
576
538
|
}
|
|
577
539
|
catch (error) {
|
|
540
|
+
// Handle token refresh error
|
|
541
|
+
Tropipay.accessToken = null;
|
|
542
|
+
Tropipay.refreshToken = null;
|
|
578
543
|
throw handleExceptions(error);
|
|
579
544
|
}
|
|
580
545
|
}
|
|
581
|
-
// Update the Authorization header in the config
|
|
582
|
-
config.headers.Authorization = `Bearer ${Tropipay.accessToken}`;
|
|
583
546
|
return config;
|
|
584
547
|
}, (error) => {
|
|
585
548
|
return Promise.reject(error);
|
|
@@ -588,12 +551,25 @@ class Tropipay {
|
|
|
588
551
|
this.paymentCards = new PaymentCard(this);
|
|
589
552
|
this.mediationPaymentCard = new MediationPaymentCard(this);
|
|
590
553
|
this.depositAccounts = new DepositAccounts(this);
|
|
591
|
-
this.accounts = new Accounts(this);
|
|
592
554
|
}
|
|
593
555
|
async login() {
|
|
594
556
|
try {
|
|
557
|
+
if (Tropipay.refreshToken) {
|
|
558
|
+
const { data } = await this.request.post("/api/v2/access/token", {
|
|
559
|
+
client_id: this.clientId,
|
|
560
|
+
client_secret: this.clientSecret,
|
|
561
|
+
grant_type: "refresh_token",
|
|
562
|
+
refresh_token: Tropipay.refreshToken,
|
|
563
|
+
}, {
|
|
564
|
+
headers: {
|
|
565
|
+
"Content-Type": "application/json",
|
|
566
|
+
Accept: "application/json",
|
|
567
|
+
},
|
|
568
|
+
});
|
|
569
|
+
return data;
|
|
570
|
+
}
|
|
595
571
|
// normal credetials login
|
|
596
|
-
const { data } = await this.
|
|
572
|
+
const { data } = await this.request.post("/api/v2/access/token", {
|
|
597
573
|
client_id: this.clientId,
|
|
598
574
|
client_secret: this.clientSecret,
|
|
599
575
|
grant_type: "client_credentials",
|
|
@@ -605,6 +581,7 @@ class Tropipay {
|
|
|
605
581
|
},
|
|
606
582
|
});
|
|
607
583
|
Tropipay.accessToken = data.access_token;
|
|
584
|
+
Tropipay.refreshToken = data.refresh_token;
|
|
608
585
|
Tropipay.expiresIn = data.expires_in;
|
|
609
586
|
return data;
|
|
610
587
|
}
|
|
@@ -612,7 +589,6 @@ class Tropipay {
|
|
|
612
589
|
Tropipay.accessToken = null;
|
|
613
590
|
Tropipay.refreshToken = null;
|
|
614
591
|
Tropipay.expiresIn = null;
|
|
615
|
-
Tropipay.expiresIn = null;
|
|
616
592
|
throw handleExceptions(error);
|
|
617
593
|
}
|
|
618
594
|
}
|
|
@@ -764,6 +740,7 @@ class Tropipay {
|
|
|
764
740
|
* belonging or not to the TropiPay platform with the particularity
|
|
765
741
|
* that the payment will be held in custody or retained until it is
|
|
766
742
|
* released with the approval of the payer.
|
|
743
|
+
* @deprecated This method is no longer supported and may be removed in a future release.
|
|
767
744
|
* @see https://tpp.stoplight.io/docs/tropipay-api-doc/12a128ff971e4-creating-a-mediation-payment-card
|
|
768
745
|
* @param config Payload with the payment details
|
|
769
746
|
*/
|
|
@@ -784,6 +761,71 @@ class Tropipay {
|
|
|
784
761
|
throw handleExceptions(error);
|
|
785
762
|
}
|
|
786
763
|
}
|
|
764
|
+
/**
|
|
765
|
+
* Refund a completed transaction.
|
|
766
|
+
* Requires 2FA enabled and ALLOW_REFUND permission on the Tropipay account.
|
|
767
|
+
*
|
|
768
|
+
* In Development mode, `securityCode` defaults to `"123456"` when omitted.
|
|
769
|
+
* In Production mode, you must first call `requestSecurityCode()` to receive
|
|
770
|
+
* the 2FA code via SMS, then pass it as the `securityCode` parameter.
|
|
771
|
+
*
|
|
772
|
+
* @see https://doc.tropipay.com/docs/api-reference/movements#refund-a-transaction
|
|
773
|
+
* @param orderCode Code of the order/transaction to refund (e.g. "ORD-123456")
|
|
774
|
+
* @param amount Amount to refund in cents (e.g. 5000 = 50.00 USD/EUR)
|
|
775
|
+
* @param securityCode 2FA confirmation code. Use "123456" in Development or
|
|
776
|
+
* the code received via SMS in Production (obtained via requestSecurityCode()).
|
|
777
|
+
*/
|
|
778
|
+
async refundMovement(orderCode, amount, securityCode) {
|
|
779
|
+
if (!Tropipay.accessToken) {
|
|
780
|
+
await this.login();
|
|
781
|
+
}
|
|
782
|
+
if (!this.scopes.includes("ALLOW_REFUND")) {
|
|
783
|
+
throw new TropipayJSException("The credential does not have the ALLOW_REFUND scope required to perform refunds. If you believe your account should have this permission, please contact Tropipay support.", 403, null);
|
|
784
|
+
}
|
|
785
|
+
try {
|
|
786
|
+
const response = await this.request.post("/api/v3/movements/in/refund", { orderCode, amount, securityCode }, {
|
|
787
|
+
headers: {
|
|
788
|
+
"Content-Type": "application/json",
|
|
789
|
+
Accept: "application/json",
|
|
790
|
+
Authorization: `Bearer ${Tropipay.accessToken}`,
|
|
791
|
+
},
|
|
792
|
+
});
|
|
793
|
+
return response.data;
|
|
794
|
+
}
|
|
795
|
+
catch (error) {
|
|
796
|
+
throw handleExceptions(error);
|
|
797
|
+
}
|
|
798
|
+
}
|
|
799
|
+
/**
|
|
800
|
+
* Request a 2FA security code to be sent via SMS for confirming sensitive
|
|
801
|
+
* operations like refunds.
|
|
802
|
+
*
|
|
803
|
+
* In Production mode, you must call this method first to trigger an SMS with
|
|
804
|
+
* the code, then use the received code when calling `refundMovement()`.
|
|
805
|
+
* In Development mode this is not required as the default code "123456"
|
|
806
|
+
* is used automatically.
|
|
807
|
+
*
|
|
808
|
+
* @see https://doc.tropipay.com/docs/api-reference/movements#refund-a-transaction
|
|
809
|
+
* @returns The API response confirming the code was sent
|
|
810
|
+
*/
|
|
811
|
+
async requestSecurityCode(type = "sms") {
|
|
812
|
+
if (!Tropipay.accessToken) {
|
|
813
|
+
await this.login();
|
|
814
|
+
}
|
|
815
|
+
try {
|
|
816
|
+
const response = await this.request.post("/api/v3/users/sendSecurityCode", { type }, {
|
|
817
|
+
headers: {
|
|
818
|
+
"Content-Type": "application/json",
|
|
819
|
+
Accept: "application/json",
|
|
820
|
+
Authorization: `Bearer ${Tropipay.accessToken}`,
|
|
821
|
+
},
|
|
822
|
+
});
|
|
823
|
+
return response.data;
|
|
824
|
+
}
|
|
825
|
+
catch (error) {
|
|
826
|
+
throw handleExceptions(error);
|
|
827
|
+
}
|
|
828
|
+
}
|
|
787
829
|
}
|
|
788
830
|
class ClientSideUtils {
|
|
789
831
|
constructor(tropipayInstance) {
|
|
@@ -799,9 +841,7 @@ class ServerSideUtils {
|
|
|
799
841
|
this.tropipay = tropipayInstance;
|
|
800
842
|
}
|
|
801
843
|
/**
|
|
802
|
-
*
|
|
803
|
-
* @deprecated This method is deprecated and will be removed in future versions.
|
|
804
|
-
* Use the `verifySignatureV3` method from the `ServerSideUtils` class instead.
|
|
844
|
+
* Verify Topipay's signature on webhooks.
|
|
805
845
|
* @param credentials Credential object or Tropipay instance
|
|
806
846
|
* @param {String} originalCurrencyAmount
|
|
807
847
|
* @param bankOrderCode
|
|
@@ -891,28 +931,6 @@ class ServerSideUtils {
|
|
|
891
931
|
throw new Error(`Error checking base64 image`);
|
|
892
932
|
}
|
|
893
933
|
}
|
|
894
|
-
/**
|
|
895
|
-
* Verify Topipay's signature on API V3 webhooks.
|
|
896
|
-
* @param {string} originalCurrencyAmount
|
|
897
|
-
* @param {string} bankOrderCode
|
|
898
|
-
* @param {string} signature signaturev3 field to be verified
|
|
899
|
-
* @returns {boolean}
|
|
900
|
-
*/
|
|
901
|
-
static verifySignatureV3(credentials, originalCurrencyAmount, bankOrderCode, signature) {
|
|
902
|
-
const sha1Secret = crypto__namespace
|
|
903
|
-
.createHash("sha1")
|
|
904
|
-
.update(credentials.clientSecret)
|
|
905
|
-
.digest("hex");
|
|
906
|
-
const dataToHash = bankOrderCode +
|
|
907
|
-
credentials.clientId +
|
|
908
|
-
sha1Secret +
|
|
909
|
-
originalCurrencyAmount;
|
|
910
|
-
const localSignature = crypto__namespace
|
|
911
|
-
.createHash("sha256")
|
|
912
|
-
.update(dataToHash)
|
|
913
|
-
.digest("hex");
|
|
914
|
-
return localSignature === signature;
|
|
915
|
-
}
|
|
916
934
|
}
|
|
917
935
|
|
|
918
936
|
const SERVER_MODE = "Development"; // Move the constant here
|