SAP Commerce Cloud: Re-Order
SAP Re-Order module allows customers to easily place a new order for the same or similar products that they have previously purchased from an ecommerce store. This module can help increase customer loyalty, retention and revenue by offering convenience and personalization.
Features
As a customer, gain instant access to the Re-Order process, designed to simplify and expedite your re-ordering journey:
- Modal with re-order functionality baked in.
- Instant visible information about state of reordering, notifications and tag on product card in cart.
The Re-Order module can be used a additional feature for already existing ordering flow.
Installation
Add the module files
To install the module, you need an enterprise license and credentials. Contact your Customer Support Manager if you're already a customer. If you're not a customer yet, contact our sales team.
From the root of your project run the following command:
npx @vsf-enterprise/storefront-cli add-module re-order -e [sapcc,sapcc-b2b]
Follow the instructions in the command line to complete the installation. To make sure the installation is finished, go to the apps/storefront-middleware/sf-modules
folder and check if there's a folder named re-order
inside.
Middleware Extension
This module adds additional, SAP-specific middleware methods. We need to install Re-Order extension in the Middleware configuration.
// storefront-middleware/integrations/sapcc/config.ts
import type { MiddlewareConfig } from "@vsf-enterprise/sapcc-api";
import type { ApiClientExtension, Integration } from "@vue-storefront/middleware";
import { multistoreExtension, unifiedApiExtension } from "./extensions";
import { reOrderExtensionFactory } from "@sf-modules-middleware/re-order";
// ...
export const config = {
location: "@vsf-enterprise/sapcc-api/server",
configuration: {
// ...
},
extensions: (extensions: ApiClientExtension[]) => [
...extensions,
unifiedApiExtension,
...(IS_MULTISTORE_ENABLED === "true" ? [multistoreExtension] : []),
reOrderExtensionFactory(), ],
} satisfies Integration<MiddlewareConfig>;
Then, export the type of the new extension in the types.ts
file in root directory of the Middleware.
// storefront-middleware/types.ts
export {
type UnifiedEndpoints,
} from "./integrations/sapcc/types";
export type { ReOrderEndpoints } from "@sf-modules-middleware/re-order";
Frontend Implementation
1. Extend SDK configuration
First, you need to add the newly installed extension to the SDK config. To do so, edit the sdk/sdk.config.ts
file in your Next.js Storefront directory.
// storefront-unified-nextjs/sdk/sdk.config.ts
import { contentfulModule } from '@vsf-enterprise/contentful-sdk';
import { CreateSdkOptions, createSdk } from '@vue-storefront/next';
import type { UnifiedEndpoints } from 'storefront-middleware/types'; import type { UnifiedEndpoints, ReOrderEndpoints, } from 'storefront-middleware/types';
//...
export const { getSdk } = createSdk(options, ({ buildModule, middlewareModule, middlewareUrl, getRequestHeaders }) => ({
unified: buildModule(middlewareModule<UnifiedEndpoints>, {
apiUrl: `${middlewareUrl}/commerce`,
defaultRequestConfig: {
headers: getRequestHeaders(),
},
}),
reorder: buildModule(middlewareModule<ReOrderEndpoints>, { apiUrl: `${middlewareUrl}/commerce/re-order`, defaultRequestConfig: { headers: getRequestHeaders(), }, }), contentful: buildModule(contentfulModule, {
apiUrl: `${middlewareUrl}/cntf`,
}),
}));
export type Sdk = ReturnType<typeof getSdk>;
2. Add Re-Order modal into your order details
In your current order details page add ReOrderConfirmationModal
modal for reordering with OrderButton
button with style matching order details page. Button component is already existing in project and can be imported from ~/components
.
// storefront-unified-nextjs/components/OrderDetailsModal/OrderDetails.tsx
import { ConfirmationModal as ReOrderConfirmationModal } from '@sf-modules/re-order'; import { SfIconShoppingCart, useDisclosure } from '@storefront-ui/react'; import { OrderButton } from '~/components';
export function OrderDetails() {
const { isOpen: reOrderModalOpen, open: openReOrderModal, close: closeReOrderModal } = useDisclosure();
return (
...
</div>
</DescriptionList>
<div className="flex flex-col gap-2 pt-10 mt-6 border-t border-neutral-200">
...
<OrderButton slotPrefix={<SfIconShoppingCart />} onClick={openReOrderModal}> Reorder </OrderButton> ...
</div>
<ReOrderConfirmationModal open={reOrderModalOpen} onCancel={closeReOrderModal} onConfirm={closeReOrderModal} /> ...
);
}
Additionally if smaller quantity
tag wants to be visible in product card section, which is CartProductCardWrapper, then desiredQuantity
property has to be set with wantedQuantities[id]
value.
// storefront-unified-nextjs/components/CartPageContent/CartPageContent.tsx
import { useReOrderProducts } from '@sf-modules/re-order';
export function CartPageContent() {
const { wantedQuantities } = useReOrderProducts();
return (
...
<ul className="col-span-7 mb-10 md:mb-0">
{cart.lineItems.map(
({ id, productId, attributes, image, name, unitPrice, quantity, slug, totalPrice, quantityLimit }) => (
<CartProductCardWrapper
key={id}
attributes={attributes}
id={id}
productId={productId}
imageUrl={image?.url}
imageAlt={image?.alt}
name={name ?? ''}
price={formatPrice(unitPrice?.value!)}
totalPrice={formatPrice(totalPrice as SfMoney)}
specialPrice={unitPrice?.isDiscounted ? formatPrice(unitPrice?.regularPrice) : undefined}
minValue={1}
maxValue={quantityLimit || Infinity}
value={quantity}
slug={slug}
desiredQuantity={wantedQuantities[id]} />
),
)}
</ul>
...
);
}
And inside CartProductCardWrapper.tsx
additional work has to be done for removing smaller quantity tag from card once product is updated.
// storefront-unified-nextjs/components/ui/CartProductCardWrapper/CartProductCardWrapper.tsx
import { useReOrderProducts } from '@sf-modules/re-order';
export function CartProductCardWrapper() {
const { removeWantedQuantities } = useReOrderProducts();
return (
<CartProductCard
{...props}
onUpdate={(quantity) => {
updateCartQuantity.mutate({ quantity });
removeWantedQuantities(id); }}
onRemove={() => {
removeCartLineItem.mutate();
removeWantedQuantities(id); }}
disabled={updateCartQuantity.isPending || removeCartLineItem.isPending}
/>
);
}
With these steps, your Re-Order feature is now effectively integrated with SAP Commerce Cloud. You've just provided a practical solution for your customers who want a hassle-free and efficient reordering process!