# 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>