<div class="wrapper">
<form class="form">
<div class="cardName-container field-container">
<label for="card-name-field">Cardholder Name</label>
<div id="card-name-field" class="hosted-field"></div>
<div class="error"></div>
</div>
<div class="cardNumber-container field-container">
<label for="card-number-field">Card Number</label>
<div id="card-number-field" class="hosted-field"></div>
<div class="error"></div>
</div>
<div class="field-columns">
<div class="cardExpiry-container field-container">
<label for="card-expiry-field">Expiry Date</label>
<div id="card-expiry-field" class="hosted-field"></div>
<div class="error"></div>
</div>
<div class="cardCvv-container field-container">
<label for="card-cvv-field">CVV</label>
<div id="card-cvv-field" class="hosted-field"></div>
<div class="error"></div>
</div>
</div>
<button class="button">Submit</button>
<div class="response"></div>
<div class="disclaimer">
Payment securely processed by Assembly Payments.
</div>
</form>
</div>
*,
:after,
:before {
box-sizing: border-box;
}
body {
font-family: system-ui, -apple-system, BlinkMacSystemFont, sans-serif;
padding: 20px;
}
.wrapper {
max-width: 460px;
margin: 0 auto;
}
form {
margin-bottom: 30px;
background: #fff;
border: 1px solid #e0e0e0;
box-sizing: border-box;
border-radius: 12px;
padding: 20px;
}
@media (min-width: 600px) {
form {
padding: 40px;
}
}
.button {
display: block;
position: relative;
align-items: center;
appearance: none;
display: inline-flex;
justify-content: center;
line-height: 1;
padding: 0 20px;
height: 60px;
text-decoration: none;
background-color: #000645;
border: none;
color: #fff;
border-radius: 3px;
font-size: 16px;
margin-top: 16px;
width: 100%;
cursor: pointer;
}
.button:hover {
box-shadow: 0px 1px 12px rgba(33, 0, 150, 0.25);
}
.button:disabled {
cursor: not-allowed;
}
.button-loading::before {
content: "";
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
background-color: #000645;
}
.button-loading::after {
content: "";
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
margin: auto;
width: 24px;
height: 24px;
border-color: currentColor;
border-style: solid;
border-radius: 99999px;
border-width: 2px;
border-left-color: transparent;
color: #fff;
animation: rotate 450ms linear 0ms infinite;
}
label {
display: block;
margin-bottom: 4px;
font-size: 14px;
color: #000645;
}
.field-container {
margin-bottom: 20px;
}
.field-columns {
display: flex;
justify-content: space-between;
}
.field-columns > * {
flex: 0 1 40%;
}
.hosted-field {
height: 40px;
padding: 0 12px;
border: 1px solid #e0e0e0;
border-radius: 3px;
}
.hosted-field-invalid {
border-color: #cc0001;
}
.hosted-field-valid {
border-color: #10b981;
}
.hosted-field-focus {
border-color: #210096;
box-shadow: 0px 1px 12px rgba(33, 0, 150, 0.25);
}
.error {
color: #cc0001;
background-color: #ffe6e6;
padding: 2px 8px;
margin-top: 12px;
font-size: 14px;
border-radius: 3px;
display: none;
}
.error.visible {
display: inline-block;
}
.disclaimer {
color: #828282;
font-size: 14px;
margin-top: 24px;
text-align: center;
}
.response {
display: none;
margin-top: 16px;
color: #fff;
padding: 10px 20px;
text-align: center;
font-size: 14px;
}
.response-success {
display: block;
background-color: #dff9ec;
color: #1b643a;
}
.response-error {
display: block;
background-color: #ffe6e6;
color: #cc0001;
}
@keyframes rotate {
0% {
transform: rotate(0deg);
}
100% {
transform: rotate(360deg);
}
}
var styles = {
input: {
color: "#000645",
"font-family": "system-ui, -apple-system, BlinkMacSystemFont, sans-serif",
"letter-spacing": "0.02em"
},
".invalid": {
color: "#cc0001"
},
"::placeholder": {
color: "#757575"
},
".invalid .card-icon": {
color: "#cc0001"
}
};
var hostedFields = assembly.hostedFields({
environment: "pre-live"
});
var cardName = hostedFields.create("cardName", {
placeholder: "Full Name",
styles: styles
});
var cardNumber = hostedFields.create("cardNumber", {
placeholder: "•••• •••• •••• ••••",
styles: styles,
});
var cardExpiry = hostedFields.create("cardExpiry", {
placeholder: "MM/YY",
styles: styles
});
var cardCvv = hostedFields.create("cardCvv", {
placeholder: "•••",
styles: styles
});
cardName.mount("#card-name-field");
cardNumber.mount("#card-number-field");
cardExpiry.mount("#card-expiry-field");
cardCvv.mount("#card-cvv-field");
var inputs = [cardName, cardNumber, cardExpiry, cardCvv];
inputs.forEach(function (field) {
field.on("change", function (event) {
var errorElement = document.querySelector(
"." + event.fieldType + "-container .error"
);
toggleError(errorElement, event);
});
});
var form = document.querySelector(".form");
var submitButton = form.querySelector(".button");
var responseContainer = document.querySelector(".response");
function toggleError(element, event) {
if (event.error) {
element.innerText = event.error.message;
element.classList.add("visible");
} else {
element.innerText = "";
element.classList.remove("visible");
}
}
form.addEventListener("submit", function (event) {
event.preventDefault();
submitButton.disabled = true;
submitButton.classList.add("button-loading");
hostedFields
.createCardAccount({
token: "YOUR_TOKEN",
user_id: "YOUR_USER_ID"
})
.then(function (response) {
resetSubmitButton();
// handle create card account succeeded
responseContainer.classList.add("response-success");
responseContainer.innerText = "Card account successfully created.";
resetForm()
})
.catch(function (response) {
resetSubmitButton();
// handle errors
responseContainer.classList.add("response-error");
if (response.errors && response.errors.token) {
responseContainer.innerText = "Your token is not authorized.";
} else {
responseContainer.innerText =
"There was an error creating your card account.";
}
});
});
function resetSubmitButton() {
submitButton.disabled = false;
submitButton.classList.remove("button-loading");
}
function resetForm() {
inputs.forEach(function (input) {
input.clear()
})
}
This Pen doesn't use any external CSS resources.