From bf383fdb2f4be884009516914fddf3bdf433645b Mon Sep 17 00:00:00 2001 From: sasakiroo Date: Thu, 24 Oct 2024 06:47:52 +0800 Subject: [PATCH] syntax in lib/snapBi/snapBi.js line 1, is fixed. -type in line 1 require --- lib/SnapBi/snapBi.js | 670 ++++++++++++++++++++++--------------------- 1 file changed, 347 insertions(+), 323 deletions(-) diff --git a/lib/SnapBi/snapBi.js b/lib/SnapBi/snapBi.js index a23f0ef..5a43ae2 100644 --- a/lib/SnapBi/snapBi.js +++ b/lib/SnapBi/snapBi.js @@ -1,328 +1,352 @@ - -const SnapBiApiRequestor = require('./SnapBiApiRequestor'); -const SnapBiConfig = require("./snapBiConfig"); +const SnapBiApiRequestor = require('./snapBiApiRequestor'); +const SnapBiConfig = require('./snapBiConfig'); const crypto = require('crypto'); class SnapBi { - static ACCESS_TOKEN = '/v1.0/access-token/b2b'; - static PAYMENT_HOST_TO_HOST = '/v1.0/debit/payment-host-to-host'; - static CREATE_VA = '/v1.0/transfer-va/create-va'; - static DEBIT_STATUS = '/v1.0/debit/status'; - static DEBIT_REFUND = '/v1.0/debit/refund'; - static DEBIT_CANCEL = '/v1.0/debit/cancel'; - static VA_STATUS = '/v1.0/transfer-va/status'; - static VA_CANCEL = '/v1.0/transfer-va/delete-va'; - static QRIS_PAYMENT = '/v1.0/qr/qr-mpm-generate'; - static QRIS_STATUS = '/v1.0/qr/qr-mpm-query'; - static QRIS_REFUND = '/v1.0/qr/qr-mpm-refund'; - static QRIS_CANCEL = '/v1.0/qr/qr-mpm-cancel'; - - constructor(paymentMethod) { - this.paymentMethod = paymentMethod; - this.apiPath = ''; - this.accessTokenHeader = []; - this.transactionHeader = []; - this.body = {}; - this.accessToken = ''; - this.deviceId = ''; - this.debugId = ''; - this.timeStamp = new Date().toISOString(); - this.timeout = null; - this.signature = ''; - this.notificationUrlPath = ''; - this.notificationPayload = {}; - } - - static directDebit() { - return new SnapBi('directDebit'); - } - - static va() { - return new SnapBi('va'); - } - - static qris() { - return new SnapBi('qris'); - } - static notification() { - return new SnapBi(''); - } - - - withAccessTokenHeader(headers) { - this.accessTokenHeader = { ...this.accessTokenHeader, ...headers }; - return this; - } - - withTransactionHeader(headers) { - this.transactionHeader = { ...this.transactionHeader, ...headers }; - return this; - } - - withAccessToken(accessToken) { - this.accessToken = accessToken; - return this; - } - - withBody(body) { - this.body = body; - return this; - } - withSignature(signature) { - this.signature = signature; - return this; - } - withTimeStamp(timeStamp) { - this.timeStamp = timeStamp; - return this; - } - withNotificationPayload(notificationPayload) { - this.notificationPayload = notificationPayload; - return this; - } - withNotificationUrlPath(notificationUrlPath) { - this.notificationUrlPath = notificationUrlPath; - return this; - } - - withPrivateKey(privateKey) { - SnapBiConfig.snapBiPrivateKey = privateKey; - return this; - } - - withClientId(clientId) { - SnapBiConfig.snapBiClientId = clientId; - return this; - } - - withClientSecret(clientSecret) { - SnapBiConfig.snapBiClientSecret = clientSecret; - return this; - } - - withPartnerId(partnerId) { - SnapBiConfig.snapBiPartnerId = partnerId; - return this; - } - - withChannelId(channelId) { - SnapBiConfig.snapBiChannelId = channelId; - return this; - } - - withDeviceId(deviceId) { - this.deviceId = deviceId; - return this; - } - - withDebugId(debugId) { - this.debugId = debugId; - return this; - } - - withTimeout(timeout) { - this.timeout = timeout; - return this; - } - - async createPayment(externalId) { - this.apiPath = this.setupCreatePaymentApiPath(this.paymentMethod); - return await this.createConnection(externalId); - } - - async cancel(externalId) { - this.apiPath = this.setupCancelApiPath(this.paymentMethod); - return await this.createConnection(externalId); - } - - async refund(externalId) { - this.apiPath = this.setupRefundApiPath(this.paymentMethod); - return await this.createConnection(externalId); - } - - async getStatus(externalId) { - this.apiPath = this.setupGetStatusApiPath(this.paymentMethod); - return await this.createConnection(externalId); - } - - isWebhookNotificationVerified() { - - if (SnapBiConfig.snapBiPublicKey == null){ - throw new Error("The public key is null, You need to set the public key from SnapBiConfig.'\n" + - "For more details, contact support at support@midtrans.com if you have any questions."); - } - var notificationHttpMethod = "POST"; - var minifiedNotificationBodyJsonString = JSON.stringify(this.notificationPayload); - var hashedNotificationBodyJsonString = crypto - .createHash("sha256") - .update(minifiedNotificationBodyJsonString) - .digest("hex") - .toLowerCase(); - - var rawStringDataToVerifyAgainstSignature = - notificationHttpMethod + - ":" + - this.notificationUrlPath + - ":" + - hashedNotificationBodyJsonString + - ":" + - this.timeStamp; - - var verifier = crypto.createVerify("SHA256"); - verifier.update(rawStringDataToVerifyAgainstSignature, "utf8"); - var isSignatureVerified = verifier.verify( - SnapBiConfig.snapBiPublicKey, - this.signature, - "base64", - ); - return isSignatureVerified - } - - async getAccessToken() { - const snapBiAccessTokenHeader = this.buildAccessTokenHeader(this.timeStamp); - const openApiPayload = { - grant_type: 'client_credentials', - }; - return await SnapBiApiRequestor.remoteCall( - SnapBiConfig.getBaseUrl() + SnapBi.ACCESS_TOKEN, - snapBiAccessTokenHeader, - openApiPayload, - this.timeout - ); - } - - async createConnection(externalId = null) { - if (!this.accessToken) { - const accessTokenResponse = await this.getAccessToken(); - if (!accessTokenResponse.accessToken) { - return accessTokenResponse; - } - this.accessToken = accessTokenResponse.accessToken; - } - - const snapBiTransactionHeader = this.buildSnapBiTransactionHeader(externalId, this.timeStamp); - return await SnapBiApiRequestor.remoteCall( - SnapBiConfig.getBaseUrl() + this.apiPath, - snapBiTransactionHeader, - this.body, - this.timeout - ); - } - - static getSymmetricSignatureHmacSh512(accessToken, requestBody, method, path, clientSecret, timeStamp) { - const minifiedBody = JSON.stringify(requestBody); - const hashedBody = crypto.createHash('sha256').update(minifiedBody).digest('hex').toLowerCase(); - - const payload = `${method.toUpperCase()}:${path}:${accessToken}:${hashedBody}:${timeStamp}`; - const hmac = crypto.createHmac('sha512', clientSecret).update(payload).digest('base64'); - - return hmac; - } - - - static getAsymmetricSignatureSha256WithRsa(clientId, xTimeStamp, privateKey) { - const stringToSign = clientId + "|" + xTimeStamp; - return crypto.sign('RSA-SHA256', Buffer.from(stringToSign), privateKey).toString("base64"); - } - - buildSnapBiTransactionHeader(externalId, timeStamp) { - let snapBiTransactionHeader = { - 'Content-Type': 'application/json', - 'Accept': 'application/json', - 'X-PARTNER-ID': SnapBiConfig.snapBiPartnerId, - 'X-EXTERNAL-ID': externalId, - 'X-DEVICE-ID': this.deviceId, - 'CHANNEL-ID': SnapBiConfig.snapBiChannelId, - 'debug-id': this.debugId, - 'Authorization': `Bearer ${this.accessToken}`, - 'X-TIMESTAMP': timeStamp, - 'X-SIGNATURE': SnapBi.getSymmetricSignatureHmacSh512( - this.accessToken, - this.body, - 'post', - this.apiPath, - SnapBiConfig.snapBiClientSecret, - timeStamp - ), - }; - - if (this.transactionHeader) { - snapBiTransactionHeader = { ...snapBiTransactionHeader, ...this.transactionHeader }; - } - - return snapBiTransactionHeader; - } - - buildAccessTokenHeader(timeStamp) { - let snapBiAccessTokenHeader = { - 'Content-Type': 'application/json', - 'Accept': 'application/json', - 'X-CLIENT-KEY': SnapBiConfig.snapBiClientId, - 'X-SIGNATURE': SnapBi.getAsymmetricSignatureSha256WithRsa( - SnapBiConfig.snapBiClientId, - timeStamp, - SnapBiConfig.snapBiPrivateKey - ), - 'X-TIMESTAMP': timeStamp, - 'debug-id': this.debugId, - }; - - if (this.accessTokenHeader) { - snapBiAccessTokenHeader = { ...snapBiAccessTokenHeader, ...this.accessTokenHeader }; - } - - return snapBiAccessTokenHeader; - } - - setupCreatePaymentApiPath(paymentMethod) { - switch (paymentMethod) { - case 'va': - return SnapBi.CREATE_VA; - case 'qris': - return SnapBi.QRIS_PAYMENT; - case 'directDebit': - return SnapBi.PAYMENT_HOST_TO_HOST; - default: - throw new Error(`Payment method not implemented: ${paymentMethod}`); - } - } - - setupRefundApiPath(paymentMethod) { - switch (paymentMethod) { - case 'qris': - return SnapBi.QRIS_REFUND; - case 'directDebit': - return SnapBi.DEBIT_REFUND; - default: - throw new Error(`Payment method not implemented: ${paymentMethod}`); - } - } - - setupCancelApiPath(paymentMethod) { - switch (paymentMethod) { - case 'va': - return SnapBi.VA_CANCEL; - case 'qris': - return SnapBi.QRIS_CANCEL; - case 'directDebit': - return SnapBi.DEBIT_CANCEL; - default: - throw new Error(`Payment method not implemented: ${paymentMethod}`); - } - } - - setupGetStatusApiPath(paymentMethod) { - switch (paymentMethod) { - case 'va': - return SnapBi.VA_STATUS; - case 'qris': - return SnapBi.QRIS_STATUS; - case 'directDebit': - return SnapBi.DEBIT_STATUS; - default: - throw new Error(`Payment method not implemented: ${paymentMethod}`); - } - } + static ACCESS_TOKEN = '/v1.0/access-token/b2b'; + static PAYMENT_HOST_TO_HOST = '/v1.0/debit/payment-host-to-host'; + static CREATE_VA = '/v1.0/transfer-va/create-va'; + static DEBIT_STATUS = '/v1.0/debit/status'; + static DEBIT_REFUND = '/v1.0/debit/refund'; + static DEBIT_CANCEL = '/v1.0/debit/cancel'; + static VA_STATUS = '/v1.0/transfer-va/status'; + static VA_CANCEL = '/v1.0/transfer-va/delete-va'; + static QRIS_PAYMENT = '/v1.0/qr/qr-mpm-generate'; + static QRIS_STATUS = '/v1.0/qr/qr-mpm-query'; + static QRIS_REFUND = '/v1.0/qr/qr-mpm-refund'; + static QRIS_CANCEL = '/v1.0/qr/qr-mpm-cancel'; + + constructor(paymentMethod) { + this.paymentMethod = paymentMethod; + this.apiPath = ''; + this.accessTokenHeader = []; + this.transactionHeader = []; + this.body = {}; + this.accessToken = ''; + this.deviceId = ''; + this.debugId = ''; + this.timeStamp = new Date().toISOString(); + this.timeout = null; + this.signature = ''; + this.notificationUrlPath = ''; + this.notificationPayload = {}; + } + + static directDebit() { + return new SnapBi('directDebit'); + } + + static va() { + return new SnapBi('va'); + } + + static qris() { + return new SnapBi('qris'); + } + static notification() { + return new SnapBi(''); + } + + withAccessTokenHeader(headers) { + this.accessTokenHeader = { ...this.accessTokenHeader, ...headers }; + return this; + } + + withTransactionHeader(headers) { + this.transactionHeader = { ...this.transactionHeader, ...headers }; + return this; + } + + withAccessToken(accessToken) { + this.accessToken = accessToken; + return this; + } + + withBody(body) { + this.body = body; + return this; + } + withSignature(signature) { + this.signature = signature; + return this; + } + withTimeStamp(timeStamp) { + this.timeStamp = timeStamp; + return this; + } + withNotificationPayload(notificationPayload) { + this.notificationPayload = notificationPayload; + return this; + } + withNotificationUrlPath(notificationUrlPath) { + this.notificationUrlPath = notificationUrlPath; + return this; + } + + withPrivateKey(privateKey) { + SnapBiConfig.snapBiPrivateKey = privateKey; + return this; + } + + withClientId(clientId) { + SnapBiConfig.snapBiClientId = clientId; + return this; + } + + withClientSecret(clientSecret) { + SnapBiConfig.snapBiClientSecret = clientSecret; + return this; + } + + withPartnerId(partnerId) { + SnapBiConfig.snapBiPartnerId = partnerId; + return this; + } + + withChannelId(channelId) { + SnapBiConfig.snapBiChannelId = channelId; + return this; + } + + withDeviceId(deviceId) { + this.deviceId = deviceId; + return this; + } + + withDebugId(debugId) { + this.debugId = debugId; + return this; + } + + withTimeout(timeout) { + this.timeout = timeout; + return this; + } + + async createPayment(externalId) { + this.apiPath = this.setupCreatePaymentApiPath(this.paymentMethod); + return await this.createConnection(externalId); + } + + async cancel(externalId) { + this.apiPath = this.setupCancelApiPath(this.paymentMethod); + return await this.createConnection(externalId); + } + + async refund(externalId) { + this.apiPath = this.setupRefundApiPath(this.paymentMethod); + return await this.createConnection(externalId); + } + + async getStatus(externalId) { + this.apiPath = this.setupGetStatusApiPath(this.paymentMethod); + return await this.createConnection(externalId); + } + + isWebhookNotificationVerified() { + if (SnapBiConfig.snapBiPublicKey == null) { + throw new Error( + "The public key is null, You need to set the public key from SnapBiConfig.'\n" + + 'For more details, contact support at support@midtrans.com if you have any questions.' + ); + } + var notificationHttpMethod = 'POST'; + var minifiedNotificationBodyJsonString = JSON.stringify( + this.notificationPayload + ); + var hashedNotificationBodyJsonString = crypto + .createHash('sha256') + .update(minifiedNotificationBodyJsonString) + .digest('hex') + .toLowerCase(); + + var rawStringDataToVerifyAgainstSignature = + notificationHttpMethod + + ':' + + this.notificationUrlPath + + ':' + + hashedNotificationBodyJsonString + + ':' + + this.timeStamp; + + var verifier = crypto.createVerify('SHA256'); + verifier.update(rawStringDataToVerifyAgainstSignature, 'utf8'); + var isSignatureVerified = verifier.verify( + SnapBiConfig.snapBiPublicKey, + this.signature, + 'base64' + ); + return isSignatureVerified; + } + + async getAccessToken() { + const snapBiAccessTokenHeader = this.buildAccessTokenHeader(this.timeStamp); + const openApiPayload = { + grant_type: 'client_credentials', + }; + return await SnapBiApiRequestor.remoteCall( + SnapBiConfig.getBaseUrl() + SnapBi.ACCESS_TOKEN, + snapBiAccessTokenHeader, + openApiPayload, + this.timeout + ); + } + + async createConnection(externalId = null) { + if (!this.accessToken) { + const accessTokenResponse = await this.getAccessToken(); + if (!accessTokenResponse.accessToken) { + return accessTokenResponse; + } + this.accessToken = accessTokenResponse.accessToken; + } + + const snapBiTransactionHeader = this.buildSnapBiTransactionHeader( + externalId, + this.timeStamp + ); + return await SnapBiApiRequestor.remoteCall( + SnapBiConfig.getBaseUrl() + this.apiPath, + snapBiTransactionHeader, + this.body, + this.timeout + ); + } + + static getSymmetricSignatureHmacSh512( + accessToken, + requestBody, + method, + path, + clientSecret, + timeStamp + ) { + const minifiedBody = JSON.stringify(requestBody); + const hashedBody = crypto + .createHash('sha256') + .update(minifiedBody) + .digest('hex') + .toLowerCase(); + + const payload = `${method.toUpperCase()}:${path}:${accessToken}:${hashedBody}:${timeStamp}`; + const hmac = crypto + .createHmac('sha512', clientSecret) + .update(payload) + .digest('base64'); + + return hmac; + } + + static getAsymmetricSignatureSha256WithRsa(clientId, xTimeStamp, privateKey) { + const stringToSign = clientId + '|' + xTimeStamp; + return crypto + .sign('RSA-SHA256', Buffer.from(stringToSign), privateKey) + .toString('base64'); + } + + buildSnapBiTransactionHeader(externalId, timeStamp) { + let snapBiTransactionHeader = { + 'Content-Type': 'application/json', + Accept: 'application/json', + 'X-PARTNER-ID': SnapBiConfig.snapBiPartnerId, + 'X-EXTERNAL-ID': externalId, + 'X-DEVICE-ID': this.deviceId, + 'CHANNEL-ID': SnapBiConfig.snapBiChannelId, + 'debug-id': this.debugId, + Authorization: `Bearer ${this.accessToken}`, + 'X-TIMESTAMP': timeStamp, + 'X-SIGNATURE': SnapBi.getSymmetricSignatureHmacSh512( + this.accessToken, + this.body, + 'post', + this.apiPath, + SnapBiConfig.snapBiClientSecret, + timeStamp + ), + }; + + if (this.transactionHeader) { + snapBiTransactionHeader = { + ...snapBiTransactionHeader, + ...this.transactionHeader, + }; + } + + return snapBiTransactionHeader; + } + + buildAccessTokenHeader(timeStamp) { + let snapBiAccessTokenHeader = { + 'Content-Type': 'application/json', + Accept: 'application/json', + 'X-CLIENT-KEY': SnapBiConfig.snapBiClientId, + 'X-SIGNATURE': SnapBi.getAsymmetricSignatureSha256WithRsa( + SnapBiConfig.snapBiClientId, + timeStamp, + SnapBiConfig.snapBiPrivateKey + ), + 'X-TIMESTAMP': timeStamp, + 'debug-id': this.debugId, + }; + + if (this.accessTokenHeader) { + snapBiAccessTokenHeader = { + ...snapBiAccessTokenHeader, + ...this.accessTokenHeader, + }; + } + + return snapBiAccessTokenHeader; + } + + setupCreatePaymentApiPath(paymentMethod) { + switch (paymentMethod) { + case 'va': + return SnapBi.CREATE_VA; + case 'qris': + return SnapBi.QRIS_PAYMENT; + case 'directDebit': + return SnapBi.PAYMENT_HOST_TO_HOST; + default: + throw new Error(`Payment method not implemented: ${paymentMethod}`); + } + } + + setupRefundApiPath(paymentMethod) { + switch (paymentMethod) { + case 'qris': + return SnapBi.QRIS_REFUND; + case 'directDebit': + return SnapBi.DEBIT_REFUND; + default: + throw new Error(`Payment method not implemented: ${paymentMethod}`); + } + } + + setupCancelApiPath(paymentMethod) { + switch (paymentMethod) { + case 'va': + return SnapBi.VA_CANCEL; + case 'qris': + return SnapBi.QRIS_CANCEL; + case 'directDebit': + return SnapBi.DEBIT_CANCEL; + default: + throw new Error(`Payment method not implemented: ${paymentMethod}`); + } + } + + setupGetStatusApiPath(paymentMethod) { + switch (paymentMethod) { + case 'va': + return SnapBi.VA_STATUS; + case 'qris': + return SnapBi.QRIS_STATUS; + case 'directDebit': + return SnapBi.DEBIT_STATUS; + default: + throw new Error(`Payment method not implemented: ${paymentMethod}`); + } + } } module.exports = SnapBi; -