Javascript: Stripe and Apple Pay Web setup

1.1k views Asked by At

I am trying to follow the guide here ( https://stripe.com/docs/stripe-js/elements/payment-request-button ) to setup Apple Pay for the web and Stripe. The initial steps such as verification of domain and all the pre-setup is done but I am having an issue following the steps for the payment.

The Apple Pay Button is showing up in my Safari browser. When the button is clicked, I fire an event called checkoutWithApplePay(). I get lost after step 3 and not sure what to do. I am posting to my backend and on the backend, creating a payment intent and returning the client_secret

checkoutWithApplePay() {
    // STEP 1 FROM GUIDE
    const stripe = Stripe("_____");
    
    // STEP 2 FROM GUIDE
    const paymentRequest = stripe.paymentRequest({
        country: 'US',
        currency: 'usd',
        total: {
            label: 'Store Total',
            amount: cartTotal() ,
        },
        requestPayerName: true,
        requestPayerEmail: true,
    });
    
    
    // STEP 3 FROM GUIDE
    const elements = stripe.elements();
    const prButton = elements.create('paymentRequestButton', {
        paymentRequest: paymentRequest,
    });
    
    paymentRequest.canMakePayment().then(function(result) {
        if (result) {
            prButton.mount('#payment-request-button');
        } else {
            document.getElementById('payment-request-button').style.display = 'none';
        }
    });
    
    // STEP 4 FROM GUIDE -- THIS RETURNS A CLIENT SECRET
    axios.post('/api/checkout/checkout-with-apple-pay-web', {
        total: this.formattedCartTotal()
    })
    .then((resp) => {
          myClientSecrent = resp.clientSecret;
    });

    // THIS IS WHERE I GET CONFUSED AND NOT SURE HOW TO HANDLE AND BELOW IS 
    JUST TEMPLATE CODE FROM THE GUIDE
    
    paymentRequest.on('paymentmethod', function(ev) {
        // Confirm the PaymentIntent without handling potential next actions (yet).
        stripe.confirmCardPayment(
        clientSecret,
        {payment_method: ev.paymentMethod.id},
        {handleActions: false}
        ).then(function(confirmResult) {
        if (confirmResult.error) {
            // Report to the browser that the payment failed, prompting it to
            // re-show the payment interface, or show an error message and close
            // the payment interface.
            ev.complete('fail');
        } else {
            // Report to the browser that the confirmation was successful, prompting
            // it to close the browser payment method collection interface.
            ev.complete('success');
            // Check if the PaymentIntent requires any actions and if so let Stripe.js
            // handle the flow. If using an API version older than "2019-02-11" instead
            // instead check for: `paymentIntent.status === "requires_source_action"`.
            if (confirmResult.paymentIntent.status === "requires_action") {
            // Let Stripe.js handle the rest of the payment flow.
            stripe.confirmCardPayment(clientSecret).then(function(result) {
                if (result.error) {
                    let data = {
                        msg: "An error occurred. Please try again."
                    }
                    this.handleShowFlashMsg(data);
                } else {
                    this.handleShowOrderConfirmModal();
                }
            });
            } else {
            // The payment has succeeded.
            }
        }
    });
}
1

There are 1 answers

2
Paul Asjes On

You're almost there. When you get the 'paymentmethod' event you would use the PaymentIntent client secret you retrieved earlier to confirm the PaymentIntent and complete the payment:

    let clientSecret;

    axios.post('/api/checkout/checkout-with-apple-pay-web', {
        total: this.formattedCartTotal()
    }).then((resp) => {
      // Assign this previously defined variable
      clientSecret = resp.clientSecret;
    });

    paymentRequest.on('paymentmethod', function(ev) {
        // Confirm the PaymentIntent without handling potential next actions (yet).
        stripe.confirmCardPayment(
        clientSecret,
        {payment_method: ev.paymentMethod.id},
        {handleActions: false}
        ).then(function(confirmResult) {
        if (confirmResult.error) {
            // Report to the browser that the payment failed, prompting it to
            // re-show the payment interface, or show an error message and close
            // the payment interface.
            ev.complete('fail');
        } else {
            // Report to the browser that the confirmation was successful, prompting
            // it to close the browser payment method collection interface.
            ev.complete('success');
            // Check if the PaymentIntent requires any actions and if so let Stripe.js
            // handle the flow. If using an API version older than "2019-02-11" instead
            // instead check for: `paymentIntent.status === "requires_source_action"`.
            if (confirmResult.paymentIntent.status === "requires_action") {
            // Let Stripe.js handle the rest of the payment flow.
            stripe.confirmCardPayment(clientSecret).then(function(result) {
                if (result.error) {
                    let data = {
                        msg: "An error occurred. Please try again."
                    }
                    this.handleShowFlashMsg(data);
                } else {
                    this.handleShowOrderConfirmModal();
                }
            });
            } else {
            // The payment has succeeded.
            }
        }
    });