Generate Stripe Subscription Link - node.js

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.

Related

NodeJs Update default credit card of customer for Stripe subscriptions and payment

I am building an app in which i am using stripe to handle all payments. And in our app we have a common feature where user can update the default card for their subscriptions but it not working as expected. I Have followed the instruction to update the customer payment method as described in the stripe documentation but it's not working as expected i still see the old credit card details as default payment method in stripe dashboard.
Updating the customer:
const customer = await stripe.customers.update(body.customerId, {
invoice_settings: {default_payment_method: body.pId},
});
Attaching payment method to customer and updating subscription:
const paymentMethod = await stripe.paymentMethods.attach(body.pId, {
customer: body.customerId,
});
await stripe.subscriptions.update(subscriptionDetails?.planId as string, {
default_payment_method: paymentMethod.id,
});
But still nothing, i am not sure what i am missing here but i couldn't update the default payment method.
The screenshot you shared refers to the payment methods saved on the Customer. If you wish to set the default payment method on the Customer, it will be under invoice_settings.default_payment_method on Customer API.
Subscription's default payment method is different from Customer's default payment method. With default_payment_method on Subscription API, it will only update the default on the Subscription object, not Customer object like the page you see. You should be able to find Subscription's default payment method at the Subscription page.
Subscription page link will be: https://dashboard.stripe.com/test/subscriptions/sub_xxx where sub_xxx is the Subscription ID.

Creating a subscription using bank account number using stripe js in node js

I have created subscription by accespting credit/debit card number, exp month, exp year and cvc from front end angular app and creating
Customer
Product
Product Price
Payment Method
Subscription
In payment method i provide following details:
async function createPaymentMethod(data) {
let body = {
type: 'card',
card: {
number: data.card?.number,
exp_month: data.card?.exp_month,
exp_year: data.card?.exp_year,
cvc: data.card?.cvc
}
};
return await stripe.paymentMethods.create(body);
}
Now i want to create payment method but want to use customer's bank account number but i am unable to find a way to do it. I want to add "type: bank_account"
Note: I am using Strip JS and Node JS. All of this I want to do on server side i.e node js
Collecting Credit Card server-side is a bad idea, since you will expose yourself to the burden on PCI-Compliance. You would want to review Stripe's Integration Security Guide. Generally you would want to use client-side SDK to collect credit card information instead.
To the question of a bank account, it depends on which specific PaymentMethod you're gonna use (which country's bank transfer?) Ie. If you are talking about ACH in the US, you should follow the ACH Guide. Similarly it will collect bank account information client-side in exchange of a token, then passing it up to your back end.

Add Stripe Credit Card without Payment in SwiftUI

I am struggling to find a solution that isn't UIKit, or one that requires you make a purchase.
My project is trying to integrate Stripe in SwiftUI, using node.js Firebase Functions for backend handling.
I built a STPPaymentCardTextField in UIViewRepresentable. Which allows me to obtain credit card details for the customer via State.
#State var params: STPPaymentMethodCardParams = STPPaymentMethodCardParams()
SwiftUI TextField
StripePaymentCardTextField(cardParams: $params, isValid: $isValid)
Then we can build paymentMethodParms like..
let paymentMethodParams = STPPaymentMethodParams(card: params, billingDetails: billingDetails, metadata: nil)
Now I could easily pass the credit card details to my backend and add the card manually using
Function for adding payment method
const createPaymentMethods = functions.https.onCall(async (data, context) => {
const paymentMethod = await stripe.paymentMethods.create({
customer: '{{CUSTOMER_ID}}',
payment_method: '{{PAYMENT_METHOD_ID}}',
}, {
stripeAccount: '{{CONNECTED_STRIPE_ACCOUNT_ID}}',
});
}
but I am understanding this is bad practice.
I found this post which might be a "duplicate", but is the closest relevant answer. Adding customer's Credit card info in stripe. That user however is using reactjs and wanted to store credit card details in a database, where I only want to pass it to Stripe.
Is there not a way I can send the credit card data to Stripe, get a paymentMethod ID back, and pass that to my backend or something? I have already solved subscriptions, and purchase charging, I just can't get a credit card setup without going through the payment setup process. I want the user to add a credit card manually on creating a new account and/or in settings.
Can you call stripe-ios's createPaymentMethod() function [0]? That is a client-side function your SwiftUI app would call to tokenize the card details from paymentMethodParams into a PaymentMethod object. You can then pass that ID server-side to attach to a Customer.
[0] https://stripe.dev/stripe-ios/docs/Classes/STPAPIClient.html#/c:#CM#Stripe#objc(cs)STPAPIClient(im)createPaymentMethodWithPayment:completion:
To expand on #hmunoz's answer and the way I got this to work is as follows.
Create your user a Stripe account. https://stripe.com/docs/api/customers/create
Log the customers stripe id in your user's Firestore database for easy reference.
Create an "Add card" view to your frontend and call to the add payment method function. https://stripe.com/docs/api/cards/create
Upon checkout as long as the customer's stripe ID is passed in the payment intent it should populate with their saved payment methods.
In summary it is best to keep track of your user that is signed in so that you can do any CRUD needed throughout.

Stripe TypeError: Cannot read property 'payment_intent' of undefined

I'm integrating the payment methods to the app with Stripe and Paypal and now working on Stripe integration.
The backend is Node, Sails.js, and the frontend is React.js.
I followed the guide they provided but and tested the payment processing using testing card.
But I got the error, which says TypeError: Cannot read property 'payment_intent' of undefined.
Here is my code.
- Frontend
this.props.stripe.createPaymentMethod({
type: 'card',
card: cardElement,
}).then(({paymentMethod}) => {
// API call
})
- Backend
subscribe = await stripe.subscriptions.create({
customer: customerId,
items: [
{price: plan.stripe.stripeId},
],
expand: ['latest_invoice.payment_intent']
});
Please help me to fix this issue.
In my opinion you don't have to create the PaymentIntent per subscrition.
Here is what Stripe API docs says about paymentIntent.
A PaymentIntent guides you through the process of collecting a payment from your customer. We recommend that you create exactly one PaymentIntent for each order or customer session in your system. You can reference the PaymentIntent later to see the history of payment attempts for a particular session.
So they recommend to create the paymentIntent per transaction and in subscription case, the payment is proceed in background automatically and paymentIntent is also generated in my experience.
But on the other hand in checkout option, you need to create the paymentIntent first before proceeding the payment.
I think you code was not wrong but I think you didn't follow the correct guide from Stripe or used wrong credit card.
Please refer this link:
Stripe API Payment_intents

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