Magento – REST API and setting the quotes Billing & Shipping addresses

apimagento2quoterest

In Magento 2.2 there is an API endpoint of:

/V1/carts/mine/billing-address

And this accepts JSON in a POST request like this:

{
  "address": {
    "region": "somewhere",
    "country_id": "GB",
    "street": [
        "a street"
    ],
    "telephone": null,
    "postcode": null,
    "city": null,
    "firstname": "test",
    "lastname": "testing",
    "email": "test@example.com"
  }
}

This will correctly update the billing address, and if the shipping address is the same I can add this flag:

"useForShipping": true

But how do I save a shipping address to the quote that is not the same as the billing address?

I have found this endpoint:

/V1/carts/mine/shipping-information

Which accepts the billing and shipping addresses but also requires a shipping carrier and method – which we cannot possibly know yet without first saving the shipping address?

This must work for both logged in customers and guest carts.

I found a number of GitHub issues related to this, such as this one, but none of them seem to provide an actual answer.

Best Answer

According to http://devdocs.magento.com/guides/v2.1/get-started/order-tutorial/order-prepare-checkout.html it looks like Magento 2 wants us to first get the shipping methods and then use that to call the shipping-information endpoint.

Interestingly enough however, Magento 2 does have a ShippingAddressManagementInterface but simply does not define an available REST API endpoint to reach this interface.

We can create this endpoint in a custom module through etc/webapi.xml:

<?xml version="1.0"?>
<routes xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Webapi:etc/webapi.xsd">

    <!-- Managing My Cart Shipping address -->
    <route url="/V1/carts/mine/shipping-address" method="GET">
        <service class="Magento\Quote\Model\ShippingAddressManagementInterface" method="get"/>
        <resources>
            <resource ref="self" />
        </resources>
        <data>
            <parameter name="cartId" force="true">%cart_id%</parameter>
        </data>
    </route>
    <route url="/V1/carts/mine/shipping-address" method="POST">
        <service class="Magento\Quote\Model\ShippingAddressManagementInterface" method="assign"/>
        <resources>
            <resource ref="self" />
        </resources>
        <data>
            <parameter name="cartId" force="true">%cart_id%</parameter>
        </data>
    </route>

</routes>

You can then call the endpoint the same way as you would with a billing address:

# /rest/default/V1/carts/mine/shipping-address

{
"address": {
    "region": "somewhere else",
    "country_id": "GB",
    "street": [
        "my shipping street"
    ],
    "telephone": null,
    "postcode": null,
    "city": null,
    "firstname": "test",
    "lastname": "testing",
    "email": "test@example.com"
  }
}
Related Topic