Skip to main content

Implement Avarda Checkout

Time to complete: 15-30 minutes

Avarda Checkout is a payment provider that offers a wide range of services including payment solutions for e-commerce. You can implement Avarda Checkout in your Ralph Storefront to offer your customers a seamless payment experience.

Pre-requisites

Steps

Create a checkout page mixin

In your storefront, run npm run ralph-create and select mixin as type and enter the name checkout-page. This will create a new mixin file in the mixins folder called MixCheckoutPage.js. You will use this mixin to load the correct checkout script, depending on the env variable RALPH_ENV. Add the following code to the file:

MixCheckoutPage.js
export default {
name: 'MixCheckoutPage',
data: () => ({
avardaScriptLoaded: false,
}),
computed: {
stage() {
return this.$config.ralphEnv === 'prod' ? '' : 'stage.';
},
},
mounted() {
if (window.avardaCheckoutInit) {
this.avardaScriptLoaded = true;
}
},
head() {
const avardaBaseUrl = `https://${this.stage}checkout-cdn.avarda.com/cdn/static/js/main.js`;
return {
script: [
{
hid: 'avarda',
src: `${avardaBaseUrl}?ts=${Date.now()}`,
callback: () => {
this.avardaScriptLoaded = true;
},
},
],
};
},
};

Add the mixin to your checkout and confirm pages

This mixin is needed in both the checkout and confirm pages. To add it, open the pages/checkout/index.vue and pages/checkout/confirm.vue files and add the following code:

...
<script>
import MixCheckoutPage from 'MixCheckoutPage';
export default {
...
mixins: [MixCheckoutPage],
...
};
</script>

Add the avardaScriptLoaded property to pass value to the CaCheckout component

In the CaCheckout component, add the avardaScriptLoaded prop.

...
props: {
avardaScriptLoaded: {
type: Boolean,
required: true,
},
},
...

In the pages/checkout/index.vue, pass the value from teh mixin to the component:

<template>
<div class="ca-checkout-page">
<CaContainer>
<CaCheckout :avarda-script-loaded="avardaScriptLoaded" />
</CaContainer>
</div>
</template>
...

Only render the checkout frame after script has loaded

In both CaCheckout and the confirm page, add v-if="avardaScriptLoaded" to the CaCheckoutExternal component. Here is an example of how you could do it in the pages/checkout/index.vue file:

<CaCheckoutExternal
v-if="selectedPaymentOption && avardaScriptLoaded"
ref="externalcheckout"
:data="selectedPaymentOption.paymentData"
:new-checkout-session="selectedPaymentOption.newCheckoutSession"
:type="paymentType"
/>

Add Avarda order validation functionality

First, in the graphql folder, create a folder (if it not already exists) named checkout and add a new file called validate-order-creation.graphql. Then add the following code to your new file:

graphql/checkout/validate-order-creation.graphql
query validateOrderCreation(
$cartId: String!
$checkout: CheckoutInputType!
$channelId: String
$languageId: String
$checkoutMarketId: String
) {
validateOrderCreation(
cartId: $cartId
checkout: $checkout
channelId: $channelId
languageId: $languageId
marketId: $checkoutMarketId
) {
isValid
message
memberType
}
}

Then, in the folder store, create a new file called avarda.js and add the following code:

store/avarda.js
import validateOrderCreation from 'checkout/validate-order-creation.graphql';

export const state = () => ({
customerValidation: null,
});

export const mutations = {
setCustomerValidation(state, data) {
state.customerValidation = data;
},
};

export const actions = {
validateOrderCreation({ commit, getters, rootState }, data) {
const { payload, checkoutInstance } = data;

const address = payload?.invoicingAddress;

const checkout = {
email: payload?.email,
billingAddress: {
firstName: address?.firstName,
lastName: address?.lastName,
addressLine1: address?.address1,
zip: address?.zip,
city: address?.city,
},
};

const client = this.app.apolloProvider.defaultClient;
client
.query({
query: validateOrderCreation,
variables: {
cartId: rootState.cart.data.id,
checkout,
checkoutMarketId: rootState.channel.checkoutMarket,
},
fetchPolicy: 'no-cache',
})
.then((result) => {
if (result?.data?.validateOrderCreation) {
const customerValidation = {
...result.data.validateOrderCreation,
paymentType: payload.selectedPaymentMethodType,
};

commit('setCustomerValidation', customerValidation);

if (getters.customerStatus === 'ok') {
checkoutInstance.beforeSubmitContinue();
} else {
checkoutInstance.beforeSubmitAbort();
}
}
})
.catch((error) => {
this.$nuxt.error({ statusCode: error.statusCode, message: error });
});
},
};

export const getters = {
customerStatus: (state) => {
const validation = state.customerValidation;

if (
!validation?.isValid &&
validation?.message === 'Customer is blacklisted'
) {
return 'blacklisted';
}

const memberType = validation?.memberType?.replace(/\s/g, '') || '';

if (
memberType.startsWith('NOCREDIT') &&
(validation?.paymentType === 'DirectInvoice' ||
validation?.paymentType === 'Loan')
) {
const type = memberType.split('-')[1];
const status = type ? type.toLowerCase() : 'limited';

return status;
}

return 'ok';
},
};

Please make sure to edit this validation function to suit your needs.