wahdx-api 1.0.3 → 2.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 CHANGED
@@ -1,189 +1,240 @@
1
- # wahdx-api
2
-
3
- Package untuk generate QRIS dan cek payment status secara realtime dengan API OrderKuota dari [https://api.wahdx.co](https://api.wahdx.co).
4
-
5
- ## Fitur
6
-
7
- - Membaca dan ekstrak kode QR dari gambar
8
- - Generate kode QR dengan nominal tertentu
9
- - Cek status pembayaran secara realtime
10
- - Generate bukti transaksi (receipt)
11
- - Kompatibel di semua platform (Windows, Linux, Mac)
12
-
13
- ## Instalasi
14
-
15
- ```bash
16
- npm install wahdx-api
17
- ```
18
-
19
- ## Konfigurasi
20
-
21
- Buat file `.env` di root project Anda:
22
-
23
- ```
24
- WAHDX_TOKENKEY=your_wahdx_token_key
25
- ORKUT_TOKEN_AUTH=your_orkut_token_auth
26
- ORKUT_USERNAME=your_orkut_username
27
- ```
28
-
29
- > **Catatan:** Untuk mendapatkan tokenKey, Anda bisa membelinya di halaman [https://api.wahdx.co](https://api.wahdx.co)
30
-
31
- ## Penggunaan
32
-
33
- ### Contoh Lengkap
34
-
35
- ```javascript
36
- import QRISPayment from 'wahdx-api';
37
- import '@dotenvx/dotenvx/config';
38
- import fs from 'fs';
39
-
40
- // Konfigurasi
41
- const config = {
42
- storeName: 'AHDX STORE',
43
- defaultQrPath: 'QRIS.png', // Path ke QRIS static yang didownload di merchant orderkuota
44
- tokenKey: process.env.WAHDX_TOKENKEY,
45
- auth_token: process.env.ORKUT_TOKEN_AUTH,
46
- auth_username: process.env.ORKUT_USERNAME
47
- };
48
-
49
- // Membuat instance QRISPayment
50
- const qrisPayment = new QRISPayment(config);
51
-
52
- async function main() {
53
- try {
54
- console.log('=== TEST REALTIME QRIS PAYMENT ===\n');
55
- const randomAmount = Math.floor(Math.random() * 99) + 1; // Random 1-99
56
- const amount = 100 + randomAmount; // Base 100 + random amount
57
- const reference = 'REF' + Date.now();
58
-
59
- // Generate QR code
60
- const { qrBuffer } = await qrisPayment.generateQRFromImage(amount);
61
-
62
- // Save QR code image
63
- fs.writeFileSync(`qr-${amount}.png`, qrBuffer);
64
-
65
- console.log('=== TRANSACTION DETAILS ===');
66
- console.log('Reference:', reference);
67
- console.log('Amount:', amount);
68
- console.log('QR Image:', `qr-${amount}.png`);
69
- console.log('\nSilakan scan QR code dan lakukan pembayaran');
70
- console.log('\nMenunggu pembayaran...\n');
71
-
72
- // Check payment status with 5 minutes timeout
73
- const startTime = Date.now();
74
- const timeout = 5 * 60 * 1000;
75
-
76
- while (Date.now() - startTime < timeout) {
77
- const result = await qrisPayment.checkPayment(reference, amount);
78
-
79
- if (result.success && result.data.status === 'PAID') {
80
- console.log('✓ Pembayaran berhasil!');
81
- if (result.receipt) {
82
- console.log('✓ Bukti transaksi:', result.receipt.filePath);
83
- }
84
- return;
85
- }
86
-
87
- await new Promise(resolve => setTimeout(resolve, 10000)); // delay 10 detik
88
- console.log('Menunggu pembayaran...');
89
- }
90
-
91
- throw new Error('Timeout: Pembayaran tidak diterima dalam 5 menit');
92
-
93
- } catch (error) {
94
- console.error('Error:', error.message);
95
- }
96
- }
97
-
98
- main();
99
- ```
100
-
101
- ### API Reference
102
-
103
- #### Inisialisasi
104
-
105
- ```javascript
106
- import QRISPayment from 'wahdx-api';
107
-
108
- const config = {
109
- storeName: 'NAMA TOKO',
110
- defaultQrPath: 'path/to/qris/template.png',
111
- tokenKey: 'your_wahdx_token_key',
112
- auth_token: 'your_orkut_token_auth',
113
- auth_username: 'your_orkut_username'
114
- };
115
-
116
- const qrisPayment = new QRISPayment(config);
117
- ```
118
-
119
- #### Generate QR dari Template
120
-
121
- ```javascript
122
- const amount = 10000; // Rp 10.000
123
- // Menggunakan default QR yang sudah diatur
124
- const { qrString, qrBuffer } = await qrisPayment.generateQRFromImage(amount);
125
- // Atau dengan path QR spesifik
126
- // const { qrString, qrBuffer } = await qrisPayment.generateQRFromImage(amount, 'path/to/qris/template.png');
127
-
128
- // Simpan QR ke file
129
- fs.writeFileSync('qr-output.png', qrBuffer);
130
- ```
131
-
132
- #### Cek Status Pembayaran
133
-
134
- ```javascript
135
- const reference = 'REF' + Date.now();
136
- const amount = 10000;
137
-
138
- const result = await qrisPayment.checkPayment(reference, amount);
139
- console.log(result);
140
- /*
141
- Output jika berhasil:
142
- {
143
- success: true,
144
- data: {
145
- status: 'PAID',
146
- amount: 10000,
147
- reference: 'REF1234567890',
148
- ...
149
- },
150
- receipt: {
151
- filePath: 'path/to/receipt.pdf',
152
- ...
153
- }
154
- }
155
- */
156
- ```
157
-
158
- ## FAQ
159
-
160
- ### Q: Bagaimana cara mendapatkan tokenKey agar bisa menggunakan module ini?
161
- A: Anda bisa membeli tokenKey di halaman utama [https://api.wahdx.co](https://api.wahdx.co)
162
-
163
- ### Q: Bagaimana cara mendapatkan kredensial API OrderKuota?
164
- A: Silahkan kunjungi dokumentasi api [https://api.wahdx.co/api-docs](https://api.wahdx.co/api-docs) untuk mendapatkan token pada akun orderkuota anda.
165
-
166
- ### Q: Apakah module ini bisa digunakan di project CommonJS?
167
- A: Ya! Package ini mendukung dual module system (ESM dan CommonJS). Anda bisa menggunakan dengan dua cara:
168
-
169
- 1. Dengan ES Modules (dalam file .js dengan `type: "module"` di package.json):
170
- ```javascript
171
- import QRISPayment from 'wahdx-api';
172
-
173
- const qrisPayment = new QRISPayment(config);
174
- // gunakan qrisPayment
175
- ```
176
-
177
- 2. Dengan CommonJS (dalam file .cjs atau project tanpa `type: "module"`):
178
- ```javascript
179
- const QRISPayment = require('wahdx-api');
180
-
181
- const qrisPayment = new QRISPayment(config);
182
- // gunakan qrisPayment
183
- ```
184
-
185
- Package secara otomatis mendeteksi format yang digunakan dan menyediakan versi yang sesuai.
186
-
187
- ## Lisensi
188
-
1
+ # wahdx-api
2
+
3
+ Package untuk generate QRIS dan cek payment status secara realtime dengan API OrderKuota dari [https://api.wahdx.co](https://api.wahdx.co).
4
+
5
+ > **⚠️ PENTING: Perubahan di Versi 2.0.0**
6
+ >
7
+ > Pada versi 2.0.0, kami melakukan perubahan besar pada package ini:
8
+ > - Fitur `generateQRFromImage` telah **DIHAPUS** sepenuhnya
9
+ > - Digantikan dengan `generateQRFromAPI` yang lebih valid dan reliable
10
+ > - Dependency `sharp` dan `jsqr` telah dihapus untuk membuat package lebih ringan
11
+ >
12
+ > Jika Anda mengupgrade dari versi sebelumnya, harap perbarikan kode Anda untuk menggunakan `generateQRFromAPI` alih-alih `generateQRFromImage`.
13
+
14
+ ## Fitur
15
+
16
+ - Generate kode QR dengan nominal tertentu (lokal atau via API)
17
+ - Cek status pembayaran secara realtime
18
+ - Generate bukti transaksi (receipt)
19
+ - Kompatibel di semua platform (Windows, Linux, Mac)
20
+
21
+ ## Instalasi
22
+
23
+ ```bash
24
+ npm install wahdx-api
25
+ ```
26
+
27
+ ## Konfigurasi
28
+
29
+ Buat file `.env` di root project Anda:
30
+
31
+ ```
32
+ WAHDX_TOKENKEY=your_wahdx_token_key
33
+ ORKUT_TOKEN_AUTH=your_orkut_token_auth
34
+ ORKUT_USERNAME=your_orkut_username
35
+ ```
36
+
37
+ > **Catatan:** Untuk mendapatkan tokenKey, Anda bisa membelinya di halaman [https://api.wahdx.co](https://api.wahdx.co)
38
+
39
+ ### Opsi Konfigurasi
40
+
41
+ | Opsi | Deskripsi | Default |
42
+ |---------------------|------------------------------------------------------------------|-------------|
43
+ | storeName | Nama toko yang akan ditampilkan pada receipt | - |
44
+ | baseQrString | Base QR string untuk generate QR secara lokal | - |
45
+ | tokenKey | Token key dari WAHDX | - |
46
+ | auth_token | Token autentikasi OrderKuota | - |
47
+ | auth_username | Username OrderKuota | - |
48
+ | autoGenerateReceipt | Mengaktifkan/menonaktifkan pembuatan receipt otomatis | true |
49
+
50
+ ## Penggunaan
51
+
52
+ ### Contoh Lengkap
53
+
54
+ ```javascript
55
+ import QRISPayment from 'wahdx-api';
56
+ import '@dotenvx/dotenvx/config';
57
+ import fs from 'fs';
58
+
59
+ // Konfigurasi
60
+ const config = {
61
+ storeName: 'AHDX STORE',
62
+ baseQrString: 'base-qr-string-anda', // Diperlukan untuk generateQR secara lokal
63
+ tokenKey: process.env.WAHDX_TOKENKEY, // Diperlukan untuk generateQRFromAPI
64
+ auth_token: process.env.ORKUT_TOKEN_AUTH, // Diperlukan untuk generateQRFromAPI
65
+ auth_username: process.env.ORKUT_USERNAME, // Diperlukan untuk generateQRFromAPI
66
+ autoGenerateReceipt: true // Atur false jika tidak ingin otomatis membuat receipt
67
+ };
68
+
69
+ // Membuat instance QRISPayment
70
+ const qrisPayment = new QRISPayment(config);
71
+
72
+ async function main() {
73
+ try {
74
+ console.log('=== TEST REALTIME QRIS PAYMENT ===\n');
75
+ const randomAmount = Math.floor(Math.random() * 99) + 1; // Random 1-99
76
+ const amount = 100 + randomAmount; // Base 100 + random amount
77
+ const reference = 'REF' + Date.now();
78
+
79
+ // Generate QR code menggunakan API OrderKuota
80
+ const { qrBuffer } = await qrisPayment.generateQRFromAPI(amount);
81
+
82
+ // Save QR code image
83
+ fs.writeFileSync(`qr-${amount}.png`, qrBuffer);
84
+
85
+ console.log('=== TRANSACTION DETAILS ===');
86
+ console.log('Reference:', reference);
87
+ console.log('Amount:', amount);
88
+ console.log('QR Image:', `qr-${amount}.png`);
89
+ console.log('\nSilakan scan QR code dan lakukan pembayaran');
90
+ console.log('\nMenunggu pembayaran...\n');
91
+
92
+ // Check payment status with 5 minutes timeout
93
+ const startTime = Date.now();
94
+ const timeout = 5 * 60 * 1000;
95
+
96
+ while (Date.now() - startTime < timeout) {
97
+ const result = await qrisPayment.checkPayment(reference, amount);
98
+
99
+ if (result.success && result.data.status === 'PAID') {
100
+ console.log('✓ Pembayaran berhasil!');
101
+ if (result.receipt) {
102
+ console.log('✓ Bukti transaksi:', result.receipt.filePath);
103
+ }
104
+ return;
105
+ }
106
+
107
+ await new Promise(resolve => setTimeout(resolve, 10000)); // delay 10 detik
108
+ console.log('Menunggu pembayaran...');
109
+ }
110
+
111
+ throw new Error('Timeout: Pembayaran tidak diterima dalam 5 menit');
112
+
113
+ } catch (error) {
114
+ console.error('Error:', error.message);
115
+ }
116
+ }
117
+
118
+ main();
119
+ ```
120
+
121
+ ### API Reference
122
+
123
+ #### Inisialisasi
124
+
125
+ ```javascript
126
+ import QRISPayment from 'wahdx-api';
127
+
128
+ const config = {
129
+ storeName: 'NAMA TOKO',
130
+ baseQrString: 'base-qr-string-anda', // Diperlukan untuk generateQR secara lokal
131
+ tokenKey: 'your_wahdx_token_key', // Diperlukan untuk generateQRFromAPI
132
+ auth_token: 'your_orkut_token_auth', // Diperlukan untuk generateQRFromAPI
133
+ auth_username: 'your_orkut_username', // Diperlukan untuk generateQRFromAPI
134
+ autoGenerateReceipt: true // Atur false jika tidak ingin otomatis membuat receipt
135
+ };
136
+
137
+ const qrisPayment = new QRISPayment(config);
138
+ ```
139
+
140
+ #### Generate QR
141
+
142
+ Ada dua metode untuk generate QR:
143
+
144
+ ##### 1. Generate QR secara lokal
145
+
146
+ ```javascript
147
+ const amount = 10000; // Rp 10.000
148
+ // Generate QR secara lokal menggunakan baseQrString
149
+ const { qrString, qrBuffer } = await qrisPayment.generateQR(amount);
150
+
151
+ // Simpan QR ke file
152
+ fs.writeFileSync('qr-output.png', qrBuffer);
153
+ ```
154
+
155
+ ##### 2. Generate QR menggunakan API OrderKuota (Lebih direkomendasikan)
156
+
157
+ ```javascript
158
+ const amount = 10000; // Rp 10.000
159
+ // Generate QR menggunakan API OrderKuota
160
+ const { qrString, qrBuffer } = await qrisPayment.generateQRFromAPI(amount);
161
+
162
+ // Simpan QR ke file
163
+ fs.writeFileSync('qr-output.png', qrBuffer);
164
+ ```
165
+
166
+ > **Catatan:** Metode `generateQRFromAPI` lebih direkomendasikan karena QR code dihasilkan langsung dari server OrderKuota, sehingga lebih valid dan reliable.
167
+
168
+ #### Cek Status Pembayaran
169
+
170
+ ```javascript
171
+ const reference = 'REF' + Date.now();
172
+ const amount = 10000;
173
+
174
+ const result = await qrisPayment.checkPayment(reference, amount);
175
+ console.log(result);
176
+ /*
177
+ Output jika berhasil:
178
+ {
179
+ success: true,
180
+ data: {
181
+ status: 'PAID',
182
+ amount: 10000,
183
+ reference: 'REF1234567890',
184
+ ...
185
+ },
186
+ receipt: {
187
+ filePath: 'path/to/receipt.pdf',
188
+ ...
189
+ }
190
+ }
191
+ */
192
+ ```
193
+
194
+ #### Generate Receipt Secara Manual
195
+
196
+ Jika Anda telah menonaktifkan `autoGenerateReceipt` dalam konfigurasi, Anda dapat menghasilkan receipt secara manual dengan metode berikut:
197
+
198
+ ```javascript
199
+ // Ketika pembayaran sudah diterima
200
+ const result = await qrisPayment.checkPayment(reference, amount);
201
+
202
+ if (result.success && result.data.status === 'PAID') {
203
+ // Generate receipt secara manual
204
+ const receipt = await qrisPayment.generateReceipt(result.data);
205
+ console.log('Receipt berhasil dibuat:', receipt.filePath);
206
+ }
207
+ ```
208
+
209
+ ## FAQ
210
+
211
+ ### Q: Bagaimana cara mendapatkan tokenKey agar bisa menggunakan module ini?
212
+ A: Anda bisa membeli tokenKey di halaman utama [https://api.wahdx.co](https://api.wahdx.co)
213
+
214
+ ### Q: Bagaimana cara mendapatkan kredensial API OrderKuota?
215
+ A: Silahkan kunjungi dokumentasi api [https://api.wahdx.co/api-docs](https://api.wahdx.co/api-docs) untuk mendapatkan token pada akun orderkuota anda.
216
+
217
+ ### Q: Apakah module ini bisa digunakan di project CommonJS?
218
+ A: Ya! Package ini mendukung dual module system (ESM dan CommonJS). Anda bisa menggunakan dengan dua cara:
219
+
220
+ 1. Dengan ES Modules (dalam file .js dengan `type: "module"` di package.json):
221
+ ```javascript
222
+ import QRISPayment from 'wahdx-api';
223
+
224
+ const qrisPayment = new QRISPayment(config);
225
+ // gunakan qrisPayment
226
+ ```
227
+
228
+ 2. Dengan CommonJS (dalam file .cjs atau project tanpa `type: "module"`):
229
+ ```javascript
230
+ const QRISPayment = require('wahdx-api');
231
+
232
+ const qrisPayment = new QRISPayment(config);
233
+ // gunakan qrisPayment
234
+ ```
235
+
236
+ Package secara otomatis mendeteksi format yang digunakan dan menyediakan versi yang sesuai.
237
+
238
+ ## Lisensi
239
+
189
240
  MIT
package/dist/index.cjs CHANGED
@@ -4,20 +4,17 @@ const ReceiptGenerator = require("./receipt-generator.cjs");
4
4
 
5
5
  class QRISPayment {
6
6
  constructor(config = {}) {
7
+ // Default config
8
+ this.config = {
9
+ autoGenerateReceipt: true, // Default-nya adalah true untuk mempertahankan kompatibilitas
10
+ ...config
11
+ };
12
+
7
13
  this.qrGenerator = new QRISGenerator(config);
8
14
  this.paymentChecker = new PaymentChecker(config);
9
15
  this.receiptGenerator = new ReceiptGenerator(config);
10
16
  }
11
17
 
12
- /**
13
- * Membaca QR code dari file gambar dan mengekstrak baseQrString
14
- * @param {string} imagePath - Path ke file gambar QR
15
- * @returns {Promise<string>} - Promise yang menghasilkan baseQrString
16
- */
17
- async readQRCode(imagePath) {
18
- return await this.qrGenerator.readQRFromImage(imagePath);
19
- }
20
-
21
18
  /**
22
19
  * Generate QR dengan nominal tertentu
23
20
  * @param {number} amount - Nominal pembayaran
@@ -28,18 +25,19 @@ class QRISPayment {
28
25
  }
29
26
 
30
27
  /**
31
- * Membaca QR dari file gambar dan langsung menghasilkan QR baru dengan nominal
28
+ * Generate QR dengan nominal tertentu menggunakan API OrderKuota
32
29
  * @param {number} amount - Nominal pembayaran
33
- * @param {string} qrImagePath - Path ke gambar QR (opsional)
34
30
  * @returns {Promise<{qrString: string, qrBuffer: Buffer}>}
35
31
  */
36
- async generateQRFromImage(amount, qrImagePath = null) {
37
- return await this.qrGenerator.generateQRFromImage(amount, qrImagePath);
32
+ async generateQRFromAPI(amount) {
33
+ return await this.qrGenerator.generateQRFromAPI(amount);
38
34
  }
39
35
 
40
36
  async checkPayment(reference, amount) {
41
37
  const result = await this.paymentChecker.checkPaymentStatus(reference, amount);
42
- if (result.success && result.data.status === 'PAID') {
38
+
39
+ // Cek apakah pembayaran sukses dan statusnya PAID, serta autoGenerateReceipt diaktifkan
40
+ if (result.success && result.data.status === 'PAID' && this.config.autoGenerateReceipt) {
43
41
  const receipt = await this.receiptGenerator.generateReceipt(result.data);
44
42
  result.receipt = receipt;
45
43
  }
package/dist/index.mjs CHANGED
@@ -4,20 +4,17 @@ import ReceiptGenerator from './receipt-generator.mjs';
4
4
 
5
5
  class QRISPayment {
6
6
  constructor(config = {}) {
7
+ // Default config
8
+ this.config = {
9
+ autoGenerateReceipt: true, // Default-nya adalah true untuk mempertahankan kompatibilitas
10
+ ...config
11
+ };
12
+
7
13
  this.qrGenerator = new QRISGenerator(config);
8
14
  this.paymentChecker = new PaymentChecker(config);
9
15
  this.receiptGenerator = new ReceiptGenerator(config);
10
16
  }
11
17
 
12
- /**
13
- * Membaca QR code dari file gambar dan mengekstrak baseQrString
14
- * @param {string} imagePath - Path ke file gambar QR
15
- * @returns {Promise<string>} - Promise yang menghasilkan baseQrString
16
- */
17
- async readQRCode(imagePath) {
18
- return await this.qrGenerator.readQRFromImage(imagePath);
19
- }
20
-
21
18
  /**
22
19
  * Generate QR dengan nominal tertentu
23
20
  * @param {number} amount - Nominal pembayaran
@@ -28,18 +25,19 @@ class QRISPayment {
28
25
  }
29
26
 
30
27
  /**
31
- * Membaca QR dari file gambar dan langsung menghasilkan QR baru dengan nominal
28
+ * Generate QR dengan nominal tertentu menggunakan API OrderKuota
32
29
  * @param {number} amount - Nominal pembayaran
33
- * @param {string} qrImagePath - Path ke gambar QR (opsional)
34
30
  * @returns {Promise<{qrString: string, qrBuffer: Buffer}>}
35
31
  */
36
- async generateQRFromImage(amount, qrImagePath = null) {
37
- return await this.qrGenerator.generateQRFromImage(amount, qrImagePath);
32
+ async generateQRFromAPI(amount) {
33
+ return await this.qrGenerator.generateQRFromAPI(amount);
38
34
  }
39
35
 
40
36
  async checkPayment(reference, amount) {
41
37
  const result = await this.paymentChecker.checkPaymentStatus(reference, amount);
42
- if (result.success && result.data.status === 'PAID') {
38
+
39
+ // Cek apakah pembayaran sukses dan statusnya PAID, serta autoGenerateReceipt diaktifkan
40
+ if (result.success && result.data.status === 'PAID' && this.config.autoGenerateReceipt) {
43
41
  const receipt = await this.receiptGenerator.generateReceipt(result.data);
44
42
  result.receipt = receipt;
45
43
  }
@@ -1,4 +1,5 @@
1
1
  const axios = require("axios");
2
+ const moment = require("moment-timezone");
2
3
 
3
4
  class PaymentChecker {
4
5
  constructor(config) {
@@ -40,11 +41,12 @@ class PaymentChecker {
40
41
 
41
42
  const matchingTransactions = transactions.filter(tx => {
42
43
  const txAmount = parseInt(tx.amount);
43
- const txDate = new Date(tx.date);
44
- const now = new Date();
45
- const timeDiff = now - txDate;
44
+ // Parse tanggal dengan timezone Jakarta
45
+ const txDate = moment.tz(tx.date, 'YYYY-MM-DD HH:mm', 'Asia/Jakarta');
46
+ const now = moment().tz("Asia/Jakarta");
47
+ const timeDiff = now.diff(txDate, 'milliseconds');
46
48
 
47
- return txAmount === amount &&
49
+ return txAmount === amount &&
48
50
  tx.qris === "static" &&
49
51
  tx.type === "CR" &&
50
52
  timeDiff <= 5 * 60 * 1000;
@@ -52,9 +54,9 @@ class PaymentChecker {
52
54
 
53
55
  if (matchingTransactions.length > 0) {
54
56
  const latestTransaction = matchingTransactions.reduce((latest, current) => {
55
- const currentDate = new Date(current.date);
56
- const latestDate = new Date(latest.date);
57
- return currentDate > latestDate ? current : latest;
57
+ const currentDate = moment.tz(current.date, 'YYYY-MM-DD HH:mm', 'Asia/Jakarta');
58
+ const latestDate = moment.tz(latest.date, 'YYYY-MM-DD HH:mm', 'Asia/Jakarta');
59
+ return currentDate.isAfter(latestDate) ? current : latest;
58
60
  });
59
61
 
60
62
  return {
@@ -1,4 +1,5 @@
1
1
  import axios from 'axios';
2
+ import moment from 'moment-timezone';
2
3
 
3
4
  class PaymentChecker {
4
5
  constructor(config) {
@@ -40,11 +41,12 @@ class PaymentChecker {
40
41
 
41
42
  const matchingTransactions = transactions.filter(tx => {
42
43
  const txAmount = parseInt(tx.amount);
43
- const txDate = new Date(tx.date);
44
- const now = new Date();
45
- const timeDiff = now - txDate;
44
+ // Parse tanggal dengan timezone Jakarta
45
+ const txDate = moment.tz(tx.date, 'YYYY-MM-DD HH:mm', 'Asia/Jakarta');
46
+ const now = moment().tz("Asia/Jakarta");
47
+ const timeDiff = now.diff(txDate, 'milliseconds');
46
48
 
47
- return txAmount === amount &&
49
+ return txAmount === amount &&
48
50
  tx.qris === "static" &&
49
51
  tx.type === "CR" &&
50
52
  timeDiff <= 5 * 60 * 1000;
@@ -52,9 +54,9 @@ class PaymentChecker {
52
54
 
53
55
  if (matchingTransactions.length > 0) {
54
56
  const latestTransaction = matchingTransactions.reduce((latest, current) => {
55
- const currentDate = new Date(current.date);
56
- const latestDate = new Date(latest.date);
57
- return currentDate > latestDate ? current : latest;
57
+ const currentDate = moment.tz(current.date, 'YYYY-MM-DD HH:mm', 'Asia/Jakarta');
58
+ const latestDate = moment.tz(latest.date, 'YYYY-MM-DD HH:mm', 'Asia/Jakarta');
59
+ return currentDate.isAfter(latestDate) ? current : latest;
58
60
  });
59
61
 
60
62
  return {