diff --git a/package-lock.json b/package-lock.json index de81b2d..541d78a 100644 --- a/package-lock.json +++ b/package-lock.json @@ -20,9 +20,11 @@ "@nestjs/typeorm": "^8.0.2", "axios": "^0.24.0", "bluebird": "^3.7.2", + "blueimp-md5": "^2.19.0", "class-transformer": "^0.4.0", "class-validator": "^0.13.1", "crypto": "^1.0.1", + "crypto-md5": "^1.0.0", "csv-parser": "^3.0.0", "decimal.js": "^10.3.1", "exceljs": "^4.3.0", @@ -30,6 +32,7 @@ "fs-extra": "^10.0.0", "joi": "^17.4.2", "lodash": "^4.17.21", + "md5-hash": "^1.0.1", "moment": "^2.29.4", "nestjs-pino": "^2.3.1", "passport": "^0.4.0", @@ -3103,6 +3106,11 @@ "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz", "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==" }, + "node_modules/blueimp-md5": { + "version": "2.19.0", + "resolved": "https://registry.npmjs.org/blueimp-md5/-/blueimp-md5-2.19.0.tgz", + "integrity": "sha512-DRQrD6gJyy8FbiE4s+bDoXS9hiW3Vbx5uCdwvcCf3zLHL+Iv7LtGHLpr+GZV8rHG8tK766FGYBwRbu8pELTt+w==" + }, "node_modules/body-parser": { "version": "1.19.0", "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.19.0.tgz", @@ -3835,6 +3843,15 @@ "integrity": "sha512-VxBKmeNcqQdiUQUW2Tzq0t377b54N2bMtXO/qiLa+6eRRmmC4qT3D4OnTGoT/U6O9aklQ/jTwbOtRMTTY8G0Ig==", "deprecated": "This package is no longer supported. It's now a built-in Node module. If you've depended on crypto, you should switch to the one that's built-in." }, + "node_modules/crypto-md5": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/crypto-md5/-/crypto-md5-1.0.0.tgz", + "integrity": "sha512-65Mtei8+EkSIK+5Ie4gpWXoJ/5bgpqPXFknHHXAyhDqKsEAAzUslGd8mOeawbfcuQ8fADNKcF4xQA3fqlZJ8Ig==", + "engines": { + "iojs": ">=1.0.0", + "node": ">=0.5.2" + } + }, "node_modules/cssom": { "version": "0.4.4", "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.4.4.tgz", @@ -7348,6 +7365,11 @@ "tmpl": "1.0.5" } }, + "node_modules/md5-hash": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/md5-hash/-/md5-hash-1.0.1.tgz", + "integrity": "sha512-McGTs7cIc3JSw9SJH5JxFCJRoI1bi9tKh89LZxpHobmY2YGGhYTnDZ2rxcvNv0Bs1gBbSwSQfCwbuFleZOkkYA==" + }, "node_modules/media-typer": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", @@ -13012,6 +13034,11 @@ "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz", "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==" }, + "blueimp-md5": { + "version": "2.19.0", + "resolved": "https://registry.npmjs.org/blueimp-md5/-/blueimp-md5-2.19.0.tgz", + "integrity": "sha512-DRQrD6gJyy8FbiE4s+bDoXS9hiW3Vbx5uCdwvcCf3zLHL+Iv7LtGHLpr+GZV8rHG8tK766FGYBwRbu8pELTt+w==" + }, "body-parser": { "version": "1.19.0", "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.19.0.tgz", @@ -13583,6 +13610,11 @@ "resolved": "https://registry.npmjs.org/crypto/-/crypto-1.0.1.tgz", "integrity": "sha512-VxBKmeNcqQdiUQUW2Tzq0t377b54N2bMtXO/qiLa+6eRRmmC4qT3D4OnTGoT/U6O9aklQ/jTwbOtRMTTY8G0Ig==" }, + "crypto-md5": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/crypto-md5/-/crypto-md5-1.0.0.tgz", + "integrity": "sha512-65Mtei8+EkSIK+5Ie4gpWXoJ/5bgpqPXFknHHXAyhDqKsEAAzUslGd8mOeawbfcuQ8fADNKcF4xQA3fqlZJ8Ig==" + }, "cssom": { "version": "0.4.4", "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.4.4.tgz", @@ -16390,6 +16422,11 @@ "tmpl": "1.0.5" } }, + "md5-hash": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/md5-hash/-/md5-hash-1.0.1.tgz", + "integrity": "sha512-McGTs7cIc3JSw9SJH5JxFCJRoI1bi9tKh89LZxpHobmY2YGGhYTnDZ2rxcvNv0Bs1gBbSwSQfCwbuFleZOkkYA==" + }, "media-typer": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", diff --git a/package.json b/package.json index 16f66db..ea2ed8f 100644 --- a/package.json +++ b/package.json @@ -33,9 +33,11 @@ "@nestjs/typeorm": "^8.0.2", "axios": "^0.24.0", "bluebird": "^3.7.2", + "blueimp-md5": "^2.19.0", "class-transformer": "^0.4.0", "class-validator": "^0.13.1", "crypto": "^1.0.1", + "crypto-md5": "^1.0.0", "csv-parser": "^3.0.0", "decimal.js": "^10.3.1", "exceljs": "^4.3.0", @@ -43,6 +45,7 @@ "fs-extra": "^10.0.0", "joi": "^17.4.2", "lodash": "^4.17.21", + "md5-hash": "^1.0.1", "moment": "^2.29.4", "nestjs-pino": "^2.3.1", "passport": "^0.4.0", diff --git a/src/helper/irs-api.ts b/src/helper/irs-api.ts index 4d7cbf0..b5e8efa 100644 --- a/src/helper/irs-api.ts +++ b/src/helper/irs-api.ts @@ -7,32 +7,107 @@ const irs_user = 'D10BD0'; const irs_pass = '6251F3'; export const doTransaction = async ( - productCode, - destination, - idtrx, - supplier, - authorization, - typePaid, + productCode, + destination, + idtrx, + supplier, + authorization, + typePaid, + billTrxId, ) => { try { if (supplier.code == 'IRS') { const res = await axios.get( - `${irs_url}?id=${irs_id}&pin=${irs_pin}&user=${irs_user}&pass=${irs_pass}&kodeproduk=${productCode}&tujuan=${destination}&counter=1&idtrx=${idtrx}`, + `${irs_url}?id=${irs_id}&pin=${irs_pin}&user=${irs_user}&pass=${irs_pass}&kodeproduk=${productCode}&tujuan=${destination}&counter=1&idtrx=${idtrx}`, ); return res.data; } else if (supplier.code == 'NIRS') { const res = await axios.get( - `${supplier.url}?id=${supplier.irs_id}&pin=${supplier.irs_pin}&user=${supplier.irs_user}&pass=${supplier.irs_pass}&kodeproduk=${productCode}&tujuan=${destination}&counter=1&idtrx=${idtrx}`, + `${supplier.url}?id=${supplier.irs_id}&pin=${supplier.irs_pin}&user=${supplier.irs_user}&pass=${supplier.irs_pass}&kodeproduk=${productCode}&tujuan=${destination}&counter=1&idtrx=${idtrx}`, ); return res.data; - } else if (supplier.code == 'Hemat') { - if (authorization != "") { - console.log("initoken", authorization) + } else if (supplier.code == 'Digiflazz') { + if (typePaid == 'INQUIRY') { + const md5HashDigiflazz = `${supplier.irs_user}${supplier.irs_pass}${idtrx}`; + const md5Hash = require("blueimp-md5"); + const options = { - headers: {'Content-Type': 'application/json', - 'Authorization': 'Bearer ' + authorization} + headers: { 'Content-Type': 'application/json' }, + }; + const data = { + commands: 'inq-pasca', + username: supplier.irs_user, + customer_no: `${destination}`, + buyer_sku_code: `${productCode}`, + ref_id: `${idtrx}`, + sign: md5Hash(md5HashDigiflazz), + testing: true, + }; + const res = await axios.post( + `${supplier.url}/transaction`, + data, + options, + ); + + return res.data.data; + } else if (typePaid == 'PAYMENT') { + const md5HashDigiflazz = `${supplier.irs_user}${supplier.irs_pass}${idtrx}`; + const md5Hash = require("blueimp-md5"); + + const options = { + headers: { 'Content-Type': 'application/json' }, + }; + const data = { + commands: 'pay-pasca', + username: supplier.irs_user, + customer_no: `${destination}`, + buyer_sku_code: `${productCode}`, + ref_id: `${billTrxId}`, + sign: md5Hash(md5HashDigiflazz), + testing: true, + }; + const res = await axios.post( + `${supplier.url}/transaction`, + data, + options, + ); + + return res.data.data; + } else { + const md5HashDigiflazz = `${supplier.irs_user}${supplier.irs_pass}${idtrx}`; + const md5Hash = require("blueimp-md5"); + console.log('testmd5', md5HashDigiflazz); + const options = { + headers: {'Content-Type': 'application/json'}, + }; + const data = { + username: supplier.irs_user, + customer_no: `${destination}`, + buyer_sku_code: `${productCode}`, + ref_id: `${idtrx}`, + sign: md5Hash(md5HashDigiflazz), + testing: true, + }; + const res = await axios.post( + `${supplier.url}/transaction`, + data, + options, + ); + + console.log('resdigiflazz', res); + return res.data.data; + } + } else if (supplier.code == 'Hemat') { + if (authorization != '') { + console.log('initoken', authorization); + + const options = { + headers: { + 'Content-Type': 'application/json', + Authorization: `Bearer ${authorization}`, + }, }; const data = { idtransaction: idtrx, @@ -40,25 +115,31 @@ export const doTransaction = async ( code: `${productCode}`, type: `${typePaid}`, }; - const res = await axios.post(`${supplier.url}/v1/transaction/request`, data, options); + const res = await axios.post( + `${supplier.url}/v1/transaction/request`, + data, + options, + ); return res.data; } } const res = await axios.get( - `${supplier.url}?memberID=${supplier.irs_id}&pin=${supplier.irs_pin}&password=${supplier.irs_pass}&product=${productCode}&dest=${destination}&counter=1&refID=${idtrx}`, + `${supplier.url}?memberID=${supplier.irs_id}&pin=${supplier.irs_pin}&password=${supplier.irs_pass}&product=${productCode}&dest=${destination}&counter=1&refID=${idtrx}`, ); return res.data; - console.log('restranshemat', res) + console.log('restranshemat', res); } catch (err) { - console.log('errtranshemat', err); + console.log('errtransaction', err); + console.log('errtransaction2', err.response.data); + if (err.includes('Maaf Saldo anda tidak mencukupi')) { throw 'maaf saat ini transaksi sedang tidak bisa diproses, silahkan hubungi WND Solutions untuk bisa di proses kembali'; } else { throw err; } - } + } }; diff --git a/src/transaction/ppob_callback.controller.ts b/src/transaction/ppob_callback.controller.ts index caef626..3a91318 100644 --- a/src/transaction/ppob_callback.controller.ts +++ b/src/transaction/ppob_callback.controller.ts @@ -152,4 +152,24 @@ export class PpobCallbackController { ); } } + + @Public() + @Post('/digiflazz') + async getDigiflazz(@Req() request: FastifyRequest) { + const response = request.body; + console.log('responsedigiflazz', response); + if (response['data']['message'] != 'Transaksi Sukses') { + //TODO: UPDATE GAGAL + await this.transactionService.checkCallbackOrderFailed( + response['data']['ref_id'], + response['data'], + ); + } else { + //TODO: UPDATE BERHASIL + await this.transactionService.checkCallbackOrderSuccess( + response['data']['ref_id'], + response['data'], + ); + } + } } diff --git a/src/transaction/transaction.service.ts b/src/transaction/transaction.service.ts index 83bf98d..a68de7b 100644 --- a/src/transaction/transaction.service.ts +++ b/src/transaction/transaction.service.ts @@ -614,12 +614,14 @@ export class TransactionService { } //HIT API SUPPLIER - const trxId = Array(11) - .fill(null) - .map(() => { - return Math.round(Math.random() * 16).toString(16); - }) - .join(''); + let trxId; + + trxId = Array(11) + .fill(null) + .map(() => { + return Math.round(Math.random() * 16).toString(16); + }) + .join(''); let hitLoginHemat; @@ -635,6 +637,7 @@ export class TransactionService { supplier, hitLoginHemat.data, product.type == 'prepaid' ? 'PURCHASE' : 'PAYMENT', + orderTransactionDto.bill_trx_id ) : await doTransaction( orderTransactionDto.productCode, orderTransactionDto.destination, @@ -642,6 +645,7 @@ export class TransactionService { supplier, "", product.type == 'prepaid' ? 'PURCHASE' : 'PAYMENT', + orderTransactionDto.bill_trx_id ); // let hitSupplier; @@ -677,6 +681,30 @@ export class TransactionService { hitSupplier = newHitSupplier; + if (orderTransactionDto.bill_trx_id !== null) { + hitSupplier.harga = product_price.price; + } + } else if (supplier.code == 'Digiflazz') { + let newHitSupplier; + + if (product.type == 'prepaid') { + newHitSupplier = { + success: hitSupplier.status.includes('Pending') || hitSupplier.status.includes('Sukses'), + sn: hitSupplier.sn, + harga: hitSupplier.price, + msg: hitSupplier.message, + }; + } else { + newHitSupplier= { + success: hitSupplier.status.includes('Pending') || hitSupplier.status.includes('Sukses'), + harga: hitSupplier.price, + msg: hitSupplier.message, + sn: hitSupplier.sn, + }; + } + + hitSupplier = newHitSupplier; + if (orderTransactionDto.bill_trx_id !== null) { hitSupplier.harga = product_price.price; } @@ -742,10 +770,9 @@ export class TransactionService { transactionData.partner_trx_id = orderTransactionDto.trx_id; transactionData.supplier_trx_id = trxId; transactionData.check_bill = orderTransactionDto.bill_trx_id; - transactionData.balance_remaining = - coaAccount.amount - product_price.mark_up_price - costInventory; if (!hitSupplier.success) { + transactionData.balance_remaining = coaAccount.amount; transactionData.status = statusTransaction.FAILED; status = statusTransaction[transactionData.status]; await this.transactionRepository.insert(transactionData); @@ -757,8 +784,20 @@ export class TransactionService { HttpStatus.INTERNAL_SERVER_ERROR, ); } else { - transactionData.status = statusTransaction.PENDING; - status = statusTransaction[transactionData.status]; + transactionData.balance_remaining = + coaAccount.amount - product_price.mark_up_price - costInventory; + if ( + hitSupplier.sn == null || + hitSupplier.sn == '' || + hitSupplier.sn == undefined + ) { + transactionData.status = statusTransaction.PENDING; + status = statusTransaction[transactionData.status]; + } else { + transactionData.seri_number = hitSupplier.sn; + transactionData.status = statusTransaction.SUCCESS; + status = statusTransaction[transactionData.status]; + } } await manager.insert(Transactions, transactionData); @@ -882,6 +921,7 @@ export class TransactionService { supplier, hitLoginHemat.data, product.type == 'prepaid' ? 'PURCHASE' : 'PAYMENT', + orderTransactionDto.bill_trx_id ) : await doTransaction( orderTransactionDto.productCode, orderTransactionDto.destination, @@ -889,6 +929,7 @@ export class TransactionService { supplier, "", product.type == 'prepaid' ? 'PURCHASE' : 'PAYMENT', + orderTransactionDto.bill_trx_id ); if (supplier.code != 'IRS') { @@ -1030,21 +1071,39 @@ export class TransactionService { hitLoginHemat = await doAuthorizeHemat(supplier.irs_user, supplier.irs_pass, supplier); } - let hitSupplier = supplier.code == 'Hemat' ? await doTransaction( + let hitSupplier; + + if (supplier.code == 'Hemat') { + hitSupplier = await doTransaction( orderTransactionDto.productCode, orderTransactionDto.destination, trxId, supplier, hitLoginHemat.data, - 'INQUIRY' - ) : await doTransaction( - `CEK${orderTransactionDto.productCode.slice(3)}`, + 'INQUIRY', + orderTransactionDto.bill_trx_id + ) + } else if (supplier.code == 'Digiflazz') { + hitSupplier = await doTransaction( + orderTransactionDto.productCode, + orderTransactionDto.destination, + trxId, + supplier, + hitLoginHemat.data, + 'INQUIRY', + orderTransactionDto.bill_trx_id + ) + } else { + await doTransaction( + hitSupplier= `CEK${orderTransactionDto.productCode.slice(3)}`, orderTransactionDto.destination, trxId, supplier, "", - 'INQUIRY' + 'INQUIRY', + orderTransactionDto.bill_trx_id ); + } // const parsingResponse = hitSupplier.split(' '); if (supplier.code == 'Hemat') { @@ -1052,6 +1111,11 @@ export class TransactionService { success: hitSupplier.success == true, msg: hitSupplier.msg, }; + } else if (supplier.code == 'Digiflazz') { + hitSupplier = { + success: hitSupplier.status.includes('Sukses'), + msg: hitSupplier.message, + }; } else { hitSupplier = { success: hitSupplier.includes('diproses') || hitSupplier.includes('dalam proses'), @@ -1500,6 +1564,10 @@ export class TransactionService { } else { dataProductHistoryPrice.price = parseInt(callback['data']['additional']['harga']); } + } else if (supplier.code == 'Digiflazz') { + if (callback['sn']) { + dataTransaction.seri_number = callback['sn']; + } } else { if (callback['sn']) { dataTransaction.seri_number = callback['sn']; diff --git a/yarn.lock b/yarn.lock index 1499c42..f70b82a 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1765,6 +1765,11 @@ "resolved" "https://registry.npmjs.org/bluebird/-/bluebird-3.4.7.tgz" "version" "3.4.7" +"blueimp-md5@^2.19.0": + "integrity" "sha512-DRQrD6gJyy8FbiE4s+bDoXS9hiW3Vbx5uCdwvcCf3zLHL+Iv7LtGHLpr+GZV8rHG8tK766FGYBwRbu8pELTt+w==" + "resolved" "https://registry.npmjs.org/blueimp-md5/-/blueimp-md5-2.19.0.tgz" + "version" "2.19.0" + "body-parser@1.19.0": "integrity" "sha512-dhEPs72UPbDnAQJ9ZKMNTP6ptJaionhP5cBb541nXPlW60Jepo9RV/a4fX4XWW9CuFNK22krhrj1+rgzifNCsw==" "resolved" "https://registry.npmjs.org/body-parser/-/body-parser-1.19.0.tgz" @@ -2265,6 +2270,11 @@ "shebang-command" "^2.0.0" "which" "^2.0.1" +"crypto-md5@^1.0.0": + "integrity" "sha512-65Mtei8+EkSIK+5Ie4gpWXoJ/5bgpqPXFknHHXAyhDqKsEAAzUslGd8mOeawbfcuQ8fADNKcF4xQA3fqlZJ8Ig==" + "resolved" "https://registry.npmjs.org/crypto-md5/-/crypto-md5-1.0.0.tgz" + "version" "1.0.0" + "crypto@^1.0.1": "integrity" "sha512-VxBKmeNcqQdiUQUW2Tzq0t377b54N2bMtXO/qiLa+6eRRmmC4qT3D4OnTGoT/U6O9aklQ/jTwbOtRMTTY8G0Ig==" "resolved" "https://registry.npmjs.org/crypto/-/crypto-1.0.1.tgz" @@ -4381,6 +4391,11 @@ dependencies: "tmpl" "1.0.5" +"md5-hash@^1.0.1": + "integrity" "sha512-McGTs7cIc3JSw9SJH5JxFCJRoI1bi9tKh89LZxpHobmY2YGGhYTnDZ2rxcvNv0Bs1gBbSwSQfCwbuFleZOkkYA==" + "resolved" "https://registry.npmjs.org/md5-hash/-/md5-hash-1.0.1.tgz" + "version" "1.0.1" + "media-typer@0.3.0": "integrity" "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=" "resolved" "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz"