JSFiddle - React, Tailwind, and code Playground
by joshmoto
HTML
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.3/umd/popper.min.js"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/js/bootstrap.min.js"></script>
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/css/bootstrap.min.css">
<script src="https://js.stripe.com/v3/"></script>
<link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.3.1/css/all.css">
<div class="container mt-3">
<form action="/charge" method="post" id="preorder-form">
<div class="form-group">
<label for="name">Name on card</label>
<div class="input-group">
<input id="card-name" type="text" class="form-control" aria-describedby="input-name" placeholder="Name on card">
</div>
</div>
<div class="form-group">
<label for="card-number">Card Number</label>
<div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text" id="input-number"><i class="fab fa-cc-visa"></i></span>
</div>
<span id="card-number" class="form-control" aria-describedby="input-name">
<!-- Stripe Card Element -->
</span>
<div class="invalid-feedback"></div>
</div>
</div>
<div class="form-row">
<div class="col-6">
<div class="form-group">
<label for="card-exp">Expiration</label>
<div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text" id="input-number"><i class="far fa-calendar"></i></span>
</div>
<span id="card-exp" class="form-control" aria-describedby="input-exp">
<!-- Stripe Card Expiry Element -->
</span>
<div class="invalid-feedback"></div>
</div>
</div>
</div>
<div class="col-6">
<div class="form-group">
<label for="card-cvc">CVC</label>
<div class="input-group">
<div...
SCSS
.input-group-text {
padding: 0rem .75rem;
font-size: 1.5rem;
background: #fff;
}
.input-group-prepend {
.input-group-text {
padding-right: 0;
border-right: #fff 1px solid;
z-index: 1;
}
}
.input-group-append {
.input-group-text {
padding-left: 0;
border-left: #fff 1px solid;
z-index: 1;
}
}
JavaScript
// create a Stripe client
var stripe = Stripe('pk_test_A45s2laXHrCRj6Tow44dk67z');
// Create an instance of Elements
var elements = stripe.elements();
// try to match bootstrap 4 styling
var style = {
base: {
'lineHeight': '1.6',
'fontSize': '1.11rem',
'color': '#495057',
'fontFamily': '-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji"'
}
};
// card mount
var card = elements.create('cardNumber', {
'placeholder': '0000 0000 0000 0000',
'style': style
});
card.mount('#card-number');
// card feedback
card.addEventListener('change', function(event) {
var id = $('#card-number');
if(event.error) {
id.next().html(event.error.message);
id.addClass('is-invalid').removeClass('is-valid');
} else {
id.next().html();
id.addClass('is-valid').removeClass('is-invalid');
}
});
// expiry mount
var exp = elements.create('cardExpiry', {
'placeholder': 'MM / YY',
'style': style
});
exp.mount('#card-exp');
// expiry feedback
exp.addEventListener('change', function(event) {
var id = $('#card-expiry');
if(event.error) {
id.next().html(event.error.message);
id.addClass('is-invalid').removeClass('is-valid');
} else {
id.next().html();
id.addClass('is-valid').removeClass('is-invalid');
}
});
// cvc mount
var cvc = elements.create('cardCvc', {
'placeholder': '###',
'style': style
});
cvc.mount('#card-cvc');
// cvc feedback
cvc.addEventListener('change', function(event) {
var id = $('#card-cvc');
if(event.error) {
id.next().html(event.error.message);
id.addClass('is-invalid').removeClass('is-valid');
} else {
id.next().html();
id.addClass('is-valid').removeClass('is-invalid');
}
});