UNPKG

@onepay-payment-sdk/server

Version:

server payment sdk for onepay payment gateway

259 lines (248 loc) 7.79 kB
'use strict'; Object.defineProperty(exports, '__esModule', { value: true }); var https = require('https'); var crypto = require('crypto'); function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; } var https__default = /*#__PURE__*/_interopDefault(https); var crypto__default = /*#__PURE__*/_interopDefault(crypto); // src/constants/environment.ts var ENVIRONMENT_API = { LIVE: "https://merchant-api-live-v2.onepay.lk/api/ipg/gateway" }; // src/exceptions/PaymentException.ts var PaymentException = class extends Error { constructor(message) { super(message); this.name = "PaymentError"; this.message = message; } }; // src/validation/inputValidators.ts function isValidUrl(url) { try { new URL(url); return true; } catch { return false; } } function isValidEmail(email) { const atIndex = email.indexOf("@"); const dotIndex = email.lastIndexOf("."); if (atIndex < 1 || atIndex === email.length - 1) { return false; } if (dotIndex < atIndex + 2 || dotIndex === email.length - 1) { return false; } if (email.includes(" ")) { return false; } return true; } function validatePayLink(url) { let urlObj; try { urlObj = new URL(url); if (!urlObj.protocol.startsWith("https")) { throw new Error("URL must use HTTPS Protocol"); } if (urlObj.searchParams.get("hash") === null) { throw new Error("Missing salt query parameter"); } return urlObj; } catch (error) { if (error instanceof PaymentException) { throw new PaymentException(error.message); } else { throw new Error("Failed to parse URL"); } } } function validatePaymentParams(basicParams) { if (typeof basicParams.firstName !== "string" || basicParams.firstName.length < 1) { throw new Error("First name must be a non-empty string"); } if (typeof basicParams.lastName !== "string" || basicParams.lastName.length < 1) { throw new Error("Last name must be a non-empty string"); } if (typeof basicParams.email !== "string" || !isValidEmail(basicParams.email)) { throw new Error("Email must be a valid email address"); } if (typeof basicParams.phone !== "string") { throw new Error("Phone number must be a string"); } if (typeof basicParams.amount !== "number" || basicParams.amount < 100) { throw new Error("Amount must be a number greater than or equal to 100"); } if (typeof basicParams.reference !== "string" || basicParams.reference.length < 10 || basicParams.reference.length > 20) { throw new Error( "Reference must be a string with a length between 10 and 20 characters" ); } if (typeof basicParams.transactionRedirectUrl !== "string" || !isValidUrl(basicParams.transactionRedirectUrl)) { throw new Error("Transaction redirect URL is not valid"); } return basicParams; } // src/constants/currency.ts var Currency = { USD: "USD", LKR: "LKR" }; async function paymentRequest(url, token, body) { if (!url && !token && !body) { throw new Error("Missing required parameters"); } const urlObj = validatePayLink(url); const hashParam = urlObj.searchParams.get("hash"); const TIMEOUT_MS = 3e4; const options = { hostname: urlObj.hostname, path: urlObj.pathname + `?hash=${hashParam}`, method: "POST", headers: { "Content-Type": "application/json", authorization: token }, timeout: TIMEOUT_MS }; return new Promise((resolve, reject) => { const req = https__default.default.request(options, (res) => { const chunks = []; res.setTimeout(TIMEOUT_MS, () => { req.destroy(new Error("Response timeout")); }); res.on("data", (chunk) => { chunks.push(Buffer.from(chunk)); }); res.on("end", () => { try { const data = Buffer.concat(chunks).toString("utf8"); const response = JSON.parse(data); if (res.statusCode === 200 && response.status === 1e3) { resolve({ status: response.status, message: response.message, data: response.data }); } else { const error = new Error(data); reject(error); } } catch (err) { const error = new Error("Failed to Process response" + err); reject(error); } }); }); req.on("error", (error) => { reject(error); }); req.write(JSON.stringify(body)); req.end(); }); } function generatePaymentLink(paymentLinkParams) { const { baseURL, salt, paymentParams } = paymentLinkParams; if (!baseURL) { throw new Error("Missing required parameter : BaseURL"); } if (!salt) { throw new Error("Missing required parameter : Salt"); } if (!paymentParams || typeof paymentParams !== "object") { throw new Error("Invalid or missing paymentParams. It must be an object."); } try { const paymentParamsString = JSON.stringify(paymentParams); const hash = crypto__default.default.createHash("sha256").update(paymentParamsString + salt).digest("hex"); const normalizeBaseURL = baseURL.endsWith("/") ? baseURL.slice(0, -1) : baseURL; const paymentLink = new URL(`${normalizeBaseURL}/request-payment-link/`); paymentLink.searchParams.append("hash", hash); return paymentLink.toString(); } catch (error) { throw new Error( `Failed to generate payment link : ${error instanceof Error ? error.message : String(error)}`, { cause: error } ); } } // src/onepay.ts var Onepay = class { appId; token; salt; baseUrl; paymentParams; constructor(onepayConfig) { this.appId = onepayConfig.appId; this.token = onepayConfig.token; this.salt = onepayConfig.salt; this.baseUrl = ENVIRONMENT_API.LIVE; this.paymentParams = null; } generatePaymentParams(basicParams) { if (!this.appId) { throw new Error("App ID not initialized"); } const validatedParams = validatePaymentParams(basicParams); const paymentDetailsWithAppId = { amount: validatedParams.amount, reference: validatedParams.reference, customer_email: validatedParams.email, customer_first_name: validatedParams.firstName, customer_last_name: validatedParams.lastName, customer_phone_number: validatedParams.phone, transaction_redirect_url: validatedParams.transactionRedirectUrl, ...validatedParams.additionalData && { additional_data: validatedParams.additionalData }, currency: validatedParams.currency || Currency.LKR, app_id: this.appId }; this.paymentParams = paymentDetailsWithAppId; try { return this.paymentParams; } catch (err) { if (err instanceof Error) { throw new Error(`Failed to serialize payment: ${err.message}`); } else { throw new Error("Failed to serialize payment:"); } } } async createPaymentRequest(onepayPaymentParams) { if (!this.token) { throw new Error("Token not initialized"); } if (!this.salt) { throw new Error("Salt not initialized"); } try { const paymentRequestUrl = generatePaymentLink({ baseURL: this.baseUrl, paymentParams: onepayPaymentParams, salt: this.salt }); const response = await paymentRequest( paymentRequestUrl, this.token, onepayPaymentParams ); return response; } catch (err) { throw new Error("Failed to create payment request" + err); } } }; // src/index.ts var src_default = Onepay; exports.Currency = Currency; exports.ENVIRONMENT_API = ENVIRONMENT_API; exports.Onepay = Onepay; exports.default = src_default; //# sourceMappingURL=index.js.map //# sourceMappingURL=index.js.map