cb-pay-merchant-api 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +101 -0
- package/dist/cjs/index.d.ts +55 -0
- package/dist/cjs/index.js +177 -0
- package/dist/cjs/types/index.d.ts +86 -0
- package/dist/cjs/types/index.js +4 -0
- package/dist/esm/index.d.ts +55 -0
- package/dist/esm/index.js +174 -0
- package/dist/esm/types/index.d.ts +86 -0
- package/dist/esm/types/index.js +3 -0
- package/package.json +41 -0
- package/src/index.ts +178 -0
- package/src/types/index.ts +105 -0
- package/test/test.js +42 -0
- package/tsconfig.cjs.json +7 -0
- package/tsconfig.json +18 -0
package/README.md
ADDED
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
# CBPay Merchant MMQR Unofficial API Integration Package
|
|
2
|
+
|
|
3
|
+
An unofficial, personal-use TypeScript API integration package for connecting CBPay Merchant's MMQR functionalities into Node.js applications.
|
|
4
|
+
It provides a simple class-based wrapper around the CBPay REST API, handling authentication, token management, dynamic QR generation, status checking, and refunds.
|
|
5
|
+
|
|
6
|
+
> **Disclaimer:** This is an unofficial, community-driven integration package intended for personal reuse. It is not affiliated with, endorsed by, or maintained by CB Bank.
|
|
7
|
+
|
|
8
|
+
## Features
|
|
9
|
+
|
|
10
|
+
* Automatic token generation and management
|
|
11
|
+
* Dynamic QR Code generation (`requestQR`)
|
|
12
|
+
* Transaction status validation (`checkQR`)
|
|
13
|
+
* Payment refunds (`refund`)
|
|
14
|
+
* Strongly typed requests and responses
|
|
15
|
+
|
|
16
|
+
## Installation
|
|
17
|
+
|
|
18
|
+
```bash
|
|
19
|
+
npm install cb-pay-merchant-api
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
## Initialization
|
|
23
|
+
|
|
24
|
+
Initialize the instance by providing your merchant credentials. The integration kit will automatically handle fetching and attaching the required authorization tokens for subsequent API calls.
|
|
25
|
+
|
|
26
|
+
```typescript
|
|
27
|
+
import { CBPayMerchantApi } from 'cb-pay-merchant-api';
|
|
28
|
+
|
|
29
|
+
const cbpay = CBPayMerchantApi({
|
|
30
|
+
baseUrl: '[https://api.uat.cbbank.com](https://api.uat.cbbank.com)', // Contact CB Pay Team
|
|
31
|
+
sourceId: 'YOUR_SOURCE_ID',
|
|
32
|
+
merchantId: 'YOUR_MERCHANT_ID',
|
|
33
|
+
terminalId: 'YOUR_TERMINAL_ID',
|
|
34
|
+
userId: 'YOUR_USER_ID',
|
|
35
|
+
password: 'YOUR_PASSWORD'
|
|
36
|
+
});
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
------------------
|
|
40
|
+
|
|
41
|
+
## API Reference
|
|
42
|
+
|
|
43
|
+
#### 1. Request Dynamic QR (requestQR)
|
|
44
|
+
```typescript
|
|
45
|
+
const qrResponse = await cbpay.requestQR({
|
|
46
|
+
transCurrency: 'MMK',
|
|
47
|
+
transAmount: 15000,
|
|
48
|
+
purposeOfTransaction: 'Purchase Order #8821',
|
|
49
|
+
referenceNo: 'PO-8821'
|
|
50
|
+
});
|
|
51
|
+
console.log(qrResponse.qrCodeInfo);
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
#### Parameters (requestQR):
|
|
55
|
+
| Property | Type | Required | Description |
|
|
56
|
+
| :--- | :--- | :---: | :--- |
|
|
57
|
+
| `transCurrency` | `string` | **Yes** | Currency code |
|
|
58
|
+
| `transAmount` | `number` | **Yes** | Transaction amount |
|
|
59
|
+
| `referenceNo` | `string` | **Yes** | Your unique order or reference number |
|
|
60
|
+
| `purposeOfTransaction` | `string` | **Yes** | Description of the payment |
|
|
61
|
+
|
|
62
|
+
------------------
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
#### 2. Check QR Status
|
|
66
|
+
```typescript
|
|
67
|
+
const statusResponse = await cbpay.checkQR({
|
|
68
|
+
qrReferenceNo: 'QR-REF-FROM-RESPONSE'
|
|
69
|
+
});
|
|
70
|
+
|
|
71
|
+
if (statusResponse.returnCode === '000') {
|
|
72
|
+
console.log(statusResponse.transactionId);
|
|
73
|
+
}
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
#### Parameters (checkQR):
|
|
77
|
+
| Property | Type | Required | Description |
|
|
78
|
+
| :--- | :--- | :---: | :--- |
|
|
79
|
+
| `qrReferenceNo` | `string` | **Yes** | The qrReferenceNo received from the requestQR response |
|
|
80
|
+
|
|
81
|
+
------------------
|
|
82
|
+
|
|
83
|
+
|
|
84
|
+
#### 3. Refund Transaction (refund)
|
|
85
|
+
|
|
86
|
+
```typescript
|
|
87
|
+
const refundResponse = await cbpay.refund({
|
|
88
|
+
transactionId: 'TXN-123456789',
|
|
89
|
+
refundCurrency: 'MMK',
|
|
90
|
+
refundAmount: 15000,
|
|
91
|
+
isPartialRedund: false
|
|
92
|
+
});
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
#### Parameters (requestQR):
|
|
96
|
+
| Property | Type | Required | Description |
|
|
97
|
+
| :--- | :--- | :---: | :--- |
|
|
98
|
+
| `transactionId` | `string` | **Yes** | The original transaction ID |
|
|
99
|
+
| `refundAmount` | `number` | **Yes** | Amount to refund |
|
|
100
|
+
| `refundCurrency` | `string` | **Yes** | Currency code |
|
|
101
|
+
| `isPartialRedund` | `boolean` | **Yes** | Set to true for partial refunds |
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import {CheckQrRequestOption, CheckQrResponse, CreateQrRequestOption, CreateQrResponse, RefundRequestOption, RefundResponse} from './types';
|
|
2
|
+
/**
|
|
3
|
+
* @Options
|
|
4
|
+
* @Options
|
|
5
|
+
* @Options
|
|
6
|
+
*/
|
|
7
|
+
export interface InstanceOptions {
|
|
8
|
+
baseUrl: string;
|
|
9
|
+
sourceId: string;
|
|
10
|
+
merchantId: string;
|
|
11
|
+
terminalId: string;
|
|
12
|
+
userId: string;
|
|
13
|
+
password: string;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* @CBPayMerchantApi
|
|
17
|
+
* @CBPayMerchantApi
|
|
18
|
+
* @CBPayMerchantApi
|
|
19
|
+
* @param {InstanceOptions} options
|
|
20
|
+
* @returns {CBPayMerchantClass} A status message string.
|
|
21
|
+
*/
|
|
22
|
+
export declare function CBPayMerchantApi(options: InstanceOptions): CBPayMerchantClass;
|
|
23
|
+
/**
|
|
24
|
+
* @CBPayMerchantClass
|
|
25
|
+
* @CBPayMerchantClass
|
|
26
|
+
* @CBPayMerchantClass
|
|
27
|
+
*/
|
|
28
|
+
declare class CBPayMerchantClass {
|
|
29
|
+
#private;
|
|
30
|
+
constructor(options: InstanceOptions);
|
|
31
|
+
/**
|
|
32
|
+
* getToken
|
|
33
|
+
* @returns {Promise<GetTokenResponse>}
|
|
34
|
+
*/
|
|
35
|
+
private getToken;
|
|
36
|
+
/**
|
|
37
|
+
* requestQR
|
|
38
|
+
* @param {CreateQrRequestOption} options
|
|
39
|
+
* @returns {Promise<CreateQrResponse>}
|
|
40
|
+
*/
|
|
41
|
+
requestQR(options: CreateQrRequestOption): Promise<CreateQrResponse>;
|
|
42
|
+
/**
|
|
43
|
+
* checkQR
|
|
44
|
+
* @param {CheckQrRequestOption} options
|
|
45
|
+
* @returns {Promise<CheckQrResponse>}
|
|
46
|
+
*/
|
|
47
|
+
checkQR(options: CheckQrRequestOption): Promise<CheckQrResponse>;
|
|
48
|
+
/**
|
|
49
|
+
* refund
|
|
50
|
+
* @param {RefundRequestOption} options
|
|
51
|
+
* @returns {Promise<RefundResponse>}
|
|
52
|
+
*/
|
|
53
|
+
refund(options: RefundRequestOption): Promise<RefundResponse>;
|
|
54
|
+
}
|
|
55
|
+
export { };
|
|
@@ -0,0 +1,177 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, state, value, kind, f) {
|
|
3
|
+
if (kind === "m") throw new TypeError("Private method is not writable");
|
|
4
|
+
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter");
|
|
5
|
+
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it");
|
|
6
|
+
return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
|
|
7
|
+
};
|
|
8
|
+
var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {
|
|
9
|
+
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
|
|
10
|
+
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
|
|
11
|
+
return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
|
|
12
|
+
};
|
|
13
|
+
var _CBPayMerchantClass_baseUrl, _CBPayMerchantClass_sourceId, _CBPayMerchantClass_merchantId, _CBPayMerchantClass_terminalId, _CBPayMerchantClass_userId, _CBPayMerchantClass_password, _CBPayMerchantClass_bToken;
|
|
14
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
|
+
exports.CBPayMerchantApi = CBPayMerchantApi;
|
|
16
|
+
/**
|
|
17
|
+
* @CBPayMerchantApi
|
|
18
|
+
* @CBPayMerchantApi
|
|
19
|
+
* @CBPayMerchantApi
|
|
20
|
+
* @param {InstanceOptions} options
|
|
21
|
+
* @returns {CBPayMerchantClass} A status message string.
|
|
22
|
+
*/
|
|
23
|
+
function CBPayMerchantApi(options) {
|
|
24
|
+
return new CBPayMerchantClass({
|
|
25
|
+
baseUrl: options.baseUrl,
|
|
26
|
+
sourceId: options.sourceId,
|
|
27
|
+
merchantId: options.merchantId,
|
|
28
|
+
terminalId: options.terminalId,
|
|
29
|
+
userId: options.userId,
|
|
30
|
+
password: options.password,
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* @CBPayMerchantClass
|
|
35
|
+
* @CBPayMerchantClass
|
|
36
|
+
* @CBPayMerchantClass
|
|
37
|
+
*/
|
|
38
|
+
class CBPayMerchantClass {
|
|
39
|
+
constructor(options) {
|
|
40
|
+
_CBPayMerchantClass_baseUrl.set(this, void 0);
|
|
41
|
+
_CBPayMerchantClass_sourceId.set(this, void 0);
|
|
42
|
+
_CBPayMerchantClass_merchantId.set(this, void 0);
|
|
43
|
+
_CBPayMerchantClass_terminalId.set(this, void 0);
|
|
44
|
+
_CBPayMerchantClass_userId.set(this, void 0);
|
|
45
|
+
_CBPayMerchantClass_password.set(this, void 0);
|
|
46
|
+
_CBPayMerchantClass_bToken.set(this, void 0);
|
|
47
|
+
__classPrivateFieldSet(this, _CBPayMerchantClass_baseUrl, options.baseUrl, "f");
|
|
48
|
+
__classPrivateFieldSet(this, _CBPayMerchantClass_sourceId, options.sourceId, "f");
|
|
49
|
+
__classPrivateFieldSet(this, _CBPayMerchantClass_merchantId, options.merchantId, "f");
|
|
50
|
+
__classPrivateFieldSet(this, _CBPayMerchantClass_terminalId, options.terminalId, "f");
|
|
51
|
+
__classPrivateFieldSet(this, _CBPayMerchantClass_userId, options.userId, "f");
|
|
52
|
+
__classPrivateFieldSet(this, _CBPayMerchantClass_password, options.password, "f");
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* getToken
|
|
56
|
+
* @returns {Promise<GetTokenResponse>}
|
|
57
|
+
*/
|
|
58
|
+
async getToken() {
|
|
59
|
+
try {
|
|
60
|
+
const config = {
|
|
61
|
+
headers: {
|
|
62
|
+
'Content-Type': 'application/json'
|
|
63
|
+
}
|
|
64
|
+
};
|
|
65
|
+
const payload = {
|
|
66
|
+
userId: __classPrivateFieldGet(this, _CBPayMerchantClass_userId, "f"),
|
|
67
|
+
password: __classPrivateFieldGet(this, _CBPayMerchantClass_password, "f"),
|
|
68
|
+
};
|
|
69
|
+
const response = await fetch(`${__classPrivateFieldGet(this, _CBPayMerchantClass_baseUrl, "f")}/auth/token`, {
|
|
70
|
+
method: 'POST',
|
|
71
|
+
headers: config.headers,
|
|
72
|
+
body: JSON.stringify(payload)
|
|
73
|
+
});
|
|
74
|
+
const originResponse = (await response.json());
|
|
75
|
+
__classPrivateFieldSet(this, _CBPayMerchantClass_bToken, originResponse.token, "f");
|
|
76
|
+
return originResponse;
|
|
77
|
+
}
|
|
78
|
+
catch (error) {
|
|
79
|
+
console.error(error);
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* requestQR
|
|
84
|
+
* @param {CreateQrRequestOption} options
|
|
85
|
+
* @returns {Promise<CreateQrResponse>}
|
|
86
|
+
*/
|
|
87
|
+
async requestQR(options) {
|
|
88
|
+
try {
|
|
89
|
+
await this.getToken(); // Get Replay Prevention Token
|
|
90
|
+
const config = {
|
|
91
|
+
headers: {
|
|
92
|
+
'Content-Type': 'application/json'
|
|
93
|
+
}
|
|
94
|
+
};
|
|
95
|
+
const payload = {
|
|
96
|
+
transCurrency: options.transCurrency,
|
|
97
|
+
transAmount: options.transAmount,
|
|
98
|
+
purposeOfTransaction: options.purposeOfTransaction,
|
|
99
|
+
referenceNo: options.referenceNo,
|
|
100
|
+
token: __classPrivateFieldGet(this, _CBPayMerchantClass_bToken, "f"),
|
|
101
|
+
sourceId: __classPrivateFieldGet(this, _CBPayMerchantClass_sourceId, "f"),
|
|
102
|
+
merchantId: __classPrivateFieldGet(this, _CBPayMerchantClass_merchantId, "f"),
|
|
103
|
+
terminalId: __classPrivateFieldGet(this, _CBPayMerchantClass_terminalId, "f"),
|
|
104
|
+
};
|
|
105
|
+
const response = await fetch(`${__classPrivateFieldGet(this, _CBPayMerchantClass_baseUrl, "f")}/dynamicqr`, {
|
|
106
|
+
method: 'POST',
|
|
107
|
+
headers: config.headers,
|
|
108
|
+
body: JSON.stringify(payload)
|
|
109
|
+
});
|
|
110
|
+
return (await response.json());
|
|
111
|
+
}
|
|
112
|
+
catch (error) {
|
|
113
|
+
console.error(error);
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
/**
|
|
117
|
+
* checkQR
|
|
118
|
+
* @param {CheckQrRequestOption} options
|
|
119
|
+
* @returns {Promise<CheckQrResponse>}
|
|
120
|
+
*/
|
|
121
|
+
async checkQR(options) {
|
|
122
|
+
try {
|
|
123
|
+
await this.getToken(); // Get Replay Prevention Token
|
|
124
|
+
const config = {
|
|
125
|
+
headers: {
|
|
126
|
+
'Content-Type': 'application/json'
|
|
127
|
+
}
|
|
128
|
+
};
|
|
129
|
+
const payload = {
|
|
130
|
+
token: __classPrivateFieldGet(this, _CBPayMerchantClass_bToken, "f"),
|
|
131
|
+
sourceId: __classPrivateFieldGet(this, _CBPayMerchantClass_sourceId, "f")
|
|
132
|
+
};
|
|
133
|
+
const response = await fetch(`${__classPrivateFieldGet(this, _CBPayMerchantClass_baseUrl, "f")}/dynamicqr/${options.qrReferenceNo}/status`, {
|
|
134
|
+
method: 'PUT',
|
|
135
|
+
headers: config.headers,
|
|
136
|
+
body: JSON.stringify(payload)
|
|
137
|
+
});
|
|
138
|
+
return (await response.json());
|
|
139
|
+
}
|
|
140
|
+
catch (error) {
|
|
141
|
+
console.error(error);
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
/**
|
|
145
|
+
* refund
|
|
146
|
+
* @param {RefundRequestOption} options
|
|
147
|
+
* @returns {Promise<RefundResponse>}
|
|
148
|
+
*/
|
|
149
|
+
async refund(options) {
|
|
150
|
+
try {
|
|
151
|
+
await this.getToken(); // Get Replay Prevention Token
|
|
152
|
+
const config = {
|
|
153
|
+
headers: {
|
|
154
|
+
'Content-Type': 'application/json'
|
|
155
|
+
}
|
|
156
|
+
};
|
|
157
|
+
const payload = {
|
|
158
|
+
token: __classPrivateFieldGet(this, _CBPayMerchantClass_bToken, "f"),
|
|
159
|
+
sourceId: __classPrivateFieldGet(this, _CBPayMerchantClass_sourceId, "f"),
|
|
160
|
+
transactionId: options.transactionId,
|
|
161
|
+
refundCurrency: options.refundCurrency,
|
|
162
|
+
refundAmount: options.refundAmount,
|
|
163
|
+
isPartialRedund: options.isPartialRedund,
|
|
164
|
+
};
|
|
165
|
+
const response = await fetch(`${__classPrivateFieldGet(this, _CBPayMerchantClass_baseUrl, "f")}/payment/refund`, {
|
|
166
|
+
method: 'POST',
|
|
167
|
+
headers: config.headers,
|
|
168
|
+
body: JSON.stringify(payload)
|
|
169
|
+
});
|
|
170
|
+
return (await response.json());
|
|
171
|
+
}
|
|
172
|
+
catch (error) {
|
|
173
|
+
console.error(error);
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
_CBPayMerchantClass_baseUrl = new WeakMap(), _CBPayMerchantClass_sourceId = new WeakMap(), _CBPayMerchantClass_merchantId = new WeakMap(), _CBPayMerchantClass_terminalId = new WeakMap(), _CBPayMerchantClass_userId = new WeakMap(), _CBPayMerchantClass_password = new WeakMap(), _CBPayMerchantClass_bToken = new WeakMap();
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
export interface GetTokenRequest {
|
|
2
|
+
userId: string;
|
|
3
|
+
password: string;
|
|
4
|
+
}
|
|
5
|
+
export interface GetTokenResponse {
|
|
6
|
+
token: string;
|
|
7
|
+
returnCode: string;
|
|
8
|
+
message: string;
|
|
9
|
+
expiredDateTime: string;
|
|
10
|
+
}
|
|
11
|
+
export interface CreateQrRequestOption {
|
|
12
|
+
transCurrency: string;
|
|
13
|
+
transAmount: number;
|
|
14
|
+
purposeOfTransaction?: string;
|
|
15
|
+
referenceNo: string;
|
|
16
|
+
}
|
|
17
|
+
export interface CreateQrRequest extends CreateQrRequestOption {
|
|
18
|
+
token: string;
|
|
19
|
+
sourceId: string;
|
|
20
|
+
merchantId: string;
|
|
21
|
+
terminalId: string;
|
|
22
|
+
}
|
|
23
|
+
export interface CreateQrResponse {
|
|
24
|
+
returnCode: string;
|
|
25
|
+
message: string;
|
|
26
|
+
referenceNo: string;
|
|
27
|
+
qrCodeInfo: string;
|
|
28
|
+
qrReferenceNo: string;
|
|
29
|
+
qrIssuedDateTime: string;
|
|
30
|
+
qrExpiredDateTime: string;
|
|
31
|
+
}
|
|
32
|
+
export interface CheckQrRequestOption {
|
|
33
|
+
qrReferenceNo: string;
|
|
34
|
+
}
|
|
35
|
+
export interface CheckQrRequest {
|
|
36
|
+
token: string;
|
|
37
|
+
sourceId: string;
|
|
38
|
+
}
|
|
39
|
+
export interface CheckQrResponse {
|
|
40
|
+
referenceNo: string;
|
|
41
|
+
returnCode: string;
|
|
42
|
+
transactionId: string;
|
|
43
|
+
transCurrency: string;
|
|
44
|
+
transDateTime: string;
|
|
45
|
+
transAmount: number;
|
|
46
|
+
qrReferenceNo: string;
|
|
47
|
+
institutionId: string;
|
|
48
|
+
institutionName: string;
|
|
49
|
+
merchantId: string;
|
|
50
|
+
message: string;
|
|
51
|
+
remark: string;
|
|
52
|
+
}
|
|
53
|
+
export interface RefundRequestOption {
|
|
54
|
+
transactionId: string;
|
|
55
|
+
refundCurrency: string;
|
|
56
|
+
refundAmount: number;
|
|
57
|
+
isPartialRedund: boolean;
|
|
58
|
+
}
|
|
59
|
+
export interface RefundRequest extends RefundRequestOption {
|
|
60
|
+
token: string;
|
|
61
|
+
sourceId: string;
|
|
62
|
+
}
|
|
63
|
+
export interface RefundResponse {
|
|
64
|
+
transactionId: string;
|
|
65
|
+
returnCode: string;
|
|
66
|
+
message: string;
|
|
67
|
+
}
|
|
68
|
+
export interface CallbackRequest {
|
|
69
|
+
apiKey: string;
|
|
70
|
+
referenceNo: string;
|
|
71
|
+
transactionId: string;
|
|
72
|
+
transCurrency: string;
|
|
73
|
+
transAmount: number;
|
|
74
|
+
transDateTime: string;
|
|
75
|
+
transStatusCode: string;
|
|
76
|
+
transStatusDescription: string;
|
|
77
|
+
qrReferenceNo: string;
|
|
78
|
+
institutionId: string;
|
|
79
|
+
institutionName: string;
|
|
80
|
+
merchantId: string;
|
|
81
|
+
}
|
|
82
|
+
export interface CallbackResponse {
|
|
83
|
+
qrReferenceNo: string;
|
|
84
|
+
returnCode: string;
|
|
85
|
+
message: string;
|
|
86
|
+
}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { CheckQrRequestOption, CheckQrResponse, CreateQrRequestOption, CreateQrResponse, RefundRequestOption, RefundResponse } from './types';
|
|
2
|
+
/**
|
|
3
|
+
* @Options
|
|
4
|
+
* @Options
|
|
5
|
+
* @Options
|
|
6
|
+
*/
|
|
7
|
+
export interface InstanceOptions {
|
|
8
|
+
baseUrl: string;
|
|
9
|
+
sourceId: string;
|
|
10
|
+
merchantId: string;
|
|
11
|
+
terminalId: string;
|
|
12
|
+
userId: string;
|
|
13
|
+
password: string;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* @CBPayMerchantApi
|
|
17
|
+
* @CBPayMerchantApi
|
|
18
|
+
* @CBPayMerchantApi
|
|
19
|
+
* @param {InstanceOptions} options
|
|
20
|
+
* @returns {CBPayMerchantClass} A status message string.
|
|
21
|
+
*/
|
|
22
|
+
export declare function CBPayMerchantApi(options: InstanceOptions): CBPayMerchantClass;
|
|
23
|
+
/**
|
|
24
|
+
* @CBPayMerchantClass
|
|
25
|
+
* @CBPayMerchantClass
|
|
26
|
+
* @CBPayMerchantClass
|
|
27
|
+
*/
|
|
28
|
+
declare class CBPayMerchantClass {
|
|
29
|
+
#private;
|
|
30
|
+
constructor(options: InstanceOptions);
|
|
31
|
+
/**
|
|
32
|
+
* getToken
|
|
33
|
+
* @returns {Promise<GetTokenResponse>}
|
|
34
|
+
*/
|
|
35
|
+
private getToken;
|
|
36
|
+
/**
|
|
37
|
+
* requestQR
|
|
38
|
+
* @param {CreateQrRequestOption} options
|
|
39
|
+
* @returns {Promise<CreateQrResponse>}
|
|
40
|
+
*/
|
|
41
|
+
requestQR(options: CreateQrRequestOption): Promise<CreateQrResponse>;
|
|
42
|
+
/**
|
|
43
|
+
* checkQR
|
|
44
|
+
* @param {CheckQrRequestOption} options
|
|
45
|
+
* @returns {Promise<CheckQrResponse>}
|
|
46
|
+
*/
|
|
47
|
+
checkQR(options: CheckQrRequestOption): Promise<CheckQrResponse>;
|
|
48
|
+
/**
|
|
49
|
+
* refund
|
|
50
|
+
* @param {RefundRequestOption} options
|
|
51
|
+
* @returns {Promise<RefundResponse>}
|
|
52
|
+
*/
|
|
53
|
+
refund(options: RefundRequestOption): Promise<RefundResponse>;
|
|
54
|
+
}
|
|
55
|
+
export {};
|
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, state, value, kind, f) {
|
|
2
|
+
if (kind === "m") throw new TypeError("Private method is not writable");
|
|
3
|
+
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter");
|
|
4
|
+
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it");
|
|
5
|
+
return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
|
|
6
|
+
};
|
|
7
|
+
var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {
|
|
8
|
+
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
|
|
9
|
+
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
|
|
10
|
+
return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
|
|
11
|
+
};
|
|
12
|
+
var _CBPayMerchantClass_baseUrl, _CBPayMerchantClass_sourceId, _CBPayMerchantClass_merchantId, _CBPayMerchantClass_terminalId, _CBPayMerchantClass_userId, _CBPayMerchantClass_password, _CBPayMerchantClass_bToken;
|
|
13
|
+
/**
|
|
14
|
+
* @CBPayMerchantApi
|
|
15
|
+
* @CBPayMerchantApi
|
|
16
|
+
* @CBPayMerchantApi
|
|
17
|
+
* @param {InstanceOptions} options
|
|
18
|
+
* @returns {CBPayMerchantClass} A status message string.
|
|
19
|
+
*/
|
|
20
|
+
export function CBPayMerchantApi(options) {
|
|
21
|
+
return new CBPayMerchantClass({
|
|
22
|
+
baseUrl: options.baseUrl,
|
|
23
|
+
sourceId: options.sourceId,
|
|
24
|
+
merchantId: options.merchantId,
|
|
25
|
+
terminalId: options.terminalId,
|
|
26
|
+
userId: options.userId,
|
|
27
|
+
password: options.password,
|
|
28
|
+
});
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* @CBPayMerchantClass
|
|
32
|
+
* @CBPayMerchantClass
|
|
33
|
+
* @CBPayMerchantClass
|
|
34
|
+
*/
|
|
35
|
+
class CBPayMerchantClass {
|
|
36
|
+
constructor(options) {
|
|
37
|
+
_CBPayMerchantClass_baseUrl.set(this, void 0);
|
|
38
|
+
_CBPayMerchantClass_sourceId.set(this, void 0);
|
|
39
|
+
_CBPayMerchantClass_merchantId.set(this, void 0);
|
|
40
|
+
_CBPayMerchantClass_terminalId.set(this, void 0);
|
|
41
|
+
_CBPayMerchantClass_userId.set(this, void 0);
|
|
42
|
+
_CBPayMerchantClass_password.set(this, void 0);
|
|
43
|
+
_CBPayMerchantClass_bToken.set(this, void 0);
|
|
44
|
+
__classPrivateFieldSet(this, _CBPayMerchantClass_baseUrl, options.baseUrl, "f");
|
|
45
|
+
__classPrivateFieldSet(this, _CBPayMerchantClass_sourceId, options.sourceId, "f");
|
|
46
|
+
__classPrivateFieldSet(this, _CBPayMerchantClass_merchantId, options.merchantId, "f");
|
|
47
|
+
__classPrivateFieldSet(this, _CBPayMerchantClass_terminalId, options.terminalId, "f");
|
|
48
|
+
__classPrivateFieldSet(this, _CBPayMerchantClass_userId, options.userId, "f");
|
|
49
|
+
__classPrivateFieldSet(this, _CBPayMerchantClass_password, options.password, "f");
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* getToken
|
|
53
|
+
* @returns {Promise<GetTokenResponse>}
|
|
54
|
+
*/
|
|
55
|
+
async getToken() {
|
|
56
|
+
try {
|
|
57
|
+
const config = {
|
|
58
|
+
headers: {
|
|
59
|
+
'Content-Type': 'application/json'
|
|
60
|
+
}
|
|
61
|
+
};
|
|
62
|
+
const payload = {
|
|
63
|
+
userId: __classPrivateFieldGet(this, _CBPayMerchantClass_userId, "f"),
|
|
64
|
+
password: __classPrivateFieldGet(this, _CBPayMerchantClass_password, "f"),
|
|
65
|
+
};
|
|
66
|
+
const response = await fetch(`${__classPrivateFieldGet(this, _CBPayMerchantClass_baseUrl, "f")}/auth/token`, {
|
|
67
|
+
method: 'POST',
|
|
68
|
+
headers: config.headers,
|
|
69
|
+
body: JSON.stringify(payload)
|
|
70
|
+
});
|
|
71
|
+
const originResponse = (await response.json());
|
|
72
|
+
__classPrivateFieldSet(this, _CBPayMerchantClass_bToken, originResponse.token, "f");
|
|
73
|
+
return originResponse;
|
|
74
|
+
}
|
|
75
|
+
catch (error) {
|
|
76
|
+
console.error(error);
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* requestQR
|
|
81
|
+
* @param {CreateQrRequestOption} options
|
|
82
|
+
* @returns {Promise<CreateQrResponse>}
|
|
83
|
+
*/
|
|
84
|
+
async requestQR(options) {
|
|
85
|
+
try {
|
|
86
|
+
await this.getToken(); // Get Replay Prevention Token
|
|
87
|
+
const config = {
|
|
88
|
+
headers: {
|
|
89
|
+
'Content-Type': 'application/json'
|
|
90
|
+
}
|
|
91
|
+
};
|
|
92
|
+
const payload = {
|
|
93
|
+
transCurrency: options.transCurrency,
|
|
94
|
+
transAmount: options.transAmount,
|
|
95
|
+
purposeOfTransaction: options.purposeOfTransaction,
|
|
96
|
+
referenceNo: options.referenceNo,
|
|
97
|
+
token: __classPrivateFieldGet(this, _CBPayMerchantClass_bToken, "f"),
|
|
98
|
+
sourceId: __classPrivateFieldGet(this, _CBPayMerchantClass_sourceId, "f"),
|
|
99
|
+
merchantId: __classPrivateFieldGet(this, _CBPayMerchantClass_merchantId, "f"),
|
|
100
|
+
terminalId: __classPrivateFieldGet(this, _CBPayMerchantClass_terminalId, "f"),
|
|
101
|
+
};
|
|
102
|
+
const response = await fetch(`${__classPrivateFieldGet(this, _CBPayMerchantClass_baseUrl, "f")}/dynamicqr`, {
|
|
103
|
+
method: 'POST',
|
|
104
|
+
headers: config.headers,
|
|
105
|
+
body: JSON.stringify(payload)
|
|
106
|
+
});
|
|
107
|
+
return (await response.json());
|
|
108
|
+
}
|
|
109
|
+
catch (error) {
|
|
110
|
+
console.error(error);
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
/**
|
|
114
|
+
* checkQR
|
|
115
|
+
* @param {CheckQrRequestOption} options
|
|
116
|
+
* @returns {Promise<CheckQrResponse>}
|
|
117
|
+
*/
|
|
118
|
+
async checkQR(options) {
|
|
119
|
+
try {
|
|
120
|
+
await this.getToken(); // Get Replay Prevention Token
|
|
121
|
+
const config = {
|
|
122
|
+
headers: {
|
|
123
|
+
'Content-Type': 'application/json'
|
|
124
|
+
}
|
|
125
|
+
};
|
|
126
|
+
const payload = {
|
|
127
|
+
token: __classPrivateFieldGet(this, _CBPayMerchantClass_bToken, "f"),
|
|
128
|
+
sourceId: __classPrivateFieldGet(this, _CBPayMerchantClass_sourceId, "f")
|
|
129
|
+
};
|
|
130
|
+
const response = await fetch(`${__classPrivateFieldGet(this, _CBPayMerchantClass_baseUrl, "f")}/dynamicqr/${options.qrReferenceNo}/status`, {
|
|
131
|
+
method: 'PUT',
|
|
132
|
+
headers: config.headers,
|
|
133
|
+
body: JSON.stringify(payload)
|
|
134
|
+
});
|
|
135
|
+
return (await response.json());
|
|
136
|
+
}
|
|
137
|
+
catch (error) {
|
|
138
|
+
console.error(error);
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
/**
|
|
142
|
+
* refund
|
|
143
|
+
* @param {RefundRequestOption} options
|
|
144
|
+
* @returns {Promise<RefundResponse>}
|
|
145
|
+
*/
|
|
146
|
+
async refund(options) {
|
|
147
|
+
try {
|
|
148
|
+
await this.getToken(); // Get Replay Prevention Token
|
|
149
|
+
const config = {
|
|
150
|
+
headers: {
|
|
151
|
+
'Content-Type': 'application/json'
|
|
152
|
+
}
|
|
153
|
+
};
|
|
154
|
+
const payload = {
|
|
155
|
+
token: __classPrivateFieldGet(this, _CBPayMerchantClass_bToken, "f"),
|
|
156
|
+
sourceId: __classPrivateFieldGet(this, _CBPayMerchantClass_sourceId, "f"),
|
|
157
|
+
transactionId: options.transactionId,
|
|
158
|
+
refundCurrency: options.refundCurrency,
|
|
159
|
+
refundAmount: options.refundAmount,
|
|
160
|
+
isPartialRedund: options.isPartialRedund,
|
|
161
|
+
};
|
|
162
|
+
const response = await fetch(`${__classPrivateFieldGet(this, _CBPayMerchantClass_baseUrl, "f")}/payment/refund`, {
|
|
163
|
+
method: 'POST',
|
|
164
|
+
headers: config.headers,
|
|
165
|
+
body: JSON.stringify(payload)
|
|
166
|
+
});
|
|
167
|
+
return (await response.json());
|
|
168
|
+
}
|
|
169
|
+
catch (error) {
|
|
170
|
+
console.error(error);
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
_CBPayMerchantClass_baseUrl = new WeakMap(), _CBPayMerchantClass_sourceId = new WeakMap(), _CBPayMerchantClass_merchantId = new WeakMap(), _CBPayMerchantClass_terminalId = new WeakMap(), _CBPayMerchantClass_userId = new WeakMap(), _CBPayMerchantClass_password = new WeakMap(), _CBPayMerchantClass_bToken = new WeakMap();
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
export interface GetTokenRequest {
|
|
2
|
+
userId: string;
|
|
3
|
+
password: string;
|
|
4
|
+
}
|
|
5
|
+
export interface GetTokenResponse {
|
|
6
|
+
token: string;
|
|
7
|
+
returnCode: string;
|
|
8
|
+
message: string;
|
|
9
|
+
expiredDateTime: string;
|
|
10
|
+
}
|
|
11
|
+
export interface CreateQrRequestOption {
|
|
12
|
+
transCurrency: string;
|
|
13
|
+
transAmount: number;
|
|
14
|
+
purposeOfTransaction?: string;
|
|
15
|
+
referenceNo: string;
|
|
16
|
+
}
|
|
17
|
+
export interface CreateQrRequest extends CreateQrRequestOption {
|
|
18
|
+
token: string;
|
|
19
|
+
sourceId: string;
|
|
20
|
+
merchantId: string;
|
|
21
|
+
terminalId: string;
|
|
22
|
+
}
|
|
23
|
+
export interface CreateQrResponse {
|
|
24
|
+
returnCode: string;
|
|
25
|
+
message: string;
|
|
26
|
+
referenceNo: string;
|
|
27
|
+
qrCodeInfo: string;
|
|
28
|
+
qrReferenceNo: string;
|
|
29
|
+
qrIssuedDateTime: string;
|
|
30
|
+
qrExpiredDateTime: string;
|
|
31
|
+
}
|
|
32
|
+
export interface CheckQrRequestOption {
|
|
33
|
+
qrReferenceNo: string;
|
|
34
|
+
}
|
|
35
|
+
export interface CheckQrRequest {
|
|
36
|
+
token: string;
|
|
37
|
+
sourceId: string;
|
|
38
|
+
}
|
|
39
|
+
export interface CheckQrResponse {
|
|
40
|
+
referenceNo: string;
|
|
41
|
+
returnCode: string;
|
|
42
|
+
transactionId: string;
|
|
43
|
+
transCurrency: string;
|
|
44
|
+
transDateTime: string;
|
|
45
|
+
transAmount: number;
|
|
46
|
+
qrReferenceNo: string;
|
|
47
|
+
institutionId: string;
|
|
48
|
+
institutionName: string;
|
|
49
|
+
merchantId: string;
|
|
50
|
+
message: string;
|
|
51
|
+
remark: string;
|
|
52
|
+
}
|
|
53
|
+
export interface RefundRequestOption {
|
|
54
|
+
transactionId: string;
|
|
55
|
+
refundCurrency: string;
|
|
56
|
+
refundAmount: number;
|
|
57
|
+
isPartialRedund: boolean;
|
|
58
|
+
}
|
|
59
|
+
export interface RefundRequest extends RefundRequestOption {
|
|
60
|
+
token: string;
|
|
61
|
+
sourceId: string;
|
|
62
|
+
}
|
|
63
|
+
export interface RefundResponse {
|
|
64
|
+
transactionId: string;
|
|
65
|
+
returnCode: string;
|
|
66
|
+
message: string;
|
|
67
|
+
}
|
|
68
|
+
export interface CallbackRequest {
|
|
69
|
+
apiKey: string;
|
|
70
|
+
referenceNo: string;
|
|
71
|
+
transactionId: string;
|
|
72
|
+
transCurrency: string;
|
|
73
|
+
transAmount: number;
|
|
74
|
+
transDateTime: string;
|
|
75
|
+
transStatusCode: string;
|
|
76
|
+
transStatusDescription: string;
|
|
77
|
+
qrReferenceNo: string;
|
|
78
|
+
institutionId: string;
|
|
79
|
+
institutionName: string;
|
|
80
|
+
merchantId: string;
|
|
81
|
+
}
|
|
82
|
+
export interface CallbackResponse {
|
|
83
|
+
qrReferenceNo: string;
|
|
84
|
+
returnCode: string;
|
|
85
|
+
message: string;
|
|
86
|
+
}
|
package/package.json
ADDED
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "cb-pay-merchant-api",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "MMQR, CB Pay - Integration Package",
|
|
5
|
+
"keywords": [
|
|
6
|
+
"MMQR",
|
|
7
|
+
"CB Pay"
|
|
8
|
+
],
|
|
9
|
+
"main": "./dist/cjs/index.js",
|
|
10
|
+
"module": "./dist/esm/index.js",
|
|
11
|
+
"types": "./dist/esm/index.d.ts",
|
|
12
|
+
"exports": {
|
|
13
|
+
".": {
|
|
14
|
+
"import": "./dist/esm/index.js",
|
|
15
|
+
"require": "./dist/cjs/index.js",
|
|
16
|
+
"types": "./dist/esm/index.d.ts"
|
|
17
|
+
}
|
|
18
|
+
},
|
|
19
|
+
"repository": {
|
|
20
|
+
"type": "git",
|
|
21
|
+
"url": "git+https://github.com/nawing/CB-Pay-Merchant-Api.git"
|
|
22
|
+
},
|
|
23
|
+
"bugs": {
|
|
24
|
+
"url": "https://github.com/nawing/CB-Pay-Merchant-Api/issues"
|
|
25
|
+
},
|
|
26
|
+
"homepage": "https://github.com/nawing/CB-Pay-Merchant-Api#readme",
|
|
27
|
+
"scripts": {
|
|
28
|
+
"build": "npm run clean && tsc && tsc -p tsconfig.cjs.json",
|
|
29
|
+
"clean": "rm -rf dist",
|
|
30
|
+
"dev": "tsc --watch"
|
|
31
|
+
},
|
|
32
|
+
"devDependencies": {
|
|
33
|
+
"@types/node": "^24.12.3",
|
|
34
|
+
"typescript": "^5.3.3"
|
|
35
|
+
},
|
|
36
|
+
"author": "Naw Ing",
|
|
37
|
+
"license": "ISC",
|
|
38
|
+
"dependencies": {
|
|
39
|
+
"dotenv": "^17.2.2"
|
|
40
|
+
}
|
|
41
|
+
}
|
package/src/index.ts
ADDED
|
@@ -0,0 +1,178 @@
|
|
|
1
|
+
import {CheckQrRequest, CheckQrRequestOption, CheckQrResponse, CreateQrRequest, CreateQrRequestOption, CreateQrResponse, GetTokenRequest, GetTokenResponse, RefundRequest, RefundRequestOption, RefundResponse} from './types';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* @Options
|
|
5
|
+
* @Options
|
|
6
|
+
* @Options
|
|
7
|
+
*/
|
|
8
|
+
export interface InstanceOptions {
|
|
9
|
+
baseUrl: string;
|
|
10
|
+
sourceId: string;
|
|
11
|
+
merchantId: string;
|
|
12
|
+
terminalId: string;
|
|
13
|
+
userId: string;
|
|
14
|
+
password: string;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* @CBPayMerchantApi
|
|
19
|
+
* @CBPayMerchantApi
|
|
20
|
+
* @CBPayMerchantApi
|
|
21
|
+
* @param {InstanceOptions} options
|
|
22
|
+
* @returns {CBPayMerchantClass} A status message string.
|
|
23
|
+
*/
|
|
24
|
+
export function CBPayMerchantApi(options: InstanceOptions): CBPayMerchantClass {
|
|
25
|
+
return new CBPayMerchantClass({
|
|
26
|
+
baseUrl: options.baseUrl,
|
|
27
|
+
sourceId: options.sourceId,
|
|
28
|
+
merchantId: options.merchantId,
|
|
29
|
+
terminalId: options.terminalId,
|
|
30
|
+
userId: options.userId,
|
|
31
|
+
password: options.password,
|
|
32
|
+
})
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* @CBPayMerchantClass
|
|
37
|
+
* @CBPayMerchantClass
|
|
38
|
+
* @CBPayMerchantClass
|
|
39
|
+
*/
|
|
40
|
+
class CBPayMerchantClass {
|
|
41
|
+
|
|
42
|
+
readonly #baseUrl: string;
|
|
43
|
+
readonly #sourceId: string;
|
|
44
|
+
readonly #merchantId: string;
|
|
45
|
+
readonly #terminalId: string;
|
|
46
|
+
readonly #userId: string;
|
|
47
|
+
readonly #password: string;
|
|
48
|
+
|
|
49
|
+
#bToken: string;
|
|
50
|
+
|
|
51
|
+
constructor(options: InstanceOptions) {
|
|
52
|
+
this.#baseUrl = options.baseUrl;
|
|
53
|
+
this.#sourceId = options.sourceId;
|
|
54
|
+
this.#merchantId = options.merchantId;
|
|
55
|
+
this.#terminalId = options.terminalId;
|
|
56
|
+
this.#userId = options.userId;
|
|
57
|
+
this.#password = options.password;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* getToken
|
|
62
|
+
* @returns {Promise<GetTokenResponse>}
|
|
63
|
+
*/
|
|
64
|
+
private async getToken(): Promise<GetTokenResponse> {
|
|
65
|
+
try {
|
|
66
|
+
const config = {
|
|
67
|
+
headers: {
|
|
68
|
+
'Content-Type': 'application/json'
|
|
69
|
+
}
|
|
70
|
+
};
|
|
71
|
+
const payload: GetTokenRequest = {
|
|
72
|
+
userId: this.#userId,
|
|
73
|
+
password: this.#password,
|
|
74
|
+
}
|
|
75
|
+
const response = await fetch(`${this.#baseUrl}/auth/token`, {
|
|
76
|
+
method: 'POST',
|
|
77
|
+
headers: config.headers,
|
|
78
|
+
body: JSON.stringify(payload)
|
|
79
|
+
});
|
|
80
|
+
const originResponse = (await response.json()) as GetTokenResponse;
|
|
81
|
+
this.#bToken = originResponse.token;
|
|
82
|
+
return originResponse;
|
|
83
|
+
} catch (error) {
|
|
84
|
+
console.error(error)
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* requestQR
|
|
89
|
+
* @param {CreateQrRequestOption} options
|
|
90
|
+
* @returns {Promise<CreateQrResponse>}
|
|
91
|
+
*/
|
|
92
|
+
public async requestQR(options: CreateQrRequestOption): Promise<CreateQrResponse> {
|
|
93
|
+
try {
|
|
94
|
+
await this.getToken(); // Get Replay Prevention Token
|
|
95
|
+
const config = {
|
|
96
|
+
headers: {
|
|
97
|
+
'Content-Type': 'application/json'
|
|
98
|
+
}
|
|
99
|
+
};
|
|
100
|
+
const payload: CreateQrRequest = {
|
|
101
|
+
transCurrency: options.transCurrency,
|
|
102
|
+
transAmount: options.transAmount,
|
|
103
|
+
purposeOfTransaction: options.purposeOfTransaction,
|
|
104
|
+
referenceNo: options.referenceNo,
|
|
105
|
+
token: this.#bToken,
|
|
106
|
+
sourceId: this.#sourceId,
|
|
107
|
+
merchantId: this.#merchantId,
|
|
108
|
+
terminalId: this.#terminalId,
|
|
109
|
+
}
|
|
110
|
+
const response = await fetch(`${this.#baseUrl}/dynamicqr`, {
|
|
111
|
+
method: 'POST',
|
|
112
|
+
headers: config.headers,
|
|
113
|
+
body: JSON.stringify(payload)
|
|
114
|
+
});
|
|
115
|
+
return (await response.json()) as CreateQrResponse;
|
|
116
|
+
} catch (error) {
|
|
117
|
+
console.error(error)
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
/**
|
|
121
|
+
* checkQR
|
|
122
|
+
* @param {CheckQrRequestOption} options
|
|
123
|
+
* @returns {Promise<CheckQrResponse>}
|
|
124
|
+
*/
|
|
125
|
+
public async checkQR(options: CheckQrRequestOption): Promise<CheckQrResponse> {
|
|
126
|
+
try {
|
|
127
|
+
await this.getToken(); // Get Replay Prevention Token
|
|
128
|
+
const config = {
|
|
129
|
+
headers: {
|
|
130
|
+
'Content-Type': 'application/json'
|
|
131
|
+
}
|
|
132
|
+
};
|
|
133
|
+
const payload: CheckQrRequest = {
|
|
134
|
+
token: this.#bToken,
|
|
135
|
+
sourceId: this.#sourceId
|
|
136
|
+
}
|
|
137
|
+
const response = await fetch(`${this.#baseUrl}/dynamicqr/${options.qrReferenceNo}/status`, {
|
|
138
|
+
method: 'PUT',
|
|
139
|
+
headers: config.headers,
|
|
140
|
+
body: JSON.stringify(payload)
|
|
141
|
+
});
|
|
142
|
+
return (await response.json()) as CheckQrResponse;
|
|
143
|
+
} catch (error) {
|
|
144
|
+
console.error(error)
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
/**
|
|
148
|
+
* refund
|
|
149
|
+
* @param {RefundRequestOption} options
|
|
150
|
+
* @returns {Promise<RefundResponse>}
|
|
151
|
+
*/
|
|
152
|
+
public async refund(options: RefundRequestOption): Promise<RefundResponse> {
|
|
153
|
+
try {
|
|
154
|
+
await this.getToken(); // Get Replay Prevention Token
|
|
155
|
+
const config = {
|
|
156
|
+
headers: {
|
|
157
|
+
'Content-Type': 'application/json'
|
|
158
|
+
}
|
|
159
|
+
};
|
|
160
|
+
const payload: RefundRequest = {
|
|
161
|
+
token: this.#bToken,
|
|
162
|
+
sourceId: this.#sourceId,
|
|
163
|
+
transactionId: options.transactionId,
|
|
164
|
+
refundCurrency: options.refundCurrency,
|
|
165
|
+
refundAmount: options.refundAmount,
|
|
166
|
+
isPartialRedund: options.isPartialRedund,
|
|
167
|
+
}
|
|
168
|
+
const response = await fetch(`${this.#baseUrl}/payment/refund`, {
|
|
169
|
+
method: 'POST',
|
|
170
|
+
headers: config.headers,
|
|
171
|
+
body: JSON.stringify(payload)
|
|
172
|
+
});
|
|
173
|
+
return (await response.json()) as RefundResponse;
|
|
174
|
+
} catch (error) {
|
|
175
|
+
console.error(error)
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
}
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
// --------- Request Token -----------
|
|
2
|
+
// --------- Request Token -----------
|
|
3
|
+
|
|
4
|
+
export interface GetTokenRequest {
|
|
5
|
+
userId: string;
|
|
6
|
+
password: string;
|
|
7
|
+
}
|
|
8
|
+
export interface GetTokenResponse {
|
|
9
|
+
token: string;
|
|
10
|
+
returnCode: string; // integer in string
|
|
11
|
+
message: string;
|
|
12
|
+
expiredDateTime: string; // timestamp in string
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
// --------- Create QR -----------
|
|
16
|
+
// --------- Create QR -----------
|
|
17
|
+
|
|
18
|
+
export interface CreateQrRequestOption {
|
|
19
|
+
transCurrency: string;
|
|
20
|
+
transAmount: number;
|
|
21
|
+
purposeOfTransaction?: string;
|
|
22
|
+
referenceNo: string;
|
|
23
|
+
}
|
|
24
|
+
export interface CreateQrRequest extends CreateQrRequestOption {
|
|
25
|
+
token: string;
|
|
26
|
+
sourceId: string;
|
|
27
|
+
merchantId: string;
|
|
28
|
+
terminalId: string;
|
|
29
|
+
}
|
|
30
|
+
export interface CreateQrResponse {
|
|
31
|
+
returnCode: string; // integer in string
|
|
32
|
+
message: string;
|
|
33
|
+
referenceNo: string;
|
|
34
|
+
qrCodeInfo: string;
|
|
35
|
+
qrReferenceNo: string;
|
|
36
|
+
qrIssuedDateTime: string;
|
|
37
|
+
qrExpiredDateTime: string;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
// --------- Check Status -----------
|
|
41
|
+
// --------- Check Status -----------
|
|
42
|
+
|
|
43
|
+
export interface CheckQrRequestOption {
|
|
44
|
+
qrReferenceNo: string;
|
|
45
|
+
}
|
|
46
|
+
export interface CheckQrRequest {
|
|
47
|
+
token: string;
|
|
48
|
+
sourceId: string;
|
|
49
|
+
}
|
|
50
|
+
export interface CheckQrResponse {
|
|
51
|
+
referenceNo: string;
|
|
52
|
+
returnCode: string;
|
|
53
|
+
transactionId: string;
|
|
54
|
+
transCurrency: string;
|
|
55
|
+
transDateTime: string;
|
|
56
|
+
transAmount: number;
|
|
57
|
+
qrReferenceNo: string;
|
|
58
|
+
institutionId: string;
|
|
59
|
+
institutionName: string;
|
|
60
|
+
merchantId: string;
|
|
61
|
+
message: string;
|
|
62
|
+
remark: string;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
// --------- Refund -----------
|
|
66
|
+
// --------- Refund -----------
|
|
67
|
+
|
|
68
|
+
export interface RefundRequestOption {
|
|
69
|
+
transactionId: string;
|
|
70
|
+
refundCurrency: string;
|
|
71
|
+
refundAmount: number;
|
|
72
|
+
isPartialRedund: boolean;
|
|
73
|
+
}
|
|
74
|
+
export interface RefundRequest extends RefundRequestOption {
|
|
75
|
+
token: string;
|
|
76
|
+
sourceId: string;
|
|
77
|
+
}
|
|
78
|
+
export interface RefundResponse {
|
|
79
|
+
transactionId: string;
|
|
80
|
+
returnCode: string;
|
|
81
|
+
message: string;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
// --------- Callback -----------
|
|
85
|
+
// --------- Callback -----------
|
|
86
|
+
|
|
87
|
+
export interface CallbackRequest {
|
|
88
|
+
apiKey: string;
|
|
89
|
+
referenceNo: string;
|
|
90
|
+
transactionId: string;
|
|
91
|
+
transCurrency: string;
|
|
92
|
+
transAmount: number;
|
|
93
|
+
transDateTime: string;
|
|
94
|
+
transStatusCode: string;
|
|
95
|
+
transStatusDescription: string;
|
|
96
|
+
qrReferenceNo: string;
|
|
97
|
+
institutionId: string;
|
|
98
|
+
institutionName: string;
|
|
99
|
+
merchantId: string;
|
|
100
|
+
}
|
|
101
|
+
export interface CallbackResponse {
|
|
102
|
+
qrReferenceNo: string;
|
|
103
|
+
returnCode: string;
|
|
104
|
+
message: string;
|
|
105
|
+
}
|
package/test/test.js
ADDED
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
const { CBPayMerchantApi } = require("../dist/cjs/index");
|
|
2
|
+
const dovenv = require("dotenv");
|
|
3
|
+
dovenv.config()
|
|
4
|
+
const { performance } = require("perf_hooks")
|
|
5
|
+
|
|
6
|
+
const CBPay = CBPayMerchantApi({
|
|
7
|
+
baseUrl: process.env.BASE_URL,
|
|
8
|
+
sourceId: process.env.SOURCE_ID,
|
|
9
|
+
merchantId: process.env.MERCHANT_ID,
|
|
10
|
+
terminalId: process.env.TERMINAL_ID,
|
|
11
|
+
userId: process.env.USER_ID,
|
|
12
|
+
password: process.env.PASSWORD,
|
|
13
|
+
});
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* @start
|
|
18
|
+
* @start
|
|
19
|
+
* @start
|
|
20
|
+
*/
|
|
21
|
+
const start = async () => {
|
|
22
|
+
const startTime = performance.now();
|
|
23
|
+
try {
|
|
24
|
+
const qrResponse = await CBPay.requestQR({
|
|
25
|
+
transAmount: 5000,
|
|
26
|
+
transCurrency: 'MMK',
|
|
27
|
+
referenceNo: 'TEST-' + new Date().getTime(),
|
|
28
|
+
// purposeOfTransaction: 'MMK',
|
|
29
|
+
})
|
|
30
|
+
console.log(qrResponse)
|
|
31
|
+
const end3Time = performance.now();
|
|
32
|
+
const latency3Ms = (end3Time - startTime).toFixed(3);
|
|
33
|
+
console.log(`\n--- Successful ---`);
|
|
34
|
+
console.log(`**Network Latency: ${latency3Ms} ms**`);
|
|
35
|
+
} catch (error) {
|
|
36
|
+
console.error(error)
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
start()
|
package/tsconfig.json
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
{
|
|
2
|
+
"compilerOptions": {
|
|
3
|
+
"target": "ES2020",
|
|
4
|
+
"module": "ES2020",
|
|
5
|
+
"declaration": true,
|
|
6
|
+
"outDir": "dist/esm",
|
|
7
|
+
"strict": false,
|
|
8
|
+
"moduleResolution": "Node",
|
|
9
|
+
"esModuleInterop": true,
|
|
10
|
+
"skipLibCheck": true,
|
|
11
|
+
"types": [
|
|
12
|
+
"node"
|
|
13
|
+
]
|
|
14
|
+
},
|
|
15
|
+
"include": [
|
|
16
|
+
"src"
|
|
17
|
+
]
|
|
18
|
+
}
|