Passing Metadata While Generating Stripe Payment Link - node.js

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).

Related

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

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']
})

Stripe APi paymentIntent and sessions object

I am having trouble finding out the difference between payment Intent and a session.
Assuming I a customer logs into a page and goes to domain.com/register how can I create session and check if customer has already visited page by using customer email address to get the customer object?
What are the difference between paymentIntent and session and how do they help? I see that session is created on Checkout but not when accepting one time payments.
Current I create a payment intent and it works find but my 'url' has no session
PaymentIntents
A PaymentIntent is an API object in Stripe's API that create encapsulates a lifecycle of a one-time payment.
You typically create your own form on your webpage when using PaymentIntents, create a PaymentIntent using the Stripe API, then confirm it using the cardElement from Stripe Elements (the frontend UI elements for collecting card details).
Checkout
Checkout is a full page "hosted UI" that creates its own PaymentIntent and provides all the UI that a customer needs to enter their card details and takes a payment. It also supports many other payment methods automatically without you having to manually add support for each one.
So a CheckoutSession under the hood uses a Subscription or a PaymentIntent object, depending on whether it was used in subscription or payment mode.

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.

Stripe - Create subscriptions with a customer with PaymentMethod instead of Source (Token)

I'm integrating Stripe Subscriptions in our workflow, but when creating a subscription with a Customer created with a paymentMethod instead of source I receive the error This customer has no attached payment source.
If I call in the browser createToken() and attach it to the customer in the source field it works.
We integrated one-time payments using the new docs with SCA that use createPaymentMethod() and not createToken(), so our customers are saved with paymentMethod, not source, like explained here:
https://stripe.com/docs/payments/cards/saving-cards-after-payment#save-payment-method
curl https://api.stripe.com/v1/customers \
-u sk_test_secret_token \
-d payment_method="{{PAYMENT_METHOD_ID}}"
Furthermore, in the migration guide it says to replace createToken() with createPaymentMethod().
In Scenario 2: Charging customers off-session for their initial payment, I saw the following:
To create subscriptions and charge customers off-session for their
initial payment, you need to:
1) Use CreatePaymentMethod to collect payment information
2) Create a customer using the ID of the PaymentMethod you created
3) Create the subscription
4) Set up error handling using handleCardSetup for authentication failures and handleCardPayment for authorization failures
I followed those steps. I don't create a SetupIntent (just like I don't create it in one-time payments and it works in these cases), and receive the error I said before when trying to create subscriptions.
Is it possible to create subscriptions with a customer with paymentMethod instead of source?
(We reuse cards using the customers created with paymentMethod for one-time payments, so it would be very important to be able to reuse the same customer/card for subscriptions, without the need for the user input data in stripe elements or anything of the sort, because it would break our flow for reusing cards)
I was able to solve it by including the payment method in the field default_payment_method.
This field is described as follows:
ID of the default payment method for the subscription. It must belong
to the customer associated with the subscription. If not set, invoices
will use the default payment method in the customer’s invoice
settings.
So I assumed that it would use the payment method I associated with the customer when not defined. It seems it is not happening, tough, so I needed to pass it explicitly (is it a Stripe bug? or creating the customer with paymentMethod doesn't make it the default payment method in the customer’s invoice settings? I will contact Stripe to make sure).
Update (2019-09-23)
I contacted Stripe asking if this was a bug and they replied:
[...] With that being said though, this wouldn't be a bug on our end, rather
expected behavior.
If you're wanting for the Payment Method that you're adding to the
customer object to be used on subscriptions, or invoices, by default
without specifying the default_payment_method when creating the
subscription then you would want to attach the Payment Method and
specify the invoice_settings.default_payment_method parameter when
updating the customer. This information can be found within our API
reference here:
https://stripe.com/docs/api/payment_methods/attach
The parameter to use when updating this can be found on the customer
object itself, here:
https://stripe.com/docs/api/customers/update#update_customer-invoice_settings-default_payment_method
This can also be specified upon customer creation, which can be seen
here:
https://stripe.com/docs/api/customers/create#create_customer-invoice_settings-default_payment_method
Specifying this parameter would indicate that the card being added
would be the default for subscriptions, as well as invoices, so that
the default_payment_method wouldn't need to be specified upon the
subscription, or invoice, creation.

Braintree API: How can I tell which payment_method is associated with my nonce?

Background:
I create a braintree customer with firstName, lastName and email
I use the dropin ui in checkout form and it creates a payment_method and token and sends me a nonce. Good so far.
I need to add a billing address to the payment_method before I charge the nonce...
Question:
How can I discover which payment_method is associated with my nonce?
Edit to add:
There is a paradoxical reference at the bottom of the javascript+PHP page to an otherwise undocumented [paymentMethodNonce] parameter which uses an also undocumented [options][verifyCard] parameter. I suppose I could run [paymentMethodNonce] sans [options] against each payment_method token associated the user and inspect the errors... lol.
I work at Braintree. If you have more questions, I suggest you reach out to our support team.
When you use the Drop-In UI, it doesn't automatically create a payment method, just a nonce. You pass the nonce back to your server and create a payment method with it:
$result = Braintree_PaymentMethod::create(array(
'customerId' => '12345',
'paymentMethodNonce' => 'nonce-from-the-client'
));
If the nonce points to an already-vaulted payment method for that customer, you'll get back the existing payment method rather than a duplicate.
You can then update that payment method to add a billing address before using it to create a transaction.

Resources