UNPKG

payunitjs-test

Version:

PayUnit is Seven's Payment aggregator created @SevenGroups by SevenGPS Core Engineers and tested by Silicon Valley professionals and Google experts

566 lines (516 loc) 22.6 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.PayUnit = PayUnit; var _payment = require("./payment.js"); var puPayment = _interopRequireWildcard(_payment); var _sdkUtilities = require("./sdkUtilities.js"); var utils = _interopRequireWildcard(_sdkUtilities); var sdkUtils = _interopRequireWildcard(_sdkUtilities); function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } } // Main function function PayUnit() { var config = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : { merchantName: "", merchantLogo: "", merchantProfileImage: "", styles: [] }; var credentials = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : { apiUsername: "", apiPassword: "", x_api_key: "", mode: "" }; var purchase = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : { return_url: "", notify_url: "", description: "", purchaseRef: "", total_amount: "", currency: "XAF" }; /** CREATING DOM ELEMENTS USED BUY PAYUNIT */ var card_inputs = create("section"); var paymentDialog = create("div"); var paymentContainer = create("div"); var merchantLogo = create("div"); var merchantIcon = create("img"); var paymentProcess = create("div"); var formBlock = create("form"); var inputRow1 = create("div"); var selectPayment = create("select"); var nextArror1 = create("span"); var inputRow2 = create("div"); var prevArrow1 = create("span"); var nameText = create("input"); var nextArror2 = create("span"); var inputRow3 = create("div"); var merchantNameHeader = create("h1"); var phoneNumber = create("input"); var prevArrow2 = create("span"); var SubmitForm = create("div"); var submit = create("input"); var style = create("style"); var closeBtn = create("span"); var isSDKLauched = false; var selectedGateway = void 0; var return_url = purchase.return_url; var notify_url = purchase.notify_url; var paymentHeader = create("div"); var errorMessage = create("p"); var processLoader = create("span"); var staticOption = create("option"); var bodyTag = document.querySelector("body"); /** * STYLES USED BY PAYUNIT JS */ style.innerHTML = "\n // @import url('https://payunit-core.sevengps.net/resources/css/payunit.css?v=1.0.0');\n // @import url('https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.1/css/all.min.css');\n "; /** SETTING CONTENT TO SOME ELEMENTS */ addProperty(merchantNameHeader, "textContent", sdkUtils.messages.payWith); // addProperty(poweredBy, "textContent", "Powered by PayUnit"); addProperty(merchantIcon, "src", "./logo/SevenPay2x.png"); addProperty(merchantIcon, "alt", "M. Logo"); addProperty(selectPayment, "placeholder", "Provider"); addProperty(errorMessage, "textContent", sdkUtils.messages.fillFormFields); addProperty(selectPayment, "name", "payment_method"); addProperty(nameText, "placeholder", "Name"); addProperty(nameText, "name", "client_name"); addProperty(nameText, "type", "text"); addProperty(phoneNumber, "placeholder", "Mobile Number"); addProperty(phoneNumber, "type", "number"); addProperty(phoneNumber, "name", "phone_number"); addProperty(submit, "value", "Pay Now"); addProperty(submit, "type", "submit"); addProperty(staticOption, "textContent", sdkUtils.messages.selectProvider); addProperty(staticOption, "value", ""); /** ADDING CSS IDs TO ELEMENTS */ card_inputs.id = "payUnit"; selectPayment.id = "selectGateway"; phoneNumber.id = "phoneNumber"; nameText.id = "userName"; formBlock.id = "payUnitF"; closeBtn.id = "closePayUnitDialog"; processLoader.id = "processingPayUnitDialog"; errorMessage.id = "errorMessage"; /** Adding css classes to elements */ addClass(paymentDialog, "payment-dialog"); addClass(paymentContainer, "payment-container"); addClass(merchantLogo, "merchant-logo"); addClass(paymentProcess, "payment-process"); addClass(formBlock, "form-block"); addClass(inputRow1, "input-row"); addClass(inputRow1, "paymedium-row"); addClass(inputRow1, "inn"); addClass(selectPayment, "select-payment"); addClass(nextArror1, "next-arrow"); addClass(nextArror1, "next-arrow-to-name"); addClass(inputRow2, "input-row"); addClass(inputRow2, "name-row"); addClass(prevArrow1, "prev-arrow"); addClass(prevArrow1, "prev-arrow-to-methods"); addClass(nameText, "name"); addClass(nextArror2, "next-arrow"); addClass(nextArror2, "next-arrow-to-phone"); addClass(inputRow3, "input-row"); addClass(inputRow3, "phone-row"); addClass(phoneNumber, "phone"); addClass(prevArrow2, "prev-arrow"); addClass(prevArrow2, "prev-arrow-to-name"); addClass(SubmitForm, "submit-form"); addClass(submit, "pay-btn"); addClass(closeBtn, "payunit-close-btn"); addClass(paymentHeader, "payment-header"); addClass(merchantNameHeader, "payunit-title"); addClass(errorMessage, "punit-msg"); // Apply config parameters to the payment form parseConfigParameter(config); /** Construct payment form */ constructPaymentForm(); // Selectors var payMethodBlock = document.querySelector(".paymedium-row"); var nameBlock = document.querySelector(".name-row"); var numberBlock = document.querySelector(".phone-row"); var name = document.querySelector("#userName"); var nextArrToName = document.querySelector(".next-arrow-to-name"); var nextArrToPhone = document.querySelector(".next-arrow-to-phone"); var prevArrToMethods = document.querySelector(".prev-arrow-to-methods"); var prevArrToName = document.querySelector(".prev-arrow-to-name"); var submitBtn = document.querySelector(".pay-btn"); var openDialogBtn = document.querySelector(".open-dialog-btn"); var validPhoneNumber = void 0; // Event Listeners nextArrToName.addEventListener("click", goToNextToName); prevArrToMethods.addEventListener("click", goToPrevToMethods); nextArrToPhone.addEventListener("click", goToNextToPhone); prevArrToName.addEventListener("click", goToPrevToName); submitBtn.addEventListener("click", submitForm); openDialogBtn.addEventListener("click", launchDialog); /** DOM ELEMENTS ARE NOW FULLY LOADED */ // Close the sdk UI and perform some garbage collection // --> All transactions are stopped, the SDK UI is ejected from the DOM and later appended. This enables the smooth stopping of network requests without causing side effects window.addEventListener("DOMContentLoaded", function () { var closeDialog = document.getElementById("closePayUnitDialog"); var paySection = document.getElementById("payUnit"); if (closeDialog !== undefined) { closeDialog.addEventListener("click", function (event) { event.preventDefault(); if (isSDKLauched && paySection.classList.contains("inn")) { var seletForm = document.querySelector(".select-payment"); seletForm.innerHTML = ""; removeClass(bodyTag, "overlay"); removeChild(bodyTag, card_inputs); constructPaymentForm(); paySection.style.display = "none"; paymentDialog.style.display = "none"; } }); } }); // calling sdk functions validateFormFields(); verifySelectedGateway(); makePayment(credentials, purchase); // Function that constructs the payment form by appending children to the parent DOM element function constructPaymentForm() { bodyTag.appendChild(card_inputs); card_inputs.appendChild(paymentDialog); paymentDialog.appendChild(paymentHeader); paymentDialog.appendChild(paymentContainer); paymentHeader.appendChild(merchantNameHeader); paymentHeader.appendChild(errorMessage); paymentContainer.appendChild(merchantLogo); merchantLogo.appendChild(merchantIcon); paymentContainer.appendChild(paymentProcess); paymentContainer.appendChild(SubmitForm); paymentContainer.appendChild(closeBtn); paymentContainer.appendChild(processLoader); SubmitForm.appendChild(submit); paymentProcess.appendChild(formBlock); formBlock.appendChild(inputRow1); formBlock.appendChild(inputRow2); formBlock.appendChild(inputRow3); inputRow1.appendChild(selectPayment); inputRow1.appendChild(processLoader); selectPayment.appendChild(staticOption); inputRow1.appendChild(nextArror1); inputRow2.appendChild(prevArrow1); inputRow2.appendChild(nameText); inputRow2.appendChild(nextArror2); inputRow3.appendChild(phoneNumber); inputRow3.appendChild(prevArrow2); } // Function that adds string properties to dynamically created elements function addProperty(element) { var property = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : ""; var value = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : ""; switch (property) { case "src": element.src = value; break; case "value": element.value = value; break; case "href": element.href = value; break; case "textContent": element.textContent = value; break; case "placeholder": element.placeholder = value; break; case "type": element.type = value; break; default: break; } } // Function that adds css classes to created html elements function addClass(element) { var className = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : ""; return element.classList.add([className]); } // Function that removes css classes to created html elements function removeClass(element) { var className = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : ""; return element.classList.remove([className]); } // Function that removes an element child function removeChild() { var element = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : HTMLElement; var child = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : HTMLElement; return element.removeChild(child); } // Function that Creates elements; function create(element) { return document.createElement(element); } // Function to go to the Name from the Payment Method Section function goToNextToName() { if (selectedGateway !== undefined) { // if(selectedGateway ==="paypal"){ // // code to render page // }else{ // if(selectedGateway === "stripe"){ // }else{ // payMethodBlock.classList.remove("inn"); // nameBlock.classList.add("inn"); // } // } payMethodBlock.classList.remove("inn"); nameBlock.classList.add("inn"); errorMessage.textContent = sdkUtils.messages.userName; } else { errorMessage.textContent = sdkUtils.messages.errors.selectValidMethod; } } // Function to go to the Phone Section from the Name function goToNextToPhone() { if (name.value.length >= 2) { nameBlock.classList.remove("inn"); numberBlock.classList.add("inn"); submitBtn.classList.add("inn"); if (selectedGateway === "mtnmomo" || selectedGateway === "orange") { errorMessage.textContent = sdkUtils.messages.enterPhoneNumber + " " + selectedGateway; } else { errorMessage.textContent = sdkUtils.messages.clickPayBtn + " " + selectedGateway; } } else { errorMessage.textContent = sdkUtils.messages.userName; } } // Function to go Back to the Name Section from the Phone Number function goToPrevToName() { submitBtn.classList.remove("inn"); numberBlock.classList.remove("inn"); nameBlock.classList.add("inn"); errorMessage.textContent = sdkUtils.messages.userName; } // Function to go Back to the Payment Selection Method from the Name function goToPrevToMethods() { nameBlock.classList.remove("inn"); payMethodBlock.classList.add("inn"); errorMessage.textContent = sdkUtils.messages.selectProvider; } // Function to submit the form and get the form values function submitForm() { var payMethod = document.querySelector("#selectGateway").value; var name = document.querySelector("#userName").value; var phone = document.querySelector("#phoneNumber").value; validPhoneNumber = phone; } // Function that launches the payment modal function launchDialog() { var paySection = document.getElementById("payUnit"); paySection.classList.add("inn"); isSDKLauched = true; if (isSDKLauched && paySection.style.display == "none") { paySection.style.removeProperty("display"); paymentDialog.style.removeProperty("display"); constructPaymentForm(); } addClass(bodyTag, "overlay"); /** SET UNIQUE TRANACTION_ID FOR ALL PAYMENT REQUESTS */ purchase.transaction_id = "" + (Math.floor(Math.random() * 100000000000) + Date.now()); /** The method below initializes payment process by calling paymentInitialize */ initPay(); } // Function that Parses the config object and customizes the rendered sdk ui function parseConfigParameter() { var config = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : { merchantName: "", merchantLogo: "", merchantProfileImage: "", styles: [{ bgColor: "", fontFamily: "", width: "", heigth: "", mgColor: "", titleColor: "" }] }; if (config.merchantLogo.length > 1) { merchantIcon.src = config.merchantLogo; } if (config.merchantName.length > 1) { merchantNameHeader.textContent = config.merchantName; } if (config.styles[0].bgColor.length > 0) { paymentDialog.style.backgroundColor = config.styles[0].bgColor; } if (config.styles[0].mgColor.length > 0) { errorMessage.style.color = config.styles[0].mgColor; } if (config.styles[0].titleColor.length > 0) { merchantNameHeader.style.color = config.styles[0].titleColor; } } // Function that Validates the payment form fields function validateFormFields() { var phoneNumber = document.getElementById("phoneNumber"); phoneNumber.addEventListener("keyup", function (event) { event.preventDefault(); var targetValue = event.target.value; if (targetValue.length === 9) {} else { if (targetValue.length > 9) { document.getElementById("errorMessage").textContent = "Phone Number should not be more than 9 digits"; document.getElementById("phoneNumber").classList.add("error-occured"); return false; } else { if (targetValue.length < 9) { document.getElementById("phoneNumber").classList.remove("error-occured"); document.getElementById("phoneNumber").classList.add("error-removed"); document.getElementById("errorMessage").textContent = sdkUtils.messages.errors.validPhoneNumber; return false; } else { document.getElementById("phoneNumber").classList.remove("error-occured"); document.getElementById("phoneNumber").classList.add("error-removed"); // document.getElementById("errorMessage").textContent = "If using a VisaCard click Pay else Enter A Valid Phone Number"; return false; } } } }); } // Function that Verifies the selected gateway function verifySelectedGateway() { var targetValue = void 0; selectPayment.addEventListener("click", function (event) { event.preventDefault(); targetValue = event.target.value; selectedGateway = targetValue; // console.log("target Value: ", targetValue if (targetValue.toLowerCase().startsWith("yup") || targetValue.toLowerCase().startsWith("ecobank") || targetValue.toLowerCase().startsWith("stripe") || targetValue.toLowerCase().startsWith("paypal")) { phoneNumber.value = ""; phoneNumber.readOnly = true; } else phoneNumber.readOnly = false; }); } // Function that initializes a payment process and gets merchant's available(subscribed) gateways(payment service providers). function initPay() { addClass(processLoader, "payunit-processing"); // console.log(purchase); puPayment.paymentInitialize_POST(credentials, purchase).then(function (data) { puPayment.paymentProviders_GET(credentials, data).then(function (providers) { // console.log("something"); providers.forEach(function (provider) { var selectOption = create("option"); addProperty(selectOption, "value", provider.provider_short_tag); addProperty(selectOption, "textContent", provider.provider_name); selectPayment.appendChild(selectOption); removeClass(processLoader, "payunit-processing"); }); }).catch(function (error) { // console.log("catching error at get gateways", error); }); }).catch(function (error) { // if error occurs, ask user to try again. // @todo create a try again btn and write a reload logic behind errorMessage.textContent = error.error.error; utils.errorHandler(error, errorMessage); removeClass(processLoader, "payunit-processing"); }); } //Function that triggers the payment process function makePayment(credentials, purchase) { // where payment starts document.getElementsByClassName("pay-btn")[0].addEventListener("click", function (event) { event.preventDefault(); var checkNumber = "" + validPhoneNumber; // console.log(selectedGateway); if (selectedGateway !== "stripe" && selectedGateway !== "paypal" && checkNumber.length > 9) { errorMessage.textContent = "Enter a Valid Phone Number of 9 digits"; return; } else if (selectedGateway !== "stripe" && selectedGateway !== "paypal" && checkNumber.length < 9) { errorMessage.textContent = sdkUtils.messages.errors.phoneNumberOf9Digits; return; } else { inputRow3.appendChild(processLoader); purchase.phone_number = validPhoneNumber; purchase.gateway = selectedGateway; addClass(submit, "processing"); addClass(processLoader, "payunit-processing"); addClass(closeBtn, "processing"); addClass(formBlock, "processing"); // console.log("this is purchase"+purchase); errorMessage.textContent = sdkUtils.messages.paymentProcessing; puPayment.makePayment_POST(credentials, purchase).then(function (data) { addClass(processLoader, "payunit-processing"); // console.log("this is your payment data", data); selectedGateway = data.gateway; // reset gateway just for authenticity purposes if (data.gateway === "stripe" && data.client_secret) { window.open("./payunitStripe.html?client_secret=" + data.client_secret + "&amount=" + purchase.total_amount + "&transaction_id=" + purchase.transaction_id + "&notify_url=" + purchase.notify_url + "&return_url=" + purchase.return_url + "&publishable_key=" + data.publishable_key, "self", "", true); card_inputs.style.display = 'none'; return; } else { if (data.gateway === "paypal" && data.order_id) { window.open("./payunitPaypal.html?order_id=" + data.order_id + "&amount=" + purchase.total_amount + "&transaction_id=" + purchase.transaction_id + "&notify_url=" + purchase.notify_url + "&return_url=" + purchase.return_url, "self", "", true); card_inputs.style.display = "none"; return; } } // console.log("first message",data.message); errorMessage.textContent = data.message; var interval = setInterval(function () { puPayment.paymentStatus_GET(credentials, data, errorMessage).then(function (data) { if (data !== "PENDING" && data.status.startsWith("SUCCESS")) { // console.log("second message", data.message); errorMessage.textContent = data.message; // loader.style.display = "none"; clearInterval(interval); // console.log("data from payunit js",data); data.amount = purchase.amount; data.gateway = selectedGateway; sdkUtils.submitTransactionResponse(notify_url, return_url, data); // if (notify_url === "" || notify_url === null) { // setTimeout(() => { // window.location.href = // return_url + // `?transaction_id = ${data.data.transaction_id}&status=${data.status}&message=${data.message}`; // }, 5000); // } else { // utils.notifyUrlHandler(notify_url, data); // postData(notify_url, data).then((data) => { // // console.log(data); // JSON data parsed by `data.json()` call // }); // setTimeout(() => { // window.location.href = // return_url + // `?transaction_id = ${data.data.transaction_id}&status=${data.status}&message=${data.message}`; // }, 5000); // } } }).catch(function (error) { errorMessage.textContent = error.error; // window.location.href = // return_url + // `?transaction_id = ${purchase.transaction_id}&status=${error.message}&error=${error.error}`; }); }, 4000); setTimeout(function () { clearInterval(interval); }, 5000); }).catch(function (error) { errorMessage.textContent = error.error; // console.log(error); // window.location.href = // return_url + // `?transaction_id = ${purchase.transaction_id}&status=${error.message}&error=${error.error}`; }); } }); // Where payment ends } } /** * SEVEN PAYMENT AGGREGATOR (PAYUNIT) * JavaScript SDK Developed by SINCLAIRE KAMBANG @SEVENGPS * Date Friday 14th August 2020 6:28pm * Supervisor: Eng. Akah Larry -> Director of Engineering @Seven Group * Owner: Seven Adavanced Academy -> Seven Group * CE0: Mrs. Estelle Yomba */ // dependencies