Custom Shipping Information
Usually, shipping methods don't need any additional information. The user only needs to select them and proceed with their order. However, some methods need more information in order to succeed. This is mostly the case for methods relying on pickup points. The user has to choose a pickup before proceeding. This documentation will show you the different steps involved to add such a method on your own.
Before tackling this documentation, please make sure that you've understood the Essentials of Front-Commerce and that you've registered a method in your backend (Magento2…).
All the code that will be created in this page should live in your own module.
You can either put it in your client code or create a specific module for the
shipping method. If you create a specific one, please keep in mind that you need
to register it in .front-commerce.js
.
Identify your shipping method
If your shipping method is correctly registered in your backend, the following GraphQL query should return your method's codes.
{
checkout {
availableShippingMethodList(
address: { country_id: "FR", postcode: "31400" }
) {
data {
carrier_code
method_code
}
}
}
}
Make sure to set an address that can be elected by your shipping method.
Display a custom input in your shipping method
Once you've done this request, you will be able to get the carrier_code
and
the method_code
of your shipping method. You should use those to register a
new component by overriding the
getAdditionalDataComponent.js
by following this template:
import CustomMethod from "theme/modules/CustomMethod/CustomMethod";
const ComponentMap = {
"<carrier_code>": {
"<method_code>": CustomMethod,
},
};
const getAdditionalDataComponent = (method) => {
return (
ComponentMap[method.carrier_code] &&
ComponentMap[method.carrier_code][method.method_code]
);
};
export default getAdditionalDataComponent;
The Custom component referenced here should be created in your own module, and display the additional information of your shipping method to the user.
import React, { useState } from "react";
import SubmitShippingMethod from "theme/modules/Checkout/ShippingMethod/SubmitShippingMethod/SubmitShippingMethod";
const CustomMethod = ({ pending, error, submitAdditionalData }) => {
const [customValue, setCustomValue] = useState();
return (
<div className="custom-shipping-method">
<input
onChange={(event) => setCustomValue(event.target.value)}
value={customValue}
name="customValue"
type="text"
/>
<SubmitShippingMethod
key="submit"
state={pending ? "pending" : error ? "disabled" : undefined}
error={error}
onSubmit={() => {
submitAdditionalData([{ key: "customValue", value: customValue }]);
}}
/>
</div>
);
};
CustomMethod.handlesNextStepButton = () => true;
CustomMethod.AddressRecapLine = (props) => (
<div>
You can change how the address is displayed in the Address Recap of the
checkout by declaring this component.
</div>
);
export default CustomMethod;
You can reference one of our implementations to get you started
Things to understand here:
- The
SubmitShippingMethod
component is a common component across all shipping methods to ensure consistency in how methods are managed. CustomMethod.handlesNextStepButton = () => true;
means that you are indeed usingSubmitShippingMethod
in your component. This should always betrue
asfalse
is the legacy behavior.CustomMethod.AddressRecapLine
(optional) is used to change how the shipping address is displayed in the checkout recap once you've selected your custom shipping method. For instance this is what you will use to display a pickup address instead of the shipping address filled by the user.submitAdditionalData
sends and array of objects with akey
andvalue
to your backend. This means that when the shipping method will be set, the additional data will be sent to your backend at the same time. We'll see in the next section how to act on them.
In this example we're only setting a text input, but you can do fancier things
like fetching a list of pickup points from GraphQL and displaying them here. To
do so, you need to use <PostalAddressSelector />
component that allows to
select a pickup. See
Add a shipping method with pickup points
documentation for more information.
Send the additional data to your backend
Once you've registered a shipping method with additional data, the
setCheckoutShippingInformation
mutation will be sent to Front-Commerce.
Front-Commerce will then send the additional data provided in this mutation to
your backend.
For instance, in Magento1, it'll be passed to the API at
/api/rest/frontcommerce/cart/mine/shipping-information
by sending a JSON
looking like this:
{
"shipping_carrier_code": "mondialrelaypickup",
"shipping_method_code": "24R",
"additional_data": [
{
"key": "customValue",
"value": "custom"
}
]
}
This means that you have two solutions to act upon these values in your backend:
-
you can either override the API in your backend (recommended way) by registering an observer (
frontcommerce_api_set_shipping_information_before_save
in Magento1's case) -
or you can trigger a function in your GraphQL module before calling the backend's API by using the following method:
loaders.ShippingMethod.registerShipmentMethodsHandler({
method: "<carrier_code>_<method_code>",
updateShippingInformation: (shippingMethod, data) => {
// By registering this method, this means that you can transform the data or send a different request before calling the backend's API.
// The resolved data here will be the data sent to your backend in the base API
return Promise.resolve(data);
},
});