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,
successUrl: url // This is needed for the non-native 3ds and external payment methods (such as paypal) to work (not needed for non-3ds)
errorUrl: url // This is needed for the non-native 3ds and external payment methods (such as paypal) to work (not needed for non-3ds)
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=`,
};
},
}
});
There is also a custom onOrderSuccess
callback in adyenConfiguration
, which is executed by our SDK after onSubmit
and after onAdditionalDetails
.
The onOrderSuccess
callback will replace the redirects we do in the default flow, so care when using with non-native 3ds or payments.
await sdk.adyen.mountPaymentElement({
// ...
adyenConfiguration: {
// ...
onOrderSuccess: async (result, component) => {
//execute any code such as redirect or order placement (as an example) here!
},
}
})
## 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.
:::warning
Failing the order in SFCC is currently not possible with the Unified SDK. Thereofre, the below example uses the [updateOrder](https://docs.vuestorefront.io/integrations/sfcc/api/sfcc-sdk/updateOrder) method of our SFCC SDK.
:::
```ts
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.