Stripe was working perfectly fine before but somewhere it stopped working properly. Stripe will create a new customer, but not charge the card provided so I'm not sure whats going on.
Logs within Stripe:
Status Description
402 err POST /v1/charges
200 OK POST /v1/customers
200 OK POST /v1/tokens
Response Body:
{
"error": {
"code": "missing",
"doc_url": "https://stripe.com/docs/error-codes/missing",
"message": "Cannot charge a customer that has no active card",
"param": "card",
"type": "card_error"
}
}
(But the card is being provided)
I have app.js in the root file and the HTML that contains this file is in public within root:
<form action="/charge" method="post" id="payment-form" style="margin-top: 40px;">
<div class="form-row">
<label for="card-element">
Reservation Deposit (Credit or Debit Card)
</label>
<div id="card-element"><!-- a Stripe Element will be inserted here. --></div>
<div id="card-errors"></div>
</div>
<p class="agree-to-terms text-center">
By submitting the request, you agree to our <a href="terms.html">Terms of Use</a>
</p>
<div class="question-container" style="margin-top: 30px;">
<button id="finalBackBtn" type="button" class="back-btn">BACK</button>
<button id="furnitureBtn" type="submit" class="text-center next-btn">SUBMIT</button>
</div>
</form>
<script type="text/javascript">
//Create a Stripe client
var stripe = Stripe('...');
// Create an instance of Elements
var elements = stripe.elements();
// Custom styling can be passed to options when creating an Element.
var style = {
base: {
...
}
},
invalid: {
...
}
};
// Create an instance of the card Element
var card = elements.create('card', {
style: style
});
// Add an instance of the card Element into the `card-element` <div>
card.mount('#card-element');
// Handle real-time validation errors from the card Element.
card.addEventListener('change', function(event) {
var displayError = document.getElementById('card-errors');
if (event.error) {
displayError.textContent = event.error.message;
} else {
displayError.textContent = '';
}
});
// Handle form submission
var form = document.getElementById('payment-form');
form.addEventListener('submit', function(event) {
event.preventDefault();
stripe.createToken(card).then(function(result) {
if (result.error) {
// Inform the user if there was an error
var errorElement = document.getElementById('card-errors');
errorElement.textContent = result.error.message;
} else {
// Send the token to your server
stripeTokenHandler(result.token);
}
});
});
function stripeTokenHandler(token) {
// Insert the token ID into the form so it gets submitted to the server
var form = document.getElementById('payment-form');
var hiddenInput = document.createElement('input');
var totalAmount = document.createElement('input');
var customerEmail = document.createElement('input');
hiddenInput.setAttribute('type', 'hidden');
hiddenInput.setAttribute('name', 'stripeToken');
hiddenInput.setAttribute('value', token.id);
// Getting the deposit amount
totalAmount.setAttribute('type', 'hidden');
totalAmount.setAttribute('name', 'totalAmount');
totalAmount.setAttribute('value', Number(document.getElementById('new_text2').innerHTML) * 100);
customerEmail.setAttribute('type', 'hidden');
customerEmail.setAttribute('name', 'email');
customerEmail.setAttribute('value', document.getElementById('emailA').innerHTML);
form.appendChild(hiddenInput);
form.appendChild(totalAmount);
form.appendChild(customerEmail);
var formData = JSON.stringify({
mytoken: token.id,
totalAmount: totalAmount.value,
customerEmail: customerEmail.value
});
$.ajax({
type: "POST",
url: "/charge",
data: formData,
success: function() {
alert("done")
},
dataType: "json",
contentType: "application/json"
});
form.submit();
}
</script>
And lastly, my app.js file:
const express = require('express');
const stripe = require('stripe')('...');
const bodyParser = require('body-parser');
const app = express();
const port = process.env.PORT || 13441;
if (process.env.NODE_ENV && process.env.NODE_ENV === 'production') {
app.use((req, res, next) => {
if (!req.secure && req.headers['x-forwarded-proto'] !== 'https') {
res.redirect('https://' + req.headers.host + req.url)
} else {
next();
}
})
}
// Set Static Folder
app.use(express.static('public'));
app.use(bodyParser.json());
// charge route
app.post('/charge', (req, res) => {
const amount = req.body.totalAmount;
const email = req.body.customerEmail;
stripe.customers.create({
email: email,
source: req.body.mytoken
})
.then(customer => {
stripe.charges.create({
amount,
description:'Muve deposit request',
currency:'USD',
customer:customer.id
})})
.then(charge => res.sendFile('public/confirmationPage.html', {root: __dirname}));
});
app.listen(port, () => {
console.log(`Server started on port ${port}`);
});
Anyone know what's going on?
Your code is calling your /charge
endpoint twice, because you use $.ajax
but also do form.submit()
. That is creating two customers, one of which has no sources because the token is only added in the ajax request, and that's the customer you are getting the error for.
Easy fix is to remove the form.submit()
line.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.