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

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

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:

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

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

{
    "error": {
        "code": "parameter_unknown",
        "doc_url": "https://stripe.com/docs/error-codes/parameter-unknown",
        "message": "Received an unknown parameter: redirect",
        "param": "redirect",
        "request_log_url": "[Redacted]",
        "setup_intent": {
            "id": "[Redacted]",
            "object": "setup_intent",
            "cancellation_reason": null,
            "client_secret": "[Redacted]",
            "created": [Redacted],
            "description": null,
            "last_setup_error": null,
            "livemode": false,
            "next_action": null,
            "payment_method": null,
            "payment_method_types": ["card"],
            "status": "requires_payment_method",
            "usage": "off_session"
        },
        "type": "invalid_request_error"
    }
}
英文:

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

    <EditForm id="payment-form" Model="@BillingProfile">
        <div id="payment-element">
            <!-- Elements will create form elements here -->
        </div>

        @if (stripeReady)
        {
            <div class="text-center mt-2">
                <button type="button" @onclick="TogglePaymentEditStripe" class="btn btn-grey text-dark">Cancel</button>  
                <button type="submit" id="submitStripeCard" disabled="@(Busy)" class="btn btn-blue">Add card</button>
            </div>                }

        <!-- We'll put the error messages in this element -->
        <div id="payment-method-errors" role="alert"></div>   
    </EditForm>

JavaScript

export function initialiseStripeAndMount(publishableKey, clientIntentSecret, redirectUrl){

    const stripe = Stripe(publishableKey);  

    const options = {
        clientSecret: clientIntentSecret, //intent
        // Fully customizable with appearance API.
        appearance: {
            theme: 'night',
            labels: 'floating',           
        }
    };

    // Set up Stripe.js and Elements to use in checkout form, passing the client secret obtained in step 3
    const elements = stripe.elements(options);

    // Create and mount the Payment Element
    const cardElement = elements.create('payment');
    cardElement.mount('#payment-element');

    // Create a token or display an error when the form is submitted.
    const form = document.getElementById('payment-form');

    form.addEventListener('submit', async (event) => {
        event.preventDefault();

        const result = await stripe.createPaymentMethod({                
            type: 'card',
            card: cardElement,
            billing_details: {

                name: 'Jenny Rosen',
            },
            })
            .then(function (result) {
                // Handle result.error or result.paymentMethod
                alert(result)
            });
    });
   
}

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:

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

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

{
  "error": {
    "code": "parameter_unknown",
    "doc_url": "https://stripe.com/docs/error-codes/parameter-unknown",
    "message": "Received unknown parameter: redirect",
    "param": "redirect",
    "request_log_url": "[Redacted]",
    "setup_intent": {
      "id": "[Redacted]",
      "object": "setup_intent",
      "cancellation_reason": null,
      "client_secret": "[Redacted]",
      "created": [Redacted],
      "description": null,
      "last_setup_error": null,
      "livemode": false,
      "next_action": null,
      "payment_method": null,
      "payment_method_types": [
        "card"
      ],
      "status": "requires_payment_method",
      "usage": "off_session"
    },
    "type": "invalid_request_error"
  }
}

答案1

得分: 2

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

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

对于您的特定错误消息,我认为问题在于您传递了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:

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

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:

确定