Payment is the heart of any ecommerce website. The user assumes a smooth transition from the cart to payment page which should show all the items pushed to the cart. Its becoming common to use rich features such as timeout, card visual animation, card tokenization, card validation and purchase button activation. In this, we will discuss each rich feature along with cart abandonment and restrict duplicate payments.
This is a very simple payment page designed with bootstrap 5. This requires downloading your own credit card logos and update it based using CSS sprite sheet technique. There is a count down timer in the middle which can be used to reset the fields after a certain timeout.
The right column looks like a ticket for which, I've used to show the cart items and the subtotal.
.form-control {
min-height:48px;
border-radius:8px;
}
button.btn {
min-height:54px;
}
#cartTable td {
padding:6px;
}
#cartTable td:nth-of-type(2){
text-align:right
}
#ticket:before {
content:"";
background:#fff;
width:32px;
height:32px;
position:absolute;
top:-16px;
left:-16px;
border-radius:100%;
}
#ticket:after {
content:"";
background:#fff;
width:32px;
height:32px;
position:absolute;
top:-16px;
right:-16px;
border-radius:100%;
}
#ticket {
background:#dde8f0;
border-top:1px dashed #bdbdbd;
position:relative;
border-bottom-left-radius:12px;
border-bottom-right-radius:12px;
}
#cardNumber {
padding-right:60px;
}
#cardType {
width:58px;
height:36px;
background:url('/static_files/images/cardLogos.png') no-repeat;
background-size:auto 100%;
background-position: -59px;
position:absolute;
right:10px;
top:5px;
}
<div class="p-4">
<div class="container">
<div class="row g-5">
<div class="col-md-8 col-sm-6 col-xs-12">
<div class="p-2">
<div class="d-flex justify-content-between align-items-center">
<div><img src="/static_files/images/logos/dbPay.jpg" alt="Payment Logo" height="48" ></div>
<div>
<span class="badge p-2 fs-5 bg-dark">0</span><span style="margin-left:2px" class="badge p-2 fs-5 bg-dark" >0</span>
<span class="fs-5">:</span> <span class="badge p-2 fs-5 bg-dark">0</span><span style="margin-left:2px" class="badge p-2 fs-5 bg-dark" >0</span>
</div>
</div>
<div class="mt-5">
<div>
<label class="d-block" for="cardNumber"><strong>Card Number</strong></label>
<small class="text-secondary">Enter the 16 - digit number printed on the card </small>
<div class="position-relative">
<input type="text" id="cardNumber" class="form-control mt-3"><span id="cardType"></span>
</div>
</div>
<div class="mt-5">
<div class="row align-items-center">
<div class="col-sm-6 col-xs-12">
<label class="d-block" for="cvv"><strong>CVV Number</strong></label>
<small class="text-secondary">Enter the 3 or 4 digit number printed at back of the card </small>
</div>
<div class="col-sm-6 col-xs-12">
<input type="text" id="cvv" class="form-control">
</div>
</div>
</div>
<div class="mt-5">
<div class="row align-items-center">
<div class="col-sm-6 col-xs-12">
<label class="d-block" for="expiry_mm"><strong>Expiry Date</strong></label>
<small class="text-secondary">Enter the expiration date of the card </small>
</div>
<div class="col-sm-6 col-xs-12">
<div class="d-flex align-items-center">
<input type="text" id="expiry_mm" class="form-control">
<span class="fs-4 mx-3">/</span>
<input type="text" id="expiry_yy" class="form-control">
</div>
</div>
</div>
</div>
<div class="mt-5">
<div class="row align-items-center">
<div class="col-sm-6 col-xs-12">
<label class="d-block" for="postal"><strong>Postal (Zip) Code</strong></label>
<small class="text-secondary">Enter the postal / Zip code of billing address </small>
</div>
<div class="col-sm-6 col-xs-12">
<div class="d-flex align-items-center">
<input type="text" id="postal" class="form-control">
</div>
</div>
</div>
</div>
<button class="btn btn-primary mt-5 w-100">Pay Now</button>
</div>
</div>
</div>
<div class="col-md-4 col-sm-6 col-xs-12">
<div style="background:#eff4f8;border-radius:16px;">
<div class="p-4">
<table class="w-100" id="cartTable">
<tr>
<td><span class="text-secondary">Order #</span></td>
<td><strong>231197</strong></td>
</tr>
<tr>
<td><span class="text-secondary">Product</span></td>
<td><strong>QR Verify</strong></td>
</tr>
<tr>
<td><span class="text-secondary">Tax (10%)</span></td>
<td><strong>12.00</strong></td>
</tr>
<tr>
<td><span class="text-secondary">Total</span></td>
<td><strong class="text-primary">$ 132.00</strong></td>
</tr>
</table>
<hr>
<table class="w-100" id="cartTable">
<tr>
<td><span class="text-secondary">Order #</span></td>
<td><strong>231198</strong></td>
</tr>
<tr>
<td><span class="text-secondary">Product</span></td>
<td><strong>DB Subscription</strong></td>
</tr>
<tr>
<td><span class="text-secondary">Tax (10%)</span></td>
<td><strong>12.88</strong></td>
</tr>
<tr>
<td><span class="text-secondary">Total</span></td>
<td><strong class="text-primary">$ 422.88</strong></td>
</tr>
</table>
</div>
<div id="ticket">
<div class="d-flex p-4 align-items-center justify-content-between">
<div>
<small class="text-secondary">You Have to Pay</small>
<div class="fs-2"><strong>$554.88</strong></div>
</div>
<div>
<img src="/static_files/svgs/shop.svg" width="48" alt="">
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
The beauty about this layout is within its simplicity. A simple javascript function creates a rich feature of card live update as soon as the user being entering. Similar to the previous template, it show the card logo based on sprite sheet technique. To validate the card, see this rich feature.
#formWrap {
z-index:2;
margin-top:-96px;
border-radius:18px;
border:1px solid #e4e4e4;
border-top:12px solid #e4e4e4;
}
#cardDesign {
border-radius:12px;
background:#232323;
color:#fff;
margin:0px 20px 0px 20px;
z-index:3
}
#cardLogo {
background:url('/static_files/images/cardLogos.png') no-repeat;
width:52px;
height:32px;
background-size:auto 100%;
background-position:-52px
}
#visualName {
max-width:220px;
text-overflow:ellipsis;
white-space:nowrap;
overflow:hidden;
display:block;
}
button.btn {
height:64px;
}
<div class="container">
<div class="row">
<div class="col-sm-4 mx-auto my-5">
<div id="cardDesign" class="position-relative shadow p-4">
<div class="d-flex align-items-center justify-content-between">
<div class="fs-4"><strong>$8228.22</strong></div>
<div><img src="/static_files/svgs/wifi.svg" alt="Wifi Svg" width="24" style="transform:rotate(90deg);filter: invert(1)"></div>
</div>
<div class="mt-4 fs-3" id="visualCC">**** **** **** ****</div>
<div><small class="text-secondary">Valid Thru <span id="visualMM">**</span> / <span id="visualYY">**</span></small></div>
<div class="mt-3">
<div class="d-flex justify-content-between align-items-center">
<div class="text-warning fs-5"><strong id="visualName">XXXX X X</strong></div>
<div id="cardLogo"></div>
</div>
</div>
</div>
<div class="p-4 shadow bg-white position-relative" id="formWrap">
<div class="p-5"></div>
<form action="">
<div class="form-floating">
<input type="text" onkeyup="updateCard(this,'visualCC')" class="form-control" id="cardNumber">
<label for="cardNumber">Card Number</label>
</div>
<div class="form-floating mt-4">
<input type="text" onkeyup="updateCard(this,'visualName')" class="form-control" id="cardName">
<label for="cardName">Name On Card</label>
</div>
<div class="row mt-2 g-3">
<div class="col">
<div class="form-floating">
<input type="text" class="form-control" id="expiryMonth" onkeyup="updateCard(this,'visualMM')">
<label for="expiryMonth">Expiry(mm)</label>
</div>
</div>
<div class="col">
<div class="form-floating">
<input type="text" class="form-control" id="expiryYear" onkeyup="updateCard(this,'visualYY')">
<label for="expiryYear">Expiry(yy)</label>
</div>
</div>
</div>
<div class="row mt-2 g-3">
<div class="col">
<div class="form-floating">
<input type="text" class="form-control" id="CVV">
<label for="CVV">CVV</label>
</div>
</div>
<div class="col">
<div class="form-floating">
<input type="text" class="form-control" id="zip">
<label for="zip">Postal / Zip code</label>
</div>
</div>
</div>
<div class="mt-3">
<button class="btn btn-primary w-100" type="submit">Pay Now</button>
</div>
<div class="text-center mt-3 text-secondary">
<small>🔒 Protected By XYZ end-to-end encryption service</small>
</div>
</form>
</div>
</div>
</div>
</div>
function updateCard(t,id){
var elem = document.getElementById(id)
if(t.value !== "") elem.innerText = t.value
}
Again, a minimalist ui with option to switch between multiple payments. In this example, you can switch between a credit card payment and an ACH.
<div class="container">
<div class="row">
<div class="col-sm-4 col-xs-8 mx-auto">
<div class="border shadow my-4 p-5">
<div class="d-flex align-items-center justify-content-between">
<div><img src="/static_files/images/logos/dbPay.jpg" alt="DB Pay logo" height="48"></div>
<div class="fs-4" style="font-family:impact"><strong><span class="text-secondary">$</span> 8,822.82</strong></div>
</div>
<div class="my-4">
<input type="radio" onchange="toggleForm('credit')" name="chargeType" id="creditCard" checked> <label class="text-primary" for="creditCard"><strong>Credit Card</strong></label>
<input class="ms-3" onchange="toggleForm('bank')" type="radio" name="chargeType" id="ach"> <label class="text-primary" for="ach"><strong>Bank ACH</strong></label>
</div>
<form action="">
<div id="formType">
</div>
<button class="mt-4 btn-primary btn btn-lg w-100">Proceed</button>
</form>
</div>
</div>
</div>
</div>
window.addEventListener('load',toggleForm('credit'))
function toggleForm(e){
document.getElementById('formType').innerHTML = e === 'credit' ? `<div class="form-floating mt-3">
<input id="nameOnCard" type="text" class="form-control">
<label for="nameOnCard">Name On Card</label>
</div>
<div class="form-floating mt-3">
<input id="cardNumber" type="text" class="form-control">
<label for="cardNumber">Card Number</label>
</div>
<div class="row g-3">
<div class="col">
<div class="form-floating mt-3">
<input id="expiry_mm" type="text" class="form-control">
<label for="expiry_mm">Expiry (mm)</label>
</div>
</div>
<div class="col">
<div class="form-floating mt-3">
<input id="cvv" type="text" class="form-control">
<label for="cvv">CVV</label>
</div>
</div>
</div>` : `<div class="form-floating mt-3">
<input id="accountHolder" type="text" class="form-control">
<label for="accountHolder">Name of Account Holder</label>
</div>
<div class="form-floating mt-3">
<input id="routing" type="text" class="form-control">
<label for="routing">Routing Number</label>
</div>
<div class="form-floating mt-3">
<select name="accountType" id="accountType" class="form-control">
<option value="checking">Checking</option>
<option value="savings">Savings</option>
</select>
<label for="accountType">Account Type</label>
</div>`
}
Suitable for platforms that accepts more than one type of payment methods. In this, we have payment by credit card, paypal and UPI (common in India). Upon selecting each method, the form will be displayed in the mode of quick accordion which can be replaced with a smooth reveal using jQuery's hide / show classes.
<div class="container">
<div class="row">
<div class="col-sm-4 col-xs-8 mx-auto">
<div class="border shadow my-4 p-5">
<div class="d-flex align-items-center justify-content-between">
<div><img src="/static_files/images/logos/dbPay.jpg" alt="DB Pay logo" height="48"></div>
<div class="fs-4" style="font-family:impact"><strong><span class="text-secondary">$</span> 8,822.82</strong></div>
</div>
<div class="my-4">
<input type="radio" onchange="toggleForm('credit')" name="chargeType" id="creditCard" checked> <label class="text-primary" for="creditCard"><strong>Credit Card</strong></label>
<input class="ms-3" onchange="toggleForm('bank')" type="radio" name="chargeType" id="ach"> <label class="text-primary" for="ach"><strong>Bank ACH</strong></label>
</div>
<form action="">
<div id="formType">
</div>
<button class="mt-4 btn-primary btn btn-lg w-100">Proceed</button>
</form>
</div>
</div>
</div>
</div>
window.addEventListener('load',toggleForm('credit'))
function toggleForm(e){
document.getElementById('formType').innerHTML = e === 'credit' ? `<div class="form-floating mt-3">
<input id="nameOnCard" type="text" class="form-control">
<label for="nameOnCard">Name On Card</label>
</div>
<div class="form-floating mt-3">
<input id="cardNumber" type="text" class="form-control">
<label for="cardNumber">Card Number</label>
</div>
<div class="row g-3">
<div class="col">
<div class="form-floating mt-3">
<input id="expiry_mm" type="text" class="form-control">
<label for="expiry_mm">Expiry (mm)</label>
</div>
</div>
<div class="col">
<div class="form-floating mt-3">
<input id="cvv" type="text" class="form-control">
<label for="cvv">CVV</label>
</div>
</div>
</div>` : `<div class="form-floating mt-3">
<input id="accountHolder" type="text" class="form-control">
<label for="accountHolder">Name of Account Holder</label>
</div>
<div class="form-floating mt-3">
<input id="routing" type="text" class="form-control">
<label for="routing">Routing Number</label>
</div>
<div class="form-floating mt-3">
<select name="accountType" id="accountType" class="form-control">
<option value="checking">Checking</option>
<option value="savings">Savings</option>
</select>
<label for="accountType">Account Type</label>
</div>`
}
Suitable for payment page of insurance products. It also has place to show the saved cards and selected car will highlighted in black as shown.
.cardStyle {
width:340px;
border-radius:12px;
}
.selectBox {
border:1px solid #222;
width:24px;
height:24px;
text-align:center;
border-radius:50%;
line-height:22px;
font-size:12px;
}
.selected {
color:#fff;
border:1px solid #f7f7f7 !important;
}
small {
font-size:12px;
letter-spacing:1px;
}
label,
h6 {
font-size:12px;
text-transform : uppercase;
color:#aaaaaa
}
a.btn {
line-height:32px;
}
a.btn,
button.btn,
select.form-control,
input.form-control {
height:48px;
border-radius:2px;
}
<div class="bg-light py-4">
<div class="container">
<div class="row">
<div class="col-lg-9 col-md-8 col-sm-6 col-xs-12">
<h4>Payment Info</h4>
<div class="shadow-sm bg-white p-4 my-4">
<h6 class="mb-4">Your Saved Cards</h6>
<div class="d-flex">
<div class="shadow cardStyle p-3 bg-black">
<div class="d-flex align-items-center justify-content-between">
<div class="text-light">VISA</div>
<div class="selectBox selected">✓</div>
</div>
<div class="my-3">
<div><small class="text-secondary">CARD NYUMBER</small></div>
<div class="fs-4 text-info">**** **** **** 2288</div>
</div>
<div class="my-3">
<div class='d-flex align-items-center justify-content-between'>
<div>
<div><small class="text-secondary">CARD HOLDER</small></div>
<div class="text-white">John Doe P W</div>
</div>
<div>
<div><small class="text-secondary">EXPIRY</small></div>
<div class="text-light">02/28</div>
</div>
</div>
</div>
</div>
<div class="ms-4 shadow cardStyle p-3 bg-white">
<div class="d-flex align-items-center justify-content-between">
<div class="text-secondary">MC</div>
<div class="selectBox"></div>
</div>
<div class="my-3">
<div><small class="text-secondary">CARD NYUMBER</small></div>
<div class="fs-4 text-dark">**** **** **** 8822</div>
</div>
<div class="my-3">
<div class='d-flex align-items-center justify-content-between'>
<div>
<div><small class="text-secondary">CARD HOLDER</small></div>
<div class="text-dark">John Doe P W</div>
</div>
<div>
<div><small class="text-secondary">EXPIRY</small></div>
<div class="text-dark">08/22</div>
</div>
</div>
</div>
</div>
</div>
<form action="">
<div class="col-sm-6 mt-5">
<label for="cardName">Name on the card</label>
<input type="text" id="cardName" class="form-control my-1">
</div>
<div class="col-sm-8 mt-4">
<label for="cardNumber">Card Number</label>
<input type="text" id="cardNumber" class="form-control my-1">
</div>
<div class="row">
<div class="col-sm-3 col-xs-6 mt-4">
<label for="expiry">Card Expiry (mm/yy)</label>
<input type="text" id="expiry" class="form-control my-1">
</div>
<div class="col-sm-3 col-xs-6 mt-4">
<label for="cvv">CVV</label>
<input type="text" id="cvv" class="form-control my-1">
</div>
</div>
<div class="row">
<div class="col-sm-4 col-xs-12 mt-4">
<label for="insuranceTerm">Choose term</label>
<select name="" id="insuranceTerm" class="form-control my-1">
<option value="">1 Year</option>
<option value="">3 Years</option>
<option value="">5 Years</option>
</select>
</div>
<div class="col-sm-4 col-xs-6 mt-4">
<label for="schedule">Payment Schedule</label>
<select name="" id="schedule" class="form-control my-1">
<option value="">Quarterly</option>
<option value="">Half Yearly</option>
<option value="">Full (15% Discount)</option>
</select>
</div>
<div class="col-sm-4 col-xs-6 mt-4">
<label for="nominee">Nominee Name</label>
<input type="text" id="nominee" class="form-control my-1">
</div>
</div>
<div class="my-3">
<small class="text-secondary">I authorize some insurance company to charge my debit / credit card for the total amount of xxx.xx</small>
</div>
<div class="mt-5 mb-3">
<div class="row">
<div class="col">
<a href="javascript:goBack()" class="btn btn-outline-secondary w-100">Go Back</a>
</div>
<div class="col">
<button role="button" type="submit" class="btn btn-primary w-100">Charge</button>
</div>
</div>
</div>
</form>
</div>
</div>
<div class="col-lg-3 col-md-4 col-sm-6 col-xs-12">
<h4>Purchase Summary</h4>
<div class="shadow-sm bg-white p-4 mt-4 mb-3">
<h5 class="h6"><strong>Policy Info</strong></h5>
<table class="w-100 mt-3">
<tr>
<td>Policy #</td>
<td>:</td>
<td><strong class="ms-2">1624-22-88</strong></td>
</tr>
<tr>
<td>Members</td>
<td>:</td>
<td><strong class="ms-2">4</strong></td>
</tr>
</table>
</div>
<div class="shadow-sm bg-white p-4 mb-3">
<h5 class="h6"><strong>Coverage</strong></h5>
<table class="w-100 mt-3">
<tr>
<td>Your Coverage</td>
<td>:</td>
<td><strong class="ms-2">Full</strong></td>
</tr>
<tr>
<td>Validity</td>
<td>:</td>
<td><strong class="ms-2">08/22/2022</strong></td>
</tr>
</table>
</div>
<div class="shadow-sm bg-white mb-3">
<div class="px-4 py-2 bg-danger text-white">
Discount Valid until : <strong>12:22 mins</strong>
</div>
<div class="p-4">
<h5 class="h6"><strong>Price Breakup</strong></h5>
<table class="w-100 mt-3">
<tr>
<td>Reg Price</td>
<td>:</td>
<td><strong class="ms-2">$11,900</strong></td>
</tr>
<tr>
<td>Tax</td>
<td>:</td>
<td><strong class="ms-2">$1,00</strong></td>
</tr>
<tr>
<td>Discount</td>
<td>:</td>
<td><strong class="ms-2">$1,000</strong></td>
</tr>
<tr>
<td colspan="3"><hr /></td>
</tr>
<tr>
<td>Total</td>
<td>:</td>
<td><strong class="ms-2 text-success">$11,000</strong></td>
</tr>
<tr>
<td colspan="3"><hr /></td>
</tr>
</table>
<div>
<div class="text-secondary"><span class="badge bg-secondary me-2">big2022</span> Offer applied</div>
<div class="text-secondary my-2">Secure payment</div>
<div class="text-secondary">30 day money back gaurantee</div>
</div>
</div>
<div class="p-4 border-top">
<h6><strong>Do you have a code? <a href="#">Click here</a></strong></h6>
</div>
</div>
</div>
</div>
</div>
</div>
Suitable for payment page of utility products or credit card payment. It has option to select a default amount or a custom amount which is generally the case for utilities. Payment method is by already saved card and a button to add new card is also available.
.customRounded {
border-radius:12px;
}
input[type="radio"] {
width:18px;
height:18px;
}
<div class="bg-light py-5">
<div class="container">
<div class="row">
<div class="col-sm-5 mx-auto">
<div class="bg-white customRounded shadow-sm">
<div class="p-3 border-bottom">Pay By Card</div>
<div class="p-4">
<h6 class="mx-3 mb-3 text-secondary">Amount</h6>
<div class="border customRounded">
<div class="d-flex align-items-center justify-content-between p-3 customRounded">
<div>
<input type="radio" name="amount" id="customAmount"> <label for="customAmount" class="align-text-bottom ms-3">Enter Amount</label>
</div>
<div class="border p-2 customRounded" style="max-width:68px"><input type="text" class="text-center form-control border-0 p-0" placeholder="$0.00"></div>
</div>
<div class="border-top d-flex align-items-center justify-content-between p-3 ">
<div>
<input type="radio" name="amount" id="customAmount" checked> <label for="customAmount" class="align-text-bottom ms-3">Enter Amount</label>
</div>
<div class="p-2" ><strong>$288.00</strong></div>
</div>
</div>
</div>
<div class="px-4 pb-4">
<h6 class="mx-3 mb-3 text-secondary">Payment Method</h6>
<div class="border customRounded">
<div class="d-flex align-items-center justify-content-between p-3 customRounded">
<div class="d-flex align-items-center">
<input type="radio" name="paymentMethood" id="customAmount" checked>
<label for="customAmount" class="ms-3">
<strong>Ending With : **** 2288</strong><br />
<small class="text-secondary">Last used : 4 days ago</small>
</label>
</div>
<div>
<img src="/static_files/images/logos/amex.jpg" alt="Amex Logo" height="28">
</div>
</div>
<div class="border-top d-flex align-items-center justify-content-between p-3 ">
<div class="d-flex align-items-center">
<input type="radio" name="paymentMethood" id="customAmount">
<label for="customAmount" class="ms-3">
<strong>Ending With : **** 2828</strong><br />
<small class="text-secondary">Last used : 4 days ago</small>
</label>
</div>
<div>
<img src="/static_files/images/logos/mastercard.jpg" alt="Amex Logo" height="28">
</div>
</div>
<div class="border-top p-3">
<button class="btn btn-outline-secondary btn-sm">Add New Card</button>
</div>
</div>
<div class="border customRounded p-2 mt-3">
<textarea name="" id="" cols="30" rows="10" class="form-control border-0" placeholder="Message"></textarea>
</div>
<div class="text-end mt-4">
<button class="btn text-secondary w-25">Cancel</button>
<button class="btn btn-primary w-25">Pay</button>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
Yet again, another simple payment with live can animation. The card updates as the user enters the card details. Includes a starter JS file. Extend it to detect the card type and update the logo.
Leave a comment if you want me to add an example with complete functionality..cardStyle {
padding:24px;
border-radius:12px;
box-shadow: 4px 8px 12px rgba(0,0,0,0.1);
max-width:360px;
width:100%;
background: rgb(33,90,201);
background: linear-gradient(90deg, rgba(33,90,201,1) 0%, rgba(70,155,242,1) 42%, rgba(0,159,255,1) 100%);
z-index:6;
position:relative
}
.cardFont {
font-family: 'Roboto Condensed', sans-serif;
letter-spacing:1px;
}
.text-shadow-white {
text-shadow : 2px 3px 1px rgba(85,85,85,0.18)
}
.text-shadow-black {
text-shadow : 1px 1px 2px rgba(0,0,0,0.5)
}
.cardBack {
background: rgb(9,54,140);
background: linear-gradient(90deg, rgba(9,54,140,1) 0%, rgba(8,70,134,1) 42%, rgba(30,85,119,1) 100%);
padding:0px;
position:relative;
z-index:5;
height:220px;
margin-top:-180px;
margin-left:50px;
}
input.form-control {
height:48px;
border-radius:8px;
}
.customRounded {
border-radius:12px;
}
input::placeholder {
color:#aaaaaa !important
}
.btn {
height:48px;
}
a.btn {
line-height:32px;
}
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Roboto+Condensed:wght@400&display=swap" rel="stylesheet">
<div class="w-100 vh-100 bg-light">
<div class="d-flex h-100 align-items-center">
<div class="col-xl-8 col-lg-10 col-md-10 col-sm-10 mx-auto">
<div class="row align-items-center">
<div class="col-md-6 col-sm-12 col-xs-12">
<div class="position-relative">
<div class="cardStyle">
<div class="text-end"><strong>DB BANK</strong></div>
<div class="mt-3 d-flex align-items-center justify-content-between">
<div><img src="/static_files/images/logos/chip.png" alt="Chip" height="32"></div>
<div><img style="transform:rotate(90deg)" src="/static_files/svgs/wifi.svg" alt="Chip" height="24"></div>
</div>
<div class="fs-4 mt-2 cardFont text-shadow-white" id="visualNumber">1234 5678 1234 5678</div>
<div class="row mt-2">
<div class="col"></div>
<div class="col text-shadow-white"><span id="visualMonth">12</span>/<span id="visualYear">24</span></div>
</div>
<div class="text-info text-shadow-black"><strong id="visualName">P John Doe</strong></div>
</div>
<div class="cardStyle cardBack pt-3" >
<div class="mt-4 p-4 bg-black"></div>
<div class="mb-3 bg-white">
<div class="d-flex justify-content-between">
<div class="p-3 bg-white"></div>
<div class="p-3 bg-light"><em id="visualCVV">123</em></div>
</div>
</div>
</div>
</div>
</div>
<div class="col-md-6 col-sm-12 col-xs-12">
<div class="px-4 py-5 bg-white customRounded shadow">
<h4>Payment Details</h4>
<form action="">
<div class="mt-4 mb-3"><input onkeyup="updateCard(this,'visualNumber')" onblur="protect(this,4)" type="text" name="cardNumber" id="cardNumber" placeholder="CARD NUMBER" class="form-control"></div>
<div class="mb-3"><input type="text" onkeyup="updateCard(this,'visualName')" name="cardholderName" id="cardholderName" placeholder="CARD HOLDER NAME" class="form-control"></div>
<div class="row">
<div class="col"><input type="text" onkeyup="updateCard(this,'visualMonth')" placeholder="12" name="month" class="form-control"></div>
<div class="col"><input type="text" onkeyup="updateCard(this,'visualYear')" placeholder="2028" name="year" class="form-control"></div>
<div class="col"><input type="text" onkeyup="updateCard(this,'visualCVV')" placeholder="CVV" name="year" class="form-control"></div>
</div>
<div class="mt-3 d-flex">
<button class="btn btn-primary w-75 me-2">PAY $22.88</button>
<a href="" class="btn btn-outline-primary w-25 ms-2 ">Cancel</a>
</div>
</form>
</div>
</div>
</div>
</div>
</div>
</div>
function updateCard(t,id){
var elem = document.getElementById(id)
var num = t.value
if(id==='visualNumber'){
if(num.length > 16) return t.value = num.substr(0,16)
num = num.toString().match(/.{4}/g) ? num.toString().match(/.{4}/g).join(' ') : num;
}
elem.innerText = num
}
function protect(t,end){
var num = t.value
t.value = num.substr(num.length-4,num.length)
}
Another beautiful UI that looks like a credit card.
#leftPanel {
background: rgb(221,221,221);
background: linear-gradient(259deg, rgba(221,221,221,1) 0%, rgba(255,255,255,1) 100%);
}
#rightPanel {
color:#fff;
background-image: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
}
body {
font-family: 'Hind', sans-serif;
}
h6 {
letter-spacing:1px;
font-weight:600
}
#pricingDollar { font-size:32px; font-weight:300; }
#pricingCents { font-size:18px; margin-left:2px; font-weight:300;}
.subHeading { font-weight:600;letter-spacing:2px; font-size:13px }
input,
select {
background:none;
color:#fff;
padding:8px 0;
font-size:20px;
border:none;
}
input:focus,
select:focus {
background:none;
color:#fff;
outline:none;
}
#cardNumber {
border:1px solid orange;
width:100%;
padding:8px 8px;
}
.singleNumber {
border:1px solid #cecece;
padding:4px;
width:38px;
text-align:center
}
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Hind:wght@300;600&display=swap" rel="stylesheet">
<div class="vh-100 bg-light d-flex align-items-center justify-content-center">
<div class="row w-100">
<div class="col-lg-5 col-md-7 col-sm-10 mx-auto">
<div class="shadow-lg">
<div class="row g-0">
<div class="col-sm-5 col-xs-4" id="leftPanel">
<div class="d-flex flex-column justify-content-between h-100 p-4 m-3 pb-5">
<div class="d-flex align-items-center justify-content-between">
<div><img src="/static_files/svgs/goBack.svg" alt="Go Back Icon" height="16"></div>
<div><img src="/static_files/images/logos/visaT.png" alt="visa Logo Transparent" height="16"></div>
</div>
<div>
<div class="subHeading">TOTAL</div>
<div><span id="pricingDollar">$2,288</span><span id="pricingCents">. 22</span></div>
</div>
<div>
<div class="subHeading">NAME</div>
<div>John Doe Jr</div>
</div>
</div>
</div>
<div class="col-sm-7 col-xs-8" id="rightPanel">
<div class="d-flex flex-column justify-content-between h-100 p-4 m-3 pb-5">
<div>
<div class="subHeading">EXPIRATION</div>
<div class="row">
<div class="col-sm-5 col-xs-4">
<select name="" id="">
<option selected value='1'>Janaury</option>
<option value='2'>February</option>
<option value='3'>March</option>
<option value='4'>April</option>
<option value='5'>May</option>
<option value='6'>June</option>
<option value='7'>July</option>
<option value='8'>August</option>
<option value='9'>September</option>
<option value='10'>October</option>
<option value='11'>November</option>
<option value='12'>December</option>
</select>
</div>
<div class="col-sm-3 col-xs-4">
<select name="" id="">
<option value="1">01</option>
<option value="2">02</option>
<option value="3">03</option>
<option value="4">04</option>
<option value="5">05</option>
<option value="6">06</option>
<option value="7">07</option>
<option value="8">08</option>
<option value="9">09</option>
<option value="10">10</option>
<option value="11">11</option>
<option value="12">12</option>
<option value="13">13</option>
<option value="14">14</option>
<option value="15">15</option>
<option value="16">16</option>
<option value="17">17</option>
<option value="18">18</option>
<option value="19">19</option>
<option value="20">20</option>
<option value="21">21</option>
<option value="22">22</option>
<option value="23">23</option>
<option value="24">24</option>
<option value="25">25</option>
<option value="26">26</option>
<option value="27">27</option>
<option value="28">28</option>
<option value="29">29</option>
<option value="30">30</option>
<option value="31">31</option>
</select>
</div>
<div class="col-sm-4 col-xs-4">
<select name="" id="">
<option value="2022">2022</option>
<option value="2023">2023</option>
<option value="2024">2024</option>
<option value="2025">2025</option>
<option value="2026">2026</option>
<option value="2027">2027</option>
<option value="2028">2028</option>
<option value="2029">2029</option>
<option value="2030">2030</option>
<option value="2031">2031</option>
<option value="2032">2032</option>
</select>
</div>
</div>
</div>
<div class="my-2">
<div class="subHeading mb-3">CARD NUMBER</div>
<input type="text" id="cardNumber">
</div>
<div>
<div class="subHeading mb-3">CVV CODE</div>
<div>
<input type="text" class="singleNumber">
<input type="text" class="mx-2 singleNumber">
<input type="text" class="singleNumber">
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
This example is apt for a single item purchase for whith the UI is page centered and the method of payment is by
credit / debit card. Since this is a bit complex, its only resposive until the md
breakpoint. you
will have to do your own mobile layout using media queries.
.mainBgn {
background: rgb(111,120,148);
background: linear-gradient(86deg, rgba(111,120,148,1) 0%, rgba(57,71,91,1) 100%);
font-family: 'Sora', sans-serif;
font-size:14px;
}
.boldfont {
font-family:impact;
}
#cardFlare {
color:#3a3a3a12;
letter-spacing:2px;
font-size:8em;
line-height:0.8em
}
.lightColor {
color:#eeeeee;
}
.lightColor2 {
color:#aaaaaa;
}
label { text-transform : uppercase; color:#aaaaaa; font-size:12px }
select,
input[type="text"] {
width:100%;
border:none;
border-bottom:1px solid #e5e5e5;
height:32px;
outline:none;
color:#919191;
font-size:18px;
margin-top:6px;
margin-bottom:24px;
}
.customRounded {
border-radius:12px;
}
.priceShadow {
text-shadow : 12px 14px 12px rgba(0,0,0,0.3)
}
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Sora:wght@200;400&display=swap" rel="stylesheet">
<div class="bg-light vh-100 d-flex align-items-center">
<div class="container">
<div class="col-lg-8 col-md-9 mx-auto">
<div class="px-5 pb-4 shadow mainBgn customRounded">
<div class="mb-3">
<h1 id="cardFlare" class="boldfont"><em>VISA</em></h1>
</div>
<div class="row align-items-center">
<div class="col-md-3 col-sm-4 col-xs-12">
<h6><small class="text-warning">RONI</small></h6>
<p class="fs-5 lightColor text-capitalize">A complete baseball starter kit</p>
<div class="border-top pt-2 mt-5">
<h6 class="pt-3"><small class="lightColor2"><strong>ORDER TOTAL</strong></small></h6>
<div class="display-2 text-white boldfont priceShadow">88.22</div>
</div>
</div>
<div class="col-md-9 col-sm-8 col-xs-12">
<div class="bg-white customRounded shadow-lg px-4 pt-4" style="transform:translateX(90px)">
<div class="row mt-3">
<div class="col-sm-6 text-center">
<div class="lightColor2 text-uppercase"><small>Zoom on move over</small></div>
<div class="my-4">
<img src="/static_files/images/html/baseballKit.jpg" alt="" class="img-fluid">
</div>
</div>
<div class="col-sm-6">
<div>
<label for="">Name</label>
<input type="text" class="customInput">
</div>
<div>
<label for="">Card Number</label>
<input type="text" class="customInput">
</div>
<div class="row">
<div class="col">
<label for="">Expires</label>
<select name="" id="">
<option selected value='1'>Janaury</option>
<option value='2'>February</option>
<option value='3'>March</option>
<option value='4'>April</option>
<option value='5'>May</option>
<option value='6'>June</option>
<option value='7'>July</option>
<option value='8'>August</option>
<option value='9'>September</option>
<option value='10'>October</option>
<option value='11'>November</option>
<option value='12'>December</option>
</select>
</div>
<div class="col">
<label for="">Expires</label>
<select name="" id="">
<option value="2022">2022</option>
<option value="2023">2023</option>
<option value="2024">2024</option>
<option value="2025">2025</option>
<option value="2026">2026</option>
<option value="2027">2027</option>
<option value="2028">2028</option>
<option value="2029">2029</option>
<option value="2030">2030</option>
<option value="2031">2031</option>
<option value="2032">2032</option>
</select>
</div>
<div class="col">
<label for="">CVV</label>
<input type="text" class="customInput">
</div>
</div>
<div class="text-end" style="transform:translateY(20px)">
<button class="btn py-3 btn-sm px-4 shadow rounded-0 btn-warning">BUY NOW</button>
</div>
</div>
</div>
</div>
<div class="lightColor2 text-end mt-5">
<input type="checkbox" checked><label for="" class="ms-2 align-text-bottom">Save Card for Further Purchases</label>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
Perfect for a membership or a renewal checkout page. Some custom spacing and width required based on the font chosen. Here, we have utilized Monsterrat google font.
body {
font-family: 'Montserrat', sans-serif;
}
h1,
h2,
.badge {
font-weight: 400 !important;
}
.boldFont {
font-weight: 600 !important;
}
.form-control {
padding-left: 24px;
padding-right: 24px;
height: 58px;
background-color: rgb(247, 247, 247);
outline: none;
box-shadow: none !important;
border:none;
border-top:1px solid #e7e7e7
}
.form-control:focus {
border : 1px solid #232323 !important
}
::placeholder {
color:#adadad !important
}
#cardInput {
padding-right : 64px;
}
#cardImg {
position: absolute;
top:8px;
right:16px;
opacity:0.2
}
#rightPanel {
background-color: aliceblue;
}
.borderDotted {
border-bottom: 1px dashed #d8d8d8;
}
#agreeTerms {
height:20px;
width:20px;
}
button.btn {
height:48px;
}
<div class="container">
<div class="text-center my-5">
<h1>Start your Account</h1>
<div><small class="text-secondary">Step 3 of 3</small></div>
</div>
<div class="row g-5">
<div class="col-lg-8 col-md-6 col-sm-12 col-xs-12">
<div class="p-4 border-top">
<div class="d-flex align-items-center justify-content-between">
<div>
<h2 class="p-0 m-0">Pay With Card</h2>
</div>
<div><span class="badge text-dark border border-dark rounded-3">Powered By <span
class="boldFont">XMPay</span></span></div>
</div>
<div class="text-secondary mt-4 mb-2">Card Information</div>
<div>
<form>
<div class="mb-3 position-relative">
<input type="text" class="form-control" placeholder="0000 0000 0000 0000" id="cardInput">
<img src="/static_files/svgs/creditCard.svg" alt="" height="32" id="cardImg">
</div>
<div class="row mb-3">
<div class="col">
<input type="text" class="form-control" placeholder="MM / YY" >
</div>
<div class="col">
<input type="text" class="form-control" placeholder="CVC" >
</div>
</div>
<div class="mb-3">
<input type="text" placeholder="Name On card" class="form-control">
</div>
<div class="text-secondary mt-4 mb-2">Billing Address</div>
<div class="row mb-3">
<div class="col-lg-8 col-md-6 col-xs-12">
<input type="text" class="form-control" placeholder="Street Address" >
</div>
<div class="col-lg-4 col-md-6 col-xs-12">
<input type="text" class="form-control" placeholder="Zipcode" >
</div>
</div>
<div class="text-secondary mt-4 mb-2">Contact Info </div>
<div class="mb-3">
<input type="text" placeholder="Name" class="form-control">
</div>
<div class="row mb-3">
<div class="col">
<input type="email" class="form-control" placeholder="Email" >
</div>
<div class="col">
<input type="text" class="form-control" placeholder="Phone" >
</div>
</div>
</form>
</div>
</div>
</div>
<div class="col-lg-4 col-md-6 col-sm-12 col-xs-12">
<div class="p-4" id="rightPanel">
<h6 class="text-uppercase"><small>Subscribe To</small></h6>
<h4 class="boldFont">Membership</h4>
<div class="my-4 d-flex justify-content-between align-items-center">
<div>Subscription<br><span class="text-secondary"><small>Billed Yearly</small></span></div>
<div class="w-100 mx-3 borderDotted"></div>
<div>$10.00</div>
</div>
<div class="my-4 d-flex justify-content-between align-items-center">
<div style="min-width:130px">Application Fee<br><span class="text-secondary"><small>1 time only</small></span></div>
<div class="w-100 mx-3 borderDotted"></div>
<div>$79.99</div>
</div>
<div class="my-4">
<h6>Apply discount code</h6>
<div class="my-3">
<input type="text" class="bg-white form-control" placeholder="Code">
</div>
</div>
<hr>
<div class="my-4 fs-4">
<div class="d-flex justify-content-between">
<div class="">Total</div>
<div class="text-primary">$89.99</div>
</div>
</div>
<div class="d-flex justify-content-between align-items-center">
<div><input type="checkbox" id="agreeTerms"></div>
<div class="mx-4"><label for="agreeTerms"><small>I agree to the <a href="#">Terms and Conditions</a> and the <a href="#">Automatic Renewal Terms</a> above</small></label></div>
</div>
<div class="my-4">
<button class="btn btn-primary text-uppercase w-100"><b>subscribe</b></button>
</div>
</div>
</div>
</div>
</div>
Timeouts are important to safeguard user's info. It's an industry standard practice to identify the user being inactive and reset the fields. For the sake of simplicity, we will do a simple countdown timer using setInterval
There are some cool libraries exist that show the numbers and text being updated on the card image along with the card logo. A very cool depiction and here I've implemented it.
.cardStyle {
padding: 24px;
border-radius: 12px;
box-shadow: 4px 8px 12px rgba(0, 0, 0, 0.1);
max-width: 360px;
width: 100%;
background: rgb(33, 90, 201);
background: linear-gradient(90deg, rgba(33, 90, 201, 1) 0%, rgba(70, 155, 242, 1) 42%, rgba(0, 159, 255, 1) 100%);
z-index: 6;
position: relative
}
.amexBgn {
background: #757F9A;
/* fallback for old browsers */
background: -webkit-linear-gradient(to right, #D7DDE8, #757F9A);
/* Chrome 10-25, Safari 5.1-6 */
background: linear-gradient(to right, #D7DDE8, #757F9A);
/* W3C, IE 10+/ Edge, Firefox 16+, Chrome 26+, Opera 12+, Safari 7+ */
}
.masterBgn {
background-color: #4158D0;
background-image: linear-gradient(43deg, #4158D0 0%, #C850C0 46%, #FFCC70 100%);
}
.visaBgn {
background: #ff6e7f;
/* fallback for old browsers */
background: -webkit-linear-gradient(to right, #bfe9ff, #ff6e7f);
/* Chrome 10-25, Safari 5.1-6 */
background: linear-gradient(to right, #bfe9ff, #ff6e7f);
/* W3C, IE 10+/ Edge, Firefox 16+, Chrome 26+, Opera 12+, Safari 7+ */
}
.discoverBgn {
background-color: #FF9A8B;
background-image: linear-gradient(90deg, #FF9A8B 0%, #FF6A88 55%, #FF99AC 100%);
}
.dinerBgn {
background-color: #FFE53B;
background-image: linear-gradient(147deg, #FFE53B 0%, #FF2525 74%);
}
.jcbBgn {
background: #F09819;
/* fallback for old browsers */
background: -webkit-linear-gradient(to right, #EDDE5D, #F09819);
/* Chrome 10-25, Safari 5.1-6 */
background: linear-gradient(to right, #EDDE5D, #F09819);
/* W3C, IE 10+/ Edge, Firefox 16+, Chrome 26+, Opera 12+, Safari 7+ */
}
.unionBgn {
background: #ED4264;
/* fallback for old browsers */
background: -webkit-linear-gradient(to right, #FFEDBC, #ED4264);
/* Chrome 10-25, Safari 5.1-6 */
background: linear-gradient(to right, #FFEDBC, #ED4264);
/* W3C, IE 10+/ Edge, Firefox 16+, Chrome 26+, Opera 12+, Safari 7+ */
}
#visualNumber {
height: 24px;
}
.cardFont {
font-family: 'Roboto Condensed', sans-serif;
letter-spacing: 1px;
}
.text-shadow-white {
text-shadow: 2px 3px 1px rgba(85, 85, 85, 0.18)
}
.text-shadow-black {
text-shadow: 1px 1px 2px rgba(0, 0, 0, 0.5)
}
.cardBack {
background: rgb(9, 54, 140);
background: linear-gradient(90deg, rgba(9, 54, 140, 1) 0%, rgba(8, 70, 134, 1) 42%, rgba(30, 85, 119, 1) 100%);
padding: 0px;
position: relative;
z-index: 5;
height: 220px;
margin-top: -180px;
margin-left: 50px;
}
input.form-control {
height: 48px;
border-radius: 8px;
}
.customRounded {
border-radius: 12px;
}
input::placeholder {
color: #aaaaaa !important
}
.btn {
height: 48px;
}
a.btn {
line-height: 32px;
}
<div class="col-lg-4 mx-auto">
<div class="position-relative my-5">
<div class="cardStyle" id="cardBgn">
<div class="text-end"><strong>DB BANK</strong></div>
<div class="mt-3 d-flex align-items-center justify-content-between">
<div><img src="/static_files/images/logos/chip.png" alt="Chip" height="32"></div>
<div><img style="transform:rotate(90deg)" src="/static_files/svgs/wifi.svg" alt="Chip" height="24">
</div>
</div>
<div class="fs-4 mt-2 cardFont text-shadow-white" id="visualNumber"></div>
<div class="row mt-2">
<div class="col"></div>
<div class="col text-shadow-white"><span id="visualMonth">12</span>/<span id="visualYear">24</span>
</div>
</div>
<div class="d-flex align-items-end justify-content-between">
<div class="text-info text-shadow-black"><strong id="visualName">P John Doe</strong></div>
<div style="height:32px"><img src="" height="32" id="cardLogo" alt=""></div>
</div>
</div>
<div class="cardStyle cardBack pt-3">
<div class="mt-4 p-4 bg-black"></div>
<div class="mb-3 bg-white">
<div class="d-flex justify-content-between">
<div class="p-3 bg-white"></div>
<div class="p-3 bg-light"><em id="visualCVV">123</em></div>
</div>
</div>
</div>
</div>
<input type="text" onkeyup="deduceCard(this)" class="form-control">
</div>
var cardLogo = document.getElementById('cardLogo')
var visualNumber = document.getElementById('visualNumber')
var cardBgn = document.getElementById('cardBgn')
function cc_format(value) {
var v = value.replace(/\s+/g, '').replace(/[^0-9]/gi, '')
var matches = v.match(/\d{4,16}/g);
var match = matches && matches[0] || ''
var parts = []
for (i = 0, len = match.length; i < len; i += 4) {
parts.push(match.substring(i, i + 4))
}
if (parts.length) {
return parts.join(' ')
} else {
return value
}
}
function deduceCard(t) {
var cc = t.value.trim().replace(/ /g, '')
visualNumber.innerText = cc_format(cc)
if(cc.length < 4) {cardLogo.src = "" ;return cardBgn.className = "cardStyle"}
var ctype = creditCardType(cc)
if (ctype) {
if (ctype === 'VISA') { cardLogo.src = "/static_files/images/logos/visaT.png"; cardBgn.className = "cardStyle visaBgn" }
else if (ctype === 'AMEX') { cardLogo.src = "/static_files/images/logos/amex.png"; cardBgn.className = "cardStyle amexBgn" }
else if (ctype === 'MASTERCARD') { cardLogo.src = "/static_files/images/logos/mastercard.png"; cardBgn.className = "cardStyle masterBgn" }
else if (ctype === 'DINERS') { cardLogo.src = "/static_files/images/logos/diner.png"; cardBgn.className = "cardStyle dinerBgn" }
else if (ctype === 'JCB') { cardLogo.src = "/static_files/images/logos/jcb.png"; cardBgn.className = "cardStyle jcbBgn" }
else if (ctype === 'CHINA_UNION_PAY') { cardLogo.src = "/static_files/images/logos/unionpay.png"; cardBgn.className = "cardStyle unionBgn" }
}
}
function creditCardType(cc) {
let amex = new RegExp('^3[47][0-9]{13}$');
let visa = new RegExp('^4[0-9]{12}(?:[0-9]{3})?$');
let cup1 = new RegExp('^62[0-9]{14}[0-9]*$');
let cup2 = new RegExp('^81[0-9]{14}[0-9]*$');
let mastercard = new RegExp('^5[1-5][0-9]{14}$');
let mastercard2 = new RegExp('^2[2-7][0-9]{14}$');
let disco1 = new RegExp('^6011[0-9]{12}[0-9]*$');
let disco2 = new RegExp('^62[24568][0-9]{13}[0-9]*$');
let disco3 = new RegExp('^6[45][0-9]{14}[0-9]*$');
let diners = new RegExp('^3[0689][0-9]{12}[0-9]*$');
let jcb = new RegExp('^35[0-9]{14}[0-9]*$');
if (visa.test(cc)) {
return 'VISA';
}
if (amex.test(cc)) {
return 'AMEX';
}
if (mastercard.test(cc) || mastercard2.test(cc)) {
return 'MASTERCARD';
}
if (disco1.test(cc) || disco2.test(cc) || disco3.test(cc)) {
return 'DISCOVER';
}
if (diners.test(cc)) {
return 'DINERS';
}
if (jcb.test(cc)) {
return 'JCB';
}
if (cup1.test(cc) || cup2.test(cc)) {
return 'CHINA_UNION_PAY';
}
return undefined;
}
Website security has become very crucial and even more so for an e-commerce. You might have come across the acronym PCI (PCI SSC). It's a standard security council with the mission to improve the data security especially for payments systems. For a website to becode PCI compliant, there are slew of things that need to be taken care of which might prove costly.
But the payment gateways now-a-days are utilizing the concept of card tokenization so that there will be no more burden on their clients to be fully compliant. In my opinion, a standard SSL will do. In a nutshell, we must not store the card information in anyway but we can store the token.
See the below image for a clear picture.
This can be done by fancy jquery libraires or a simple javascript regex to identify the type of the card and valid format. This will help reduce the number of trips to the server when not validated.
function GetCardType(number)
{
// visa
var re = new RegExp("^4");
if (number.match(re) != null)
return "Visa";
// Mastercard
// Updated for Mastercard 2017 BINs expansion
if (/^(5[1-5][0-9]{14}|2(22[1-9][0-9]{12}|2[3-9][0-9]{13}|[3-6][0-9]{14}|7[0-1][0-9]{13}|720[0-9]{12}))$/.test(number))
return "Mastercard";
// AMEX
re = new RegExp("^3[47]");
if (number.match(re) != null)
return "AMEX";
// Discover
re = new RegExp("^(6011|622(12[6-9]|1[3-9][0-9]|[2-8][0-9]{2}|9[0-1][0-9]|92[0-5]|64[4-9])|65)");
if (number.match(re) != null)
return "Discover";
// Diners
re = new RegExp("^36");
if (number.match(re) != null)
return "Diners";
// Diners - Carte Blanche
re = new RegExp("^30[0-5]");
if (number.match(re) != null)
return "Diners - Carte Blanche";
// JCB
re = new RegExp("^35(2[89]|[3-8][0-9])");
if (number.match(re) != null)
return "JCB";
// Visa Electron
re = new RegExp("^(4026|417500|4508|4844|491(3|7))");
if (number.match(re) != null)
return "Visa Electron";
return "";
}
This is another feature to stop accidental button presses by the user without filling the form. We can create our own custom validation and then enable the button to proceed.
Sometimes, the button might get pressed twice, triggering double charges. It needs to be restricted at all costs. Usually, payment gateways provide a technique called idempotency by which once can get only single effect despite multiple calls to the server / api. Since we are not dealing with the server here, all we need to do is disable the button immediately its been pressed. Its as simple as that.
Payment page designed with bootstrap 5 for a restaurant / eatery / pickup business. Simple but elegant looking page with payment options like paypal and visa. This page has JS designed to increase order.
Car payment page designed with bootstrap 5. Choose from multiple cards that are already saved.
Do you want to access your webcamera remotely? Then this article is for you.
Calendar Picker / Appointment Setter JS CSS Library. Inspired by Calendly.
Create a local file sharing server with realtime sync feature using Socket IO.
Most beautiful Navbars designed with tailwind css. Fully responsive templates.
Most beautiful dashboards designed with bootstrap 5. Inspired mostly from dribble and other sources.
Most commonly used HTML email templates. Welcome email, sign up, password reset etc.
Checkout our most downloaded payment page ui designed with bootstrap.
Detect user's inactivity and auto logout after certain timeout using various JS features.
Keep the user engaged and gain recurring website traffic. Includes templates.
How to get a user's location using Javascript and other techniques available today.
This website uses cookies and similar technologies, to enhance your browsing experience and provide personalized recommendations. By continuing to use our website, you agree to our Privacy policy.