Overview
According to Shopify docs, a Carrier Service is:
A carrier service (also known as a carrier calculated service or shipping service) provides real-time shipping rates to Shopify. Some common carrier services include Canada Post, FedEx, UPS, and USPS. The term carrier is often used interchangeably with the terms shipping company and rate provider.
If we are creating an app that provides shipping rates on the checkout, then we need to provide an endpoint which will accept a POST request from Shopify and then return rates accordingly.
In order to do that, we need to use CarrierService API and send a request like below:
POST /admin/api/2021-01/carrier_services.json
{
"carrier_service": {
"name": "Shipping Rate Provider",
"callback_url": "http://shippingrateprovider.com",
"service_discovery": true
}
}
callback_url points to the endpoint in our app which will accept the POST request from Shopify and provide rates in return.
There is also another attribute called service_discovery which is set to true. This post aims to explain all about this option.
Service Discovery
service_discovery attribute. What is it about?
According to Shopify docs:
Whether merchants are able to send dummy data to your service through the Shopify admin to see shipping rate examples, if set to true
Above statement is a bit misleading, as some would think that there will be a form in Shopify Admin which merchants would fill to send dummy data to get example rates. But that's not the case. We'll now see how this request is sent to our endpoint.
How service discovery request is sent?
After a merchant creates a Shipping Zone inside a Shipping Profile on Shopify. They can Add rate to that shipping zone. They can set up their own rates or use a third party app to calculate rates. We are interested in the second option. Apps which have registered their endpoint using CarrierService API will appear in the dropdown as shown in the screenshot below:
Postcode Shipping is a third-party app which provides rates.
The moment merchant selects the app from the dropdown, a request is sent to the registered callback endpoint of that app.
How to identify service discovery request?
Unfortunately, there is no special identifier for this request. You can explore the JSON data (shown below) to select an attribute for yourself to differentiate the service discovery request from original request of checkout.
What data is sent with service discovery request?
Dummy data is sent when Shopify makes the service discovery request. Merchants cannot alter that data ( at the time writing this article, but this may change in future ).
Below is the JSON structure of the dummy data sent with service discovery request.
{
"rate":{
"origin":{
"country":"PK",
"postal_code":"54700",
"province":null,
"city":"Lahore",
"name":"House 584 Model Town Q Block",
"address1":"House 584 Model Town Q Block",
"address2":null,
"address3":null,
"phone":null,
"fax":null,
"email":null,
"address_type":null,
"company_name":"rateprovidertest"
},
"destination":{
"country":"US",
"postal_code":"90210",
"province":"CA",
"city":"rate test",
"name":null,
"address1":"rate test",
"address2":null,
"address3":null,
"phone":null,
"fax":null,
"email":null,
"address_type":null,
"company_name":null
},
"items":[
{
"name":null,
"sku":"XXXXXXXX",
"quantity":1,
"grams":100,
"price":0,
"vendor":null,
"requires_shipping":true,
"taxable":true,
"fulfillment_service":"manual",
"properties":null,
"product_id":null,
"variant_id":null
}
],
"currency":"PKR",
"locale":"en"
}
}
- origin contains the address of pickup location for the selected shipping profile.
- destination contains a dummy/random address of the country according to created shipping zone.
- items attribute is an array which represent dummy cart items.
Rest of World shipping zone
If the shipping zone we created is only for one country then Shopify will send one request with destination country set to selected country.
If shipping zone is Rest of World then Shopify sends four requests for four different countries.
While working on it, we found out that Shopify sends four requests with country set to United States of America (US), Mexico (MX), Denmark (DE) and Japan (JP) respectively. This pattern of requests may change in future.
This can cause confusion in the case when merchant has setup a separate shipping zone and rates for a country like US and then also see those rates in Rest of World shipping zone. Be ready to answer some support tickets.
How rates/services are shown to merchants?
When merchant selects the app from dropdown and a request is sent to third-party app, if they return rates/services, it will be shown in the SERVICES section of the modal as shown below:
Two rates returned from third party app for the US country.
What happens when merchant selects a rate/service?
If a merchant selects one rate from above screenshot, only that rate will be shown on checkout.
Lets take a look at an example. If merchant creates a shipping zone for USA and third-party app returns two rates in response to service discovery request. Merchant selects one of them. Then only selected rate will be shown on the checkout. Even though third-party will still be providing two rates in response to request made on the checkout.
Conclusion
In this post we explored the service discovery request sent by Shopify to a third-party shipping rate provider app. We looked at service_discovery attribute, what is it and what happens when it is set to true. How service discovery is sent, identifying such request and what data is sent along with this request. We also looked at differences for Rest of World shipping zone. In the end, we discovered how rates/services are shown to merchants inside Shopify and what happens on the checkout when they select one of them.
Unfortunately, this feature is not properly documented in Shopify docs. All the information that is stated above, was found by trial and error approach.
You can follow me on Twitter as I keep learning and writing about Shopify, Laravel and React.
Top comments (3)
Hello,
I add a carrier service. But, when the customer visit the checkout section, the next message is shown:
Your cart has been updated and the items you added can’t be shipped to your address. Remove the items to complete your order.
I delete products, create them again, modify zones. Change package and products weights...but nothing works...
Do you have any idea about this error?
Thanks,
Hi Gaston, there could be many reasons for this.
You can contact me on Twitter and maybe we can debug this. Thanks!
I have the same problem
configure an endpoint with a static response
as in the documentation this is my active link
script.google.com/macros/s/AKfycby...
you can send a json {}
but when making a purchase the error displays
Your cart has been updated and the items you added cannot be shipped to your address. Remove the items to complete your order.