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
JavaScript
;
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 + "¬ify_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 + "¬ify_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