Vue Storefront is now Alokai! Learn More
Placing your first order

Placing your first order

This guide will help you get started with the Adyen integration for SFCC. You'll learn how to:

  • create a payment session,
  • mount and style the Adyen Drop-in component,
  • submit a payments request,
  • handle payment errors,
  • remove a saved card.

Alokai Storefront

Code examples in this guide will show you how to call various Adyen SFCC SDK methods in our Alokai Storefront. Here's how you can access the sdk object.

const sdk = useSdk();

Payment Session

The first step in the payment process is to create a payment session. This is done by calling the createSession method from the Adyen SFCC SDK. Although not required, it is highly advisible to pass the shopper shopperLocale to it.

const session = await sdk.adyen.createSession({ shopperLocale: 'en-US' });

The createSession call returns the Session object. We will need it to mount the Adyen Drop-in component.

Mounting the Adyen Drop-in

The next step is to mount the Adyen Drop-in.

Alokai Storefront

In an Alokai Storefront project, the Drop-in should be mounted in the page component responsible for rendering the /checkout page: checkout.vue in the Nuxt version and checkout.tsx in the Next version.

First, add a new anchor element with some unique ID to the template of the page component:

<div id="payment-element" />

Second, call the mountPaymentElement method. Pass the session object returned by the createSession call and the ID of the anchor element to it.

const session = await sdk.adyen.createSession();

await sdk.adyen.mountPaymentElement({
  session,
  paymentDOMElement: '#payment-element'
});

Adyen Drop-in is not styled by default. This is because you might want to apply your own styles. To learn how to implement default Adyen Drop-in stylesheet jump to this section.

Placing the first order and accepting the first payment

There are 2 different flows implemented in our Adyen SFCC integration:

  • the Simple flow
  • the Advanced flow

Use the Advanced flow

Unfortunately, as of March 2024, only the Advanced flow is valid. If SFCC does further updates to SCAPI in regards to order ID prediction, the Simple flow might become usable.

Prepare your cart

Keep in mind creating a payment session requires your cart to have a shipping method and a billing address set. In addition, to place an order in SFCC, the cart has to have an email and a shipping address set.

Therefore, to test the entire flow, use the following Unified SDK methods:

const email = 'test@gmail.com';
const address = {
  address1: "Some Street",
  city: "New York",
  country: "US",
  firstName: "John",
  lastName: "Doe",
  phoneNumber: "+12065550100",
  postalCode: "54-022",
  state: "NY",
  titleCode: "Mr",
}

await sdk.unified.setCustomerEmail({ email });
await sdk.unified.setCartAddress({ shippingAddress: address });
await sdk.unified.setCartBillingAddress({ billingAddress: address });

const { methods } = await sdk.unified.getAvailableShippingMethods();
await sdk.unified.setShippingMethod({ shippingMethodId: methods[0]?.id });

The Simple flow

The Simple flow approach is to add the onPaymentCompleted callback to the adyenConfiguration object. This callback triggers when payment concludes, whether successful or not. It receives two arguments: result and component. The result object holds the payment outcome, while the component object refers to the Drop-in component instance. It has to return

await sdk.adyen.mountPaymentElement({
  session,
  paymentDOMElement,
  adyenConfiguration: {
    onPaymentCompleted: (result, component) => {
      return {}
    }
  }
});

The Advanced flow

In the Advanced flow, to achieve the bare minimum (i.e. placing an order in SFCC and letting Adyen process the payment), add the onSubmit callback to the dropinConfiguration object. In the callback:

  • place an order in SFCC using the placeOrder method of the Unified SDK,
  • return an object containing data required by Adyen to process the payment.
await sdk.adyen.mountPaymentElement({
  // ...
  dropinConfiguration: {
    onSubmit: async (result) => {
      const order = await sdk.unified.placeOrder();
      const { id, totalPrice } = order;
      const { amount, currency } = totalPrice;

      return {
        shopperReference: '<shopper_reference>',
        reference: id,
        amount: {
          value: amount,
          currency,
        },
        ...result.data
      }
    }
  }
});

As a next step, you can add the onAdditionalDetails callback to the adyenConfiguration object. It will be triggered whenever a /payments/details call will need to be made or any extra action will have to be taken after the /payments call. It simply needs to return the information provided in state along with a redirectUrl.

await sdk.adyen.mountPaymentElement({
  // ...
  adyenConfiguration: {
    onAdditionalDetails: async (state, component) => {
      return {
        state,
        component,
        redirectUrl: `${window.location.origin}/checkout/thank-you?order=`,
      };
    },
  }
});

Handling order failure

The mountPaymentElement method allows you to define two callbacks responsile for handling unsuccessful payments: onOrderFail and onError.

Use onOrderFail to handle errors thrown by the Drop-in. For example, when a customer clicks the Pay button and an order in SFCC is created but the card CVC code verification fails, you can use the callback to fail the order in SFCC and restore the customer's cart.

Failing the order in SFCC is currently not possible with the Unified SDK. Thereofre, the below example uses the updateOrder method of our SFCC SDK.

await sdk.adyen.mountPaymentElement({
  // ...
  adyenConfiguration: {
    // ...
    onOrderFail: async (result, component) => {
      const order = await sdk.sfcc.updateOrder({
        orderNo: result.merchantReference,
        status: 'failed',
      });
    },
  }
})

When the Drop-in verification is successful, the payment request will be sent to Adyen. However, at this point it might still fail. Then the onError callback will be triggered and you can use it for the same purpose as onOrderFail: to withdraw the SFCC order and restore the customer's cart.

await sdk.adyen.mountPaymentElement({
  // ...
  adyenConfiguration: {
    // ...
    onError: async (error) => {
      const order = await sdk.sfcc.updateOrder({
        orderNo: result.merchantReference,
        status: 'failed',
      });
    },
  }
})

Removing a Saved Card

To remove a saved card, call the removeCard method from the Adyen SFCC SDK. It should be used in the onDisableStoredPaymentMethod callback added to the dropinConfiguration object.

await sdk.adyen.mountPaymentElement({
  // ...
  dropinConfiguration: {
    showRemovePaymentMethodButton: true,
    async onDisableStoredPaymentMethod(
      recurringDetailReference,
      resolve,
      reject
    ) {
      try {
        await sdk.adyen.removeCard({ recurringDetailReference });
        return resolve();
      } catch (err) {
        return reject();
      }
    },
  },
});

Including CSS for the Adyen Drop-in

To style the Adyen Drop-in, use the .css file provided by the @adyen/adyen-web library. The whole process is described in detail by the Adyen documentation.

import "@adyen/adyen-web/dist/adyen.css";

If you want to extend the default stylesheet, follow this guide.