如何在挂载元素时使用Stripe创建支付方法

huangapple go评论107阅读模式
英文:

How to use the Stripe create payment method with mounted element

问题

I'm integrating Stripe into my Blazor application. The functionality I need is to replace an existing 'Add a card' component.

I have successfully achieved this using the stripe.confirmSetup method in the JS library. However, this method requires a redirect URL, which is causing issues because the rest of our application does not behave in that manner.

I have identified the createPaymentMethod as an alternative option because it does not require a redirect URL. It opens any 3DS page in a modal and supports a 'then' callback method, where I can display a success popup and update the DOM accordingly.

The issue arises when I pass the card element that I have previously mounted. I encounter the following error:

Invalid value for createPaymentMethod: the card was a 'payment' Element, which cannot be used to create card PaymentMethods.

If I try using confirmSetup with the following:

  1. stripe.confirmSetup({
  2. elements,
  3. confirmParams: {
  4. // Return URL where the customer should be redirected after the SetupIntent is confirmed.
  5. return_url: 'http://www.google.co.uk',
  6. redirect: "if_required"
  7. },
  8. })

Then I receive a 400 error response with the following response object:

  1. {
  2. "error": {
  3. "code": "parameter_unknown",
  4. "doc_url": "https://stripe.com/docs/error-codes/parameter-unknown",
  5. "message": "Received an unknown parameter: redirect",
  6. "param": "redirect",
  7. "request_log_url": "[Redacted]",
  8. "setup_intent": {
  9. "id": "[Redacted]",
  10. "object": "setup_intent",
  11. "cancellation_reason": null,
  12. "client_secret": "[Redacted]",
  13. "created": [Redacted],
  14. "description": null,
  15. "last_setup_error": null,
  16. "livemode": false,
  17. "next_action": null,
  18. "payment_method": null,
  19. "payment_method_types": ["card"],
  20. "status": "requires_payment_method",
  21. "usage": "off_session"
  22. },
  23. "type": "invalid_request_error"
  24. }
  25. }
英文:

I'm integrating Stripe to my Blazor application. The functionality I need is to replace an existing 'Add a card' component.

I have successfully achieved this using the stripe.confirmSetup method in the JS library however this requires a redirect URL which is causing issues as the rest of our application does not behave like that.

I have identified the createPaymentMethod as an alternative due to the fact that it does not require a redirect URL, opens any 3DS page in a modal and supports a 'then' callback method, where I can show a success popup and update the DOM accordingly.

The issue is when I pass the card element that I have previously mounted I get this error.

> Invalid value for createPaymentMethod: card was payment Element,
> which cannot be used to create card PaymentMethods

razor/html

  1. <EditForm id="payment-form" Model="@BillingProfile">
  2. <div id="payment-element">
  3. <!-- Elements will create form elements here -->
  4. </div>
  5. @if (stripeReady)
  6. {
  7. <div class="text-center mt-2">
  8. <button type="button" @onclick="TogglePaymentEditStripe" class="btn btn-grey text-dark">Cancel</button>
  9. <button type="submit" id="submitStripeCard" disabled="@(Busy)" class="btn btn-blue">Add card</button>
  10. </div> }
  11. <!-- We'll put the error messages in this element -->
  12. <div id="payment-method-errors" role="alert"></div>
  13. </EditForm>

JavaScript

  1. export function initialiseStripeAndMount(publishableKey, clientIntentSecret, redirectUrl){
  2. const stripe = Stripe(publishableKey);
  3. const options = {
  4. clientSecret: clientIntentSecret, //intent
  5. // Fully customizable with appearance API.
  6. appearance: {
  7. theme: 'night',
  8. labels: 'floating',
  9. }
  10. };
  11. // Set up Stripe.js and Elements to use in checkout form, passing the client secret obtained in step 3
  12. const elements = stripe.elements(options);
  13. // Create and mount the Payment Element
  14. const cardElement = elements.create('payment');
  15. cardElement.mount('#payment-element');
  16. // Create a token or display an error when the form is submitted.
  17. const form = document.getElementById('payment-form');
  18. form.addEventListener('submit', async (event) => {
  19. event.preventDefault();
  20. const result = await stripe.createPaymentMethod({
  21. type: 'card',
  22. card: cardElement,
  23. billing_details: {
  24. name: 'Jenny Rosen',
  25. },
  26. })
  27. .then(function (result) {
  28. // Handle result.error or result.paymentMethod
  29. alert(result)
  30. });
  31. });
  32. }

Question

How can I use the 'createPaymentMethod' function with the stripe mounted element so that I can avoid the page posting back as per their documentation:

如何在挂载元素时使用Stripe创建支付方法

edit

If I try using confirmSetup with the following:

  1. stripe.confirmSetup({
  2. elements,
  3. confirmParams: {
  4. // Return URL where the customer should be redirected after the SetupIntent is confirmed.
  5. return_url: 'http://www.google.co.uk',
  6. redirect: "if_required"
  7. },
  8. })

Then I get a error code 400 response, with the following response object:

  1. {
  2. "error": {
  3. "code": "parameter_unknown",
  4. "doc_url": "https://stripe.com/docs/error-codes/parameter-unknown",
  5. "message": "Received unknown parameter: redirect",
  6. "param": "redirect",
  7. "request_log_url": "[Redacted]",
  8. "setup_intent": {
  9. "id": "[Redacted]",
  10. "object": "setup_intent",
  11. "cancellation_reason": null,
  12. "client_secret": "[Redacted]",
  13. "created": [Redacted],
  14. "description": null,
  15. "last_setup_error": null,
  16. "livemode": false,
  17. "next_action": null,
  18. "payment_method": null,
  19. "payment_method_types": [
  20. "card"
  21. ],
  22. "status": "requires_payment_method",
  23. "usage": "off_session"
  24. },
  25. "type": "invalid_request_error"
  26. }
  27. }

答案1

得分: 2

如果您仅接受信用卡付款,那么在使用SetupIntents时,可以在调用stripe.confirmSetup()时添加redirect: "if_required"以避免重定向。了解更多。应该看起来像这样:

  1. stripe.confirmSetup({
  2. elements,
  3. redirect: "if_required",
  4. confirmParams: { return_url: 'http://foo.bar' }
  5. })

对于您的特定错误消息,我认为问题在于您传递了Card: cardElement(大写C)而不是card: cardElement(小写c)。但请注意,createPaymentMethod仅适用于Card Element(而不是Payment Element)。

英文:

If you are only accepting card payments, then it's possible to have no redirects when using SetupIntents. Just add redirect: "if_required" when calling stripe.confirmSetup(). Learn more. It should look something like this:

  1. stripe.confirmSetup({
  2. elements,
  3. redirect: "if_required",
  4. confirmParams: { return_url: 'http://foo.bar' }
  5. })

For your specific error message, I think the issue is that you are passing Card: cardElement (uppercase C) instead of card: cardElement (lowercase c). But note that createPaymentMethod will only work with the Card Element (and not the Payment Element).

huangapple
  • 本文由 发表于 2023年2月6日 18:42:58
  • 转载请务必保留本文链接:https://go.coder-hub.com/75360242.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定