EasyPost Integration Audit: Configuration Review, Error Fixes, and Testing Protocol

Amber Mingione 25 min read
EasyPost Integration Audit - Technical documentation cover showing shipping integration workflow with code and testing elements

Executive Summary

This document provides a complete audit of the FAS Motorsports EasyPost shipping integration, identifies configuration issues, and provides fixes with testing procedures. The integration is mostly correctly wired but has key issues that need resolution for full functionality.

Part 1: Configuration Audit

Environment Variables Checklist

Verify these environment variables are set in Netlify:

[@portabletext/react] Unknown block type "code", specify a component for it in the `components.types` prop

Current Issues Identified

Issue 1: Duplicate Sanity Client Initialization

Files affected: easypostCreateLabel.ts, easypostWebhook.ts, fulfill-order.ts

Problem: Multiple Sanity clients initialized with different configurations

Fix: Create a shared client utility

[@portabletext/react] Unknown block type "code", specify a component for it in the `components.types` prop

Then import in all functions:

[@portabletext/react] Unknown block type "code", specify a component for it in the `components.types` prop

Issue 2: Inconsistent Field Mapping in Shipment Schema

File: shipment.ts

Problem: Duplicate fields at root level AND in selectedRate object: carrier (root) vs selectedRate.carrier, service (root) vs selectedRate.service, rate (root) vs selectedRate.rate

Fix: Remove root-level duplicates, use only selectedRate

[@portabletext/react] Unknown block type "code", specify a component for it in the `components.types` prop

Issue 3: Webhook Data Not Populating Shipment Documents

File: easypostWebhook.ts

Problem: Webhook creates shipment documents but may not be linking to orders correctly

Fix: Enhanced order lookup with better fallbacks. The upsertShipmentDocument function needs to properly map the selectedRate object instead of using root-level fields, and ensure proper order linking via reference.

Issue 4: PDF Thumbnail Not Rendering

File: PDFThumbnail.tsx

Problem: EasyPost PDFs have CORS restrictions preventing iframe/canvas rendering

Fix: Use styled icon placeholder (PDFs are clickable to open)

[@portabletext/react] Unknown block type "code", specify a component for it in the `components.types` prop

Issue 5: Duplicate Document Actions

Files: purchaseOrderLabel.tsx, purchaseShippingLabel.tsx

Problem: Both actions registered on order schema, but one is for invoices

Fix: Keep only purchaseOrderLabelAction in order schema, move purchaseShippingLabelAction to invoice schema

Part 2: Data Flow Verification

Label Creation Flow

1. User clicks "Purchase Shipping Label" on order

2. purchaseOrderLabelAction calls /.netlify/functions/easypostCreateLabel

3. easypostCreateLabel function: Fetches order from Sanity, calculates package dimensions from cart, creates EasyPost shipment, buys lowest rate, downloads label PDF, uploads PDF to Sanity assets, creates shipment document, updates order with tracking info

4. Order document updated with: shippingLabelUrl, trackingNumber, trackingUrl, easyPostShipmentId, fulfillment.status = 'label_created'

Webhook Flow

1. EasyPost sends webhook to /.netlify/functions/easypostWebhook

2. Webhook verifies signature using EASYPOST_WEBHOOK_SECRET

3. Processes event types: tracker.updated → Updates order shipping status, shipment.created → Creates/updates shipment document, refund.created → Marks label as refunded

4. Updates linked order via metadata lookup

Part 3: Testing Protocol

Test 1: Environment Variables

[@portabletext/react] Unknown block type "code", specify a component for it in the `components.types` prop

Test 2: Create Label from Order

Steps:

1. Open an order with paymentStatus: 'paid'

2. Verify shipping address is complete

3. Click "Purchase Shipping Label" action

4. Verify success message with tracking number

5. Check order document for: shippingLabelUrl populated, trackingNumber populated, easyPostShipmentId populated

6. Click label URL - should open PDF in new tab

Expected Result: Label PDF downloads/opens, order status updates to 'fulfilled', shipment document created in Sanity

Test 3: Webhook Processing

Steps:

1. In EasyPost dashboard, configure webhook: URL: https://your-site.netlify.app/.netlify/functions/easypostWebhook, Secret: Your EASYPOST_WEBHOOK_SECRET, Events: tracker.updated, shipment.created

2. Create a test shipment via API or dashboard

3. Check Netlify function logs for webhook receipt

4. Verify shipment document created in Sanity

5. Verify order document updated with tracking

Expected Result: Webhook receives event, signature validates, shipment document created/updated, order linked correctly

Test 4: Shipments Panel Display

Steps:

1. Navigate to Shipments in Sanity Studio

2. Verify shipments list displays

3. Check each shipment card shows: Customer name, order number, tracking number • service • cost, PDF thumbnail (gradient with icon), status icon

4. Click PDF thumbnail - should open label

5. Click "Open" button - should open tracking URL

Expected Result: All shipments display correctly, PDFs open when clicked, tracking links work

Test 5: Shipping Quote Dialog

Steps:

1. Open ShipmentsHeader actions menu

2. Click "Get Shipping Quote"

3. Enter test address

4. Enter manual dimensions OR search for product

5. Click "Get Quotes"

6. Verify rates display

7. Enter customer ID

8. Click "Save to Customer"

9. Check customer document for saved quote PDF

Expected Result: Rates fetch successfully, PDF generates, quote saves to customer.shippingQuotes array

Part 4: Common Errors and Fixes

Error: "Missing EASYPOST_API_KEY"

Cause: Environment variable not set in Netlify

[@portabletext/react] Unknown block type "code", specify a component for it in the `components.types` prop

Error: "Incomplete shipping address"

Cause: Order missing required address fields

Fix: Ensure order has shippingAddress.addressLine1, shippingAddress.city, shippingAddress.state, shippingAddress.postalCode, shippingAddress.country

Error: "No EasyPost rates available"

Cause: Invalid package dimensions or address

Fix: Check weight > 0, dimensions all > 0, address is valid US address, not exceeding carrier limits (150 lbs, 108" longest side)

Error: "Failed to persist shipping label PDF"

Cause: Sanity token lacks upload permissions

Fix: Verify SANITY_API_TOKEN has write permissions in Sanity project settings

Error: "Webhook signature verification failed"

Cause: EASYPOST_WEBHOOK_SECRET doesn't match EasyPost dashboard

Fix: 1. Copy secret from EasyPost webhook settings, 2. Set in Netlify: netlify env:set EASYPOST_WEBHOOK_SECRET "secret_here", 3. Redeploy site

Part 5: Code Fixes Required

Fix 1: Update easypostCreateLabel.ts

Change shipment document creation to use selectedRate object instead of root-level fields:

[@portabletext/react] Unknown block type "code", specify a component for it in the `components.types` prop

Fix 2: Update ShipmentsPanel Query

File: ShipmentsPanel.tsx

Change query projection to fetch entire selectedRate object:

[@portabletext/react] Unknown block type "code", specify a component for it in the `components.types` prop

Fix 3: Update Shipment Schema Preview

File: shipment.ts

Replace preview section to use selectedRate fields:

[@portabletext/react] Unknown block type "code", specify a component for it in the `components.types` prop

Part 6: Testing Checklist

Pre-Deployment

☐ All environment variables set in Netlify

☐ Sanity token has write permissions

☐ EasyPost API key is production key (not test)

☐ Webhook secret matches EasyPost dashboard

☐ Sender address configured correctly

Post-Deployment

☐ Create test order with complete shipping address

☐ Purchase label via document action

☐ Verify label PDF opens

☐ Verify tracking number saved

☐ Verify shipment document created

☐ Check shipment appears in ShipmentsPanel

☐ Click PDF thumbnail - opens label

☐ Click Open button - opens tracking

☐ Test shipping quote dialog

☐ Verify webhook receives events (check Netlify logs)

☐ Verify tracking updates sync to order

Monitoring

Netlify Function Logs:

[@portabletext/react] Unknown block type "code", specify a component for it in the `components.types` prop

Sanity Query to Check Shipments:

[@portabletext/react] Unknown block type "code", specify a component for it in the `components.types` prop

Part 7: Performance Optimization

Recommendation 1: Cache Shipping Rates

Add caching to easypostGetRates to avoid redundant API calls:

[@portabletext/react] Unknown block type "code", specify a component for it in the `components.types` prop

Recommendation 2: Batch Shipment Queries

Update ShipmentsPanel to use pagination:

[@portabletext/react] Unknown block type "code", specify a component for it in the `components.types` prop

Part 8: Deployment Instructions

Step 1: Update Code

[@portabletext/react] Unknown block type "code", specify a component for it in the `components.types` prop

Step 2: Set Environment Variables

[@portabletext/react] Unknown block type "code", specify a component for it in the `components.types` prop

Step 3: Deploy

[@portabletext/react] Unknown block type "code", specify a component for it in the `components.types` prop

Step 4: Configure EasyPost Webhook

1. Go to EasyPost Dashboard → Webhooks

2. Add webhook: URL: https://fassanity.fasmotorsports.com/.netlify/functions/easypostWebhook, Secret: (copy from Netlify env vars), Events: Select all tracker and shipment events

3. Test webhook with sample event

Step 5: Verify Integration

1. Create test order in Sanity

2. Purchase label

3. Verify shipment created

4. Check webhook logs in Netlify

5. Verify tracking updates

Summary

The EasyPost integration is mostly correctly wired but has these key issues:

1. ✅ Duplicate schema fields - Remove root carrier/service/rate

2. ✅ PDF thumbnail CORS - Use styled icon instead

3. ✅ Inconsistent data mapping - Standardize on selectedRate object

4. ✅ Duplicate document actions - Separate order vs invoice actions

5. ⚠️ Missing webhook configuration - Needs setup in EasyPost dashboard

After applying these fixes and running the test protocol, the integration will be fully functional. This audit provides clear action items, code fixes, and comprehensive testing procedures to ensure the EasyPost shipping integration operates correctly across all workflows.

Related Posts

Top Products

Explore our most requested billet components and performance upgrades, each engineered in-house and backed by track data.

Top Services

Pair your hardware upgrades with professional installation, calibration, and security options from the F.A.S. Motorsports team.