#greggles_best-practices

1 messages ¡ Page 1 of 1 (latest)

river phoenixBOT
#

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

wild violet
#

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?

kindred wadi
#

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

wild violet
#

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?

river phoenixBOT
kindred wadi
#

That sounds about right

wild violet
#

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.

kindred wadi
#

Try specifying the Customer when you create the Invoice.

wild violet
#

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);
karmic spear
#

Hello two-shoes has to step out, catching up on this thread and will get back to you

wild violet
#

Thank you.

karmic spear
#

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

wild violet
#

Let me run this scenario again and get back to you in a few minutes.

wild violet
#

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.

karmic spear
#

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.

wild violet
#

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

karmic spear
#

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?

wild violet
#
{
    "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)

karmic spear
#

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.

wild violet
#

I've never set those. I don't see Google Pay available there.

karmic spear
#

Google Pay falls under cards

wild violet
#

So I'd need to explicitly set payment types instead of using automatic?

karmic spear
#

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

wild violet
#

I'd want to use all available.

karmic spear
wild violet
#

Many payment types aren't available for use with subscriptions but are with single payments.

karmic spear
#

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

wild violet
#

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.

karmic spear
#

To be clear, are you saying that the PMs are ordered incorrectly? Or that this does not effect which PMs are shown?

wild violet
#

Ah, my mistake. I think paymentMethodOrder is not correct.

karmic spear
#

Agreed that you shouldn't need to specify this again. It should work like standard automatic payment methods, I will file feedback about this.

wild violet
#

I thought it specified order AND excluded what was not listed.

#

What you linked to:
paymentMethodCreation: 'manual',
Also had no effect.

karmic spear
#

Ah gotcha, thank you for trying that. Apologies I was mistaken there.

wild violet
#

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?

karmic spear
wild violet
#

So I can take a payment, but not associate it with a product/price?

karmic spear
river phoenixBOT
wild violet
#

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.

karmic spear
#

Of course, same to you. Glad we could find something that helped here

wild violet
#

So if I want all available payment methods, I just need to list them all, correct?

karmic spear
#

Yes

wild violet
#

I'd definitely flag that as clunky. Thanks again for all of your help.

wild violet
#

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?