Make email in Stripe Checkout for already existing customer read-only - node.js

I'm creating a Stripe checkout session (server-side) for already existing customer. According to Stripe documentation, I should pass customer Id as a customer parameter. Stripe internally gets the customer object and fills his email addess in the checkout UI. It works, but the email field is editable and I don't want users to be able to change their billing email. Is it possible to make this field read-only? Here my code:
await stripe.checkout.sessions.create({
line_items: [{ price: stripePriceId, quantity: 1 }],
customer: stripeCustomerId, // here I fill the stripe customer ID of the user
mode: 'subscription',
payment_method_types: ['card'],
allow_promotion_codes: true,
success_url: `${process.env.FRONTEND_URL}/premium-payment-success`,
cancel_url: `${process.env.FRONTEND_URL}/premium-payment-failure`
});
I'd really like to prevent users changing their Stripe checkout email, because knowing each user has the same billing email in Stripe would make things much easier.
Side note: When the user buys something for the first time, instead of customer parameter, I pass customer_email and the email is in this scenario read-only.
Any help is appreciated!

This is not currently possible, but I believe it's something Stripe is considering adding.

Related

Generate Stripe Subscription Link

I want to create a payment link for a subscription in the backend and send it to the client without having any frontend site.
const customer = await stripe.customers.create({
metadata: {
author_id: "author_id",
custom_id: "custom_id",
},
....
}
First I created a customer, using my app specific credentials. Then I want to generate a link using this custome id, but I'm kinda confused how to make it work,
Stripe documentation shows something like this,
await stripe.paymentLinks.create({
line_items: [{price: price_id, quantity: 1}],
});
But it creates a completely new product price.
Is there any way to create a link using pre made product price id and customer metadata using Stripe NodeJS backend?
You cannot pass a pre-existing Customer object (cus_xxx) when creating a Payment Link. The default behaviour for Payment Links infer that a new Customer object be created depending on other parameters set on the Payment Link, as noted in the documentation:
The Checkout Session will only create a Customer if it is required for Session confirmation. Currently, only subscription mode Sessions require a Customer.

Stripe: Make transfers from a user's card and not from my account balance

I have already followed Stripe's documentation to make transfers. I get an error telling me that I do not have sufficient funds on my balance. In my case, I would like not to transfer the money from my account but from the card of the user making the purchase. I specify that I need to make transfers because I can have several accounts connected for a single payment.
Here is the steps I follow:
On the client side (Flutter), I ask a user to enter his bank card information. I then generate a PaymentMethod object that I send to my server (Node.js).
(server side), I execute the paymentIntent.create method
const paymentIntent = await stripe.paymentIntents.create({
amount: amount,
currency: "eur",
payment_method: paym,// id get from client side
payment_method_types: ["card"],
transfer_group: "{ORDER1}",
});
(server side), create transfers
const transfer1 = await stripe.transfers.create({
amount: amount / 2,
currency: "eur",
destination: "acct_###########",
transfer_group: "{ORDER1}",
source_transaction: ?,
});
I know that I have to fill in the source_transaction field to make the link between PaymentIntent and Transfer. I can retrieve this information in the PaymentIntent object with the charge field but it is empty. This means that I must first validate the payment on the client side before making the transfer.
Only when I validate it on the customer side, I receive the following error No such payment_intent when I execute:
StripePayment.confirmPaymentIntent(PaymentIntent(
paymentMethodId: result.data['paymentIntent']['payment_method'],
clientSecret: result.data['paymentIntent']['client_secret']))
Is there something I do wrong or missing ? Do you have an example of a simple implementation ?
Thank you for your time.
You should be able to use the Payment Intent ID as the source_transaction value.

Send money to a bank account using Stripe | Node JS

So I have this React application where users can buy gift cards online, and I'm using Stripe Payments. So far, the users can pay the money, except it will go to me(through Stripe), not to the merchant selling the Gift Cards on my app.
Is there a way with Stripe to send money to a bank account? Keep in mind that the bank account will be different for each Gift Card any users can buy.
For example, one person selling the gift cards will be the one earning the money through a different bank account than another person.
If there is a way, please tell me how to implement it, and thank you very much in advance.
I finally figured how to do this. You have to follow these steps:
1: Integrate Stripe Checkout
2: Integrate Stripe Onboarding for express accounts
These two steps are the fundamental steps in doing this.
How To Integrate Stripe Checkout:
You can get stripe checkout by using the
stripe.checkout.sessions.create
method. You can then pass in arguments like:
payment_method_types: ["card"],
locale: locale,
line_items: [
{
name: `${Name}`,
images: ["Images"],
quantity: 1,
currency: usd,
amount: price, // Keep the
// amount on the server to prevent customers
// from manipulating on client
},
],
payment_intent_data: {
transfer_data: {
destination: product.id,
},
},
success_url: `success`,
cancel_url: `cancel`,
What this will do is create a new checkout session to use.
Next Step, Onboard the businesses
All you have to do for this is to go to a URL:
const url = `https://connect.stripe.com/express/oauth/authorize?${args.toString()}
where args is this:
const state = uuid();
const args = new URLSearchParams({
state,
client_id: process.env.STRIPE_CLIENT_ID,
});
Send this data to your frontend and you will get a good looking form that onboard users and creates express accounts for them.
The basic concept is simple, you onboard the businesses, which creates a stripe account for them. Then with the checkout form, you send the money to that created stripe account. This account will automatically deliver to the businesses bank or debit account, thus making customer to merchant payments.
Here are some helpful documentation I used to solve the problem:
https://stripe.com/docs/payments/checkout
https://stripe.com/docs/payments/checkout/accept-a-payment
https://stripe.com/docs/connect
https://stripe.com/docs/connect/collect-then-transfer-guide
https://stripe.com/docs/connect/express-accounts
I hope this helps!

Stripe invoice for one time charge

I'm trying to create a one-time charge in Stripe, I have already added all my products to Stripe, and I'm creating an order and charge like this:
const order = await stripe.orders.create({
customer: customer.id,
currency: 'usd',
items: [
'sku_0001',
'sku_0002',
],
email: 'test#test.com',
});
const charge = await stripe.orders.pay(order.id, {
customer: customer.id,
email: 'test#test.com',
});
However, on the invoice send my Stripe, it only shows one item, with description: Payment for order or_1GTmxxxxxxQjbLdncktm0.
How can I have all the ordered items show up on the invoice, or at the very least, something a bit more descriptive. My customers have no idea what this order ID means, or what they have paid for.
If you're developing a new integration, I'd advise against using Orders, since it is deprecated.
The best solution depends on what you're trying to do, beyond the invoice mechanics. One great option is to use Checkout for one-time payments to charge your customers. It does not leverage the products directly, but you can use that same data on your server to populate the line items.
Your other option is to create the Invoice directly, by adding line items to your customer. When you do this, and choose to send an email invoice, your customer will see a hosted invoice page with all invoiced items included.

New Customer created by Checkout, then create Subscription on Customer results in Error: This customer has no attached payment source

New Customer created by Checkout, then create a new Subscription on the same Customer by Node SDK results in Error: This customer has no attached payment source.
However if I look at the Customer at the dashboard, there is a Card, but not set as Default. Once it is "Set as Default" by clicking the ... it works.
Here is the code I used to create a new Subscription on a Customer:
const customer = 'cus_xxxxxx'
const plan = 'plan_xxxxxx'
stripe.subscriptions.create({
customer,
items: [
{
plan
}
]
})
I'm not sure if this is a limitation of Checkout since https://stripe.com/docs/payments/checkout says
Better support for saving customer details and reusing saved payment methods
Right now my workaround is to use webhook to update Customer's invoice_settings.default_payment_method on payment_method.attached.
This works but it feels strange. Did I miss something? Why does Checkout not set the only Card as invoice_settings.default_payment_method?
This behavior seems intentional on Stripe's part, the card from Checkout is attached to the Customer as a Payment Method, and is not set as default.
The same thing happens if you create a Customer directly with a PM,
let cust = await stripe.customers.create({ payment_method: "pm_card_visa" });
Also, fwiw, one can create their subscription directly from Checkout, passing a plan instead of sku https://stripe.com/docs/stripe-js/reference#stripe-redirect-to-checkout
From Stripe support:
Checkout does not currently support the ability to reuse saved payment
methods. We are aware that this is a feature request for a lot of our
users, and we are working on implementing this in the future.
If you'd like, you can see a roadmap of the updates we'll be making to
Checkout in the document below.
https://stripe.com/docs/payments/checkout#checkout-roadmap
That said, the work around you're doing for the moment is the same
work around that we're suggesting to users for the time being.
After a lot of digging I realized there is one step that is easy to miss in the docs: take the attached payment method and set it up as a default.
Here is my full server node.js code for creating a subscription:
const customerResponse = await stripe.customers.create({ email, name })
const customer = customerResponse.id
await stripe.paymentMethods.attach(paymentMethodId, { customer })
await stripe.customers.update(customer, {
invoice_settings: { default_payment_method: paymentMethodId }
})
await stripe.subscriptions.create({
customer,
items: [{ price: 'price_XXXXXX' }]
})
paymentMethodId name and email come from the client.

Resources