@exode-team/multicard-uz.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/.eslintrc.js ADDED
@@ -0,0 +1,5 @@
1
+ module.exports = {
2
+ env: {
3
+ jest: true,
4
+ },
5
+ };
@@ -0,0 +1,25 @@
1
+ /**
2
+ * Helpers
3
+ *
4
+ * @author: exode <hello@exode.ru>
5
+ */
6
+ /**
7
+ * Проверка подписи callback (success)
8
+ * sign = MD5("{store_id}{invoice_id}{amount}{secret}")
9
+ */
10
+ export declare const verifyCallbackSign: (payload: {
11
+ store_id: number | string;
12
+ invoice_id: string;
13
+ amount: number | string;
14
+ sign: string;
15
+ }, secret: string) => boolean;
16
+ /**
17
+ * Проверка подписи webhook (status change)
18
+ * sign = SHA1("{uuid}{invoice_id}{amount}{secret}")
19
+ */
20
+ export declare const verifyWebhookSign: (payload: {
21
+ uuid: string;
22
+ sign: string;
23
+ amount: number | string;
24
+ invoice_id: string;
25
+ }, secret: string) => boolean;
@@ -0,0 +1,45 @@
1
+ /**
2
+ * Helpers
3
+ *
4
+ * @author: exode <hello@exode.ru>
5
+ */
6
+ (function (factory) {
7
+ if (typeof module === "object" && typeof module.exports === "object") {
8
+ var v = factory(require, exports);
9
+ if (v !== undefined) module.exports = v;
10
+ }
11
+ else if (typeof define === "function" && define.amd) {
12
+ define(["require", "exports", "crypto"], factory);
13
+ }
14
+ })(function (require, exports) {
15
+ "use strict";
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ exports.verifyWebhookSign = exports.verifyCallbackSign = void 0;
18
+ const crypto_1 = require("crypto");
19
+ /**
20
+ * Проверка подписи callback (success)
21
+ * sign = MD5("{store_id}{invoice_id}{amount}{secret}")
22
+ */
23
+ const verifyCallbackSign = (payload, secret) => {
24
+ const { amount, invoice_id, sign, store_id, } = payload;
25
+ const dataToHash = `${store_id}${invoice_id}${amount}${secret}`;
26
+ const calculatedSign = (0, crypto_1.createHash)('md5')
27
+ .update(dataToHash)
28
+ .digest('hex');
29
+ return sign === calculatedSign;
30
+ };
31
+ exports.verifyCallbackSign = verifyCallbackSign;
32
+ /**
33
+ * Проверка подписи webhook (status change)
34
+ * sign = SHA1("{uuid}{invoice_id}{amount}{secret}")
35
+ */
36
+ const verifyWebhookSign = (payload, secret) => {
37
+ const { amount, invoice_id, sign, uuid, } = payload;
38
+ const dataToHash = `${uuid}${invoice_id}${amount}${secret}`;
39
+ const calculatedSign = (0, crypto_1.createHash)('sha1')
40
+ .update(dataToHash)
41
+ .digest('hex');
42
+ return sign === calculatedSign;
43
+ };
44
+ exports.verifyWebhookSign = verifyWebhookSign;
45
+ });
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Index
3
+ *
4
+ * @author: exode <hello@exode.ru>
5
+ */
6
+ export * from './types';
7
+ export * from './helpers';
8
+ export * from './multicard-api';
package/dist/index.js ADDED
@@ -0,0 +1,34 @@
1
+ /**
2
+ * Index
3
+ *
4
+ * @author: exode <hello@exode.ru>
5
+ */
6
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
7
+ if (k2 === undefined) k2 = k;
8
+ var desc = Object.getOwnPropertyDescriptor(m, k);
9
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
10
+ desc = { enumerable: true, get: function() { return m[k]; } };
11
+ }
12
+ Object.defineProperty(o, k2, desc);
13
+ }) : (function(o, m, k, k2) {
14
+ if (k2 === undefined) k2 = k;
15
+ o[k2] = m[k];
16
+ }));
17
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
18
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
19
+ };
20
+ (function (factory) {
21
+ if (typeof module === "object" && typeof module.exports === "object") {
22
+ var v = factory(require, exports);
23
+ if (v !== undefined) module.exports = v;
24
+ }
25
+ else if (typeof define === "function" && define.amd) {
26
+ define(["require", "exports", "./types", "./helpers", "./multicard-api"], factory);
27
+ }
28
+ })(function (require, exports) {
29
+ "use strict";
30
+ Object.defineProperty(exports, "__esModule", { value: true });
31
+ __exportStar(require("./types"), exports);
32
+ __exportStar(require("./helpers"), exports);
33
+ __exportStar(require("./multicard-api"), exports);
34
+ });
@@ -0,0 +1,142 @@
1
+ /**
2
+ * MulticardApi
3
+ *
4
+ * @author: exode <hello@exode.ru>
5
+ */
6
+ import { MulticardBase } from './multicard-base';
7
+ import { AuthGetTokenResponse, CardBindCreateRequest, CardBindCreateResponse, CardBindGetStatusResponse, CardDeleteResponse, CardGetResponse, FiscalSendLinkRequest, FiscalSendLinkResponse, InvoiceCreateRequest, InvoiceCreateResponse, InvoiceDeleteResponse, InvoiceGetResponse, MulticardResponse, PaymentCancelResponse, PaymentConfirmRequest, PaymentConfirmResponse, PaymentCreateByTokenRequest, PaymentCreateResponse, PaymentGetResponse, PaymentPartialRefundRequest, PaymentPartialRefundResponse } from './types';
8
+ export declare class MulticardApi extends MulticardBase {
9
+ /**
10
+ * Запрос к API
11
+ * @param {string} apiUrl
12
+ * @param {Record<any, any>} data
13
+ * @param {Record<any, any>} headers
14
+ * @param {'post' | 'get' | 'put' | 'delete' | 'patch'} httpMethod
15
+ * @returns {Promise<T>}
16
+ * @private
17
+ */
18
+ private requestApi;
19
+ /**
20
+ * ===========================
21
+ * Auth
22
+ * ===========================
23
+ */
24
+ /**
25
+ * Получение JWT-токена (24ч)
26
+ * @param {string} applicationId
27
+ * @param {string} secret
28
+ * @returns {Promise<MulticardResponse<AuthGetTokenResponse>>}
29
+ */
30
+ getToken(applicationId: string, secret: string): Promise<MulticardResponse<AuthGetTokenResponse>>;
31
+ /**
32
+ * ===========================
33
+ * Invoice (checkout redirect)
34
+ * ===========================
35
+ */
36
+ /**
37
+ * Создание инвойса
38
+ * @param {InvoiceCreateRequest} request
39
+ * @returns {Promise<InvoiceCreateResponse>}
40
+ */
41
+ createInvoice(request: InvoiceCreateRequest): Promise<InvoiceCreateResponse>;
42
+ /**
43
+ * Получение информации об инвойсе
44
+ * @param {string} uuid
45
+ * @returns {Promise<InvoiceGetResponse>}
46
+ */
47
+ getInvoice(uuid: string): Promise<InvoiceGetResponse>;
48
+ /**
49
+ * Удаление/аннулирование инвойса
50
+ * @param {string} uuid
51
+ * @returns {Promise<InvoiceDeleteResponse>}
52
+ */
53
+ deleteInvoice(uuid: string): Promise<InvoiceDeleteResponse>;
54
+ /**
55
+ * ===========================
56
+ * Card Binding (Form)
57
+ * ===========================
58
+ */
59
+ /**
60
+ * Создание сессии привязки карты (redirect на форму Multicard)
61
+ * @param {CardBindCreateRequest} request
62
+ * @returns {Promise<CardBindCreateResponse>}
63
+ */
64
+ createBindSession(request: CardBindCreateRequest): Promise<CardBindCreateResponse>;
65
+ /**
66
+ * Проверка статуса привязки карты
67
+ * @param {string} sessionId
68
+ * @returns {Promise<CardBindGetStatusResponse>}
69
+ */
70
+ getBindStatus(sessionId: string): Promise<CardBindGetStatusResponse>;
71
+ /**
72
+ * ===========================
73
+ * Card Management
74
+ * ===========================
75
+ */
76
+ /**
77
+ * Получение информации о карте по токену
78
+ * @param {string} cardToken
79
+ * @returns {Promise<CardGetResponse>}
80
+ */
81
+ getCard(cardToken: string): Promise<CardGetResponse>;
82
+ /**
83
+ * Аннулирование токена карты
84
+ * @param {string} cardToken
85
+ * @returns {Promise<CardDeleteResponse>}
86
+ */
87
+ removeCard(cardToken: string): Promise<CardDeleteResponse>;
88
+ /**
89
+ * ===========================
90
+ * Payment by Token
91
+ * ===========================
92
+ */
93
+ /**
94
+ * Создание платежа по токену карты
95
+ * @param {PaymentCreateByTokenRequest} request
96
+ * @returns {Promise<PaymentCreateResponse>}
97
+ */
98
+ createPayment(request: PaymentCreateByTokenRequest): Promise<PaymentCreateResponse>;
99
+ /**
100
+ * Подтверждение платежа (OTP или безакцептное)
101
+ * @param {string} paymentUuid
102
+ * @param {PaymentConfirmRequest} request
103
+ * @returns {Promise<PaymentConfirmResponse>}
104
+ */
105
+ confirmPayment(paymentUuid: string, request?: PaymentConfirmRequest): Promise<PaymentConfirmResponse>;
106
+ /**
107
+ * Получение информации о платеже
108
+ * @param {string} uuid
109
+ * @returns {Promise<PaymentGetResponse>}
110
+ */
111
+ getPayment(uuid: string): Promise<PaymentGetResponse>;
112
+ /**
113
+ * ===========================
114
+ * Refund
115
+ * ===========================
116
+ */
117
+ /**
118
+ * Полная отмена платежа (полный возврат)
119
+ * @param {string} uuid
120
+ * @returns {Promise<PaymentCancelResponse>}
121
+ */
122
+ cancelPayment(uuid: string): Promise<PaymentCancelResponse>;
123
+ /**
124
+ * Частичный возврат
125
+ * @param {string} uuid
126
+ * @param {PaymentPartialRefundRequest} request
127
+ * @returns {Promise<PaymentPartialRefundResponse>}
128
+ */
129
+ partialRefund(uuid: string, request: PaymentPartialRefundRequest): Promise<PaymentPartialRefundResponse>;
130
+ /**
131
+ * ===========================
132
+ * Fiscal
133
+ * ===========================
134
+ */
135
+ /**
136
+ * Отправка фискальной ссылки
137
+ * @param {string} paymentUuid
138
+ * @param {FiscalSendLinkRequest} request
139
+ * @returns {Promise<FiscalSendLinkResponse>}
140
+ */
141
+ sendFiscalLink(paymentUuid: string, request: FiscalSendLinkRequest): Promise<FiscalSendLinkResponse>;
142
+ }
@@ -0,0 +1,220 @@
1
+ /**
2
+ * MulticardApi
3
+ *
4
+ * @author: exode <hello@exode.ru>
5
+ */
6
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
7
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
8
+ return new (P || (P = Promise))(function (resolve, reject) {
9
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
10
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
11
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
12
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
13
+ });
14
+ };
15
+ var __importDefault = (this && this.__importDefault) || function (mod) {
16
+ return (mod && mod.__esModule) ? mod : { "default": mod };
17
+ };
18
+ (function (factory) {
19
+ if (typeof module === "object" && typeof module.exports === "object") {
20
+ var v = factory(require, exports);
21
+ if (v !== undefined) module.exports = v;
22
+ }
23
+ else if (typeof define === "function" && define.amd) {
24
+ define(["require", "exports", "axios", "./multicard-base"], factory);
25
+ }
26
+ })(function (require, exports) {
27
+ "use strict";
28
+ Object.defineProperty(exports, "__esModule", { value: true });
29
+ exports.MulticardApi = void 0;
30
+ const axios_1 = __importDefault(require("axios"));
31
+ const multicard_base_1 = require("./multicard-base");
32
+ class MulticardApi extends multicard_base_1.MulticardBase {
33
+ /**
34
+ * Запрос к API
35
+ * @param {string} apiUrl
36
+ * @param {Record<any, any>} data
37
+ * @param {Record<any, any>} headers
38
+ * @param {'post' | 'get' | 'put' | 'delete' | 'patch'} httpMethod
39
+ * @returns {Promise<T>}
40
+ * @private
41
+ */
42
+ requestApi(apiUrl_1) {
43
+ return __awaiter(this, arguments, void 0, function* (apiUrl, data = {}, headers, httpMethod = 'post') {
44
+ const config = {
45
+ timeout: this.timeoutMs,
46
+ url: `${this.baseUrl}${apiUrl}`,
47
+ method: httpMethod,
48
+ maxBodyLength: Infinity,
49
+ data: httpMethod !== 'get' ? data : {},
50
+ params: httpMethod === 'get' ? data : {},
51
+ headers: Object.assign(Object.assign({ 'Accept': 'application/json', 'Content-Type': 'application/json' }, (this.accessToken ? { 'Authorization': `Bearer ${this.accessToken}` } : {})), headers),
52
+ };
53
+ if (this.mode === 'sandbox') {
54
+ console.log('[PACKAGE:multicard-uz.api]', JSON.stringify(config));
55
+ }
56
+ try {
57
+ const response = yield axios_1.default.request(config);
58
+ return response.data;
59
+ }
60
+ catch (error) {
61
+ const response = error === null || error === void 0 ? void 0 : error.response;
62
+ console.error('[PACKAGE:multicard-uz.api]', `status=${response === null || response === void 0 ? void 0 : response.status}`, `config=[${JSON.stringify(config)}]`, JSON.stringify(response === null || response === void 0 ? void 0 : response.data));
63
+ throw error;
64
+ }
65
+ });
66
+ }
67
+ /**
68
+ * ===========================
69
+ * Auth
70
+ * ===========================
71
+ */
72
+ /**
73
+ * Получение JWT-токена (24ч)
74
+ * @param {string} applicationId
75
+ * @param {string} secret
76
+ * @returns {Promise<MulticardResponse<AuthGetTokenResponse>>}
77
+ */
78
+ getToken(applicationId, secret) {
79
+ return this.requestApi('/auth', { secret, application_id: applicationId });
80
+ }
81
+ /**
82
+ * ===========================
83
+ * Invoice (checkout redirect)
84
+ * ===========================
85
+ */
86
+ /**
87
+ * Создание инвойса
88
+ * @param {InvoiceCreateRequest} request
89
+ * @returns {Promise<InvoiceCreateResponse>}
90
+ */
91
+ createInvoice(request) {
92
+ return this.requestApi('/payment/invoice', request);
93
+ }
94
+ /**
95
+ * Получение информации об инвойсе
96
+ * @param {string} uuid
97
+ * @returns {Promise<InvoiceGetResponse>}
98
+ */
99
+ getInvoice(uuid) {
100
+ return this.requestApi(`/payment/invoice/${uuid}`, {}, undefined, 'get');
101
+ }
102
+ /**
103
+ * Удаление/аннулирование инвойса
104
+ * @param {string} uuid
105
+ * @returns {Promise<InvoiceDeleteResponse>}
106
+ */
107
+ deleteInvoice(uuid) {
108
+ return this.requestApi(`/payment/invoice/${uuid}`, {}, undefined, 'delete');
109
+ }
110
+ /**
111
+ * ===========================
112
+ * Card Binding (Form)
113
+ * ===========================
114
+ */
115
+ /**
116
+ * Создание сессии привязки карты (redirect на форму Multicard)
117
+ * @param {CardBindCreateRequest} request
118
+ * @returns {Promise<CardBindCreateResponse>}
119
+ */
120
+ createBindSession(request) {
121
+ return this.requestApi('/payment/card/bind', request);
122
+ }
123
+ /**
124
+ * Проверка статуса привязки карты
125
+ * @param {string} sessionId
126
+ * @returns {Promise<CardBindGetStatusResponse>}
127
+ */
128
+ getBindStatus(sessionId) {
129
+ return this.requestApi(`/payment/card/bind/${sessionId}`, {}, undefined, 'get');
130
+ }
131
+ /**
132
+ * ===========================
133
+ * Card Management
134
+ * ===========================
135
+ */
136
+ /**
137
+ * Получение информации о карте по токену
138
+ * @param {string} cardToken
139
+ * @returns {Promise<CardGetResponse>}
140
+ */
141
+ getCard(cardToken) {
142
+ return this.requestApi(`/payment/card/${cardToken}`, {}, undefined, 'get');
143
+ }
144
+ /**
145
+ * Аннулирование токена карты
146
+ * @param {string} cardToken
147
+ * @returns {Promise<CardDeleteResponse>}
148
+ */
149
+ removeCard(cardToken) {
150
+ return this.requestApi(`/payment/card/${cardToken}`, {}, undefined, 'delete');
151
+ }
152
+ /**
153
+ * ===========================
154
+ * Payment by Token
155
+ * ===========================
156
+ */
157
+ /**
158
+ * Создание платежа по токену карты
159
+ * @param {PaymentCreateByTokenRequest} request
160
+ * @returns {Promise<PaymentCreateResponse>}
161
+ */
162
+ createPayment(request) {
163
+ return this.requestApi('/payment', request);
164
+ }
165
+ /**
166
+ * Подтверждение платежа (OTP или безакцептное)
167
+ * @param {string} paymentUuid
168
+ * @param {PaymentConfirmRequest} request
169
+ * @returns {Promise<PaymentConfirmResponse>}
170
+ */
171
+ confirmPayment(paymentUuid, request = {}) {
172
+ return this.requestApi(`/payment/${paymentUuid}`, request, undefined, 'put');
173
+ }
174
+ /**
175
+ * Получение информации о платеже
176
+ * @param {string} uuid
177
+ * @returns {Promise<PaymentGetResponse>}
178
+ */
179
+ getPayment(uuid) {
180
+ return this.requestApi(`/payment/${uuid}`, {}, undefined, 'get');
181
+ }
182
+ /**
183
+ * ===========================
184
+ * Refund
185
+ * ===========================
186
+ */
187
+ /**
188
+ * Полная отмена платежа (полный возврат)
189
+ * @param {string} uuid
190
+ * @returns {Promise<PaymentCancelResponse>}
191
+ */
192
+ cancelPayment(uuid) {
193
+ return this.requestApi(`/payment/${uuid}`, {}, undefined, 'delete');
194
+ }
195
+ /**
196
+ * Частичный возврат
197
+ * @param {string} uuid
198
+ * @param {PaymentPartialRefundRequest} request
199
+ * @returns {Promise<PaymentPartialRefundResponse>}
200
+ */
201
+ partialRefund(uuid, request) {
202
+ return this.requestApi(`/payment/${uuid}/partial`, request, undefined, 'delete');
203
+ }
204
+ /**
205
+ * ===========================
206
+ * Fiscal
207
+ * ===========================
208
+ */
209
+ /**
210
+ * Отправка фискальной ссылки
211
+ * @param {string} paymentUuid
212
+ * @param {FiscalSendLinkRequest} request
213
+ * @returns {Promise<FiscalSendLinkResponse>}
214
+ */
215
+ sendFiscalLink(paymentUuid, request) {
216
+ return this.requestApi(`/payment/${paymentUuid}/fiscal`, request, undefined, 'patch');
217
+ }
218
+ }
219
+ exports.MulticardApi = MulticardApi;
220
+ });
@@ -0,0 +1,38 @@
1
+ /**
2
+ * MulticardBase
3
+ *
4
+ * @author: exode <hello@exode.ru>
5
+ */
6
+ import { MulticardApiConfig } from './types';
7
+ export declare class MulticardBase {
8
+ constructor(options: MulticardApiConfig);
9
+ /**
10
+ * Токен авторизации
11
+ * @type {string | null}
12
+ * @protected
13
+ */
14
+ protected accessToken: string | null;
15
+ /**
16
+ * Окружение исполнения
17
+ * @type {MulticardApiConfig['mode']}
18
+ * @protected
19
+ */
20
+ protected readonly mode: MulticardApiConfig['mode'];
21
+ /**
22
+ * Таймаут (MS)
23
+ * @type {MulticardApiConfig['timeoutMs']}
24
+ * @protected
25
+ */
26
+ protected readonly timeoutMs: MulticardApiConfig['timeoutMs'];
27
+ /**
28
+ * Base URL по окружению
29
+ * @returns {string}
30
+ * @protected
31
+ */
32
+ protected get baseUrl(): string;
33
+ /**
34
+ * Установка токена
35
+ * @param {string} token
36
+ */
37
+ setAccessToken(token: string): void;
38
+ }
@@ -0,0 +1,49 @@
1
+ /**
2
+ * MulticardBase
3
+ *
4
+ * @author: exode <hello@exode.ru>
5
+ */
6
+ (function (factory) {
7
+ if (typeof module === "object" && typeof module.exports === "object") {
8
+ var v = factory(require, exports);
9
+ if (v !== undefined) module.exports = v;
10
+ }
11
+ else if (typeof define === "function" && define.amd) {
12
+ define(["require", "exports"], factory);
13
+ }
14
+ })(function (require, exports) {
15
+ "use strict";
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ exports.MulticardBase = void 0;
18
+ class MulticardBase {
19
+ constructor(options) {
20
+ var _a, _b;
21
+ /**
22
+ * Токен авторизации
23
+ * @type {string | null}
24
+ * @protected
25
+ */
26
+ this.accessToken = null;
27
+ this.mode = (_a = options.mode) !== null && _a !== void 0 ? _a : 'production';
28
+ this.timeoutMs = (_b = options.timeoutMs) !== null && _b !== void 0 ? _b : 30000;
29
+ }
30
+ /**
31
+ * Base URL по окружению
32
+ * @returns {string}
33
+ * @protected
34
+ */
35
+ get baseUrl() {
36
+ return this.mode === 'sandbox'
37
+ ? 'https://dev-mesh.multicard.uz'
38
+ : 'https://mesh.multicard.uz';
39
+ }
40
+ /**
41
+ * Установка токена
42
+ * @param {string} token
43
+ */
44
+ setAccessToken(token) {
45
+ this.accessToken = token;
46
+ }
47
+ }
48
+ exports.MulticardBase = MulticardBase;
49
+ });
@@ -0,0 +1,372 @@
1
+ /**
2
+ * Types
3
+ *
4
+ * @author: exode <hello@exode.ru>
5
+ */
6
+ /**
7
+ * @Common:
8
+ */
9
+ export interface MulticardApiConfig {
10
+ mode?: 'production' | 'sandbox';
11
+ timeoutMs?: number;
12
+ }
13
+ export interface MulticardSuccessResponse<T = any> {
14
+ success: true;
15
+ data: T;
16
+ }
17
+ export interface MulticardErrorResponse {
18
+ success: false;
19
+ error: {
20
+ code: MulticardErrorCode;
21
+ details: string;
22
+ };
23
+ }
24
+ export type MulticardResponse<T = any> = MulticardSuccessResponse<T> | MulticardErrorResponse;
25
+ export declare enum MulticardErrorCode {
26
+ ERROR_FIELDS = "ERROR_FIELDS",
27
+ ERROR_NOT_FOUND = "ERROR_NOT_FOUND",
28
+ ERROR_CARD_NOT_FOUND = "ERROR_CARD_NOT_FOUND",
29
+ ERROR_WRONG_OTP = "ERROR_WRONG_OTP",
30
+ ERROR_SMS_ALREADY_SENT = "ERROR_SMS_ALREADY_SENT",
31
+ ERROR_CARD_SMS = "ERROR_CARD_SMS",
32
+ ERROR_TRANS_NOT_READY = "ERROR_TRANS_NOT_READY",
33
+ ERROR_DEBIT_UNKNOWN = "ERROR_DEBIT_UNKNOWN",
34
+ ERROR_CALLBACK_TIMEOUT = "ERROR_CALLBACK_TIMEOUT",
35
+ ERROR_UNKNOWN = "ERROR_UNKNOWN"
36
+ }
37
+ export declare enum MulticardPaymentStatus {
38
+ Draft = "draft",
39
+ Progress = "progress",
40
+ Billing = "billing",
41
+ Success = "success",
42
+ Error = "error",
43
+ Revert = "revert",
44
+ Hold = "hold"
45
+ }
46
+ export declare enum MulticardPaymentService {
47
+ Uzcard = "uzcard",
48
+ Humo = "humo",
49
+ Visa = "visa",
50
+ Mastercard = "mastercard",
51
+ Account = "account",
52
+ Payme = "payme",
53
+ Click = "click",
54
+ Uzum = "uzum",
55
+ Anorbank = "anorbank",
56
+ Oson = "oson",
57
+ Alif = "alif",
58
+ Xazna = "xazna",
59
+ Beepul = "beepul",
60
+ Trastpay = "trastpay",
61
+ Sbp = "sbp"
62
+ }
63
+ export declare enum MulticardCommissionType {
64
+ Up = "up",
65
+ Down = "down"
66
+ }
67
+ export declare enum MulticardCardStatus {
68
+ Active = "active",
69
+ Inactive = "inactive"
70
+ }
71
+ /**
72
+ * @Auth:
73
+ */
74
+ export interface AuthGetTokenRequest {
75
+ application_id: string;
76
+ secret: string;
77
+ }
78
+ export interface AuthGetTokenResponse {
79
+ token: string;
80
+ role: string;
81
+ expiry: string;
82
+ }
83
+ /**
84
+ * @Invoice:
85
+ */
86
+ export interface OfdItem {
87
+ /** Количество товара */
88
+ qty: number;
89
+ /** Цена за единицу (тийины) */
90
+ price: number;
91
+ /** ИКПУ код товара */
92
+ mxik: string;
93
+ /** Итого (тийины) */
94
+ total: number;
95
+ /** Код упаковки */
96
+ package_code: string;
97
+ /** Наименование товара/услуги */
98
+ name: string;
99
+ /** Ставка НДС (%) */
100
+ vat: number;
101
+ /** ИНН продавца */
102
+ tin: string;
103
+ /** Маркировка (может быть null) */
104
+ mark?: string | null;
105
+ }
106
+ export interface InvoiceCreateRequest {
107
+ /** Идентификатор магазина */
108
+ store_id: number;
109
+ /** Сумма платежа (тийины) */
110
+ amount: number;
111
+ /** Идентификатор инвойса на стороне партнёра */
112
+ invoice_id: string;
113
+ /** URL для редиректа после оплаты */
114
+ return_url?: string;
115
+ /** URL для callback при успешной оплате */
116
+ callback_url?: string;
117
+ /** Данные для фискализации */
118
+ ofd?: OfdItem[];
119
+ /** Описание платежа */
120
+ description?: string;
121
+ }
122
+ export interface InvoiceModel {
123
+ /** UUID инвойса */
124
+ uuid: string;
125
+ /** Идентификатор магазина */
126
+ store_id: number;
127
+ /** Сумма (тийины) */
128
+ amount: number;
129
+ /** Идентификатор инвойса на стороне партнёра */
130
+ invoice_id: string;
131
+ /** Статус платежа */
132
+ status: MulticardPaymentStatus;
133
+ /** URL для редиректа на страницу оплаты */
134
+ checkout_url: string;
135
+ /** URL для редиректа после оплаты */
136
+ return_url?: string;
137
+ /** URL для callback */
138
+ callback_url?: string;
139
+ /** URL чека */
140
+ receipt_url?: string | null;
141
+ }
142
+ export type InvoiceCreateResponse = MulticardSuccessResponse<InvoiceModel>;
143
+ export type InvoiceGetResponse = MulticardSuccessResponse<InvoiceModel>;
144
+ export type InvoiceDeleteResponse = MulticardSuccessResponse<void>;
145
+ /**
146
+ * @Card Binding (Form):
147
+ */
148
+ export interface CardBindCreateRequest {
149
+ /** Идентификатор магазина */
150
+ store_id: number;
151
+ /** URL для редиректа после успешной привязки */
152
+ redirect_url: string;
153
+ /** URL для редиректа при отклонении привязки */
154
+ redirect_decline_url: string;
155
+ /** URL для callback с данными привязки */
156
+ callback_url: string;
157
+ /** Идентификатор пользователя на стороне партнёра */
158
+ payer_id?: string;
159
+ }
160
+ export interface CardBindSession {
161
+ /** Идентификатор сессии привязки */
162
+ session_id: string;
163
+ /** URL формы привязки карты (для redirect) */
164
+ form_url: string;
165
+ }
166
+ export type CardBindCreateResponse = MulticardSuccessResponse<CardBindSession>;
167
+ export interface CardBindStatusData {
168
+ /** Идентификатор сессии привязки */
169
+ session_id: string;
170
+ /** Статус привязки */
171
+ status: string;
172
+ /** Данные карты (при успешной привязке) */
173
+ card?: CardModel;
174
+ }
175
+ export type CardBindGetStatusResponse = MulticardSuccessResponse<CardBindStatusData>;
176
+ /**
177
+ * @Card Binding Callback:
178
+ */
179
+ export interface CardBindCallbackPayload {
180
+ /** Токен привязанной карты */
181
+ card_token: string;
182
+ /** Маскированный номер карты */
183
+ card_pan: string;
184
+ /** Номер телефона держателя карты */
185
+ phone: string;
186
+ /** Платёжная система */
187
+ ps: MulticardPaymentService;
188
+ /** Имя держателя карты */
189
+ holder_name?: string;
190
+ /** Идентификатор пользователя */
191
+ payer_id?: string;
192
+ }
193
+ /**
194
+ * @Card Management:
195
+ */
196
+ export interface CardModel {
197
+ /** ID карты */
198
+ id: number;
199
+ /** ID приложения */
200
+ application_id: number;
201
+ /** Идентификатор пользователя */
202
+ payer_id: string;
203
+ /** Маскированный номер карты */
204
+ card_pan: string;
205
+ /** Токен карты */
206
+ card_token: string;
207
+ /** Номер телефона */
208
+ phone: string;
209
+ /** Имя держателя карты */
210
+ holder_name: string;
211
+ /** ПИНФЛ (может быть null) */
212
+ pinfl: string | null;
213
+ /** Платёжная система */
214
+ ps: MulticardPaymentService;
215
+ /** Статус карты */
216
+ status: MulticardCardStatus;
217
+ /** Дата добавления */
218
+ added_on: string;
219
+ /** Статус карты (от эмитента) */
220
+ card_status: {
221
+ code: number;
222
+ description: string;
223
+ };
224
+ /** Подключено ли SMS-информирование */
225
+ sms_inform: boolean;
226
+ }
227
+ export type CardGetResponse = MulticardSuccessResponse<CardModel>;
228
+ export type CardDeleteResponse = MulticardSuccessResponse<void>;
229
+ /**
230
+ * @Payment:
231
+ */
232
+ export interface PaymentCreateByTokenRequest {
233
+ /** Данные карты (по токену) */
234
+ card: {
235
+ token: string;
236
+ };
237
+ /** Сумма платежа (тийины) */
238
+ amount: number;
239
+ /** Идентификатор магазина */
240
+ store_id: number;
241
+ /** Идентификатор инвойса на стороне партнёра */
242
+ invoice_id: string;
243
+ /** URL для callback при успешной оплате */
244
+ callback_url?: string;
245
+ /** Данные для фискализации */
246
+ ofd?: OfdItem[];
247
+ /** Информация об устройстве */
248
+ device_details?: Record<string, any>;
249
+ }
250
+ export interface PaymentModel {
251
+ /** ID платежа */
252
+ id: number;
253
+ /** UUID платежа */
254
+ uuid: string;
255
+ /** Идентификатор магазина */
256
+ store_id: number;
257
+ /** Сумма платежа (тийины) */
258
+ payment_amount: number;
259
+ /** Тип комиссии */
260
+ commission_type: MulticardCommissionType;
261
+ /** Сумма комиссии (тийины) */
262
+ commission_amount: number;
263
+ /** Итоговая сумма (тийины) */
264
+ total_amount: number;
265
+ /** Идентификатор инвойса на стороне партнёра */
266
+ store_invoice_id: string;
267
+ /** Статус платежа */
268
+ status: MulticardPaymentStatus;
269
+ /** URL для callback */
270
+ callback_url: string;
271
+ /** Идентификатор биллинга */
272
+ billing_id: string;
273
+ /** Номер телефона */
274
+ phone: string;
275
+ /** Платёжная система */
276
+ ps: MulticardPaymentService;
277
+ /** URL чека */
278
+ receipt_url: string | null;
279
+ /** Хеш OTP (null = безакцептный платёж) */
280
+ otp_hash: string | null;
281
+ /** KYC данные */
282
+ kyc_data: {
283
+ last_name: string;
284
+ first_name: string;
285
+ middle_name: string;
286
+ pinfl: string;
287
+ } | null;
288
+ /** URL для checkout (для инвойсов) */
289
+ checkout_url: string | null;
290
+ }
291
+ export interface PaymentConfirmRequest {
292
+ /** OTP код (необязательный при безакцептном платеже) */
293
+ otp?: string;
294
+ }
295
+ export type PaymentCreateResponse = MulticardSuccessResponse<PaymentModel>;
296
+ export type PaymentConfirmResponse = MulticardSuccessResponse<PaymentModel>;
297
+ export type PaymentGetResponse = MulticardSuccessResponse<PaymentModel>;
298
+ export type PaymentCancelResponse = MulticardSuccessResponse<PaymentModel>;
299
+ export interface PaymentPartialRefundRequest {
300
+ /** Маскированный номер карты */
301
+ card_pan: string;
302
+ /** Сумма возврата (тийины) */
303
+ refund_amount: number;
304
+ /** Данные для фискализации */
305
+ ofd?: OfdItem[];
306
+ }
307
+ export type PaymentPartialRefundResponse = MulticardSuccessResponse<PaymentModel>;
308
+ /**
309
+ * @Fiscal:
310
+ */
311
+ export interface FiscalSendLinkRequest {
312
+ /** URL фискального чека */
313
+ url: string;
314
+ }
315
+ export type FiscalSendLinkResponse = MulticardSuccessResponse<void>;
316
+ /**
317
+ * @Callbacks (Webhooks):
318
+ */
319
+ export interface CallbackSuccessPayload {
320
+ /** Идентификатор магазина */
321
+ store_id: number;
322
+ /** Сумма (тийины) */
323
+ amount: number;
324
+ /** Идентификатор инвойса */
325
+ invoice_id: string;
326
+ /** Идентификатор биллинга */
327
+ billing_id: string;
328
+ /** Время платежа */
329
+ payment_time: string;
330
+ /** Номер телефона */
331
+ phone: string;
332
+ /** Маскированный номер карты */
333
+ card_pan: string;
334
+ /** Платёжная система */
335
+ ps: MulticardPaymentService;
336
+ /** Токен карты */
337
+ card_token: string;
338
+ /** UUID платежа */
339
+ uuid: string;
340
+ /** URL чека */
341
+ receipt_url: string;
342
+ /** Подпись MD5("{store_id}{invoice_id}{amount}{secret}") */
343
+ sign: string;
344
+ }
345
+ export interface WebhookStatusPayload {
346
+ /** UUID платежа */
347
+ uuid: string;
348
+ /** Сумма (тийины) */
349
+ amount: number;
350
+ /** Идентификатор инвойса */
351
+ invoice_id: string;
352
+ /** Статус платежа */
353
+ status: MulticardPaymentStatus;
354
+ /** Идентификатор биллинга */
355
+ billing_id: string;
356
+ /** Время платежа */
357
+ payment_time: string;
358
+ /** Время возврата (null если не было возврата) */
359
+ refund_time: string | null;
360
+ /** Номер телефона */
361
+ phone: string;
362
+ /** Маскированный номер карты */
363
+ card_pan: string;
364
+ /** Платёжная система */
365
+ ps: MulticardPaymentService;
366
+ /** Токен карты */
367
+ card_token: string;
368
+ /** URL чека */
369
+ receipt_url: string | null;
370
+ /** Подпись SHA1("{uuid}{invoice_id}{amount}{secret}") */
371
+ sign: string;
372
+ }
package/dist/types.js ADDED
@@ -0,0 +1,69 @@
1
+ /**
2
+ * Types
3
+ *
4
+ * @author: exode <hello@exode.ru>
5
+ */
6
+ (function (factory) {
7
+ if (typeof module === "object" && typeof module.exports === "object") {
8
+ var v = factory(require, exports);
9
+ if (v !== undefined) module.exports = v;
10
+ }
11
+ else if (typeof define === "function" && define.amd) {
12
+ define(["require", "exports"], factory);
13
+ }
14
+ })(function (require, exports) {
15
+ "use strict";
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ exports.MulticardCardStatus = exports.MulticardCommissionType = exports.MulticardPaymentService = exports.MulticardPaymentStatus = exports.MulticardErrorCode = void 0;
18
+ var MulticardErrorCode;
19
+ (function (MulticardErrorCode) {
20
+ MulticardErrorCode["ERROR_FIELDS"] = "ERROR_FIELDS";
21
+ MulticardErrorCode["ERROR_NOT_FOUND"] = "ERROR_NOT_FOUND";
22
+ MulticardErrorCode["ERROR_CARD_NOT_FOUND"] = "ERROR_CARD_NOT_FOUND";
23
+ MulticardErrorCode["ERROR_WRONG_OTP"] = "ERROR_WRONG_OTP";
24
+ MulticardErrorCode["ERROR_SMS_ALREADY_SENT"] = "ERROR_SMS_ALREADY_SENT";
25
+ MulticardErrorCode["ERROR_CARD_SMS"] = "ERROR_CARD_SMS";
26
+ MulticardErrorCode["ERROR_TRANS_NOT_READY"] = "ERROR_TRANS_NOT_READY";
27
+ MulticardErrorCode["ERROR_DEBIT_UNKNOWN"] = "ERROR_DEBIT_UNKNOWN";
28
+ MulticardErrorCode["ERROR_CALLBACK_TIMEOUT"] = "ERROR_CALLBACK_TIMEOUT";
29
+ MulticardErrorCode["ERROR_UNKNOWN"] = "ERROR_UNKNOWN";
30
+ })(MulticardErrorCode || (exports.MulticardErrorCode = MulticardErrorCode = {}));
31
+ var MulticardPaymentStatus;
32
+ (function (MulticardPaymentStatus) {
33
+ MulticardPaymentStatus["Draft"] = "draft";
34
+ MulticardPaymentStatus["Progress"] = "progress";
35
+ MulticardPaymentStatus["Billing"] = "billing";
36
+ MulticardPaymentStatus["Success"] = "success";
37
+ MulticardPaymentStatus["Error"] = "error";
38
+ MulticardPaymentStatus["Revert"] = "revert";
39
+ MulticardPaymentStatus["Hold"] = "hold";
40
+ })(MulticardPaymentStatus || (exports.MulticardPaymentStatus = MulticardPaymentStatus = {}));
41
+ var MulticardPaymentService;
42
+ (function (MulticardPaymentService) {
43
+ MulticardPaymentService["Uzcard"] = "uzcard";
44
+ MulticardPaymentService["Humo"] = "humo";
45
+ MulticardPaymentService["Visa"] = "visa";
46
+ MulticardPaymentService["Mastercard"] = "mastercard";
47
+ MulticardPaymentService["Account"] = "account";
48
+ MulticardPaymentService["Payme"] = "payme";
49
+ MulticardPaymentService["Click"] = "click";
50
+ MulticardPaymentService["Uzum"] = "uzum";
51
+ MulticardPaymentService["Anorbank"] = "anorbank";
52
+ MulticardPaymentService["Oson"] = "oson";
53
+ MulticardPaymentService["Alif"] = "alif";
54
+ MulticardPaymentService["Xazna"] = "xazna";
55
+ MulticardPaymentService["Beepul"] = "beepul";
56
+ MulticardPaymentService["Trastpay"] = "trastpay";
57
+ MulticardPaymentService["Sbp"] = "sbp";
58
+ })(MulticardPaymentService || (exports.MulticardPaymentService = MulticardPaymentService = {}));
59
+ var MulticardCommissionType;
60
+ (function (MulticardCommissionType) {
61
+ MulticardCommissionType["Up"] = "up";
62
+ MulticardCommissionType["Down"] = "down";
63
+ })(MulticardCommissionType || (exports.MulticardCommissionType = MulticardCommissionType = {}));
64
+ var MulticardCardStatus;
65
+ (function (MulticardCardStatus) {
66
+ MulticardCardStatus["Active"] = "active";
67
+ MulticardCardStatus["Inactive"] = "inactive";
68
+ })(MulticardCardStatus || (exports.MulticardCardStatus = MulticardCardStatus = {}));
69
+ });
package/package.json ADDED
@@ -0,0 +1,35 @@
1
+ {
2
+ "name": "@exode-team/multicard-uz.api",
3
+ "version": "1.0.0",
4
+ "description": "multicard.uz API",
5
+ "main": "./dist/index.js",
6
+ "types": "./dist/index.d.ts",
7
+ "scripts": {
8
+ "build": "yarn clean && tsc && yarn copy-definitions",
9
+ "build:watch": "yarn clean && tsc-watch",
10
+ "lint": "eslint -c ./.eslintrc.js ./src --ext .ts,.js --fix",
11
+ "lint:test": "eslint -c ./.eslintrc.js ./src --ext .ts,.js",
12
+ "clean": "rimraf dist",
13
+ "copy-definitions": "copyfiles -u 1 \"src/**/*.d.ts\" dist",
14
+ "npm:publish": "npm run build && npm publish",
15
+ "test": "npx ts-node api-test.ts"
16
+ },
17
+ "dependencies": {
18
+ "axios": "1.8.4"
19
+ },
20
+ "devDependencies": {
21
+ "@babel/core": "^7.24.3",
22
+ "@babel/preset-env": "^7.24.3",
23
+ "@babel/preset-typescript": "^7.24.1",
24
+ "@types/jest": "^29.5.12",
25
+ "@types/node": "^20.12.12",
26
+ "babel-jest": "^29.7.0",
27
+ "copyfiles": "^2.4.1",
28
+ "eslint": "^8.57.0",
29
+ "jest": "^29.7.0",
30
+ "rimraf": "^5.0.5",
31
+ "ts-jest": "^29.1.2",
32
+ "ts-watch": "^1.0.8",
33
+ "typescript": "^5.4.3"
34
+ }
35
+ }
package/tsconfig.json ADDED
@@ -0,0 +1,18 @@
1
+ {
2
+ "compilerOptions": {
3
+ "target": "es6",
4
+ "module": "umd",
5
+ "strict": true,
6
+ "allowJs": true,
7
+ "declaration": true,
8
+ "outDir": "./dist",
9
+ "rootDir": "./src",
10
+ "moduleResolution": "node",
11
+ "baseUrl": "./src",
12
+ "paths": {},
13
+ "esModuleInterop": true
14
+ },
15
+ "include": [
16
+ "./src/**/*"
17
+ ]
18
+ }