#henkcorporaal-react native
1 messages · Page 1 of 1 (latest)
@limber vector do you have the PaymentIntent pi_xxx you're using with the instance of the PaymentSheet that crashes?
yes. The PaymentSheet does not crash. It simply shows up an instance of a second and immediately disappears.
can you share the ID of the PaymentIntent? (it's not sensitive, you can just share it here)
pi_3JdAExEniMTe3FpI0XOuHo4J
thanks, give me a little time to look
oh it's the PaymentIntent from an Invoice and you're trying to pay it through the RN SDK, interesting
Correct.
not seeing any thing useful in our logs unfortunately, and I highly doubt we ever tested this exact scenario, so we'd probably have to sit down and replicate this. Can you write to https://support.stripe.com/email with the exact code you're using, that PaymentIntent ID and the exact contents of your npx output or any other errors/logs you're seeing?
The common scenario would be to create a PaymentIntent directly and process payments off of that I assume.
Problem with that is that I still need a detailed invoice with all purchase items and tax and I believe it's not possible to set a PaymentIntent on an invoice item or to create an invoice off of a PaymentIntent. Correct?
yep! But it should technically work the same with an Invoice's PaymentIntent
and yes PaymentIntents don't support line items or tax(they just take raw amounts) and you can't associate a PI with an Invoice separately
I can try to quickly test this in an iOS app, one sec
So my setup is the only way to go about this?
yep it's totally reasonable
like I said, we probably didn't test this(especially with React Native) so maybe something is broken
if you could run a quick test on your setup, I'd much appreciate that.
so I tested it at least on iOS and it works(having a customer with just an ACH bank account and then using the PaymentSheet to pay an Invoice's PaymentIntent). You can't pay with an ACH debit, the sheet doesn't support that, but adding a card and paying works.
looking at your logs you are voiding the invoice soon after creating it. Maybe you do that before attempting the payment in the app? That would explain things at least.
That's somewhat good news! I am voiding the invoice when the paymentsheet gets dismissed. I can run a test with not voiding the invoice, but I doubt that's going to change my outcome.
I'm working with @stripe/stripe-react-native version 0.2.2. Is that same with yours?
I'm not using react-native, I'm using our native iOS SDK
I don't have a set up of the React Native SDK using the PaymentSheet unfortunately which is why I asked you to write in with complete details(also please share the exact code you've written) so we can spend time to reproduce your exact set up as it will probably take a while unfortunately
Beyond that, I'd imagine there has to be some error getting logged somewhere
if you're running the app with npx run android maybe try checking Logcat logs on the simulator with the adb shell and see if anything appears at the time sheet closes itself; or if there are logs in the npx output itself in your terminal
Android debug mode gives me the following: 'A PaymentIntent with status='requires_payment_method' or 'requires_action` is required.\nThe current PaymentIntent has status requires_confirmation.\nSee https://stripe.com/docs/api/payment_intents/object#payment_intent_object-status.'
Complete reference documentation for the Stripe API. Includes code snippets and examples for our Python, Java, PHP, Node.js, Go, Ruby, and .NET libraries.
Can I control the payment status by creating/updating the Invoice object?
oh interesting
oh I think I see
when I do this on my account, which is Irish, the PaymentIntent can't be paid using ACH, but you're a US account so it can. You probably have ACH available as a 'Default payment terms' on https://dashboard.stripe.com/settings/billing/invoice , right?
Yes. Looks like it.
so yeah, we attach the customer's default source(the ACH bank account) to the Invoice's PaymentIntent which is why it's requires_confirmation (the payment method is attached and just needs an API call to process the payment).
I mean to be clear, you can't pay this invoice with ACH debit in the PaymentSheet this way(unfortunately) , so I'm not sure why you're using it
maybe you can remove the attached PM, let me try that
Understood. Though how do I avoid that the ACH is automatically linked to the PaymentSheet? Once an ACH bank account is verified, but a customer decides they want to user Credit Card, there should be a way to do so. Correct?
no, you can't remove the PM, damn
oh I know how to fix this
and set it to just ["card"]
gimme a sec and I'll share the backend code I'm using
I believe I tried that, but let's give it another shot.
well yeah the problem is that if the customer has an eligible payment method, when you finalize the invoice, it will be attached to the PaymentIntent and it moves to requires_confirmation , and the mobile SDKs don't handle that
so you might not be able to avoid this entirely unfortunately and this use case (PaymentSheet + Invoice PaymentIntent) won't work(but you can use the the other parts of the SDK like calling confirmPayment directly and they'd work; the PaymentSheet is not really intended for anything except the documented flow of a fresh PI)
Actually, looks like it worked!
yeah it probably does work
but my worry is if you have a customer with an existing card, and also ACH, it will stop working; testing something
yeah, damn.
if the customer has a card as their default payment method then it will get pulled in when finalizing the invoice
let customer = await stripe.customers.create({
email: "test@example.com",
// ach bank account
source:"btok_1JdC6cG3FLYv8PYMfN1b7np8"
});
const bankAccount = stripe.customers.verifySource(
customer.id,
customer.default_source,
{
amounts: [32, 45],
}
);
// add a card as well
let pm = await stripe.paymentMethods.attach("pm_card_visa", {customer: customer.id});
await stripe.customers.update(customer.id,{invoice_settings:{default_payment_method:pm.id}})
// invoice
const invoiceItem = await stripe.invoiceItems.create({
customer: customer.id,
price: "price_1JUWKdG3FLYv8PYM8aaqsvV2"
});
// we only want invoice to paid with a card
let invoice = await stripe.invoices.create({
customer: customer.id,
payment_settings:{payment_method_types: ["card"]},
auto_advance: true, // auto-finalize this draft after ~1 hour
});
invoice = await stripe.invoices.finalizeInvoice(invoice.id, {expand:["payment_intent"]})
console.log(invoice.payment_intent.client_secret)
console.log(invoice.payment_intent.status)
console.log(invoice.customer)
await stripe.ephemeralKeys.create({customer:customer.id},{apiVersion:"2020-08-27"})
but yeah that's just how Invoices work unfortunately. When finalized, they try to find a valid payment method based on the types (which by default is the ones on that Dashboard page, or can be overriden by that payment_method_types API). But you want a fresh PI with no payment method since that's what the sheet needs.
Overall it will work if you just never set a default payment method for the customer(like I do above), so that is at least an option, but it feels brittle and easy to break if you change things in future.
It's working for both types of payment.
I'm setting payment_method_types to ['card'] if requested payment type is Credit card payment or ['ach_debit'] if requested payment type is bank transfer.
yep, I'm looking at your account and see that! But just to be clear, if you ever make the attached card the default for the customer then this will stop working
my example above is it not working, and the bit that makes it not work is await stripe.customers.update(customer.id,{invoice_settings:{default_payment_method:pm.id}}) when I make a card the invoice default payment method
as soon as I do that, when an invoice is finalised, it will try to use that, and you get a requires_confirmation status instead of requires_payment_method
so this will probably work for you overall, but that part(you have to never set invoice_settings:{default_payment_method} ) feels slightly brittle, but it is workable.
hopefully I make sense!
I think it does. I'll make a backup of your comments above, just in case. I'll avoid setting a default payment method and always make customers select a payment method.