Error when creating a customer using test card - node.js

When attempting to begin a Subscription for a newly created Customer, I receive the following error from Stripe:
invalid_request_error
Error: This customer has no attached payment source
The customer seems to be created just fine. I am using Stripe Checkout to collect the card token. For testing, I am using Stripe's 4242 4242 4242 4242 card number with random information. The token seems to be getting created and passed to my server just fine. Below is my server side code:
stripe.plans.retrieve(
"basic-monthly",
function(err, plan) {
if (err) {
console.error(err)
res.sendStatus(500)
} else {
stripe.customers.create({
email: owner,
source: token.id,
}, function(err, customer) {
if (err) {
console.error(err)
res.sendStatus(500)
} else {
stripe.subscriptions.create({
customer: customer.id,
items: [
{
plan: "basic-monthly",
quantity: 1
},
],
}, function(err, subscription) {
if (err) {
console.error(err)
console.log('##### UNABLE TO CREATE SUBSCRIPTION ####')
res.sendStatus(500)
} else {
console.log('Subscription created.')
console.dir(subscription)
res.sendStatus(200);
}
});
}
});
}
});
##### UNABLE TO CREATE SUBSCRIPTION #### is logged, along with the errors described above. I understand what the error means, but I am not sure how it is occurring. As you can see above, I am passing in the Token Id when creating a customer, source: token.id,.
What is the issue here?

The most likely cause here is that token.id is empty, so the Customer is being created without a Source. I'd suggest logging the contents of token and see what you get.

Related

Stripe subscription always gives me "status: 'requires_confirmation'

I have a subscription route like this. My flow looks like this
User select a plan.
User enter card details through Stripe Card Element
User click Subscribe button.
As per docs,
I'm creating a customer.
Then creating a subscription for this customer.
But, my dashboard says payment incomplete and response object on creating subscriptions shows status: 'requires_confirmation'. What I am doing wrong?
router.post('/subscription', auth, async (req, res) => {
const { payment_method, price_id } = req.body;
const customer = await Stripe.customers.create({
email: 'test#gmail.com',
payment_method: payment_method,
description: 'New Customer',
invoice_settings: { default_payment_method: payment_method }
});
try {
const subscription = await Stripe.subscriptions.create({
customer: customer.id,
items: [
{
price: price_id
}
],
payment_behavior: 'default_incomplete',
expand: ['latest_invoice.payment_intent']
});
res.send({
status: subscription.latest_invoice.payment_intent.status,
subscriptionId: subscription.id,
});
} catch (error) {
return res.status(400).send({ error: { message: error.message } });
}
});
[![Stripe dashboard][1]][1]
[1]: https://i.stack.imgur.com/Sx0zN.png
It sounds like you’re doing things a bit out of order from the way the Stripe docs suggest. In this guide, the subscription object is created prior to collecting the payment method. The reason your invoice isn’t automatically paid is because you are explicitly passing in a payment_behavior of default_incomplete, which tells Stripe not to pay the invoice and allows you to collect payment details client-side and confirm the payment. Since you have already collected payment details, don’t pass in a payment_bevavior of default_incomplete.

Stripe create Token bank account

I'm trying to add a token to create a bank account with stripe.
tokenAccount: async (req, res) => {
Serveur.findOne({ _id: req.user._id }, async (err, user) => {
try {
await stripe.tokens.create({
bank_account: {
country: req.body.country,
currency: req.body.currency,
account_number: req.body.account_number,
routing_number: req.body.routing_number,
},
});
} catch (error) {
return res.status("402").send({ error: { message: error.message } });
}
});
},
and when i test the back end with postman with a "test" bank details from stripe i have this error :
{
"error": {
"message": "You cannot use a live bank account number when making transfers or debits in test mode"
}
}
Which is weird because i used the test stripe's bank details. Do you have any idea what the problem could be ???
Each Stripe account offers both live and test keys. When you use their fake test accounts (for banks, MasterCards, and the like) you must also use their test keys. Don't try to use the live keys for testing; and, honestly, be happy they caught this for you.

Stripe Connect - shared customer , cant charge

Hi I am trying to implement stripe connect where the platform takes an application fee but the connected user gets majority of charge.
Following this as my guide
https://stripe.com/docs/connect/shared-customers
I have this as my code. The user is saved w/ default credit card source in another view.
Parse.Cloud.define("chargeCard", function(req, res){
stripe.tokens.create({
customer: req.params.customer,
}, {
stripe_account: req.params.stripeAccount,
}).then((token) => {
console.log("successfully created token");
stripe.charges.create({
amount: req.params.amount,
currency: req.params.currency,
source: token.id,
application_fee: req.params.fee,
}, {
stripe_account: req.params.stripeAccount,
}).then((charge) => {
console.log("successfully charged card");
res.success(charge);
}).catch((error) => {
console.log(error);
res.error(error.message);
});
}).catch((error) => {
console.log(error);
res.error(error.message);
});
});
But receive the error:
"You provided a customer without specifying a source. The default source of the customer is a source and cannot be shared from existing customer".
Im not able to specify its default source in the create token body. any help?
This issue was with the users source. Although the user had a credit card source it is not "shareable" (as the error kinda states) , you need to create a shared source when using stripe-connect.
https://stripe.com/docs/sources/connect#creating-direct-charges
You want to use this instead of the above tokens.create for direct charges in stripe-connect.
stripe.sources.create({
customer: "cus_AFGbOSiITuJVDs",
usage: "reusable",
original_source: "src_19YP2AAHEMiOZZp1Di4rt1K6",
}, {
stripe_account: "{CONNECTED_STRIPE_ACCOUNT_ID}",
}).then(function(token) {
// asynchronously called
});
FYI: I do not save or attach this new source, kept the primary one and the regenerate a new token for each purchase since my application is 1 to many sellers.

Handling Stripe errors with Node.JS

I am attempting to charge a user when they create an account. Everything is set up and working perfect with the code before. When a user sign's up for a "premium" section of the website they have an account created and are charged with the code below.
The problem: If a user's credit card ends up getting declined for various reasons... their user account is STILL created. How would I change my code below to not reach that part of the code if the credit card fails?
Note: this DOES work for when the user trys to create an account with a username that is taken. The web app redirects them to /buy to select a new username. However it does not work to handle the credit card errors because the user is created first.
Thank you for the help!
user.save(function(err) {
console.log('this is the problem' + ' ' + err)
if(err){
return res.redirect('/buy')
}
var token = req.body.stripeToken; // Using Express
var charge = stripe.charges.create({
amount: 749,
currency: "usd",
description: "Website.com Premium - One time Payment",
source: token,
}, function(err, charge) {
if(err) {
console.log(err);
return res.redirect('/buy')
}
console.log('charged')
req.logIn(user, function(err) {
if(err) {
console.log(err);
}
console.log('all looks good')
res.redirect('/results');
});
});
});
});

PassportJS and Stripe

I am attempting to charge a user when they create an account. Everything is set up and working perfect with the code before. When a user sign's up for a "premium" section of the website they have an account created and are charged with the code below.
The problem: If a user's credit card ends up getting declined for various reasons... their user account is STILL created. How would I change my code below to not reach that part of the code if the credit card fails?
Note: this DOES work for when the user trys to create an account with a username that is taken. The web app redirects them to /buy to select a new username. However it does not work to handle the credit card errors because the user is created first.
Thank you for the help!
user.save(function(err) {
console.log('this is the problem' + ' ' + err)
if(err){
return res.redirect('/buy')
}
var token = req.body.stripeToken; // Using Express
var charge = stripe.charges.create({
amount: 749,
currency: "usd",
description: "Website.com Premium - One time Payment",
source: token,
}, function(err, charge) {
if(err) {
console.log(err);
return res.redirect('/buy')
}
console.log('charged')
req.logIn(user, function(err) {
if(err) {
console.log(err);
}
console.log('all looks good')
res.redirect('/results');
});
});
});
});
The problem is you are handling the payment after you save the user to your database. There are two ways you could solve this. Either you could delete the user from your database if the payment fails. Or you could handle the payment THEN save the user to the database. So basically switching the order and which callbacks are nested inside of which callbacks.
I'd personally suggest the second solution because you will be making less calls to your database which will reduce the stress and load on your database.
Here is a basic example of how to achieve that. I don't know all of the in and outs of your code so you might have to make a few adjustments to fit how you are doing things but the basic idea is the there.
var token = req.body.stripeToken; // Using Express
var charge = stripe.charges.create({
amount: 749,
currency: "usd",
description: "Website.com Premium - One time Payment",
source: token,
}, function(err, charge) {
if (err) {
console.log(err);
return res.redirect('/buy')
}
console.log('charged')
user.save(function(err) {
console.log('this is the problem' + ' ' + err);
if (err) {
return res.redirect('/buy')
}
req.logIn(user, function(err) {
if (err) {
console.log(err);
}
console.log('all looks good')
res.redirect('/results');
});
});
});
So you are basically creating the stripe charge, and if it is successful then you create the user in your database.
Hopefully this helps!

Resources