I’m using Stripe Elements to create payment and have control over the look of the form. I got it working well hitting a Route through the form’s action when submitted. However, now I want to try to send the POST request without changing/loading a page. Which I presume is best done through AJAX. I have attempted this but I cannot get a 200 response with the JSON. Below I have included snippets of the code, any help as to where I’m going wrong would be greatly appreciated.
JS
//snippet
const form = document.getElementById('payment-form');
form.addEventListener('submit', async (event) => {
event.preventDefault();
const {token, error} = await stripe.createToken(card);
if (error) {
const errorElement = document.getElementById('card-errors');
errorElement.textContent = error.message;
} else {
stripeTokenHandler(token);
}
});
const stripeTokenHandler = (token) => {
const form = document.getElementById('payment-form');
const hiddenInput = document.createElement('input');
const submitButton = document.querySelector('.submit-form');
hiddenInput.setAttribute('type', 'hidden');
hiddenInput.setAttribute('name', 'stripeToken');
hiddenInput.setAttribute('value', token.id);
form.appendChild(hiddenInput);
// form.submit();
//new AJAX code
const submitForm = (e) => {
e.preventDefault();
const request = new XMLHttpRequest();
request.open('POST', e.target.action);
if (e.target.status === 200) {
console.log('successs:' + e.target.response)
} else {
console.log('fail')
}
};
form.addEventListener('submit', submitForm);
FORM
<form action="<?= $page->url() ?>/charge" method="POST" id="payment-form">
<input type="text" name="name" class="StripeElement StripeElement--empty" placeholder="First Name">
<input type="email" name="email" class="StripeElement StripeElement--empty" placeholder="Email Address">
<div id="card-element">
<!-- A Stripe Element will be inserted here. -->
</div>
<!-- Used to display Element errors. -->
<div id="card-errors" role="alert"></div>
<button class="submit-form stripe-button">Pay <?= $symbol ?><?= $page->amount()->html() ?></button>
</form>
PHP
<?php
function stripeCheckout() {
require_once('stripe-php/init.php');
\Stripe\Stripe::setApiKey(sk_test_xX5xxxxxxxxxxx);
$POST = filter_var_array($_POST, FILTER_SANITIZE_STRING);
$name = $POST['name'];
$email = $POST['email'];
$token = $POST['stripeToken'];
$currency = 'gbp';
$amount = s::get('stripeAmount');
$description = s::get('stripeDescription');
$customer = \Stripe\Customer::create(array(
'email' => $email,
'source' => $token
));
// Charge the user's card:
$charge = \Stripe\Charge::create(array(
"amount" => $amount,
"currency" => $currency,
"description" => $description,
"customer" => $customer->id,
));
// print_r($charge);
$charge_json = $charge->__toJSON();
}
Route (Route built into CMS)
c::set('routes', array(
array(
'pattern' => 'products/(:any)/charge',
'method' => 'POST',
'action' => function() {
stripeCheckout();
},
)
));
== EDIT ==
Screenshot of Network Requests