@wikha/sdk 1.1.12

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 ADDED
@@ -0,0 +1,365 @@
1
+ # Usage
2
+
3
+ ## Initialization
4
+
5
+ Import the `WikhaSDK` class and initialize it with your API key, merchant ID, and public key:
6
+
7
+ ```typescript
8
+ import WikhaSDK from 'wikha-sdk';
9
+
10
+ const sdk = new WikhaSDK(
11
+ 'YOUR_API_KEY',
12
+ 'YOUR_MERCHANT_ID',
13
+ 'YOUR_PUBLIC_KEY'
14
+ );
15
+
16
+ // You can also access static enums for convenience
17
+ console.log(WikhaSDK.PaymentType.payin);
18
+ console.log(WikhaSDK.Environment.sandbox);
19
+
20
+
21
+ # Processing a Payment
22
+ ## Use the processPayment method to initiate a payment.
23
+ You'll need to provide a WikhaPayload object with the necessary payment details.
24
+
25
+ ```TypeScript
26
+
27
+ import WikhaSDK from 'wikha-sdk';
28
+
29
+ const sdk = new WikhaSDK(
30
+ 'YOUR_API_KEY',
31
+ 'YOUR_MERCHANT_ID',
32
+ 'YOUR_PUBLIC_KEY'
33
+ );
34
+
35
+ async function initiatePayment() {
36
+ const paymentData: WikhaSDK.WikhaPayload = {
37
+ provider: WikhaSDK.PaymentProviderType.mpesa,
38
+ payer_phone: '081XXXXXXX',
39
+ order_id: 'ORDER-12345',
40
+ amount: 100,
41
+ payer_name: 'John Tshisola',
42
+ operation: WikhaSDK.PaymentType.payin,
43
+ currency: 'CDF',
44
+ notify_url: '[https://your-callback-url.com/notify](https://www.google.com/search?q=https://your-callback-url.com/notify)',
45
+ return_url: '[https://your-website.com/success](https://www.google.com/search?q=https://your-website.com/success)',
46
+ };
47
+
48
+ try {
49
+ const response = await sdk.processPayment(paymentData);
50
+ console.log('Payment initiated successfully:', response);
51
+ // Handle the response, which might contain a payment URL or other instructions
52
+ } catch (error: any) {
53
+ console.error('Error initiating payment:', error.message);
54
+ // Handle the error
55
+ }
56
+ }
57
+
58
+ initiatePayment();
59
+ ```
60
+ # Query transaction status
61
+
62
+ ```typescript
63
+ import WikhaSDK from 'wikha-sdk';
64
+
65
+ // Initialize your SDK instance (API Key, Merchant ID, Public Key are required)
66
+ const sdk = new WikhaSDK(
67
+ 'YOUR_API_KEY',
68
+ 'YOUR_MERCHANT_ID',
69
+ 'YOUR_PUBLIC_KEY'
70
+ );
71
+
72
+ async function checkTransactionStatus(transactionId: string) {
73
+ try {
74
+ const transaction = await sdk.queryTransaction(transactionId);
75
+ console.log('Transaction details:', transaction);
76
+ if (transaction && transaction.status === WikhaSDK.PaymentStatus.accepted) {
77
+ console.log('Transaction was successful.');
78
+ } else if (transaction && transaction.status === WikhaSDK.PaymentStatus.rejected) {
79
+ console.log('Transaction was rejected.');
80
+ } else if (transaction && transaction.status === WikhaSDK.PaymentStatus.pending) {
81
+ console.log('Transaction is still pending.');
82
+ } else {
83
+ console.log('Transaction not found or status is unknown.');
84
+ }
85
+ } catch (error: any) {
86
+ console.error('Error querying transaction:', error.message);
87
+ // Handle the error
88
+ }
89
+ }
90
+
91
+ // Replace 'YOUR_TRANSACTION_ID' with the actual transaction ID you want to query
92
+ checkTransactionStatus('YOUR_TRANSACTION_ID');
93
+ ```
94
+
95
+
96
+ #Using Static Enums
97
+
98
+ ```typescript
99
+ import WikhaSDK from 'wikha-sdk';
100
+
101
+ function handlePaymentEvent(event: WikhaSDK.PaymentEventPayload) {
102
+ console.log('Payment Event Received:', event);
103
+ if (event.data?.type === WikhaSDK.PaymentType.payin && event.data?.status === WikhaSDK.PaymentStatus.accepted) {
104
+ console.log('A successful payin event occurred.');
105
+ }
106
+ }
107
+
108
+ // Example PaymentEventPayload (this would typically come from your backend or a webhook)
109
+ const samplePaymentEvent: WikhaSDK.PaymentEventPayload = {
110
+ id: 'evt_123',
111
+ eventType: 'payment.updated',
112
+ data: {
113
+ order_id: 'ORDER-12345',
114
+ type: WikhaSDK.PaymentType.payin,
115
+ status: WikhaSDK.PaymentStatus.accepted,
116
+ // ... other payment details
117
+ },
118
+ };
119
+
120
+ handlePaymentEvent(samplePaymentEvent);
121
+
122
+ console.log('Available Payment Providers:', Object.values(WikhaSDK.PaymentProviderType));
123
+ console.log('Sandbox Environment Value:', WikhaSDK.Environment.sandbox);
124
+ ```
125
+ #Client side usage
126
+ ```html
127
+ <!DOCTYPE html>
128
+
129
+
130
+
131
+ <!DOCTYPE html>
132
+ <html lang="en">
133
+ <head>
134
+ <meta charset="UTF-8">
135
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
136
+ <title>WikhaSDK Payment</title>
137
+ <link rel="stylesheet" href="https://fonts.googleapis.com/icon?family=Material+Icons">
138
+ <link rel="stylesheet" href="https://code.getmdl.io/1.3.0/material.blue-indigo.min.css" />
139
+ <style>
140
+ body {
141
+ font-family: 'Roboto', sans-serif;
142
+ background-color: #f3f3f3;
143
+ display: flex;
144
+ justify-content: center;
145
+ align-items: center;
146
+ min-height: 100vh;
147
+ margin: 0;
148
+ }
149
+ .container {
150
+ background-color: #fff;
151
+ padding: 32px;
152
+ border-radius: 8px;
153
+ box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
154
+ width: 90%;
155
+ max-width: 600px;
156
+ text-align: center;
157
+ }
158
+ h1 {
159
+ color: #3f51b5; /* Material Design Blue */
160
+ margin-bottom: 24px;
161
+ }
162
+ .mdl-textfield {
163
+ width: 100%;
164
+ margin-bottom: 16px;
165
+ display: block;
166
+ }
167
+ .mdl-button {
168
+ background-color: #3f51b5; /* Material Design Blue */
169
+ color: white;
170
+ margin-top: 24px;
171
+ }
172
+ #paymentResponse, #paymentError {
173
+ margin-top: 24px;
174
+ padding: 16px;
175
+ border-radius: 4px;
176
+ text-align: left;
177
+ }
178
+ #paymentResponse {
179
+ background-color: #e3f2fd; /* Light Blue */
180
+ border: 1px solid #bbdefb;
181
+ color: #1e88e5;
182
+ }
183
+ #paymentError {
184
+ background-color: #ffebee; /* Light Red */
185
+ border: 1px solid #ef9a9a;
186
+ color: #d32f2f;
187
+ }
188
+ #checkTransactionButton {
189
+ background-color: #3f51b5; /* Material Design Blue */
190
+ color: white;
191
+ margin-top: 16px;
192
+ }
193
+ </style>
194
+ </head>
195
+ <body>
196
+ <div class="container">
197
+ <h1>WikhaSDK Payment</h1>
198
+ <form id="paymentForm" class="mdl-grid">
199
+ <div class="mdl-cell mdl-cell--12-col">
200
+ <div class="mdl-textfield mdl-js-textfield mdl-textfield--floating-label">
201
+ <select class="mdl-textfield__input" id="provider">
202
+ <option value="mpesa">Mpesa</option>
203
+ <option value="orangemoney">Orange Money</option>
204
+ <option value="afrimoney">Afrimoney</option>
205
+ <option value="airtelmoney">Airtel Money</option>
206
+ </select>
207
+ <label class="mdl-textfield__label" for="provider">Payment Provider</label>
208
+ </div>
209
+ </div>
210
+ <div class="mdl-cell mdl-cell--12-col">
211
+ <div class="mdl-textfield mdl-js-textfield mdl-textfield--floating-label">
212
+ <input class="mdl-textfield__input" type="tel" id="payer_phone" required>
213
+ <label class="mdl-textfield__label" for="payer_phone">Payer Phone</label>
214
+ <span class="mdl-textfield__error">Phone number required</span>
215
+ </div>
216
+ </div>
217
+ <div class="mdl-cell mdl-cell--12-col">
218
+ <div class="mdl-textfield mdl-js-textfield mdl-textfield--floating-label">
219
+ <input class="mdl-textfield__input" type="text" id="order_id" required>
220
+ <label class="mdl-textfield__label" for="order_id">Order ID</label>
221
+ <span class="mdl-textfield__error">Order ID required</span>
222
+ </div>
223
+ </div>
224
+ <div class="mdl-cell mdl-cell--6-col mdl-cell--4-col-tablet">
225
+ <div class="mdl-textfield mdl-js-textfield mdl-textfield--floating-label">
226
+ <input class="mdl-textfield__input" type="number" id="amount" required>
227
+ <label class="mdl-textfield__label" for="amount">Amount</label>
228
+ <span class="mdl-textfield__error">Amount required</span>
229
+ </div>
230
+ </div>
231
+ <div class="mdl-cell mdl-cell--6-col mdl-cell--4-col-tablet">
232
+ <div class="mdl-textfield mdl-js-textfield mdl-textfield--floating-label">
233
+ <input class="mdl-textfield__input" type="text" id="payer_name" required>
234
+ <label class="mdl-textfield__label" for="payer_name">Payer Name</label>
235
+ <span class="mdl-textfield__error">Payer Name required</span>
236
+ </div>
237
+ </div>
238
+ <div class="mdl-cell mdl-cell--12-col">
239
+ <div class="mdl-textfield mdl-js-textfield mdl-textfield--floating-label">
240
+ <select class="mdl-textfield__input" id="currency">
241
+ <option value="CDF">CDF</option>
242
+ <option value="USD">USD</option>
243
+ </select>
244
+ <label class="mdl-textfield__label" for="currency">Currency</label>
245
+ </div>
246
+ </div>
247
+ <div class="mdl-cell mdl-cell--12-col">
248
+ <button class="mdl-button mdl-js-button mdl-button--raised" type="button" onclick="initiatePayment()">
249
+ Initiate Payment
250
+ </button>
251
+ </div>
252
+ </form>
253
+ <div id="paymentResponse" style="display: none;"></div>
254
+ <div id="paymentError" style="display: none;"></div>
255
+ <button id="checkTransactionButton" class="mdl-button mdl-js-button mdl-button--raised" style="display: none;" onclick="checkTransactionStatus()">
256
+ Check Transaction Status
257
+ </button>
258
+ </div>
259
+
260
+ <script src="https://unpkg.com/wikha-sdk@latest/dist/wikha-sdk.umd.js"></script>
261
+ <script src="https://code.getmdl.io/1.3.0/material.min.js"></script>
262
+ <script>
263
+ let sdk;
264
+ let transactionId;
265
+
266
+ async function initiatePayment() {
267
+ const apiKey = ' API_KEY'; // Replace with your actual API key
268
+ const merchantId = 'MERCHANT_ID'; // Replace with your actual merchant ID
269
+ const publicKey = 'PUBLIC_KEY'; // Replace with your actual public key
270
+
271
+ const provider = document.getElementById('provider').value;
272
+ const payer_phone = document.getElementById('payer_phone').value;
273
+ const order_id = document.getElementById('order_id').value;
274
+ const amount = parseInt(document.getElementById('amount').value);
275
+ const payer_name = document.getElementById('payer_name').value;
276
+ const currency = document.getElementById('currency').value;
277
+
278
+ const paymentData = {
279
+ provider: provider,
280
+ payer_phone: payer_phone,
281
+ order_id: order_id,
282
+ amount: amount,
283
+ payer_name: payer_name,
284
+ operation: wikha.PaymentType.payin, // Assuming this is a payin
285
+ currency: currency,
286
+ // You can add optional fields like notify_url and return_url here
287
+ };
288
+
289
+ sdk = new wikha.WikhaSDK(apiKey, merchantId, publicKey);
290
+ const responseDiv = document.getElementById('paymentResponse');
291
+ const errorDiv = document.getElementById('paymentError');
292
+ const checkTransactionButton = document.getElementById('checkTransactionButton');
293
+ responseDiv.style.display = 'none';
294
+ errorDiv.style.display = 'none';
295
+ checkTransactionButton.style.display = 'none';
296
+
297
+ try {
298
+ const response = await sdk.processPayment(paymentData);
299
+ console.log('Payment Response:', response);
300
+ responseDiv.textContent = JSON.stringify(response, null, 2);
301
+ responseDiv.style.display = 'block';
302
+
303
+ // Assuming a successful response might contain a transaction ID
304
+ if (response?.paymentResult?.paymentId) {
305
+ transactionId = response.paymentResult.paymentId;
306
+ checkTransactionButton.style.display = 'block';
307
+ } else {
308
+ checkTransactionButton.style.display = 'none';
309
+ }
310
+
311
+ } catch (error) {
312
+ console.error('Payment Error:', error);
313
+ errorDiv.textContent = error.message;
314
+ errorDiv.style.display = 'block';
315
+ checkTransactionButton.style.display = 'none';
316
+ }
317
+ }
318
+
319
+ async function checkTransactionStatus() {
320
+ if (!sdk || !transactionId) {
321
+ alert('Payment must be initiated successfully first.');
322
+ return;
323
+ }
324
+
325
+ const responseDiv = document.getElementById('paymentResponse');
326
+ const errorDiv = document.getElementById('paymentError');
327
+ responseDiv.style.display = 'none';
328
+ errorDiv.style.display = 'none';
329
+
330
+ try {
331
+ const transaction = await sdk.queryTransaction(transactionId);
332
+ console.log('Transaction Status:', transaction);
333
+ responseDiv.textContent = 'Transaction Status: ' + JSON.stringify(transaction, null, 2);
334
+ responseDiv.style.display = 'block';
335
+ } catch (error) {
336
+ console.error('Error checking transaction status:', error);
337
+ errorDiv.textContent = 'Error checking transaction status: ' + error.message;
338
+ errorDiv.style.display = 'block';
339
+ }
340
+ }
341
+ </script>
342
+ </body>
343
+ </html>
344
+ ```
345
+
346
+
347
+
348
+ ```
349
+ # Error Handling
350
+ ## The processPayment method returns a promise that resolves with the payment response or rejects with an error. Handle these cases accordingly.
351
+
352
+ # Node.js and Browser Compatibility
353
+ ## This SDK is designed to work in both Node.js and browser environments.
354
+
355
+ # Dependencies
356
+ ## node-fetch (for Node.js)
357
+
358
+ # Contributing
359
+ ## Contributions are welcome! Please submit a pull request or open an issue on GitHub.
360
+
361
+ # # License
362
+ MIT
363
+
364
+ # Author
365
+ ## Sylvain Kambiya, Wikha Hi-tech SARL
@@ -0,0 +1 @@
1
+ export * from "./src/sdk";
package/dist/index.js ADDED
@@ -0,0 +1,17 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ __exportStar(require("./src/sdk"), exports);
@@ -0,0 +1,105 @@
1
+ export declare const PAY_ENDPOINT = "https://api.wikha-hitech.com/v2";
2
+ export declare const TRANSACTION_QUERY_ENDPOINT = "https://api.wikha-hitech.com/v2/query";
3
+ export declare enum PaymentProviderType {
4
+ mpesa = "mpesa",
5
+ orangemoney = "orangemoney",
6
+ afrimoney = "afrimoney",
7
+ airtelmoney = "airtelmoney",
8
+ paypal = "paypal",
9
+ braintree = "braintree"
10
+ }
11
+ export declare enum PaymentType {
12
+ payin = "payin",
13
+ payout = "payout",
14
+ transfert = "transfert"
15
+ }
16
+ export declare enum PaymentStatus {
17
+ accepted = "accepted",
18
+ rejected = "rejected",
19
+ pending = "pending",
20
+ canceled = "canceled"
21
+ }
22
+ export declare enum PaymentAggregatorType {
23
+ unipesa = "unipesa",
24
+ direct = "direct",
25
+ ligdicash = "ligdicash",
26
+ paypal = "bank",
27
+ pawapay = "pawapay"
28
+ }
29
+ export declare enum MerchantStatus {
30
+ active = "active",
31
+ inactive = "inactive"
32
+ }
33
+ export declare enum Environment {
34
+ sandbox = "sandbox",
35
+ production = "production"
36
+ }
37
+ export interface ProviderData {
38
+ id: string;
39
+ name: string;
40
+ payin_fees: number;
41
+ payout_fees: number;
42
+ provider: PaymentProviderType;
43
+ isActive: boolean;
44
+ created_at: any;
45
+ }
46
+ export interface WikhaPayload {
47
+ provider: PaymentProviderType;
48
+ payer_phone: string;
49
+ amount: number;
50
+ currency: string | "CDF";
51
+ order_id: string;
52
+ operation: PaymentType;
53
+ country?: string | "CD";
54
+ payer_name?: string;
55
+ payer_email?: string;
56
+ payer_address?: string;
57
+ notify_url?: string;
58
+ return_url?: string;
59
+ reason?: string;
60
+ user_id?: string;
61
+ merchant_id?: string;
62
+ }
63
+ export interface WikhaPayment {
64
+ merchant_id?: string;
65
+ fees?: number;
66
+ external_id?: string;
67
+ service_provider?: string;
68
+ environnement?: Environment | Environment.sandbox;
69
+ payment_aggregator?: PaymentAggregatorType;
70
+ callback_url?: string;
71
+ result_message?: string;
72
+ created_at?: any;
73
+ type?: PaymentType;
74
+ status?: PaymentStatus;
75
+ notified?: boolean;
76
+ order_id?: string;
77
+ payload?: WikhaPayload;
78
+ }
79
+ export interface WikhaMerchant {
80
+ id: string;
81
+ name: string;
82
+ apiKey: string;
83
+ status: MerchantStatus;
84
+ environnement: Environment | Environment.sandbox;
85
+ linkedProvider: PaymentAggregatorType;
86
+ usd_balance: number;
87
+ cdf_balance: number;
88
+ payout_fees: number;
89
+ payin_fees: number;
90
+ notify_url?: string;
91
+ ips: string[];
92
+ admins: any[];
93
+ finances: any[];
94
+ }
95
+ export declare class WikhaSDK {
96
+ private apiKey;
97
+ private merchantId;
98
+ private publicKey;
99
+ constructor(apiKey: string, merchantId: string, publicKey?: string);
100
+ private getFetch;
101
+ private fetchPublicKey;
102
+ private encryptData;
103
+ processPayment(paymentData: WikhaPayload): Promise<any>;
104
+ queryTransaction(transactionId: string): Promise<WikhaPayment>;
105
+ }
@@ -0,0 +1,191 @@
1
+ "use strict";
2
+ // src/sdk.ts
3
+ Object.defineProperty(exports, "__esModule", { value: true });
4
+ exports.WikhaSDK = exports.Environment = exports.MerchantStatus = exports.PaymentAggregatorType = exports.PaymentStatus = exports.PaymentType = exports.PaymentProviderType = exports.TRANSACTION_QUERY_ENDPOINT = exports.PAY_ENDPOINT = void 0;
5
+ // Constants
6
+ exports.PAY_ENDPOINT = "https://api.wikha-hitech.com/v2";
7
+ exports.TRANSACTION_QUERY_ENDPOINT = "https://api.wikha-hitech.com/v2/query";
8
+ const isNode = typeof window === 'undefined' && typeof process !== 'undefined';
9
+ // Interfaces & Enums
10
+ var PaymentProviderType;
11
+ (function (PaymentProviderType) {
12
+ PaymentProviderType["mpesa"] = "mpesa";
13
+ PaymentProviderType["orangemoney"] = "orangemoney";
14
+ PaymentProviderType["afrimoney"] = "afrimoney";
15
+ PaymentProviderType["airtelmoney"] = "airtelmoney";
16
+ PaymentProviderType["paypal"] = "paypal";
17
+ PaymentProviderType["braintree"] = "braintree";
18
+ })(PaymentProviderType || (exports.PaymentProviderType = PaymentProviderType = {}));
19
+ var PaymentType;
20
+ (function (PaymentType) {
21
+ PaymentType["payin"] = "payin";
22
+ PaymentType["payout"] = "payout";
23
+ PaymentType["transfert"] = "transfert";
24
+ })(PaymentType || (exports.PaymentType = PaymentType = {}));
25
+ var PaymentStatus;
26
+ (function (PaymentStatus) {
27
+ PaymentStatus["accepted"] = "accepted";
28
+ PaymentStatus["rejected"] = "rejected";
29
+ PaymentStatus["pending"] = "pending";
30
+ PaymentStatus["canceled"] = "canceled";
31
+ })(PaymentStatus || (exports.PaymentStatus = PaymentStatus = {}));
32
+ var PaymentAggregatorType;
33
+ (function (PaymentAggregatorType) {
34
+ PaymentAggregatorType["unipesa"] = "unipesa";
35
+ PaymentAggregatorType["direct"] = "direct";
36
+ PaymentAggregatorType["ligdicash"] = "ligdicash";
37
+ PaymentAggregatorType["paypal"] = "bank";
38
+ PaymentAggregatorType["pawapay"] = "pawapay";
39
+ })(PaymentAggregatorType || (exports.PaymentAggregatorType = PaymentAggregatorType = {}));
40
+ var MerchantStatus;
41
+ (function (MerchantStatus) {
42
+ MerchantStatus["active"] = "active";
43
+ MerchantStatus["inactive"] = "inactive";
44
+ })(MerchantStatus || (exports.MerchantStatus = MerchantStatus = {}));
45
+ var Environment;
46
+ (function (Environment) {
47
+ Environment["sandbox"] = "sandbox";
48
+ Environment["production"] = "production";
49
+ })(Environment || (exports.Environment = Environment = {}));
50
+ class WikhaSDK {
51
+ constructor(apiKey, merchantId, publicKey) {
52
+ this.apiKey = apiKey;
53
+ this.merchantId = merchantId;
54
+ this.publicKey = publicKey || null;
55
+ }
56
+ getFetch() {
57
+ if (typeof globalThis.fetch === 'function') {
58
+ return globalThis.fetch;
59
+ }
60
+ if (isNode) {
61
+ try {
62
+ return require('node-fetch');
63
+ }
64
+ catch (e) {
65
+ console.warn("Native fetch not found and 'node-fetch' not installed.");
66
+ }
67
+ }
68
+ throw new Error("Fetch API not found. Please use Node.js 18+ or install 'node-fetch'.");
69
+ }
70
+ async fetchPublicKey() {
71
+ console.log("[WikhaSDK] Fetching public key from server...");
72
+ const myFetch = this.getFetch();
73
+ try {
74
+ const response = await myFetch(`${exports.PAY_ENDPOINT}/pk`, {
75
+ method: "GET",
76
+ headers: { "Authorization": `Bearer ${this.apiKey}` }
77
+ });
78
+ if (!response.ok) {
79
+ throw new Error(`Failed to fetch public key: ${response.statusText}`);
80
+ }
81
+ const data = await response.json();
82
+ if (!data.publicKey)
83
+ throw new Error("Public key not present in response");
84
+ this.publicKey = data.publicKey;
85
+ return data.publicKey;
86
+ }
87
+ catch (error) {
88
+ console.error("[WikhaSDK] Error fetching public key:", error);
89
+ throw error;
90
+ }
91
+ }
92
+ async encryptData(data) {
93
+ if (!this.publicKey) {
94
+ await this.fetchPublicKey();
95
+ }
96
+ const dataString = JSON.stringify({ ...data, merchant_id: this.merchantId });
97
+ if (isNode) {
98
+ const crypto = require('crypto');
99
+ try {
100
+ const encrypted = crypto.publicEncrypt({
101
+ key: this.publicKey,
102
+ padding: crypto.constants.RSA_PKCS1_OAEP_PADDING,
103
+ oaepHash: 'SHA256',
104
+ }, Buffer.from(dataString, 'utf-8'));
105
+ return encrypted.toString('base64');
106
+ }
107
+ catch (e) {
108
+ console.error("Encryption failed (Node.js legacy mode):", e);
109
+ throw e;
110
+ }
111
+ }
112
+ else {
113
+ const crypto = window.crypto;
114
+ try {
115
+ const pemHeader = "-----BEGIN PUBLIC KEY-----";
116
+ const pemFooter = "-----END PUBLIC KEY-----";
117
+ const pemContents = this.publicKey
118
+ .replace(pemHeader, "")
119
+ .replace(pemFooter, "")
120
+ .replace(/\s/g, "");
121
+ const binaryDer = atob(pemContents);
122
+ const binaryDerBuffer = new Uint8Array(binaryDer.length);
123
+ for (let i = 0; i < binaryDer.length; i++) {
124
+ binaryDerBuffer[i] = binaryDer.charCodeAt(i);
125
+ }
126
+ const key = await crypto.subtle.importKey("spki", binaryDerBuffer.buffer, {
127
+ name: "RSA-OAEP",
128
+ hash: "SHA-256",
129
+ }, false, ["encrypt"]);
130
+ const encodedData = new TextEncoder().encode(dataString);
131
+ const encryptedData = await crypto.subtle.encrypt({ name: "RSA-OAEP" }, key, encodedData);
132
+ return btoa(String.fromCharCode(...new Uint8Array(encryptedData)));
133
+ }
134
+ catch (e) {
135
+ console.error("Encryption failed (Browser mode):", e);
136
+ throw e;
137
+ }
138
+ }
139
+ }
140
+ async processPayment(paymentData) {
141
+ try {
142
+ const encryptedData = await this.encryptData(paymentData);
143
+ const myFetch = this.getFetch();
144
+ const response = await myFetch(exports.PAY_ENDPOINT, {
145
+ method: 'POST',
146
+ headers: {
147
+ Authorization: `Bearer ${this.apiKey}`,
148
+ 'Content-Type': 'application/json',
149
+ },
150
+ body: JSON.stringify({
151
+ encryptedData,
152
+ merchant_id: this.merchantId,
153
+ }),
154
+ });
155
+ if (!response.ok) {
156
+ const errorBody = await response.text();
157
+ throw new Error(`HTTP error! status: ${response.status}, body: ${errorBody}`);
158
+ }
159
+ return await response.json();
160
+ }
161
+ catch (error) {
162
+ console.error("Error processing payment:", error);
163
+ throw error;
164
+ }
165
+ }
166
+ async queryTransaction(transactionId) {
167
+ try {
168
+ const myFetch = this.getFetch();
169
+ const url = new URL(exports.TRANSACTION_QUERY_ENDPOINT);
170
+ url.searchParams.append("merchant_id", this.merchantId);
171
+ url.searchParams.append("transaction_id", transactionId);
172
+ const response = await myFetch(url.toString(), {
173
+ method: 'GET',
174
+ headers: {
175
+ Authorization: `Bearer ${this.apiKey}`,
176
+ 'Content-Type': 'application/json',
177
+ },
178
+ });
179
+ if (!response.ok) {
180
+ const errorBody = await response.text();
181
+ throw new Error(`HTTP error! status: ${response.status}, body: ${errorBody}`);
182
+ }
183
+ return await response.json();
184
+ }
185
+ catch (error) {
186
+ console.error("Error querying transaction:", error);
187
+ throw error;
188
+ }
189
+ }
190
+ }
191
+ exports.WikhaSDK = WikhaSDK;