# Express Checkout

# Express Checkout component

Use the PaymentPaypalExpressProvider.vue component in place where Express Checkout should begin. For example, in the default theme, it could be above the Go to checkout button in the components/CartSidebar.vue component:



 













 



 




<template>
  <div>
    <PaymentPaypalExpressProvider />

    <nuxt-link :to="localePath({ name: 'shipping' })">
      <SfButton
        class="sf-button--full-width color-secondary"
        @click="toggleCartSidebar"
      >
        {{ $t('Go to checkout') }}
      </SfButton>
    </nuxt-link>
  </div>
</template>

<script>
import PaymentPaypalExpressProvider from '@vsf-enterprise/paypal-commercetools/src/components/PaymentPaypalExpressProvider';

export default {
  components: {
    PaymentPaypalExpressProvider
  }
};
</script>

PaymentPaypalExpressProvider will redirect the user to the URI from the checkoutSummaryStepUrl field provided in the middleware.config.js file.

# Performing actions after redirect

You might want to perform additional actions after redirect, e.g., hide the cart sidebar. To do that, use the afterRedirect prop:

<PaymentPaypalExpressProvider :afterRedirect="toggleCartSidebar" />

# Configuration of "Make order" button in the checkout summary step

The purpose of the button is to authorize the payment and place an order.

In order to implement it, open the Vue page component for the URL defined in the checkoutSummaryStepUrl field. It is the same component as in the Usage on the frontend step. Add these parts:

import { useRoute, useRouter } from '@nuxtjs/composition-api';
import { usePaypal, MALFORMED_PRICE_ERROR, MALFORMED_PRICE_QUERY_STRING } from '@vsf-enterprise/paypal-commercetools';
import { useCart } from '@vsf-enterprise/commercetools';

export default {
  setup(props, { root: { localePath }}) {
    const { onApprove, orderId, error: paypalError, loading } = usePaypal();
    const router = useRouter();
    const route = useRoute();
    const { load, setCart } = useCart();

    const reloadCart = async () => {
      setCart(null);
      await load();
    };

    const afterPayAndOrder = ({ order }) => {
      router.push({ path: localePath(`/checkout/thank-you?order=${order.id}`) });
      setCart(null);
    };

    const processExpressOrder = async () => {
      const result = await onApprove(route.value.query.poid);
      if (paypalError.value.onApprove?.data?.message === MALFORMED_PRICE_ERROR) {
        await reloadCart();
        const query = {...route.query};
        delete query.poid;
        query.error = MALFORMED_PRICE_QUERY_STRING;
        return router.push({
          ...route,
          query
        });
      } else if (paypalError.value.onApprove) {
        // HANDLE UNUSUAL ERROR
      }
      return afterPayAndOrder(result);
    };

    return {
      // ...
      query: computed(() => route.value.query),
      processExpressOrder,
      afterPayAndOrder,
      loading
    }
  }
}

In the template, replace PaymentPaypalProvider from Usage on the frontend step with:

<template>
  <div v-if="query && query.poid" class="pp-express">
    <div class="pp-express__summary">
      If you want to modify shipping or billing address then use tabs above. It will require to fulfill PayPal's modal once again. Account won't be charged multiple times.
    </div>
    <div class="pp-express__submit">
      <SfButton class="summary__action-button" @click="processExpressOrder" :disabled="loading">
        {{ $t('Make an order') }}
      </SfButton>
    </div>
  </div>
  <PaymentPaypalProvider :afterPay="afterPayAndOrder" v-else />
</template>