bennypowers / stripe-elements

Custom Element Wrapper for Stripe.js v3 Elements
https://stripe-elements.netlify.app/
79 stars 20 forks source link

Example of using the stripe-elements component with Stripe's PaymentIntent #57

Open Canuckaholic opened 4 years ago

Canuckaholic commented 4 years ago

Thanks for this web component!

One request: It would be great to have an example of using the "stripe-elements" component with Stripe's PaymentIntent workflow. My team is struggling a little bit to figure out how to get it working.

Cheers.

bennypowers commented 4 years ago

like this one? https://bennypowers.dev/stripe-elements/?path=/docs/elements-stripe-payment-request--payment-request-with-payment-intent (may need to refresh due to storybook bug)

Canuckaholic commented 4 years ago

Thanks @bennypowers ... That example shows using PaymentIntent with the Payment Request button, but I'm looking for an example using the fallback component. Here is what I did to get it working. Does this look right?

// Load Stripe
this.stripe = await loadStripe(this.config.get('STRIPE_PUBLISHABLE_KEY'))

...

html`
<stripe-elements
                    ?hidden="${!this.unsupported}"
                    generate="payment-method"
                    id="card-element"
                    publishable-key="${this.unsupported ? this.config.get('STRIPE_PUBLISHABLE_KEY') : undefined}"
                    @change="${this.onChange}"
                    @error="${this.onError}"
                    @payment-method="${this.onPaymentMethod}"
></stripe-elements>
`

onPaymentMethod = (e) => {
        this.stripe.confirmCardPayment(this.paymentIntentsStore.clientSecret, {
            payment_method: e.detail.id
        }).then(result => {
            if (result.error) {
                this.cardErrors.textContent = result.error.message
            } else {
                // The payment has been processed!
                if (result.paymentIntent.status === 'succeeded') {
                    this.onSuccess()
                }
            }
        })
 }
bennypowers commented 4 years ago

yeah that looks about right at a glance, without getting in to the weeds of how you're managing the paymentIntentsStore state or the minutiae of the stripejs api. The general approach - using the element's stripe instance to run api calls, is how I would do it too.

bennypowers commented 4 years ago

How's the weather in BC?

Canuckaholic commented 4 years ago

How's the weather in BC?

It's raining, of course ;-)

Canuckaholic commented 4 years ago

Hello again @bennypowers ... one more question for you. With the <stripe-payment-request> component I'm doing the following:

<stripe-payment-request
                    amount="${price}"
                    client-secret="${clientSecret}"
                    country="${country}"
                    currency="${currency}"
                    generate="payment-method"
                    ?hidden="${this.unsupported}"
                    id="payment-request-btn"
                    label="${this.edition.displayName}"
                    publishable-key="${this.config.get('STRIPE_PUBLISHABLE_KEY')}"
                    request-payer-email
                    request-payer-name
                    request-payer-phone
                    @error="${this.onError}"
                    @fail="${this.onFail}"
                    @payment-method="${this.onPaymentMethod}"
                    @ready="${this.onReady}"
                    @unsupported="${this.onUnsupported}"
></stripe-payment-request>

...

onPaymentMethod = (e) => {
        this.stripe.confirmCardPayment(this.paymentIntentsStore.clientSecret, {
            payment_method: e.detail.id
        }).then(
...
        })
    }

I'm following the example you have for using this with a Stripe PaymentIntents. The thing I'm not clear on is what does passing the client-secret attribute to the component do since Stripe only needs it when the confirmCardPayment method is called?

Thanks!

bennypowers commented 4 years ago

you can do a bunch of stuff with that

https://stripe.com/docs/api/setup_intents/object#setup_intent_object-client_secret

One thing we do is expose confirmCardPayment for you

https://github.com/bennypowers/stripe-elements/blob/208c1593039c6a0b82ed7b618253896ee9209605/src/stripe-payment-request.ts#L458-L463

Canuckaholic commented 3 years ago

Nice. Yes I removed @payment-method="${this.onPaymentMethod}" from my <stripe-payment-request> component and it works just fine.

So question... why not add a similar confirmCardPayment method to the fallback <stripe-payment> component as well? And then all we would need to do is provide it the client secret like in the payment request component.

bennypowers commented 3 years ago

Good question, I'm not entirely sure why we don't do that 😂

If you can get it to work, PRs are welcome