#rohailkamran
1 messages · Page 1 of 1 (latest)
Hello! We'll be with you shortly. Below are links to other discussions we've had with you in the past week in case you want to review that information. If your question is related to one of these previous discussions, please provide a comprehensive summary of the current state and what you need help with now. We help many users simultaneously, so a summary allows us to resolve your issue as soon as possible.
- rohail-checkout-embedded, 17 hours ago, 5 messages
Thanks! And yes.
I strongly recommend against using Charges and Sources API since it's legacy.
And even more, you should absolutely never save credit card info in metadata, since it breaks PCI-compliance: https://stripe.com/gb/guides/pci-compliance
What guides are you following?
I see! I would do away with the meta data part immediately.
I have been following the docs here:
https://stripe.com/docs/api
If I should not use charges, what should I use? Payment Intents?
Complete reference documentation for the Stripe API. Includes code snippets and examples for our Python, Java, PHP, Node.js, Go, Ruby, and .NET libraries.
If I use payment intents, my step 2 should look something like this:
const paymentIntent = await stripe.paymentIntents.create({
amount: 2000,
currency: 'usd',
automatic_payment_methods: {
enabled: true,
},
customer: customerId,
});
Thanks. I feel a lot better using things that are actively supported.
Let me try this and get back to you. Do you think this will solve my problem?
Depends what are you trying to do exactly.
About this, I don't really want any payment related detail to go to my server.
Sure, let me explain.
And you shouldn't have, unless your server is PCI-compliant. If you use the recommended Stripe integrations you will not have to worry about it.
I am only trying to do a poc for the following user story:
-
User goes to a sign up form and optionally puts in their payment details
-
The payment details go to stripe and a customer id is returned
-
We create a user in our db with returned customer id with the intention of ideally not having to use anything other than this customer id in the future for payments etc.
-
Customer goes to dashboard and decides pay for something (a product, subscription, donation whatever)
-
We simply get the customer id from our db, and use the stripe api to charge the customer the amount for whatever they chose in step 4
Here, steps 1, 2, 3 work, I have also been able to unit test charges and they have worked in test mode.
But doing steps 1, 2, 3, 4, 5 in sequence for a poc has resulted in the following error:
Error: Customer <customer_id> does not have card with ID tok_visa
at StripeError.generate (Error.js:10:20)
at res.toJSON.then.Error_js_1.StripeAPIError.message (RequestSender.js:105:54)
To save Payment Method to charge them in the future you need to use SetupIntents: https://stripe.com/docs/payments/save-and-reuse?platform=web&ui=elements
I think the code of interest to this error should only mainly be the following two snippets:
- How I create a customer:
const customer = await stripe.customers.create({
name: fullName,
email: email,
metadata:{
credit_card_number: creditCardNumber,
expiry_month: expiryMonth,
expiry_year: expiryYear,
cvv:cvv,
address:address,
city:city,
state:state,
zipCode:zipCode,
}
});
- How I am trying to charge that customer:
const charge = await stripe.charges.create({
amount: amount,
currency: 'usd',
source: 'tok_visa',
customer: customerId
});
I will remove the metadata and switch to payment intents but I think the problem will still persist. How can I add a card for the customer in test mode or broadly speaking, how can I solve this?
I recommend you to drop the code you currently have and explore the guides I shared with you, and then start over. This error message is only relevant to the code you shared, however it has nothing to do with what you're trying to achieve and uses outdated APIs.
Hmm I see. Thanks for your help!
If there is no easier way to accomplish this, kindly tell me if I understand the whole thing correctly this time:
hi! I'm taking over this thread.
Aoa Hi!
let me know if you have any other questions
Should I give a small recap of what I am trying to do?
Very briefly, I am just trying to create a customer, store the id of the customer in my db and then every time a user wants to make a purchase, charge the associated customer_id.
got it
I have been told that I should use setup intents for this. Is there a simpler way? One that would allow me to make minimal changes to what I already have?
Yes SetupIntent work for this! Another option that is simpler to implement is to use Checkout Sessions (https://stripe.com/docs/payments/save-and-reuse?platform=web&ui=checkout)
I see! Thanks!
If I go for Checkout Sessions, can I do this (all on client side):
Step 1: Creating a customer
const customer = await stripe.customers.create({
name: fullName,
email: email,
});
Step 2: Attaching a payment method to the customer:
const checkoutSession = await stripe.checkout.sessions.create({
payment_method_types: ["card"],
mode: "setup",
customer: customer.id,
success_url: `<what-should-I-put-here-on-localhost>`,
cancel_url: `<what-should-I-put-here-on-localhost>`
});
Step 3: Charge a payment when they buy a product:
const paymentIntent = await stripe.paymentIntents.create({
amount: 2000,
currency: 'usd',
automatic_payment_methods: {
enabled: true,
},
customer: customerId,
});
If I go for Checkout Sessions, can I do this (all on client side):
everything has to be done on the backend side
and in step 3 you forgot to set the payment_method property
other that than, it looks correct
I see, can you please share an example of how I would do that?
you can see an example of this here: https://stripe.com/docs/payments/save-and-reuse?platform=web&ui=elements#charge-saved-payment-method
I see.... Thanks. I think I can manage that if I must.... but just to be sure, is there no way that save me from having to write server side code for this?
If not, is this one of the minimal server side approaches?
Checkout Session in setup mode would be the simplest option yes
Oh so:
Step 1: Creating a customer
const customer = await stripe.customers.create({
name: fullName,
email: email,
});
Step 2: Attaching a payment method to the customer:
const checkoutSession = await stripe.checkout.sessions.create({
payment_method_types: ["card"],
mode: "setup",
customer: customer.id,
success_url: `<what-should-I-put-here-on-localhost>`,
cancel_url: `<what-should-I-put-here-on-localhost>`
});
Step 3: Getting payment methods for customer when they buy a product:
const paymentMethods = await stripe.paymentMethods.list({
customer: '{{CUSTOMER_ID}}',
type: 'card',
});
Step 4: Charge a payment from one of their payment methods:
const paymentIntent = await stripe.paymentIntents.create({
amount: 2000,
currency: 'usd',
automatic_payment_methods: {
enabled: true,
},
customer: customerId,
payment_method: paymentMethods[0].id
});
got it! Thanks! Please just review the steps and I think I am good to go.
One last thing though that's been confusing me a bit... in the documentation what does the client_secret refer to?
you forgot step 2.5 : redirect the user to the Checkout Session URL so they can entier their payment details.
I see!! Thanks!!
and step 4: you can remove automatic_payment_methods and you should add confirm:true and return_url, as mentionned in the link I shared
got it! thank you so much!!
the urls can be localhost urls over http right?
cuz I am in test mode
also, if everything checks out, there was this last thing about client_secret that was confusing... what is it referring to and where/how do I get it?
yes you can test everything in localhost
also, if everything checks out, there was this last thing about client_secret that was confusing... what is it referring to and where/how do I get it?
if the PaymentIntent fails because the bank requires the user to go though 3DS, then you'll need to retrieve theclient_secretof the PaymentIntent to try to re-confirm the PaymentIntent on the frontend with https://stripe.com/docs/js/payment_intents/confirm_card_payment#stripe_confirm_card_payment-attached
but don't worry about this for now. first, make sure that everything else works.
Alrighty! I will get to it then. Thanks for all your help Soma and Vanya.