I am working with stripe, using the code found on their page to create a new account. Everything works fine, however when someone inserts wrong data in a field and we press on submit nothing happens and I can see in the console:
{
"error": {
"message": "This value must be greater than 1900 (it currently is '1670').",
"param": "account[individual][dob][year]",
"type": "invalid_request_error"
}
this being the response of the api (I tried to enter 1670 in the date of birth). how can I display this on the page for the user?
here is my html code for the page:
<form class="my-form" method="post" role="form">
{% csrf_token %}
<input type="hidden" name="token" id="token">
<label>
<span>First Name</span>
<input class="inp-first-name" name="first_name" required>
</label>
<label>
<span>Last Name</span>
<input class="inp-last-name" name="last_name" required>
</label>
<label>
<span>dob year</span>
<input class="inp-dob-year" name="dob_year" required>
</label>
<label>
<span>dob month</span>
<input class="inp-dob-month" name="dob_month" required>
</label>
<label>
<span>dob day</span>
<input class="inp-dob-day" name="dob_day" required>
</label>
<fieldset>
<legend>Address</legend>
<label>
<span>Street Address Line 1</span>
<input class="inp-street-address1" name="street_address1" required>
</label>
<label>
<span>Street Address Line 2</span>
<input class="inp-street-address2" name="street_address2">
</label>
<label>
<span>City</span>
<input class="inp-city" name="city" required>
</label>
<label>
<span>State</span>
<input class="inp-state" name="state" required>
</label>
<label>
<span>Postal Code</span>
<input class="inp-zip" name="zip" required>
</label>
{{ form }}
</fieldset>
<button type="submit">Submit</button>
</form>
</table>
{% endblock %}
{% block body_scripts %}
<script>
const stripe = Stripekey
const myForm = document.querySelector('.my-form');
myForm.addEventListener('submit', handleForm);
async function handleForm(event) {
event.preventDefault();
const result = await stripe.createToken('account', {
legal_entity: {
type:'individual',
first_name: document.querySelector('.inp-first-name').value,
last_name: document.querySelector('.inp-last-name').value,
dob:{
year: parseInt(document.querySelector('.inp-dob-year').value),
month: parseInt(document.querySelector('.inp-dob-month').value),
day: parseInt(document.querySelector('.inp-dob-day').value),
},
address: {
line1: document.querySelector('.inp-street-address1').value,
line2: document.querySelector('.inp-street-address2').value,
city: document.querySelector('.inp-city').value,
state: document.querySelector('.inp-state').value,
postal_code: document.querySelector('.inp-zip').value,
},
},
tos_shown_and_accepted: true,
});
if (result.token) {
document.querySelector('#token').value = result.token.id;
myForm.submit();
}
}
</script>
I am building a website with python, so my knowledge with javascript is limited. Any help would be appreciated.
You can achieve this by adding a new HTML element to contain error messages and setting the innerText
to the error message.
I added a div with an id of stripe-errors
if (result.token) {
document.querySelector('#token').value = result.token.id;
myForm.submit();
} else if (result.error) {
let stripeErrors = document.getElementById('stripe-errors');
stripeErrors.innerText = result.error.message;
}
The limitation of that is that you only have one place to display the error messages and the error messages don't explicitly say what field they're referencing, although within context it is probably clear enough. To be crystal clear you could use the error.param
to map account[individual][dob][year]
to the .inp-dob-year
input field or to another element to display the error message.
This would look something like:
if (result.token) {
document.querySelector('#token').value = result.token.id;
myForm.submit();
} else if (result.error) {
// create an object as a map from the error.param to the elements that should be used to display error messages
const errorTypeFieldMap = {
'account[individual][dob][year]': '.inp-dob-year-error'
}
let errorElementSelector = errorTypeFieldMap[result.error.param];
if (errorElementSelector !== undefined) {
let errorElement = document.querySelector(errorElementSelector);
errorElement.innerText = result.error.message;
} else {
// display a generic error?
}
}