Stripe - Get risk score from checkout.session.completed event - stripe-payments

I have a webhook for checkout.session.completed. There is no information about risk score in the object I receive. How can I get the risk evaluation information for my customers' payments?
I can see the risk score from Stripe dashboard, but I also need it in my database.

The risk_score field is set on the Charge object associated with the payment. This object is not directly available on the Checkout Session object or events.
In order to retrieve these details, you'd need to make an additional API request in your webhook handler. My recommendation would be to retrieve the associated Payment Intent using the pi_xxx ID from the payment_intent field on your checkout.session.completed event, and expand the latest_charge field. The response will include the full Charge object, including the required outcome.risk_score field.
This will look something like this using the stripe-node library:
const paymentIntent = await stripe.paymentIntents.retrieve('pi_xxx', {
expand: ['latest_charge']
})

Related

Passing Metadata While Generating Stripe Payment Link

I want to pass a few app specific credentials with stripe url for checkout.
I tried something like the following,
const paymentLink = await stripe.paymentLinks.create({
line_items: [{price: "price_1XXXXK", quantity: 1}],
metadata: {
author_id: "author_id",
server_id: "server_id",
},
});
But in payments tab, the metadata is still empty.
I can only see those metadata in generated payment link section. But I can't find any relations or references about the link that was used to make the purchase on the payment response data.
So is there any better way to add metadata to the checkout while creating a payment link, instead of adding metadata just for the generated link?
Passing the metadata parameter when creating a Payment Link will only persist on the generated Checkout Session object, and not the underlying payment:
Metadata associated with this Payment Link will automatically be copied to checkout sessions created by this payment link.
But I can't find any relations or references about the link that was used to make the purchase on the payment response data.
To reconcile the Payment Intent object with the associated Payment Link that was the origin of the payment:
List all Checkout Sessions, passing the payment_intent parameter.
Expand the payment_link field on the returned Checkout Session object.
The Create method for Checkout Sessions supports these parameters:
payment_intent_data
metadata passed this way will be available in both payment_intent.succeeded and charge.succeeded events.
setup_intent_data
subscription_data
That let you pass data to the underlying payment_intent/setup_intent/subscription objects and it supports metadata.
So you'd be able to pass metadata to, say, a PaymentIntent this way.
See: https://support.stripe.com/questions/using-metadata-with-checkout-sessions
In passing / rant: most people will need to use metadata so as to get an "easy" way to know which products are in the order, because out of the box the Stripe API does NOT tell you, in an event, which product was ordered 🙄 (except for Payment Links).

Stripe Elements update subscriber payment method

How to enable users to update their subscription's payment method using Stripe Elements?
I couldn't find any reference to this neither in the docs nor on Stackoverflow.
This is how I'm currently setting the default payment method when the user first subscribes to our service.
Create a Stripe subscription object
Render the React CardElement component.
On submit, I call the browser's side Stripe library with stripe.confirmCardPayment(cardElement)
This then triggers a invoice.payment_succeeded webhook event.
In the webhook event, I get the payment intent ID which I use to retrieve the payment intent object which has the ID of the payment_method attached to it.
I then update Stripe's subscription object to use the successful payment_method's ID as the default payment method.
Is there a way to update the subscription's payment method without making a payment_intent first? Link to docs would be appreciated.
Thank you
You can use SetupIntents to save a customer’s card without an initial payment : https://stripe.com/docs/payments/save-and-reuse-cards-only [until step 4]
Listen for the setup_intent.succeeded webhook event to know when the SetupIntent is successful since the customer could close the browser window or quit the app before the stripe.confirmPayment callback executes.
Update the Subscription to use the resulting PaymentMethod ID as the default payment method.
Alternatively, you could also make use of the Customer Portal to allow customers to update their payment method for a subscription : https://stripe.com/docs/billing/subscriptions/customer-portal

How to save card details (payment method) in Stripe using backend?

The docs only covers the case where the payment method is created by the frontend (JS). But there is a risk that the user leaves the website before the frontend sends the information to the backend that the card has been added (and its ID).
In order to make a payment, I need ID of the payment method. I don't want to query Stripe's API for user cards IDs every time before making a payment, so I want to save the payment method ID in my local database. I also want to allow the user to define more payment methods and choose the default one.
Is there a reason you are using the non-recommended workflow you linked to? The most up-to-date version can be found here
Have you checked out using webhook listeners? I use them to create/update my local records.
In the workflow you reference, 3 webhook events potentially fire. First the setup_intent.created event is triggered when your server code generates the SetupIntent and its client_secret. Then, when the user fills out whatever Payment or Card element you instantiate and your frontend code calls the stripe.confirmCardSetup() (or stripe.confirmSetup() in the case of a PaymentElement), both the setup_intent.succeeded and payment_method.attached events will fire.
This last one will POST the payment_method object that was just attached to your customer back to your system. This object will have both the Payment Method ID as well as the associated Customer ID. You can use these to update your local records to map payment methods to customers in your server and avoid unnecessary API calls.

How do you match a Stripe Checkout to a charge.succeeded webhook?

We are using the Stripe Checkout and setting our metadata when we create the Session. This allows us to catch the checkout.session.completed webhook and that webhook contains the metadata.
However, we also use Sources, like WeChat, and these are not handled by the Stripe Checkout. To use WeChat, we create a Source and when the user confirms via the QR code, we charge it.
We want to use the charge.succeeded webhook as a central place to fulfil orders, regardless of where they come.
The issue is that the charge.succeeded webhook generated from a successful Stripe Checkout does not contain any of the Session metadata we set, so we can't link it to a Checkout Session and hence have no idea what it relates to
The only way we can see how to do this is:
Stripe Checkout
Catch the checkout.session.completed webhook and use the included metadata to fulfil the order. For the customer details, we can call the Payment Intent
WeChat (And other sources)
Catch the charge.succeeded webhook which contains both the customer data and the Source, which contains the metadata.
The Charge object will have a payment_intent and you can list CheckoutSessions by that PaymentIntent's id.
Alternatively, you can also set the metadata directly on the PaymentIntent when creating the CheckoutSession.

Get charge id associated with Stripe checkout session

I am using Stripe checkout sessions. I am capturing 'checkout.session.completed' webhook. I need to know charge id associated with the session so I can refund the customer later. I am not finding any reference to charge object in the session object.
How can I get charge object associated with checkout session?
I tried capturing charge object in charge.succeeded webhook, but it doesn't have any reference to the price object customer used to purchase.
A completed Checkout Session will have an associated PaymentIntent, which in turn has a list of Charges associated with it.

Resources