EasyPost Integration Audit: Configuration Review, Error Fixes, and Testing Protocol
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:
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
Then import in all functions:
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
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)
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
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
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:
Fix 2: Update ShipmentsPanel Query
File: ShipmentsPanel.tsx
Change query projection to fetch entire selectedRate object:
Fix 3: Update Shipment Schema Preview
File: shipment.ts
Replace preview section to use selectedRate fields:
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:
Sanity Query to Check Shipments:
Part 7: Performance Optimization
Recommendation 1: Cache Shipping Rates
Add caching to easypostGetRates to avoid redundant API calls:
Recommendation 2: Batch Shipment Queries
Update ShipmentsPanel to use pagination:
Part 8: Deployment Instructions
Step 1: Update Code
Step 2: Set Environment Variables
Step 3: Deploy
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
The Biggest Sale In F.A.S. History: Extended Cyber Monday Week
Professional porting and custom coating services at 10% off - the perfect time to upgrade your performance. - F.A.S. Motorsports
NEW PRODUCT DROP: 2020+ 6.7L Powerstroke Piping Kit – Hand-Fabricated Performance
Introducing our latest in-house fabrication: a premium piping kit engineered for 2020-2026 6.7L Ford Powerstroke trucks.