#greggles_best-practices
1 messages ¡ Page 1 of 1 (latest)
đ Welcome to your new thread!
â˛ď¸ We'll be here soon! We typically respond in a few minutes, but in some cases we might need a bit more time (e.g., server's busy, you've got a complex question, etc.).
âąď¸ We close idle threads, which makes them read-only. Once a thread is closed it won't be reopened, but you can start a new thread if you have another question.
đ This thread will always be available, even after it's closed. You can find it again using Discord's search, or you can save this link: https://discord.com/channels/841573134531821608/1252330257474781225
đ Have more to share? Add details, code, screenshots, videos, etc. below.
I'm confused what the high-level order should be for this scenario. Collect payment first or upon submission, create/retrieve Stripe customer, create an invoice and associate it with the customer, add lineItem, finalize the invoice. Then how do I associate the payment element submission with the customer invoice?
Sample transaction pi_3PSjliGxG8m2870U0gdwqT84 how do I associate this paymentintent with the customer?
You would need to create teh Customer ahead of the Payment Intent creation step, so that you can supply a Customer ID to the Payment Intent
To back up:
I submit the elements on the client side
Then create the customer
Then create the paymentintent and associate the customer ID with it
Then create the invoice?
After that, confirm the payment on the client side?
That sounds about right
Thank you. Is there documentation to support that flow? Everything I've seen seems fragmented. Maybe I missed something.
Also I think I tried something like that using
$pi = $stripe->invoices->finalizeInvoice(
$invoice->id,
['expand' => ['payment_intent']]
);
But finalizing an invoice creates its own paymentintent unassociated with the payment element.
Try specifying the Customer when you create the Invoice.
I did that
// Create the invoice
$invoice_arr = array(
'customer' => $stripe_customer_id,
"collection_method" => "charge_automatically",
'pending_invoice_items_behavior' => "exclude",
'automatic_tax' => array(
'enabled' => false
)
);
$invoice = $stripe->invoices->create($invoice_arr);
// Add the product
$invoice_line_items = array(
'customer' => $stripe_customer_id,
'price' =>$_POST['giftPriceId'],
'currency' => 'usd',
'invoice' => $invoice->id
);
// if Discount, apply discount
if(isset($_POST['couponCode']) && $_POST['couponCode']) {
$invoice_line_items['discounts'] = array(
array(
'coupon' => $_POST['couponCode']
)
);
}
// print_stmt($product_array);
$ii = $stripe->invoiceItems->create($invoice_line_items);
Hello two-shoes has to step out, catching up on this thread and will get back to you
Thank you.
But finalizing an invoice creates its own paymentintent unassociated with the payment element.
Can you tell me more about how this is an issue? With the deferred intents flow, the element is always not initially connected to an intent, but you should still be able to try to confirm the PaymentIntent with it
Let me run this scenario again and get back to you in a few minutes.
the error I got was
Payment details were collected through Stripe Elements using automatic payment methods and cannot be confirmed with a Payment Intent configured with payment_method_types.
Interesting, I did not realize that mandates would act as though payment_method_types was used. Trying to think of the best way forward here.
I did see this SO response by one of your colleagues but I'm not specifying any payment method types when doing the customer->Invoice->invoiceItems->finalizeInvoice flow.
finalizing the invoice with ['expand' => ['payment_intent']] param should return the paymentintent
Right, invoice payment methods are determined by a setting in your dashboard that is similar to but separate from the standard automatic payment methods settings. So it seems like despite us automatically picking PM types for you, the API here still acts like you specified payment_method_tpyes
And yes it should. Are you not seeing a payment intent when you finalize? If so can you send me the ID?
{
"error": {
"message": "Payment details were collected through Stripe Elements using automatic payment methods and cannot be confirmed with a Payment Intent configured with payment_method_types.",
"payment_intent": {
"id": "pi_3PSlRAGxG8m2870U1OIVrQ7r",
"object": "payment_intent",
"amount": 9995,
"amount_details": {
"tip": {}
},
"automatic_payment_methods": null,
"canceled_at": null,
"cancellation_reason": null,
"capture_method": "automatic",
"client_secret": "pi_3PSlRAGxG8m2870U1OIVrQ7r_secret_gkc76gikrkd2PfMIpS3B6xK0I",
"confirmation_method": "automatic",
"created": 1718653316,
"currency": "usd",
"description": "Payment for Invoice",
"last_payment_error": null,
"livemode": false,
"next_action": null,
"payment_method": null,
"payment_method_configuration_details": null,
"payment_method_options": {
"us_bank_account": {
"verification_method": "automatic"
}
},
"payment_method_types": [
"card",
"cashapp",
"link",
"us_bank_account"
],
"processing": null,
"receipt_email": "greg.ulrich@me.com",
"setup_future_usage": null,
"shipping": null,
"source": null,
"status": "requires_payment_method"
},
"request_log_url": "https://dashboard.stripe.com/test/logs/req_dntomZomAdE412?t=1718653316",
"type": "invalid_request_error"
}
}
Interestingly, Google Pay, and Amazon Pay are missing from that error object as payment_method_types
Also Klarna, Affirm etc. They show on the page and are selectable(I submitted the payment using Google Pay)
Do you have these same payment methods turned on in your invoice settings specifically? https://dashboard.stripe.com/settings/billing/invoice
Sign in to the Stripe Dashboard to manage business payments and operations in your account. Manage payments and refunds, respond to disputes and more.
That may be why they are showing up in one but not the other
I think to get this to work on the frontend, you would need to provide a payment_method_types list that includes all of the posible PM types for your invoice.
I've never set those. I don't see Google Pay available there.
Google Pay falls under cards
So I'd need to explicitly set payment types instead of using automatic?
And you need to set that setting for invoices. I am not sure why we have it as a separate setting but we do and that is the setting that controls this invoice setting
Just on the frontend, your backend can still just pull from that setting
I'd want to use all available.
The alternative that I can think of is this flow which is similar but I don't think it makes this specific check https://docs.stripe.com/payments/finalize-payments-on-the-server
Many payment types aren't available for use with subscriptions but are with single payments.
Right, you'd still be specifying payment mode and pass all of the payment method types in to the frontend
They'd be usable, it just looks like the Stripe.js interface is a bit clunky here
Hmm. OK. Let me try that and see what happens.
const options = {
appearance: appearance,
'mode': 'payment',
amount: 9995,
'currency': 'usd',
paymentMethodOrder: ['apple_pay', 'google_pay', 'card', 'klarna']
};
const elements = stripe.elements(options);
const paymentElement = elements.create('payment');
https://docs.stripe.com/payments/customize-payment-methods
Weirdly, specifying payment element order has no effect.
Documentation says specify them in the dashboard.
...but really it seems redundant to have to specify payment methods on the front end.
[by specifying in the dashboard,]This allows Stripe to pull your payment method preferences from the Dashboard to dynamically show the most relevant payment methods to your customers.
To be clear, are you saying that the PMs are ordered incorrectly? Or that this does not effect which PMs are shown?
Ah, my mistake. I think paymentMethodOrder is not correct.
Agreed that you shouldn't need to specify this again. It should work like standard automatic payment methods, I will file feedback about this.
I thought it specified order AND excluded what was not listed.
What you linked to:
paymentMethodCreation: 'manual',
Also had no effect.
Ah gotcha, thank you for trying that. Apologies I was mistaken there.
No worries! Thanks for being patient with me.
OK so one question. Is there any documentation on how to use a payment element while selling a one off price product?
Unfortunately not for this specific flow. It looks like we show how to do this for non-invoice one-off payments and for subscription invoice payments. And we have a doc on one-off invoice payments with Elements but it is for the flow where you creat ethe payment element after the invoice is finalized. https://docs.stripe.com/invoicing/integration?method=elements#accept-invoice-payment
So I can take a payment, but not associate it with a product/price?
You can, the thing is that you need to specify the payment method types in the paymentMethodTypes when initializing elements. I think you should be able to specify your full list of desired payment methods and we would filter out any that don't apply but I have not been able to test that. https://docs.stripe.com/js/elements_object/create_without_intent#stripe_elements_no_intent-options-paymentMethodTypes
Actually, that seemed to work. paymentMethodCreation: 'manual' was unnecessary. Using the paymentMethodTypes seemed to get rid of that error. Thank you so much for remaining patient.
Of course, same to you. Glad we could find something that helped here
So if I want all available payment methods, I just need to list them all, correct?
Yes
I'd definitely flag that as clunky. Thanks again for all of your help.
Last question, I promise. Is there any reason not to explicitly list every payment method listed here?
https://docs.stripe.com/api/payment_methods/object#payment_method_object-type
The answer is yes. Not all payment methods work with the U.S. dollar.
Is there any documentation on which payment methods work with a specified currency?
I recommend reviewing this: https://docs.stripe.com/payments/payment-methods/integration-options#payment-method-availability