Stripe Session Getting Customer Name - stripe-payments

I would also like to retrieve the name of the person who paid. How can I get the name value from the stripe session? I have tried this:
const sessions = await stripe.checkout.sessions.list({
limit: 1,
});
console.log(sessions.data[0].customer)
const customer = await stripe.customers.retrieve(sessions.data[0].customer);
console.log(customer)
which gets me the email, but the name is null.

UPDATE: Customers created through Checkout have a null name because it is not collected/set. The "name on card" field on the Checkout page is for the cardholder name for the payment method, not the name of the customer (see https://stripe.com/docs/api/payment_methods/object#payment_method_object-billing_details-name). If you want a Customer created through Checkout to not have a null name, you'll have to update the Customer after the session is completed.
Stripe has a dashboard setting (https://dashboard.stripe.com/settings/emails) you can enable that automatically sends receipts to customers for successful payments completed in live mode. Payments completed in test mode will not automatically send an email, but you can trigger one manually through the dashboard. You can read more about sending receipts here: https://stripe.com/docs/receipts#automatically-send-receipts-when-payments-are-successful.
If you want to grab the customer’s email and send a receipt yourself it’ll be a bit more complicated.
Wait for the Checkout Session to finish by listening for checkout_session.completed through a webhook endpoint (https://stripe.com/docs/payments/checkout/fulfill-orders#handle-the-checkoutsessioncompleted-event).
Grab the customer ID from the Checkout Session object that comes in with the checkout_session.completed event.
Using the customer ID from the previous step, retrieve the Customer object (https://stripe.com/docs/api/customers/retrieve) and get the customer’s email.

Related

How to retrieve receipt_url upon successful payment completion in Stripe

We are using the Stripe API to make payments for invoices using a SAPUI5/Fiori UI. The payment intent create happens via a node.js project. We are successfully able to initiate the payment and from the Stripe dashboard Payments section we can see that the payment gets processed successfully.
We have the requirement, that upon successful payment completion, we need to redirect the user to the receipt URL (receipt_url) to display the payment receipt of the just processed invoice. Below is the code we are using to invoke the create payment intent on the Stripe server:
const paymentIntent = await stripe.paymentIntents.create(
{
payment_method_types: ['card', 'us_bank_account'],
metadata: {
....
....
....
},
},
{apiKey: secretKey}
);
res.send({
clientSecret: paymentIntent.client_secret,
});
According to the Stripe documentation, we can retrieve the receipt URL by retrieving the charge within the paymentIntent, but the response we receive upon successful processing of the payment by Stripe does not contain the charge object, it just has the payment id. Is it possible in any way, to retrieve the receipt URL using only the payment intent id?
Calling the payment intent create on Stripe to process the payment, but we are not getting in the response the receipt_url value where we want to redirect the user to, upon successful payment completion.
You can find the receipt_url property on the latest_charge property (make sure you use an API version greater than 2022-11-15; in older versions, it was the last item of charges property), which you can expand on your successful Payment Intent.
For that, you need to add a parameter expand when you create a Payment Intent:
const paymentIntent = await stripe.paymentIntents.create({
…
expand: [“latest_charge”]
});
const receiptUrl = paymentIntent.latest_charge.receipt_url;

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.

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.

How to prevent creating duplicate subscription in stripe when trial period is set on subscription

I am encoutering a problem with stripe. let me explain my working
scenario.my requirement is do not charge user for 14 days with card up front
1)user enter card details
2)sca popup appear
3)regardless of user complete the authentication or not a subscription is created in stripe because i set trial_end_date=>now()+14 days
4)user payment fails in some reason and attempt again, another subscription created
i am worried about the duplicate subscription as the stripe will attempt to pay after the 14 days for both of these subscription as it send a Stripe-hosted link for cardholders for both of these subscription
let me give a snapshot of what i have so far
$data['customer']='customerId';
$data['items']=[];
$data['items'][0]['plan']='stripe_plan_id'
$data['default_payment_method']='pm_xxxx'
$data['trial_end']= strtotime('+14 days');
$data['prorate']=true;
$data['tax_percent']=env('VAT_PERCENTAGE');
$data['expand']= ['latest_invoice.payment_intent', 'pending_setup_intent'];
try {
$subscription=\Stripe\Subscription::create($data);
}
catch(Exception $e) {
return response()->json(['success' => false,'message'=>$e->getMessage()]);
}
what i am missing? how to prevent the duplicate subscription scenario.please expain with the correct example which is i am missing.thanks in advance
I think the problem is in your payment flow, there is not a stripe api that explicitly detects duplicate subscription. You are after all allowed to assign more then 1 subscription per customer id. You can create idempotent keys, but that isn't for the same thing you're talking about, idempotent keys are for accidently hitting the submit button twice within the same timeframe.
The solution would be to attach a payment method to your stripe customer id before your subscription trial is over. For example if you are using stripe elements you would call
Node/JS Example below :
const result = await stripe.createPaymentMethod({
type: 'card',
card: card
})
then pass that result to your backend
const result = await stripe.paymentMethods.attach(paymentMethodId, {customerId})
You do not need to create a new subscription, as one has already been created for that user. Credit cards are assigned to customer Ids, and not to subscriptions. Stripe will do the rest.
You do also need to update the customer with the default payment method as follows :
const customer_update = await stripe.customers.update(stripeCustomerId,{invoice_settings: {default_payment_method:paymentMethodId}});
Now when you visit your dashboard you will see a default card assigned to your customer. Once the subscriptions falls out of the trail period, the default card will be charged.
So in this case there wont be a duplicate subscription created, as you are not calling stripe.subscriptions.create again.

What to do when Strong Customer Authentication fails?

I am trying to implement a Subscription signup and payment flow with Stripe.js V3 and Strong Customer Authentication (SCA) like this:
var stripe = Stripe('pk_test_9hA8gecxBFTY3O6kUm7hl16j');
var paymentIntentSecret = 'pi_91_secret_W9';
stripe.handleCardPayment(
paymentIntentSecret
).then(function (result) {
if (result.error) {
// Display error.message in your UI.
} else {
// The payment has succeeded. Display a success message.
}
})
Everything works great when the payment succeeds.
But what am I supposed to do when it fails?
Should I redirect the user to the initial payment screen, so s/he can start over?
When I do that I get this error:
You cannot confirm this PaymentIntent because it has a status of canceled. Only a PaymentIntent with one of the following statuses may be confirmed: requires_confirmation, requires_action.
Or should I delete everything, including the previously created stripe_customer and stripe_subscription, and then start over?
Thanks for any help.
If the payment fails entirely(maybe it was declined, or 3D Secure was attempted but not completed successfully) , the PaymentIntent from the first invoice should be in the requires_payment_method state and the subscription is incomplete.
You can choose to attempt to collect new payment information from the user and use that to complete the invoice payment and activate the subscription. You can re-use the same PaymentIntent throughout this and try as many times as you wish. For example, if you had a payment form with a Card Element for collecting details, you can have the user enter a new card and call this again :
stripe.handleCardPayment(cardElement,
paymentIntentSecret
).then(function(res){...})
Alternatively you can choose to cancel the subscription entirely if you wish. Otherwise if you do nothing, or the customer isn't able to provide a payment method that works, after 24 hours, Stripe effectively cancels the subscription for you.
Your error message seems to indicate the PaymentIntent was cancelled, which might mean you cancelled the subscription, or you're trying this more than 24 hours after the initial payment, I'm not sure.
This link goes into more detail:
https://stripe.com/docs/billing/lifecycle#incomplete

Resources