Shipping to the EU with AWS Lambda

I’ve been itching to try out Amazon’s serverless services for some time now. The European Union gave me the excuse I was looking for! This post is about how I used AWS Lambda to handle some new EU new customs requirements.

A company I work with was preparing for the EU’s requirements for more detailed customs declarations. Even before the new rules came into effect on July 1, customers had started to see more packages get stopped by customs with a request for details on every item inside.

We faced 3 problems:

  1. Their storefront software (Shopify) allows only 1 tariff code per “product”—not enough for gift sets or bundles.
  2. Shopify’s API does not expose customs information, so even if we could enter more details into Shopify, that information couldn’t flow automatically to the shipping software.
  3. Their shipping software (ShipStation) can fill in customs information for orders, but again it allows only 1 tariff code per product.

I came up with a 3-part solution:

  1. When a product in Shopify needs more than 1 tariff code, store the codes (along with description, quantity, and value) in Shopify metafields. A nice thing about metafields is that they are visible in Shopify’s API! We use the Accentuate Custom Fields app to allow store admins to view and edit the metafields in a friendly way.
  2. When a new order appears in ShipStation, use ShipStation’s webhooks to send order details to a small piece of code hosted in AWS Lambda.
  3. If the order needs tariff codes filled in, retrieve the metafields from Shopify, modify the order, and send it back to ShipStation.

AWS Lambda is a good fit for this task: too complicated for a duct-tape tool like Zapier, but too small to justify having a server.

When multiple software tools are communicating about products, SKUs—compact, unique names assigned to each product—are the keys that tie everything together. Strangely, Shopify’s REST API does not let you look up a product by SKU. Thankfully, Shopify’s GraphQL API does allow that. Here’s what a query to retrieve metafields given a product SKU looks like:

{
  products(first:1, query:"sku:SOME-PRODUCT") {
    edges {
      node {
        legacyResourceId
        metafields(first:25, namespace:"accentuate") {
          edges {
            node {
              key
              value
            }
          }
        }
      }
    }
  }
}

Overall verdict on AWS Lambda: Setting up a small piece of code that runs on demand was easy. A facility for testing was right there next to the code editor, which was nice. The Secrets Manager was convenient for safely storing API keys. The policies that govern permissions were ugly, but you can’t win ’em all. 🙂 I will certainly use Lambda for more projects in the future.