Changing shipment option using python requests.put

Hi,
I’m trying to update shipping method of orders using Python and the Shopify API.
Long story short our shipment provider has a bug and I needed to make new shipment profiles. There does not seem to be a way to change shipping method of existing orders so I’m trying to do so using Python…

Anyway the following code (thanks ChatGPT) seems to be working but shipping methods are not being updated… Can anyone point out what I’m doing wrong?
Thanks!!

from types import NoneType
# API endpoint
BASE_URL = f'https://{API_KEY}:{PASSWORD}@{SHOP_NAME}.myshopify.com/admin/api/2024-10'

# Order ID to update
TARGET_ORDER_NUMBER = '#1873'  # Change to the desired order ID

# Mapping of countries to shipping methods
SHIPPING_METHODS = {
    "Netherlands": "Standard Shipment NL",
    "France": "Livraison Standard FR"
}

# Fetch last 250 orders
def get_recent_orders():
    url = f"{BASE_URL}/orders.json?limit=250&status=any"
    response = requests.get(url)

# Update order shipping method
def update_order_shipping(order_id, new_shipping_method):
    # Correct URL format for updating order shipping method
    url = f"https://{API_KEY}:{PASSWORD}@{SHOP_NAME}.myshopify.com/admin/api/2024-10/orders/{order_id}.json"

    # Prepare update data (shipping_lines)
    update_data = {
        "order": {
            "id": order_id,
            "shipping_lines": [{"code": new_shipping_method}]
        }
    }

    # Request headers
    headers = {"Content-Type": "application/json"}

    # Send PUT request to update the order
    response = requests.put(url, headers=headers, json=update_data)

    response_data = response.text  # If JSON parsing fails, get raw text
    # print(response_data)
    # print(response.status_code)

    if response.status_code == 200:
        print(f"✅ Successfully updated Order ID {order_id} to {new_shipping_method}.")
    else:
        print(f"❌ Failed to update Order ID {order_id}.")
        print(f"   - HTTP Status Code: {response.status_code}")
        print(f"   - Response: {response_data}")  # Print detailed error

# Process all recent orders
orders = get_recent_orders()

if not orders:
    print("No recent orders found.")
else:
    for order in orders:
        order_number = order.get("name")
        order_id = order.get("id")

        if order_number == TARGET_ORDER_NUMBER:
            shipping_country = order.get("shipping_address", {}).get("country", "Unknown")
            old_shipping_method = order.get("shipping_lines", [{}])[0].get("code", "Unknown")
            print(order_id)

            if shipping_country in SHIPPING_METHODS:
                new_shipping_method = SHIPPING_METHODS[shipping_country]

                print(f"📦 Order ID: {order_id}")
                print(f"   - Shipping Country: {shipping_country}")
                print(f"   - Old Shipping Method: {old_shipping_method}")
                print(f"   - New Shipping Method: {new_shipping_method}")

                update_order_shipping(order_id, new_shipping_method)
            else:
                print(f"🚫 No predefined shipping method for country: {shipping_country}. No update performed.")

Is it a specific order you are looking to update or looking to update batches of orders?

Hey @Velor-cycling

Looking at your code, I can see why your shipping methods aren’t updating. The Admin REST API endpoint you’re using doesn’t support changing shipping lines on existing orders. It only allows updates to specific fields like buyer_accepts_marketing, email, note, tags, etc.

For what you’re trying to accomplish, you’ll need to use the GraphQL Admin API instead, specifically the order editing process to remove the existing shipping line and adding the new one through mutations.

We have a detailed guide here on editing orders. It provides example mutations and a step-by-step guide to follow.

Since you’re using chatgpt, just going to also plug our .dev assistant as it’s specifically tuned to work with our APIs