Shipping & Pickup Rates

This feature allows your logistic app to display shipping methods or pickup locations with real-time rates during checkout. When a customer enters their address, EasyStore sends a request to your endpoint, and you return the available shipping options.

How It Works

  1. Customer selects "Shipping" or "Pickup" as the delivery method and fills in their address on the checkout page
  2. EasyStore sends an API request to your Shipping CURL endpoint with:
    • Shipping/pickup address (destination)
    • Sender address (origin)
    • Item weights and dimensions
  3. Your Shipping CURL processes the data and returns the available shipping/pickup methods with name and fees
┌─────────────────────────────────────────────────────────────────────────────────────────┐
│                           Shipping Rate Request Flow                                    │
└─────────────────────────────────────────────────────────────────────────────────────────┘

┌──────────────┐         ┌──────────────┐         ┌──────────────┐         ┌──────────────┐
│   Customer   │         │   EasyStore  │         │   Your App   │         │   Logistics  │
│   Checkout   │         │    Server    │         │  CURL Endpoint│        │     API      │
└──────┬───────┘         └──────┬───────┘         └──────┬───────┘         └──────┬───────┘
       │                        │                        │                        │
       │  1. Enter Address      │                        │                        │
       │  ───────────────────►  │                        │                        │
       │                        │                        │                        │
       │                        │  2. POST Request       │                        │
       │                        │  ───────────────────►  │                        │
       │                        │  • destination address │                        │
       │                        │  • origin address      │                        │
       │                        │  • item weights/dims   │                        │
       │                        │                        │                        │
       │                        │                        │  3. Calculate Rates    │
       │                        │                        │  ───────────────────►  │
       │                        │                        │  (optional)            │
       │                        │                        │                        │
       │                        │                        │  4. Return Rates       │
       │                        │                        │  ◄───────────────────  │
       │                        │                        │                        │
       │                        │  5. JSON Response      │                        │
       │                        │  ◄───────────────────  │                        │
       │                        │  • shipping methods    │                        │
       │                        │  • fees & names        │                        │
       │                        │                        │                        │
       │  6. Display Options    │                        │                        │
       │  ◄───────────────────  │                        │                        │
       │  • Method 1: $X.XX     │                        │                        │
       │  • Method 2: $X.XX     │                        │                        │
       ▼                        ▼                        ▼                        ▼
      

Registering Your CURL Endpoint

To receive shipping/pickup requests from EasyStore, register your CURL endpoint using the EasyStore API:

curl --location 'https://{shop}/api/3.0/curls.json' \
--header 'Easystore-Access-Token: {app_access_token}' \
--header 'Content-Type: application/json' \
--data '{
    "curl": {
        "url": "https://your-app.com/shipping_rate",
        "topic": "shipping/list/non_cod"
    }
}'
      

Available Topics for Registration

Topic Description
shipping/list/cod Shipping rates for COD (Cash on Delivery) orders
shipping/list/non_cod Shipping rates for non-COD orders
pickup/methods/list Pickup methods list
pos/pickup/methods/list POS pickup methods list
pickup/locations/list Pickup locations list
pickup/verify Verify pickup location
pos/pickup/verify POS verify pickup location

📖 Full documentation on CURL API: EasyStore Postman Collection

Request Headers

EasyStore includes the following headers with each request:

Header Value
Easystore-Topic shipping/list/cod, shipping/list/non_cod, pickup/methods/list, pos/pickup/methods/list, pickup/locations/list, pickup/verify, or pos/pickup/verify
Easystore-Shop-Domain Store's EasyStore domain (without https://)
Easystore-Hmac-Sha256 HMAC-SHA256 signature of payload using app secret
Content-Type application/json
User-Agent EasyStore

Request Format (Shipping)

EasyStore sends a POST request to your Shipping CURL with the following JSON payload for shipping topics (shipping/list/cod, shipping/list/non_cod):

{
  "order_token": "string | null",
  "cart_token": "string | null",
  "currency_code": "MYR",
  "total_discount": 0.00,
  "subtotal_price": 100.00,
  "total_item_weight": 500.0,
  "total_item_quantity": 2,
  "items": [
    {
      "width": 10,
      "length": 20,
      "height": 5,
      "weight_grams": 250,
      "grams": 250,
      "quantity": 1,
      "price": 50.00,
      "fulfillable_quantity": 1,
      "shipping_required": true,
      "shipping_condition": "general",
      "product_name": "Product Name",
      "sku": "SKU-001"
    }
  ],
  "origin": {
    "name": "Warehouse",
    "phone": "+60123456789",
    "email": "warehouse@example.com",
    "address1": "123 Origin St",
    "address2": "Unit A",
    "city": "Kuala Lumpur",
    "zip": "50000",
    "district_code": "DC001",
    "province": "Selangor",
    "province_code": "SG",
    "country": "Malaysia",
    "country_code": "MY",
    "company_name": "Company Name"
  },
  "destination": {
    "first_name": "John",
    "last_name": "Doe",
    "phone": "+60198765432",
    "email": "john@example.com",
    "company": "Customer Co",
    "address1": "456 Destination Ave",
    "address2": "Floor 2",
    "city": "Petaling Jaya",
    "zip": "47800",
    "province": "Selangor",
    "province_code": "SG",
    "country": "Malaysia",
    "country_code": "MY"
  },
  "pickup_data": null,
  "channel": null,
  "cod_type": 0
}
      

Response Format (Shipping)

Your endpoint should return a JSON response for shipping rates (shipping/list/cod, shipping/list/non_cod):

{
  "rate": [
    {
      "id": "rate_123",
      "courier_name": "Pos Laju",
      "shipping_charge": 10.00,
      "courier_url": "https://example.com/logo.png",
      "description": "2-3 business days",
      "is_email_required": true
    }
  ]
}
      
Field Type Description
id string Unique identifier for the rate
courier_name string Name of the courier/shipping method
shipping_charge number Shipping fee amount
courier_url string URL to courier logo image
description string Delivery time estimate or description
is_email_required boolean Whether customer email is required

Pickup Methods Response

For pickup/methods/list and pos/pickup/methods/list topics:

{
  "methods": [
    {
      "id": "method_123",
      "name": "Store Pickup",
      "cod_type": 0,
      "help_url": "https://example.com/help",
      "pickup_methods_url": "https://example.com/methods",
      "is_email_required": true
    }
  ]
}
      

Pickup Locations Response

For pickup/locations/list topic:

{
  "location": [
    {
      "id": "loc_123",
      "name": "Main Store",
      "email": "store@example.com",
      "phone": "+60123456789",
      "address1": "123 Main St",
      "address2": "",
      "city": "Kuala Lumpur",
      "zip": "50000",
      "province": "Selangor",
      "province_code": "SG",
      "country": "Malaysia",
      "country_code": "MY",
      "pickup_charge": 0,
      "cod_type": 0,
      "cutoff_day": 1,
      "cutoff_value": 2,
      "cutoff_unit": "day",
      "cod_min_amount": 0,
      "cod_max_amount": 1000,
      "business_hour": "[{\"day\":\"monday\",\"open\":\"09:00\",\"close\":\"18:00\"}]",
      "disabled_date": null
    }
  ]
}
      

Pickup Verify Response

For pickup/verify and pos/pickup/verify topics:

{
  "location": {
    "name": "Verified Location",
    "address1": "123 Main St",
    "city": "Kuala Lumpur"
  }
}
      

Next Steps

Once you have shipping rates working, learn how to handle Order Fulfillment when merchants want to create shipments.

icon-accounticon-add-newicon-add-storeicon-appicon-appleicon-archiveicon-arrowdownicon-ascicon-bookicon-cancelicon-cart-addonicon-checkouticon-cherryicon-collectionicon-comfirmicon-confirmicon-couponicon-creditsicon-currencyicon-dashboardicon-discounticon-disintegrateicon-domainicon-dscicon-duplicateicon-editicon-emailicon-exclamation-triangleicon-exporticon-eyeicon-eye-slashicon-fullscreenicon-fullscreen-closeicon-generalicon-gifticon-gridicon-hddicon-helpicon-importicon-infoicon-integrationicon-invoiceicon-likeicon-listicon-locationicon-logouticon-new-tabicon-not-secureicon-optionicon-ordericon-outline-arrowdownicon-pageicon-paymenticon-plusicon-posicon-pricingicon-printericon-producticon-product-sumicon-product-sum-xicon-redirecticon-reporticon-reseticon-searchicon-secureicon-settingicon-shippingicon-staricon-storeicon-switch-storeicon-tagicon-taxesicon-templateicon-themeicon-tickicon-trashicon-unarchiveicon-uploadicon-user-tagicon-usersicon-weighticon-wholesale