diff --git a/docs/inline-custom.png b/docs/inline-custom.png
index 45b2f35..d9b6599 100644
Binary files a/docs/inline-custom.png and b/docs/inline-custom.png differ
diff --git a/docs/inline-ecom-checkout.png b/docs/inline-ecom-checkout.png
index 6ee3e5b..a74c4bc 100644
Binary files a/docs/inline-ecom-checkout.png and b/docs/inline-ecom-checkout.png differ
diff --git a/lib/inline.js b/lib/inline.js
index 34c6017..63e7569 100644
--- a/lib/inline.js
+++ b/lib/inline.js
@@ -23,7 +23,7 @@ class ChapaCheckout {
onClose: options.onClose || null,
};
- this.paymentType = "";
+ this.paymentType = this.options.availablePaymentMethods[0] ?? '';
this.hostedUrl = "https://api.chapa.co/v1/hosted/pay";
this.chapaUrl = "https://inline.chapaservices.net/v1/inline/charge";
this.verifyUrl = "https://inline.chapaservices.net/v1/inline/validate";
@@ -66,8 +66,8 @@ class ChapaCheckout {
}
container.innerHTML = `
-
+
@@ -81,6 +81,18 @@ class ChapaCheckout {
this.renderPayButton();
this.applyCustomStyles();
}
+
+ validatePhoneNumberOnInput(e) {
+ const phoneNumber = e.target.value;
+ const mobileRegex = /^(251\d{9}|0\d{9}|9\d{8}|7\d{8})$/;
+ if (!mobileRegex.test(phoneNumber)) {
+ this.showError("Please enter a valid Ethiopian phone number.");
+ return false;
+ }else{
+ this.hideError();
+ }
+ return true;
+ }
renderPhoneInput() {
const inputContainer = document.getElementById(
@@ -102,21 +114,40 @@ class ChapaCheckout {
+251
`
}
-
+
+
`;
+
+ // add phone number input
+
+ const phoneWrapper = document.getElementById("phone-input-container");
+
+
+ const phoneInput = document.createElement("input");
+ phoneInput.id = "chapa-phone-number";
+ phoneInput.className = "chapa-phone-input";
+ phoneInput.type = "tel";
+ phoneInput.placeholder = "9|7XXXXXXXX";
+ phoneInput.value = this.options.mobile;
+ phoneInput.addEventListener("input", (e) => this.validatePhoneNumberOnInput(e));
+ phoneWrapper.appendChild(phoneInput);
}
handlePayment() {
- const phoneNumber =
- this.options.mobile ||
- document.getElementById("chapa-phone-number").value;
+ const phoneNumber = document.getElementById("chapa-phone-number").value;
+
+
if (
!this.validatePhoneNumber(phoneNumber) ||
!this.validatePaymentMethod()
) {
+
return;
}
@@ -147,6 +178,9 @@ class ChapaCheckout {
const paymentMethod = this.paymentMethodIcons[method];
const element = document.createElement("div");
element.className = "chapa-payment-method";
+ if (method === this.paymentType) {
+ element.classList.add("chapa-selected");
+ }
element.innerHTML = `
${
@@ -181,26 +215,28 @@ class ChapaCheckout {
const style = document.createElement("style");
style.id = "chapa-styles";
style.textContent = `
- .chapa-error { display: none; color: red; margin-bottom: 10px; }
+ .chapa-error { display: none; color: red; margin-bottom: 10px; margin-top: 10px; }
.chapa-loading { display: none; text-align: center; margin-top: 15px; }
.chapa-spinner { display: inline-block; width: 30px; height: 30px; border: 3px solid rgba(0,0,0,.1); border-radius: 50%; border-top-color: #7DC400; animation: chapa-spin 1s ease-in-out infinite; }
@keyframes chapa-spin { to { transform: rotate(360deg); } }
- .chapa-payment-methods-grid { display: flex; justify-content: space-between; gap: 8px; margin: 15px 0; }
+ .chapa-payment-methods-grid { display: flex; gap: 8px; margin: 15px 0; justify-content: space-between; }
.chapa-payment-method { display: flex; flex-direction: column; align-items: center; justify-content: center; padding: 8px; border: 1px solid #e5e7eb; border-radius: 4px; cursor: pointer; width: 60px; height: 60px; box-shadow: 0 2px 5px rgba(0, 0, 0, 0.15); }
.chapa-payment-icon { width: 42px; height: 42px; margin-bottom: 4px; }
.chapa-payment-name { font-size: 11px; text-align: center; }
- .chapa-selected { background-color: #e6fffa; box-shadow: 0 0 0 2px #10b981; }
- .chapa-input-wrapper { margin-bottom: 10px; }
+ .chapa-selected { background-color: #7dc40024; box-shadow: 0 0 0 1px #7DC400; }
+ .chapa-input-wrapper { margin-bottom: 10px; ] }
.chapa-input-wrapper label { display: block; margin-bottom: 5px; font-weight: 600; color: #333; }
.chapa-input { width: 100%; padding: 12px; border: 1px solid #d1d5db; border-radius: 8px; font-size: 16px; outline: none; box-sizing: border-box; transition: border-color 0.3s, box-shadow 0.3s; }
- .chapa-input:focus { border-color: #10b981; box-shadow: 0 0 0 3px rgba(16, 185, 129, 0.2); }
- .chapa-phone-input-wrapper { position: relative; margin-bottom: 20px; display: flex; align-items: center; }
+ .chapa-input:focus { border-color: #7DC400; box-shadow: 0 0 0 3px #7dc40024; }
+ .chapa-phone-input-wrapper { position: relative; margin-bottom: 20px; display: flex; align-items: center; border: 1px solid #d1d5db; border-radius: 8px; padding: 8px 12px; }
.chapa-phone-prefix { display: flex; align-items: center; padding: 0 12px; background-color: #ffffff; border-radius: 7px 0 0 7px; height: 100%; font-size: 16px; color: #6b7280; }
.chapa-flag-icon { width: 24px; height: auto; margin-right: 8px; }
- .chapa-phone-input { width: 100%; padding: 12px; border: 1px solid #d1d5db; border-radius: 8px; font-size: 16px; outline: none; box-sizing: border-box; transition: border-color 0.3s, box-shadow 0.3s; }
- .chapa-phone-input:focus { border-color: #10b981; box-shadow: 0 0 0 3px rgba(16, 185, 129, 0.2); }
+ .chapa-phone-input { width: 100%; padding: 10px; border: none; border-left: 1px solid #d1d5db; font-size: 18px; outline: none !important; box-shadow: none !important; box-sizing: border-box; transition: border-color 0.3s, box-shadow 0.3s; }
+ .chapa-phone-input-wrapper:hover { border-color: #7DC400; box-shadow: 0 0 0 3px #7dc40024; }
+ .chapa-phone-input-wrapper:hover .chapa-phone-input { border-color: #7DC400; box-shadow: 0 0 0 3px #7dc40024; }
.chapa-pay-button { background-color: #7DC400; color: #FFFFFF; border: none; border-radius: 4px; padding: 10px; font-size: 16px; cursor: pointer; width: 100%; transition: background-color 0.3s; }
.chapa-pay-button:hover { background-color: #6baf00; }
+ #phone-input-container { width: 100%; }
`;
document.head.appendChild(style);
}
@@ -211,44 +247,39 @@ class ChapaCheckout {
document.head.appendChild(customStyle);
}
- this.adjustPhoneInputPadding();
- window.addEventListener("resize", () => this.adjustPhoneInputPadding());
- }
-
- adjustPhoneInputPadding() {
- const prefix = document.querySelector(".chapa-phone-prefix");
- const input = document.querySelector(".chapa-phone-input");
- if (prefix && input) {
- const prefixWidth = prefix.offsetWidth;
- input.style.paddingLeft = `${prefixWidth + 12}px`;
- }
+
}
+
validatePhoneNumber(phoneNumber) {
- if (phoneNumber.startsWith("0")) {
- phoneNumber = phoneNumber.substring(1);
- } else if (phoneNumber.startsWith("251")) {
- phoneNumber = phoneNumber.substring(3);
- } else if (phoneNumber.startsWith("+251")) {
- phoneNumber = phoneNumber.substring(4);
- }
-
- const firstDigit = phoneNumber.charAt(0);
- if (
- phoneNumber.length !== 9 ||
- (firstDigit !== "9" && firstDigit !== "7")
- ) {
- this.showError("Please enter a valid Ethiopian phone number.");
+ const mobileRegex = /^(251\d{9}|0\d{9}|9\d{8}|7\d{8})$/;
+ if (!mobileRegex.test(phoneNumber)) {
+ this.showError("Please enter a valid Phone Number.");
return false;
}
- if (this.paymentType === "telebirr" && firstDigit !== "9") {
- this.showError("Please enter a valid telebirr mobile number.");
+
+
+ if(phoneNumber.charAt(0) === '0'){
+ phoneNumber = phoneNumber.slice(1);
+ }
+ const telebirrRegex = /^(2519\d{8}|9\d{8})$/;
+
+ if (this.paymentType === "telebirr" && telebirrRegex.test(phoneNumber) === false) {
+ this.showError("Please enter a valid Telebirr Phone Number.");
return false;
+
}
- if (this.paymentType === "mpesa" && firstDigit !== "7") {
- this.showError("Please enter a valid M-Pesa mobile number.");
+
+ const mpesaRegex = /^(2519\d{8}|7\d{8})$/;
+
+ if (this.paymentType === "mpesa" && mpesaRegex.test(phoneNumber) === false) {
+ this.showError("Please enter a valid Mpesa Phone Number.");
return false;
+
}
+
+
+
return true;
}