@yosle/tropipayjs 0.2.0 → 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 -2
- package/index.d.ts +41 -17
- package/index.js +99 -50
- package/interfaces/index.d.ts +10 -1
- 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 -27
- package/src/depositAccount/depositAccounts.ts +5 -5
- package/src/index.ts +1 -0
- package/src/interfaces/index.ts +11 -1
- 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/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,7 +5,7 @@
|
|
|
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";
|
|
@@ -16,7 +16,6 @@ export declare class Tropipay {
|
|
|
16
16
|
readonly clientSecret: string;
|
|
17
17
|
readonly scopes: String[];
|
|
18
18
|
request: Axios;
|
|
19
|
-
loginRequest: Axios;
|
|
20
19
|
static accessToken: string | null;
|
|
21
20
|
static refreshToken: string | null;
|
|
22
21
|
static expiresIn: number | null;
|
|
@@ -83,10 +82,39 @@ export declare class Tropipay {
|
|
|
83
82
|
* belonging or not to the TropiPay platform with the particularity
|
|
84
83
|
* that the payment will be held in custody or retained until it is
|
|
85
84
|
* released with the approval of the payer.
|
|
85
|
+
* @deprecated This method is no longer supported and may be removed in a future release.
|
|
86
86
|
* @see https://tpp.stoplight.io/docs/tropipay-api-doc/12a128ff971e4-creating-a-mediation-payment-card
|
|
87
87
|
* @param config Payload with the payment details
|
|
88
88
|
*/
|
|
89
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>;
|
|
90
118
|
}
|
|
91
119
|
export declare class ClientSideUtils {
|
|
92
120
|
constructor(tropipayInstance: Tropipay);
|
|
@@ -100,5 +128,6 @@ export declare const Scopes: {
|
|
|
100
128
|
ALLOW_GET_BALANCE: string;
|
|
101
129
|
ALLOW_GET_MOVEMENT_LIST: string;
|
|
102
130
|
ALLOW_GET_CREDENTIAL: string;
|
|
131
|
+
ALLOW_REFUND: string;
|
|
103
132
|
};
|
|
104
133
|
export {};
|
package/index.d.ts
CHANGED
|
@@ -40,7 +40,6 @@ interface UserHookSubscribed extends UserHook {
|
|
|
40
40
|
updatedAt: string;
|
|
41
41
|
}
|
|
42
42
|
interface PaymentLinkPayload {
|
|
43
|
-
accountId: number;
|
|
44
43
|
reference: string;
|
|
45
44
|
concept: string;
|
|
46
45
|
favorite: boolean;
|
|
@@ -169,6 +168,16 @@ type AccountDeposits = {
|
|
|
169
168
|
count: number;
|
|
170
169
|
rows: Deposit[];
|
|
171
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
|
+
};
|
|
172
181
|
|
|
173
182
|
declare class TropipayHooks {
|
|
174
183
|
private tropipay;
|
|
@@ -334,7 +343,6 @@ declare class Tropipay {
|
|
|
334
343
|
readonly clientSecret: string;
|
|
335
344
|
readonly scopes: String[];
|
|
336
345
|
request: Axios;
|
|
337
|
-
loginRequest: Axios;
|
|
338
346
|
static accessToken: string | null;
|
|
339
347
|
static refreshToken: string | null;
|
|
340
348
|
static expiresIn: number | null;
|
|
@@ -401,10 +409,39 @@ declare class Tropipay {
|
|
|
401
409
|
* belonging or not to the TropiPay platform with the particularity
|
|
402
410
|
* that the payment will be held in custody or retained until it is
|
|
403
411
|
* released with the approval of the payer.
|
|
412
|
+
* @deprecated This method is no longer supported and may be removed in a future release.
|
|
404
413
|
* @see https://tpp.stoplight.io/docs/tropipay-api-doc/12a128ff971e4-creating-a-mediation-payment-card
|
|
405
414
|
* @param config Payload with the payment details
|
|
406
415
|
*/
|
|
407
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>;
|
|
408
445
|
}
|
|
409
446
|
declare class ClientSideUtils {
|
|
410
447
|
constructor(tropipayInstance: Tropipay);
|
|
@@ -414,9 +451,7 @@ declare class ServerSideUtils {
|
|
|
414
451
|
private tropipay;
|
|
415
452
|
constructor(tropipayInstance: Tropipay);
|
|
416
453
|
/**
|
|
417
|
-
*
|
|
418
|
-
* @deprecated This method is deprecated and will be removed in future versions.
|
|
419
|
-
* Use the `verifySignatureV3` method from the `ServerSideUtils` class instead.
|
|
454
|
+
* Verify Topipay's signature on webhooks.
|
|
420
455
|
* @param credentials Credential object or Tropipay instance
|
|
421
456
|
* @param {String} originalCurrencyAmount
|
|
422
457
|
* @param bankOrderCode
|
|
@@ -455,19 +490,8 @@ declare class ServerSideUtils {
|
|
|
455
490
|
* @return {Promise<string>} the valid base64 image
|
|
456
491
|
*/
|
|
457
492
|
static isValidImage(base64Image: string): boolean;
|
|
458
|
-
/**
|
|
459
|
-
* Verify Topipay's signature on API V3 webhooks.
|
|
460
|
-
* @param {string} originalCurrencyAmount
|
|
461
|
-
* @param {string} bankOrderCode
|
|
462
|
-
* @param {string} signature signaturev3 field to be verified
|
|
463
|
-
* @returns {boolean}
|
|
464
|
-
*/
|
|
465
|
-
static verifySignatureV3(credentials: {
|
|
466
|
-
clientId: string;
|
|
467
|
-
clientSecret: string;
|
|
468
|
-
} | Tropipay, originalCurrencyAmount: string, bankOrderCode: string, signature: string): boolean;
|
|
469
493
|
}
|
|
470
494
|
|
|
471
495
|
declare const SERVER_MODE: ServerMode$1;
|
|
472
496
|
|
|
473
|
-
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}`,
|
|
@@ -479,7 +479,6 @@ class Tropipay {
|
|
|
479
479
|
clientSecret;
|
|
480
480
|
scopes;
|
|
481
481
|
request;
|
|
482
|
-
loginRequest;
|
|
483
482
|
static accessToken;
|
|
484
483
|
static refreshToken;
|
|
485
484
|
static expiresIn;
|
|
@@ -506,6 +505,7 @@ class Tropipay {
|
|
|
506
505
|
"ALLOW_GET_BALANCE",
|
|
507
506
|
"ALLOW_GET_MOVEMENT_LIST",
|
|
508
507
|
"ALLOW_GET_CREDENTIAL",
|
|
508
|
+
"ALLOW_REFUND",
|
|
509
509
|
];
|
|
510
510
|
}
|
|
511
511
|
else {
|
|
@@ -519,7 +519,7 @@ class Tropipay {
|
|
|
519
519
|
this.serverMode = config.serverMode || "Development";
|
|
520
520
|
const tpp_env = this.serverMode === "Production"
|
|
521
521
|
? "https://www.tropipay.com"
|
|
522
|
-
: "https://
|
|
522
|
+
: "https://tropipay-dev.herokuapp.com";
|
|
523
523
|
this.request = axios__default["default"].create({
|
|
524
524
|
baseURL: config.customTropipayUrl || tpp_env,
|
|
525
525
|
headers: {
|
|
@@ -528,28 +528,21 @@ class Tropipay {
|
|
|
528
528
|
Authorization: `Bearer ${Tropipay.accessToken}`,
|
|
529
529
|
},
|
|
530
530
|
});
|
|
531
|
-
// Create a separate instance for login requests
|
|
532
|
-
this.loginRequest = axios__default["default"].create({
|
|
533
|
-
baseURL: config.customTropipayUrl || tpp_env,
|
|
534
|
-
headers: {
|
|
535
|
-
"Content-Type": "application/json",
|
|
536
|
-
Accept: "application/json",
|
|
537
|
-
},
|
|
538
|
-
});
|
|
539
531
|
// Add request interceptor for Token expired
|
|
540
532
|
this.request.interceptors.request.use(async (config) => {
|
|
541
|
-
const currentTimestamp = Math.floor(Date.now() / 1000);
|
|
533
|
+
const currentTimestamp = Math.floor(Date.now() / 1000); // Current time in seconds
|
|
542
534
|
if (Tropipay.expiresIn && Tropipay.expiresIn < currentTimestamp) {
|
|
543
|
-
|
|
535
|
+
// Token has expired, attempt to refresh it
|
|
544
536
|
try {
|
|
545
537
|
await this.login();
|
|
546
538
|
}
|
|
547
539
|
catch (error) {
|
|
540
|
+
// Handle token refresh error
|
|
541
|
+
Tropipay.accessToken = null;
|
|
542
|
+
Tropipay.refreshToken = null;
|
|
548
543
|
throw handleExceptions(error);
|
|
549
544
|
}
|
|
550
545
|
}
|
|
551
|
-
// Update the Authorization header in the config
|
|
552
|
-
config.headers.Authorization = `Bearer ${Tropipay.accessToken}`;
|
|
553
546
|
return config;
|
|
554
547
|
}, (error) => {
|
|
555
548
|
return Promise.reject(error);
|
|
@@ -561,8 +554,22 @@ class Tropipay {
|
|
|
561
554
|
}
|
|
562
555
|
async login() {
|
|
563
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
|
+
}
|
|
564
571
|
// normal credetials login
|
|
565
|
-
const { data } = await this.
|
|
572
|
+
const { data } = await this.request.post("/api/v2/access/token", {
|
|
566
573
|
client_id: this.clientId,
|
|
567
574
|
client_secret: this.clientSecret,
|
|
568
575
|
grant_type: "client_credentials",
|
|
@@ -574,6 +581,7 @@ class Tropipay {
|
|
|
574
581
|
},
|
|
575
582
|
});
|
|
576
583
|
Tropipay.accessToken = data.access_token;
|
|
584
|
+
Tropipay.refreshToken = data.refresh_token;
|
|
577
585
|
Tropipay.expiresIn = data.expires_in;
|
|
578
586
|
return data;
|
|
579
587
|
}
|
|
@@ -581,7 +589,6 @@ class Tropipay {
|
|
|
581
589
|
Tropipay.accessToken = null;
|
|
582
590
|
Tropipay.refreshToken = null;
|
|
583
591
|
Tropipay.expiresIn = null;
|
|
584
|
-
Tropipay.expiresIn = null;
|
|
585
592
|
throw handleExceptions(error);
|
|
586
593
|
}
|
|
587
594
|
}
|
|
@@ -733,6 +740,7 @@ class Tropipay {
|
|
|
733
740
|
* belonging or not to the TropiPay platform with the particularity
|
|
734
741
|
* that the payment will be held in custody or retained until it is
|
|
735
742
|
* released with the approval of the payer.
|
|
743
|
+
* @deprecated This method is no longer supported and may be removed in a future release.
|
|
736
744
|
* @see https://tpp.stoplight.io/docs/tropipay-api-doc/12a128ff971e4-creating-a-mediation-payment-card
|
|
737
745
|
* @param config Payload with the payment details
|
|
738
746
|
*/
|
|
@@ -753,6 +761,71 @@ class Tropipay {
|
|
|
753
761
|
throw handleExceptions(error);
|
|
754
762
|
}
|
|
755
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
|
+
}
|
|
756
829
|
}
|
|
757
830
|
class ClientSideUtils {
|
|
758
831
|
constructor(tropipayInstance) {
|
|
@@ -768,9 +841,7 @@ class ServerSideUtils {
|
|
|
768
841
|
this.tropipay = tropipayInstance;
|
|
769
842
|
}
|
|
770
843
|
/**
|
|
771
|
-
*
|
|
772
|
-
* @deprecated This method is deprecated and will be removed in future versions.
|
|
773
|
-
* Use the `verifySignatureV3` method from the `ServerSideUtils` class instead.
|
|
844
|
+
* Verify Topipay's signature on webhooks.
|
|
774
845
|
* @param credentials Credential object or Tropipay instance
|
|
775
846
|
* @param {String} originalCurrencyAmount
|
|
776
847
|
* @param bankOrderCode
|
|
@@ -860,28 +931,6 @@ class ServerSideUtils {
|
|
|
860
931
|
throw new Error(`Error checking base64 image`);
|
|
861
932
|
}
|
|
862
933
|
}
|
|
863
|
-
/**
|
|
864
|
-
* Verify Topipay's signature on API V3 webhooks.
|
|
865
|
-
* @param {string} originalCurrencyAmount
|
|
866
|
-
* @param {string} bankOrderCode
|
|
867
|
-
* @param {string} signature signaturev3 field to be verified
|
|
868
|
-
* @returns {boolean}
|
|
869
|
-
*/
|
|
870
|
-
static verifySignatureV3(credentials, originalCurrencyAmount, bankOrderCode, signature) {
|
|
871
|
-
const sha1Secret = crypto__namespace
|
|
872
|
-
.createHash("sha1")
|
|
873
|
-
.update(credentials.clientSecret)
|
|
874
|
-
.digest("hex");
|
|
875
|
-
const dataToHash = bankOrderCode +
|
|
876
|
-
credentials.clientId +
|
|
877
|
-
sha1Secret +
|
|
878
|
-
originalCurrencyAmount;
|
|
879
|
-
const localSignature = crypto__namespace
|
|
880
|
-
.createHash("sha256")
|
|
881
|
-
.update(dataToHash)
|
|
882
|
-
.digest("hex");
|
|
883
|
-
return localSignature === signature;
|
|
884
|
-
}
|
|
885
934
|
}
|
|
886
935
|
|
|
887
936
|
const SERVER_MODE = "Development"; // Move the constant here
|
package/interfaces/index.d.ts
CHANGED
|
@@ -36,7 +36,6 @@ export interface UserHookSubscribed extends UserHook {
|
|
|
36
36
|
updatedAt: string;
|
|
37
37
|
}
|
|
38
38
|
export interface PaymentLinkPayload {
|
|
39
|
-
accountId: number;
|
|
40
39
|
reference: string;
|
|
41
40
|
concept: string;
|
|
42
41
|
favorite: boolean;
|
|
@@ -165,3 +164,13 @@ export type AccountDeposits = {
|
|
|
165
164
|
count: number;
|
|
166
165
|
rows: Deposit[];
|
|
167
166
|
};
|
|
167
|
+
export type RefundResponse = {
|
|
168
|
+
id: number;
|
|
169
|
+
orderCode: string;
|
|
170
|
+
amount: number;
|
|
171
|
+
currency: string;
|
|
172
|
+
state: string;
|
|
173
|
+
type: string;
|
|
174
|
+
createdAt: string;
|
|
175
|
+
completedAt: string;
|
|
176
|
+
};
|
|
@@ -46,7 +46,6 @@ declare enum Reasons {
|
|
|
46
46
|
SENDING_YOU_A_KISS = 80
|
|
47
47
|
}
|
|
48
48
|
export interface PaymentLinkPayload {
|
|
49
|
-
accountId: number;
|
|
50
49
|
reference: string;
|
|
51
50
|
concept: string;
|
|
52
51
|
favorite: boolean;
|
|
@@ -61,6 +60,9 @@ export interface PaymentLinkPayload {
|
|
|
61
60
|
urlFailed: string;
|
|
62
61
|
urlNotification: string;
|
|
63
62
|
serviceDate: string;
|
|
63
|
+
/**
|
|
64
|
+
* fgfsgdfgdfgd
|
|
65
|
+
*/
|
|
64
66
|
client?: {
|
|
65
67
|
name: string;
|
|
66
68
|
lastName: string;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@yosle/tropipayjs",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.2",
|
|
4
4
|
"description": "Javascript / Typescript SDK for the Tropipay API",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"scripts": {
|
|
@@ -12,7 +12,10 @@
|
|
|
12
12
|
},
|
|
13
13
|
"repository": {
|
|
14
14
|
"type": "git",
|
|
15
|
-
"url": "https://github.com/yosle/tropipayjs"
|
|
15
|
+
"url": "git+https://github.com/yosle/tropipayjs.git"
|
|
16
|
+
},
|
|
17
|
+
"publishConfig": {
|
|
18
|
+
"access": "public"
|
|
16
19
|
},
|
|
17
20
|
"keywords": [
|
|
18
21
|
"Javascript",
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
declare function sum(a: number, b: number): number;
|
package/src/api/TropipayAPI.ts
CHANGED
|
@@ -15,6 +15,7 @@ import {
|
|
|
15
15
|
MediationPaymentCardConfig,
|
|
16
16
|
LoginResponse,
|
|
17
17
|
AccountDeposits,
|
|
18
|
+
RefundResponse,
|
|
18
19
|
} from "../interfaces";
|
|
19
20
|
type ServerMode = "Development" | "Production";
|
|
20
21
|
import TropipayHooks from "../hooks/TropipayHooks";
|
|
@@ -27,7 +28,6 @@ export class Tropipay {
|
|
|
27
28
|
readonly clientSecret: string;
|
|
28
29
|
readonly scopes: String[];
|
|
29
30
|
public request: Axios;
|
|
30
|
-
public loginRequest: Axios;
|
|
31
31
|
public static accessToken: string | null;
|
|
32
32
|
public static refreshToken: string | null;
|
|
33
33
|
public static expiresIn: number | null;
|
|
@@ -56,6 +56,7 @@ export class Tropipay {
|
|
|
56
56
|
"ALLOW_GET_BALANCE",
|
|
57
57
|
"ALLOW_GET_MOVEMENT_LIST",
|
|
58
58
|
"ALLOW_GET_CREDENTIAL",
|
|
59
|
+
"ALLOW_REFUND",
|
|
59
60
|
];
|
|
60
61
|
} else {
|
|
61
62
|
this.scopes = config.scopes;
|
|
@@ -73,12 +74,11 @@ export class Tropipay {
|
|
|
73
74
|
this.clientSecret = config.clientSecret;
|
|
74
75
|
this.serverMode = config.serverMode || "Development";
|
|
75
76
|
|
|
76
|
-
const tpp_env =
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
: "https://sandbox.tropipay.me";
|
|
77
|
+
const tpp_env = this.serverMode === "Production"
|
|
78
|
+
? "https://www.tropipay.com"
|
|
79
|
+
: "https://tropipay-dev.herokuapp.com";
|
|
80
80
|
this.request = axios.create({
|
|
81
|
-
baseURL: config.customTropipayUrl || tpp_env,
|
|
81
|
+
baseURL: config.customTropipayUrl || tpp_env,
|
|
82
82
|
headers: {
|
|
83
83
|
"Content-Type": "application/json",
|
|
84
84
|
Accept: "application/json",
|
|
@@ -86,33 +86,27 @@ export class Tropipay {
|
|
|
86
86
|
},
|
|
87
87
|
});
|
|
88
88
|
|
|
89
|
-
// Create a separate instance for login requests
|
|
90
|
-
this.loginRequest = axios.create({
|
|
91
|
-
baseURL: config.customTropipayUrl || tpp_env,
|
|
92
|
-
headers: {
|
|
93
|
-
"Content-Type": "application/json",
|
|
94
|
-
Accept: "application/json",
|
|
95
|
-
},
|
|
96
|
-
});
|
|
97
89
|
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
async (config) => {
|
|
101
|
-
const currentTimestamp = Math.floor(Date.now() / 1000);
|
|
90
|
+
// Add request interceptor for Token expired
|
|
91
|
+
this.request.interceptors.request.use(
|
|
92
|
+
async (config: any) => {
|
|
93
|
+
const currentTimestamp = Math.floor(Date.now() / 1000); // Current time in seconds
|
|
102
94
|
|
|
103
95
|
if (Tropipay.expiresIn && Tropipay.expiresIn < currentTimestamp) {
|
|
104
|
-
|
|
96
|
+
// Token has expired, attempt to refresh it
|
|
105
97
|
try {
|
|
106
|
-
|
|
98
|
+
await this.login();
|
|
107
99
|
} catch (error) {
|
|
108
|
-
|
|
100
|
+
// Handle token refresh error
|
|
101
|
+
Tropipay.accessToken = null;
|
|
102
|
+
Tropipay.refreshToken = null;
|
|
103
|
+
throw handleExceptions(error as any);
|
|
109
104
|
}
|
|
110
105
|
}
|
|
111
|
-
|
|
112
|
-
config.headers.Authorization = `Bearer ${Tropipay.accessToken}`;
|
|
106
|
+
|
|
113
107
|
return config;
|
|
114
108
|
},
|
|
115
|
-
(error) => {
|
|
109
|
+
(error: AxiosError) => {
|
|
116
110
|
return Promise.reject(error);
|
|
117
111
|
}
|
|
118
112
|
);
|
|
@@ -122,13 +116,34 @@ export class Tropipay {
|
|
|
122
116
|
this.mediationPaymentCard = new MediationPaymentCard(this);
|
|
123
117
|
|
|
124
118
|
this.depositAccounts = new DepositAccounts(this);
|
|
119
|
+
|
|
120
|
+
|
|
125
121
|
}
|
|
126
122
|
|
|
127
123
|
public async login() {
|
|
128
124
|
try {
|
|
125
|
+
if (Tropipay.refreshToken) {
|
|
126
|
+
const { data } = await this.request.post<LoginResponse>(
|
|
127
|
+
"/api/v2/access/token",
|
|
128
|
+
{
|
|
129
|
+
client_id: this.clientId,
|
|
130
|
+
client_secret: this.clientSecret,
|
|
131
|
+
grant_type: "refresh_token",
|
|
132
|
+
refresh_token: Tropipay.refreshToken,
|
|
133
|
+
},
|
|
134
|
+
{
|
|
135
|
+
headers: {
|
|
136
|
+
"Content-Type": "application/json",
|
|
137
|
+
Accept: "application/json",
|
|
138
|
+
},
|
|
139
|
+
}
|
|
140
|
+
);
|
|
141
|
+
return data;
|
|
142
|
+
}
|
|
143
|
+
|
|
129
144
|
// normal credetials login
|
|
130
|
-
const { data } = await this.
|
|
131
|
-
"/api/
|
|
145
|
+
const { data } = await this.request.post<LoginResponse>(
|
|
146
|
+
"/api/v2/access/token",
|
|
132
147
|
{
|
|
133
148
|
client_id: this.clientId,
|
|
134
149
|
client_secret: this.clientSecret,
|
|
@@ -144,13 +159,13 @@ export class Tropipay {
|
|
|
144
159
|
);
|
|
145
160
|
|
|
146
161
|
Tropipay.accessToken = data.access_token;
|
|
162
|
+
Tropipay.refreshToken = data.refresh_token;
|
|
147
163
|
Tropipay.expiresIn = data.expires_in;
|
|
148
164
|
return data;
|
|
149
165
|
} catch (error) {
|
|
150
166
|
Tropipay.accessToken = null;
|
|
151
167
|
Tropipay.refreshToken = null;
|
|
152
168
|
Tropipay.expiresIn = null;
|
|
153
|
-
Tropipay.expiresIn = null;
|
|
154
169
|
throw handleExceptions(error as any);
|
|
155
170
|
}
|
|
156
171
|
}
|
|
@@ -313,6 +328,7 @@ export class Tropipay {
|
|
|
313
328
|
* belonging or not to the TropiPay platform with the particularity
|
|
314
329
|
* that the payment will be held in custody or retained until it is
|
|
315
330
|
* released with the approval of the payer.
|
|
331
|
+
* @deprecated This method is no longer supported and may be removed in a future release.
|
|
316
332
|
* @see https://tpp.stoplight.io/docs/tropipay-api-doc/12a128ff971e4-creating-a-mediation-payment-card
|
|
317
333
|
* @param config Payload with the payment details
|
|
318
334
|
*/
|
|
@@ -337,6 +353,91 @@ export class Tropipay {
|
|
|
337
353
|
throw handleExceptions(error as any);
|
|
338
354
|
}
|
|
339
355
|
}
|
|
356
|
+
|
|
357
|
+
/**
|
|
358
|
+
* Refund a completed transaction.
|
|
359
|
+
* Requires 2FA enabled and ALLOW_REFUND permission on the Tropipay account.
|
|
360
|
+
*
|
|
361
|
+
* In Development mode, `securityCode` defaults to `"123456"` when omitted.
|
|
362
|
+
* In Production mode, you must first call `requestSecurityCode()` to receive
|
|
363
|
+
* the 2FA code via SMS, then pass it as the `securityCode` parameter.
|
|
364
|
+
*
|
|
365
|
+
* @see https://doc.tropipay.com/docs/api-reference/movements#refund-a-transaction
|
|
366
|
+
* @param orderCode Code of the order/transaction to refund (e.g. "ORD-123456")
|
|
367
|
+
* @param amount Amount to refund in cents (e.g. 5000 = 50.00 USD/EUR)
|
|
368
|
+
* @param securityCode 2FA confirmation code. Use "123456" in Development or
|
|
369
|
+
* the code received via SMS in Production (obtained via requestSecurityCode()).
|
|
370
|
+
*/
|
|
371
|
+
async refundMovement(
|
|
372
|
+
orderCode: string,
|
|
373
|
+
amount: number,
|
|
374
|
+
securityCode: string
|
|
375
|
+
): Promise<RefundResponse> {
|
|
376
|
+
if (!Tropipay.accessToken) {
|
|
377
|
+
await this.login();
|
|
378
|
+
}
|
|
379
|
+
|
|
380
|
+
if (!this.scopes.includes("ALLOW_REFUND")) {
|
|
381
|
+
throw new TropipayJSException(
|
|
382
|
+
"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.",
|
|
383
|
+
403,
|
|
384
|
+
null
|
|
385
|
+
);
|
|
386
|
+
}
|
|
387
|
+
|
|
388
|
+
try {
|
|
389
|
+
const response = await this.request.post(
|
|
390
|
+
"/api/v3/movements/in/refund",
|
|
391
|
+
{ orderCode, amount, securityCode },
|
|
392
|
+
{
|
|
393
|
+
headers: {
|
|
394
|
+
"Content-Type": "application/json",
|
|
395
|
+
Accept: "application/json",
|
|
396
|
+
Authorization: `Bearer ${Tropipay.accessToken}`,
|
|
397
|
+
},
|
|
398
|
+
}
|
|
399
|
+
);
|
|
400
|
+
return response.data as RefundResponse;
|
|
401
|
+
} catch (error) {
|
|
402
|
+
throw handleExceptions(error as any);
|
|
403
|
+
}
|
|
404
|
+
}
|
|
405
|
+
|
|
406
|
+
/**
|
|
407
|
+
* Request a 2FA security code to be sent via SMS for confirming sensitive
|
|
408
|
+
* operations like refunds.
|
|
409
|
+
*
|
|
410
|
+
* In Production mode, you must call this method first to trigger an SMS with
|
|
411
|
+
* the code, then use the received code when calling `refundMovement()`.
|
|
412
|
+
* In Development mode this is not required as the default code "123456"
|
|
413
|
+
* is used automatically.
|
|
414
|
+
*
|
|
415
|
+
* @see https://doc.tropipay.com/docs/api-reference/movements#refund-a-transaction
|
|
416
|
+
* @returns The API response confirming the code was sent
|
|
417
|
+
*/
|
|
418
|
+
async requestSecurityCode(type: "sms" | "email" = "sms"): Promise<any> {
|
|
419
|
+
if (!Tropipay.accessToken) {
|
|
420
|
+
await this.login();
|
|
421
|
+
}
|
|
422
|
+
|
|
423
|
+
try {
|
|
424
|
+
const response = await this.request.post(
|
|
425
|
+
"/api/v3/users/sendSecurityCode",
|
|
426
|
+
{ type },
|
|
427
|
+
{
|
|
428
|
+
headers: {
|
|
429
|
+
"Content-Type": "application/json",
|
|
430
|
+
Accept: "application/json",
|
|
431
|
+
Authorization: `Bearer ${Tropipay.accessToken}`,
|
|
432
|
+
},
|
|
433
|
+
}
|
|
434
|
+
);
|
|
435
|
+
return response.data;
|
|
436
|
+
} catch (error) {
|
|
437
|
+
throw handleExceptions(error as any);
|
|
438
|
+
}
|
|
439
|
+
}
|
|
440
|
+
|
|
340
441
|
}
|
|
341
442
|
|
|
342
443
|
export class ClientSideUtils {
|
|
@@ -354,4 +455,5 @@ export const Scopes = {
|
|
|
354
455
|
ALLOW_GET_BALANCE: "ALLOW_GET_BALANCE",
|
|
355
456
|
ALLOW_GET_MOVEMENT_LIST: "ALLOW_GET_MOVEMENT_LIST",
|
|
356
457
|
ALLOW_GET_CREDENTIAL: "ALLOW_GET_CREDENTIAL",
|
|
458
|
+
ALLOW_REFUND: "ALLOW_REFUND",
|
|
357
459
|
};
|
|
@@ -18,7 +18,7 @@ export default class DepositAccounts {
|
|
|
18
18
|
}
|
|
19
19
|
try {
|
|
20
20
|
const deposit = await this.tropipay.request.get(
|
|
21
|
-
`/api/
|
|
21
|
+
`/api/v2/deposit_accounts`,
|
|
22
22
|
{
|
|
23
23
|
headers: {
|
|
24
24
|
"Content-Type": "application/json",
|
|
@@ -43,7 +43,7 @@ export default class DepositAccounts {
|
|
|
43
43
|
}
|
|
44
44
|
try {
|
|
45
45
|
const deposit = await this.tropipay.request.post(
|
|
46
|
-
"/api/
|
|
46
|
+
"/api/v2/deposit_accounts",
|
|
47
47
|
depositAccountObj,
|
|
48
48
|
{
|
|
49
49
|
headers: {
|
|
@@ -70,7 +70,7 @@ export default class DepositAccounts {
|
|
|
70
70
|
}
|
|
71
71
|
try {
|
|
72
72
|
const deposit = await this.tropipay.request.get(
|
|
73
|
-
`/api/
|
|
73
|
+
`/api/v2/deposit_accounts/${id}`,
|
|
74
74
|
{
|
|
75
75
|
headers: {
|
|
76
76
|
"Content-Type": "application/json",
|
|
@@ -96,7 +96,7 @@ export default class DepositAccounts {
|
|
|
96
96
|
}
|
|
97
97
|
try {
|
|
98
98
|
const deposit = await this.tropipay.request.put(
|
|
99
|
-
`/api/
|
|
99
|
+
`/api/v2/deposit_accounts/`,
|
|
100
100
|
{
|
|
101
101
|
headers: {
|
|
102
102
|
"Content-Type": "application/json",
|
|
@@ -122,7 +122,7 @@ export default class DepositAccounts {
|
|
|
122
122
|
}
|
|
123
123
|
try {
|
|
124
124
|
const deposit = await this.tropipay.request.delete(
|
|
125
|
-
`/api/
|
|
125
|
+
`/api/v2/deposit_accounts/${id}`,
|
|
126
126
|
{
|
|
127
127
|
headers: {
|
|
128
128
|
"Content-Type": "application/json",
|
package/src/index.ts
CHANGED
package/src/interfaces/index.ts
CHANGED
|
@@ -64,7 +64,6 @@ export interface UserHookSubscribed extends UserHook {
|
|
|
64
64
|
}
|
|
65
65
|
|
|
66
66
|
export interface PaymentLinkPayload {
|
|
67
|
-
accountId: number;
|
|
68
67
|
reference: string;
|
|
69
68
|
concept: string;
|
|
70
69
|
favorite: boolean;
|
|
@@ -200,3 +199,14 @@ export type AccountDeposits = {
|
|
|
200
199
|
count: number;
|
|
201
200
|
rows: Deposit[];
|
|
202
201
|
};
|
|
202
|
+
|
|
203
|
+
export type RefundResponse = {
|
|
204
|
+
id: number;
|
|
205
|
+
orderCode: string;
|
|
206
|
+
amount: number;
|
|
207
|
+
currency: string;
|
|
208
|
+
state: string;
|
|
209
|
+
type: string;
|
|
210
|
+
createdAt: string;
|
|
211
|
+
completedAt: string;
|
|
212
|
+
};
|
|
@@ -1,37 +1,36 @@
|
|
|
1
1
|
export interface PaymentLinkPayload {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
paymentMethods?: string[];
|
|
2
|
+
reference: string;
|
|
3
|
+
concept: string;
|
|
4
|
+
favorite: boolean;
|
|
5
|
+
amount: number;
|
|
6
|
+
currency: string;
|
|
7
|
+
description: string;
|
|
8
|
+
singleUse: boolean;
|
|
9
|
+
reasonId: number;
|
|
10
|
+
expirationDays: number;
|
|
11
|
+
lang: string;
|
|
12
|
+
urlSuccess: string;
|
|
13
|
+
urlFailed: string;
|
|
14
|
+
urlNotification: string;
|
|
15
|
+
serviceDate: string;
|
|
16
|
+
client: {
|
|
17
|
+
name: string;
|
|
18
|
+
lastName: string;
|
|
19
|
+
address: string;
|
|
20
|
+
phone: string;
|
|
21
|
+
email: string;
|
|
22
|
+
countryId: number;
|
|
23
|
+
termsAndConditions: boolean;
|
|
24
|
+
};
|
|
25
|
+
directPayment: boolean;
|
|
26
|
+
paymentMethods?: string[];
|
|
28
27
|
}
|
|
29
28
|
export interface PaymentLink extends PaymentLinkPayload {
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
29
|
+
expirationDate: string;
|
|
30
|
+
hasClient: boolean;
|
|
31
|
+
updatedAt: string;
|
|
32
|
+
createdAt: string;
|
|
33
|
+
qrImage: string;
|
|
34
|
+
shortUrl: string;
|
|
35
|
+
paymentUrl: string;
|
|
37
36
|
}
|
|
@@ -50,7 +50,6 @@ enum Reasons {
|
|
|
50
50
|
}
|
|
51
51
|
|
|
52
52
|
export interface PaymentLinkPayload {
|
|
53
|
-
accountId: number;
|
|
54
53
|
reference: string;
|
|
55
54
|
concept: string;
|
|
56
55
|
favorite: boolean;
|
|
@@ -65,6 +64,9 @@ export interface PaymentLinkPayload {
|
|
|
65
64
|
urlFailed: string;
|
|
66
65
|
urlNotification: string;
|
|
67
66
|
serviceDate: string;
|
|
67
|
+
/**
|
|
68
|
+
* fgfsgdfgdfgd
|
|
69
|
+
*/
|
|
68
70
|
client?: {
|
|
69
71
|
name: string;
|
|
70
72
|
lastName: string;
|
|
@@ -20,7 +20,7 @@ export default class PaymentCard {
|
|
|
20
20
|
}
|
|
21
21
|
try {
|
|
22
22
|
const paylink = await this.tropipay.request.post(
|
|
23
|
-
"/api/
|
|
23
|
+
"/api/v2/paymentcards",
|
|
24
24
|
payload,
|
|
25
25
|
{
|
|
26
26
|
headers: {
|
|
@@ -46,7 +46,7 @@ export default class PaymentCard {
|
|
|
46
46
|
}
|
|
47
47
|
try {
|
|
48
48
|
const paymentcards = await this.tropipay.request.get(
|
|
49
|
-
`/api/
|
|
49
|
+
`/api/v2/paymentcards`,
|
|
50
50
|
{
|
|
51
51
|
headers: {
|
|
52
52
|
"Content-Type": "application/json",
|
|
@@ -74,7 +74,7 @@ export default class PaymentCard {
|
|
|
74
74
|
}
|
|
75
75
|
try {
|
|
76
76
|
const paymentcard = await this.tropipay.request.get(
|
|
77
|
-
`/api/
|
|
77
|
+
`/api/v2/paymentcards/${id}`,
|
|
78
78
|
{
|
|
79
79
|
headers: {
|
|
80
80
|
"Content-Type": "application/json",
|
|
@@ -103,7 +103,7 @@ export default class PaymentCard {
|
|
|
103
103
|
}
|
|
104
104
|
try {
|
|
105
105
|
const paymentcard = await this.tropipay.request.delete(
|
|
106
|
-
`/api/
|
|
106
|
+
`/api/v2/paymentcards/`,
|
|
107
107
|
{
|
|
108
108
|
headers: {
|
|
109
109
|
"Content-Type": "application/json",
|
|
@@ -11,9 +11,7 @@ export class ServerSideUtils {
|
|
|
11
11
|
}
|
|
12
12
|
|
|
13
13
|
/**
|
|
14
|
-
*
|
|
15
|
-
* @deprecated This method is deprecated and will be removed in future versions.
|
|
16
|
-
* Use the `verifySignatureV3` method from the `ServerSideUtils` class instead.
|
|
14
|
+
* Verify Topipay's signature on webhooks.
|
|
17
15
|
* @param credentials Credential object or Tropipay instance
|
|
18
16
|
* @param {String} originalCurrencyAmount
|
|
19
17
|
* @param bankOrderCode
|
|
@@ -125,41 +123,4 @@ export class ServerSideUtils {
|
|
|
125
123
|
throw new Error(`Error checking base64 image`);
|
|
126
124
|
}
|
|
127
125
|
}
|
|
128
|
-
|
|
129
|
-
/**
|
|
130
|
-
* Verify Topipay's signature on API V3 webhooks.
|
|
131
|
-
* @param {string} originalCurrencyAmount
|
|
132
|
-
* @param {string} bankOrderCode
|
|
133
|
-
* @param {string} signature signaturev3 field to be verified
|
|
134
|
-
* @returns {boolean}
|
|
135
|
-
*/
|
|
136
|
-
public static verifySignatureV3(
|
|
137
|
-
credentials:
|
|
138
|
-
| {
|
|
139
|
-
clientId: string;
|
|
140
|
-
clientSecret: string;
|
|
141
|
-
}
|
|
142
|
-
| Tropipay,
|
|
143
|
-
originalCurrencyAmount: string,
|
|
144
|
-
bankOrderCode: string,
|
|
145
|
-
signature: string
|
|
146
|
-
): boolean {
|
|
147
|
-
const sha1Secret = crypto
|
|
148
|
-
.createHash("sha1")
|
|
149
|
-
.update(credentials.clientSecret)
|
|
150
|
-
.digest("hex");
|
|
151
|
-
|
|
152
|
-
const dataToHash =
|
|
153
|
-
bankOrderCode +
|
|
154
|
-
credentials.clientId +
|
|
155
|
-
sha1Secret +
|
|
156
|
-
originalCurrencyAmount;
|
|
157
|
-
|
|
158
|
-
const localSignature = crypto
|
|
159
|
-
.createHash("sha256")
|
|
160
|
-
.update(dataToHash)
|
|
161
|
-
.digest("hex");
|
|
162
|
-
|
|
163
|
-
return localSignature === signature;
|
|
164
|
-
}
|
|
165
126
|
}
|
package/utils/TropipayUtils.d.ts
CHANGED
|
@@ -3,9 +3,7 @@ export declare class ServerSideUtils {
|
|
|
3
3
|
private tropipay;
|
|
4
4
|
constructor(tropipayInstance: Tropipay);
|
|
5
5
|
/**
|
|
6
|
-
*
|
|
7
|
-
* @deprecated This method is deprecated and will be removed in future versions.
|
|
8
|
-
* Use the `verifySignatureV3` method from the `ServerSideUtils` class instead.
|
|
6
|
+
* Verify Topipay's signature on webhooks.
|
|
9
7
|
* @param credentials Credential object or Tropipay instance
|
|
10
8
|
* @param {String} originalCurrencyAmount
|
|
11
9
|
* @param bankOrderCode
|
|
@@ -44,15 +42,4 @@ export declare class ServerSideUtils {
|
|
|
44
42
|
* @return {Promise<string>} the valid base64 image
|
|
45
43
|
*/
|
|
46
44
|
static isValidImage(base64Image: string): boolean;
|
|
47
|
-
/**
|
|
48
|
-
* Verify Topipay's signature on API V3 webhooks.
|
|
49
|
-
* @param {string} originalCurrencyAmount
|
|
50
|
-
* @param {string} bankOrderCode
|
|
51
|
-
* @param {string} signature signaturev3 field to be verified
|
|
52
|
-
* @returns {boolean}
|
|
53
|
-
*/
|
|
54
|
-
static verifySignatureV3(credentials: {
|
|
55
|
-
clientId: string;
|
|
56
|
-
clientSecret: string;
|
|
57
|
-
} | Tropipay, originalCurrencyAmount: string, bankOrderCode: string, signature: string): boolean;
|
|
58
45
|
}
|