Dieser Artikel richtet sich an Entwickler, die die neue Methode GetShipAdvise mit einer anderen API verbinden möchten.
Obwohl wir in diesem Beispiel die E-Commerce-Plattform Shopify verwenden, dürfte der Ansatz auf anderen Plattformen ähnlich sein.
Hinweis: Dies soll nur eine grundlegende Möglichkeit zeigen, wie Anfragen/Antworten zwischen den beiden APIs konvertiert werden können.
Sie müssen Ihre eigene Geschäftslogik und Fehlerbehandlung anwenden.
Sie sollten keine Fragen zu Shopify an den nShift Support richten.
Nutzen Sie stattdessen das Shopify Community-Forum hier.
Inhalt dieses Artikels:
- Registrieren eines Carrier Service in einem Entwicklungs-Shop
- Datenaustausch zwischen Shopify und ShipAdvisor
- Versandregeln
- Carrier Performance
Voraussetzungen
-
Die Shipment Server API
In der API verwenden wir die Methode GetShipAdvise
-
Die Shopify Carrier Service API
Die Carrier Service API ermöglicht es Shopify-Shops, benutzerdefinierte Versandmethoden einzubinden. Dies geschieht durch eine externe API-Anfrage an die App, die die Carrier-/Versandbeschreibungen und Preise abruft.Wenn ein Benutzer den Checkout startet, wird eine Anfrage an die URL gesendet, auf die der Carrier Service zeigt. Die Anfrage enthält Informationen zu den Artikeln, Empfänger & Absender.
Weitere Informationen zur Shopify Carrier Service API finden Sie in der offiziellen Dokumentation hier:
https://help.shopify.com/en/api/reference/shipping-and-fulfillment/carrierservice
-
Versandregeln
Eine XML-Datei, die die Produkte enthält, die im Shop angezeigt werden sollen -
Carrier Performance
Eine XML-Datei, die die Berechnung der voraussichtlichen Ankunftszeit (ETA) für die verschiedenen Produkte enthält -
Ein Shopify-Entwicklungs-Shop
https://www.shopify.com/partners
Registrieren eines Carrier Service in einem Shopify-Shop
Erstellen Sie eine neue private App.
Die App benötigt Lese- und Schreibrechte im Bereich Versandtarife, Länder und Provinzen.
Verwenden Sie die hier beschriebene Methode hier, um einen neuen Service zu registrieren.
Das Beispielskript verwendet Node.js und node-fetch, um die Daten per POST an die Carrier API zu senden.
fetch('https://YOUR_STORE.myshopify.com/admin/api/2019-07/carrier_services.json',{
headers: {
'X-Shopify-Access-Token':'YOUR_PASSWORD_FROM_THE_PRIVATE_APP',
'Content-Type':'application/json'
},
body: JSON.stringify({
"carrier_service": {
"name": "SA Shipping Rate Provider",
"callback_url": "URL_TO_YOUR_WEB_SERVICE_THAT_THE_CARRIER_SERVICE_CONNECTS_TO",
"service_discovery": true
}
}),
method: 'POST'
})Danach sollte ein neuer Tarifanbieter im Shop sichtbar sein.
Datenaustausch zwischen Shopify und Ship Advisor
Die Anfrage vom Carrier Service muss in ein Format übersetzt werden, das die Methode GetShipAdvise versteht. Die Daten werden als Shipment Object erwartet.
Um ein Beispiel für das Request-Objekt der Carrier API zu sehen, klicken Sie hier
Die folgende Beispiel-Funktion verwendet dies als Eingabe und gibt ein Objekt mit Receiver, Sender & Lines zurück.
Das .filter(x => x.requires_shipping) wird verwendet, um Produkte aus dem Shopify-Shop herauszufiltern, die nicht als versandpflichtig markiert sind. Sie können diesen Teil entfernen, wenn Sie ihn nicht benötigen.
Es gibt verschiedene Möglichkeiten, das Lines-Array so zu konstruieren, dass es dem Inhalt des Warenkorbs entspricht.
In diesem Beispiel ist fest kodiert, dass jeder Artikel ein Paket in der Sendung darstellt.
const translateShopifyRequest = ({origin, destination, items}, output = {}) = {
let tmpLineObject = items.filter(x = x.requires_shipping).map((item) = {
return {
"References": [{
"Kind": 23,
"Value": item.vendor || ""
}],
"PkgWeight": item.grams,
"Number": 1
}
})
output = {
"Addresses": [{
"Kind": 1,
"Name1": destination.name,
"Street1": destination.address1,
"PostCode": destination.postal_code,
"City": destination.city,
"CountryCode": destination.country
}, {
"Kind": 2,
"Name1": origin.name,
"Street1": origin.address1,
"PostCode": origin.postal_code,
"City": origin.city,
"CountryCode": origin.country
}],
"Lines": tmpLineObject
}
return output
}Die Shopify Carrier Service API erwartet, dass die Antwort ein rates-Objekt ist.
Die folgende Beispiel-Funktion nimmt die Antwort von GetShipAdvise und gibt das erwartete Objekt zurück.
Hinweis: Die CustomFields können beliebige benutzerdefinierte Werte enthalten, die Sie ebenfalls mit den Produkten zurückgeben möchten.
const translateShipAdvisorResponse = ({Products}, output = {"rates": []}) = {
output.rates = Products.map((product) = {
let startDate = new Date(Date.parse(product.DeliveryDate))
let serviceName = (product.CustomFields && product.CustomFields.type) ? product.CustomFields.type : "",
let serviceCode = (product.CustomFields && product.CustomFields.servicecode) ? product.CustomFields.servicecode : "",
return {
"service_name": serviceName,
"service_code": serviceCode,
"total_price": product.Price,
"description": product.ProdName,
"currency": product.PriceCurrency,
"min_delivery_date": startDate.toISOString(),
"max_delivery_date": startDate.toISOString()
}
}) || []
return output
}
Shipping Rules
Das Shipping Rules (Carrier Service Rules) übernimmt die Filterung der Produkte.
Das Attribut carriervalidation im CSR-Knoten gibt an, ob die Standard-Carrier-Validierung verwendet werden soll.
In diesem Beispiel ist die Standardvalidierung deaktiviert, und es wird eine benutzerdefinierte Validierung direkt an den Produkten verwendet. Beide können bei Bedarf gleichzeitig genutzt werden.
<?xml version="1.0" encoding="utf-8"?>
<CSR carriervalidation="0" defaultservicelevel="Service_Level_Configured_For_SA">
<Prices>
<Price name="fixed59" currency="DKK">
<Exceptions>
<Exception price="5900">
<ValidationRules>
</ValidationRules>
</Exception>
</Exceptions>
<Fees>
<Fee price="1900">
<ValidationRules>
</ValidationRules>
</Fee>
</Fees>
</Price>
<Price name="fixed39" currency="DKK">
<Exceptions>
<Exception price="3900">
<ValidationRules>
</ValidationRules>
</Exception>
</Exceptions>
</Price>
</Prices>
<ServiceLevels>
<ServiceLevel name="Service_Level_Configured_For_SA">
<Products>
<Product adviseprice="fixed39" name="GLS DK - Pakkeshop med Drop Points" conceptid="1551">
<ProductGoodsType goodstypeid="0"/>
<CustomFields type="Pickup Point" servicecode="P1"/>
<ValidationRules>
<ValidationRule name="country" allowcountries="DK" field="fld_AdrCountry"/>
</ValidationRules>
</Product>
<Product adviseprice="fixed59" name="GLS DK - Normal erhvervspakke" conceptid="113">
<ProductGoodsType goodstypeid="0"/>
<CustomFields type="Home Delivery" servicecode="P2"/>
<ValidationRules>
<ValidationRule name="country" allowcountries="DK" field="fld_AdrCountry"/>
</ValidationRules>
<Services>
<Service serviceid="11020" name="Private Delivery Service"/>
</Services>
</Product>
<Product adviseprice="fixed59" name="GLS DK - Export" conceptid="189">
<ProductGoodsType goodstypeid="0"/>
<CustomFields type="Home Delivery" servicecode="P3"/>
<ValidationRules>
<ValidationRule name="country" allowcountries="SE" field="fld_AdrCountry"/>
</ValidationRules>
</Product>
</Products>
</ServiceLevel>
</ServiceLevels>
</CSR>
Carrier Performance
Dies ist ein sehr einfaches Beispiel, das die ETA-Berechnungen für die in der CSR-Konfiguration verwendeten Produkte zeigt.
<?xml version="1.0" encoding="utf-8"?>
<ConsignorETA>
<Areas>
<Area name="Nordic" type="countries">
<AreaItem countries="DK,SE"/>
</Area>
</Areas>
<PickupSchedules>
<PickupSchedule name="default" pickingtime="00:10" weekstartsonsunday="0">
<Pickup time="11:00" days="1,2,3,4,5"/>
</PickupSchedule>
</PickupSchedules>
<TransitTimes>
<TransitTime name="profile1" pickupschedule="default" trigger="submit" initiatedays="1,2,3,4,5" deliverydays="1,2,3,4,5" transportdays="1,2,3,4,5" weekstartsonsunday="0">
<Products>
<Product id="1551" name="GLS DK - Pakkeshop med Drop Points"/>
</Products>
<TimeTable>
<From area="Nordic">
<To area="Nordic" days="1" earliest="07:00" latest="18:00"/>
</From>
</TimeTable>
</TransitTime>
<TransitTime name="profile2" pickupschedule="default" trigger="submit" initiatedays="1,2,3,4,5" deliverydays="1,2,3,4,5" transportdays="1,2,3,4,5" weekstartsonsunday="0">
<Products>
<Product id="113" name="GLS DK - Normal erhvervspakke"/>
</Products>
<TimeTable>
<From area="Nordic">
<To area="Nordic" days="2" earliest="07:00" latest="18:00"/>
</From>
</TimeTable>
</TransitTime>
<TransitTime name="profile3" pickupschedule="default" trigger="submit" initiatedays="1,2,3,4,5" deliverydays="1,2,3,4,5" transportdays="1,2,3,4,5" weekstartsonsunday="0">
<Products>
<Product id="189" name="GLS DK - Export"/>
</Products>
<TimeTable>
<From area="Nordic">
<To area="Nordic" days="3" earliest="07:00" latest="18:00"/>
</From>
</TimeTable>
</TransitTime>
</TransitTimes>
</ConsignorETA>
Das erwartete Ergebnis, wenn eine Adresse aus Dänemark verwendet wird.
Das erwartete Ergebnis, wenn eine Adresse aus Schweden verwendet wird.