Linkable

Integration Guide

Hướng dẫn tích hợp API tạo đơn POD — giải thích chi tiết các field, rules, và ví dụ.

Download OpenAPI Spec

Version: 1.0.0Base URL: https://api.eod-infinitee.com
JSONYAML

Download via terminal:

curl -O /openapi.json

Overview

API tạo đơn POD hỗ trợ 2 loại đơn:

  • Đơn thường — Hệ thống tính phí ship
  • Đơn có label — Bạn cung cấp sẵn shipping label (TikTok, Etsy, v.v.)

Authentication

Authorization: Bearer <your_token>

Ví dụ nhanh

Đơn thường (không có label)

POST /v1/orders/pod

{
  "reference_id": "MY-ORDER-001",
  "customer": {
    "email": "customer@example.com",
    "first_name": "John",
    "last_name": "Doe",
    "phone": "+14155551234"
  },
  "shipping_address": {
    "address1": "123 Main St",
    "address2": "Apt 4B",
    "city": "Los Angeles",
    "province": "CA",
    "country_code": "US",
    "zip": "90001"
  },
  "shipping_service": "eco",
  "line_items": [
    {
      "variant_id": "3c371069-9ff6-4930-ab3a-3f130fe77afe",
      "quantity": 2,
      "sides": {
        "front_large": "https://cdn.example.com/design-front.png",
        "back": "https://cdn.example.com/design-back.png"
      },
      "printing_technique": "DTG"
    }
  ],
  "note": "Please prioritize",
  "tags": "rush,vip"
}

Đơn có label (TikTok/Etsy)

POST /v1/orders/pod

{
  "reference_id": "TIKTOK-ORDER-001",
  "customer": {
    "email": "customer@example.com",
    "first_name": "Jane",
    "last_name": "Smith"
  },
  "label_link": "https://labels.tiktok.com/your-label.pdf",
  "tracking_number": "9400111899223456789012",
  "shipping_service": "eco",
  "line_items": [
    {
      "variant_id": "3c371069-9ff6-4930-ab3a-3f130fe77afe",
      "quantity": 1,
      "sides": {
        "front_large": "https://cdn.example.com/design.png"
      },
      "printing_technique": "DTF"
    }
  ]
}

Hai loại đơn

Warning: Bạn chỉ được chọn 1 trong 2 loại. Không được truyền cả shipping_address lẫn label_link.

Loại 1: Đơn thường

Truyền shipping_address. Hệ thống sẽ tính phí ship dựa trên shipping_service và country_code.

FieldBắt buộcMô tả
shipping_address.address1CóĐịa chỉ dòng 1
shipping_address.address2KhôngĐịa chỉ dòng 2 (optional)
shipping_address.cityCóThành phố
shipping_address.provinceCóTỉnh/Bang (viết tắt: "CA", "TX"...)
shipping_address.country_codeCóMã quốc gia 2 ký tự ("US", "VN"...)
shipping_address.zipCóMã bưu chính

Loại 2: Đơn có label

Truyền label_link + tracking_number. Không truyền shipping_address.

FieldBắt buộcMô tả
label_linkCóURL file shipping label (PDF)
tracking_numberCóMã tracking từ nhà vận chuyển

Important: label_link và tracking_number phải đi đôi — truyền 1 thiếu 1 sẽ bị reject.


Tìm product / variant

Mỗi line item cần một variant_id. Lấy nó từ API Products, có thể lọc bằng q + search_type:

search_typeCách so khớp qVí dụ
name (mặc định)Một phần tên product, không phân biệt hoa thường?q=hoodie
product_idKhớp chính xác product_id (UUID)?q=3f2a…&search_type=product_id
skuMột phần SKU của variant, không phân biệt hoa thường, tối thiểu 3 ký tự?q=MAROON-L&search_type=sku
GET /v1/stores/{store_id}/products?q=HOODIE&search_type=sku

// Trả về mọi product có ít nhất 1 variant mà SKU chứa "HOODIE" (rút gọn):
{
  "data": [
    {
      "product_id": "…",
      "title": "Embroidered Hoodie",
      "variants": [
        { "variant_id": "abc-123", "title": "Maroon / L", "sku": "emb - HOODIE - MAROON-L" },
        { "variant_id": "abc-124", "title": "Black / S", "sku": "emb - HOODIE - BLACK-S" }
      ]
    }
  ],
  "next_cursor": null
}
  • HOODIE, hoodie, MAROON-L hay emb - HOODIE đều khớp SKU emb - HOODIE - MAROON-L.
  • q có 1–2 ký tự với search_type=sku → 400 (q: SKU search requires at least 3 characters).
  • Kết quả là product (kèm toàn bộ variant của nó), không phải từng variant. Nếu bạn đang có SKU đầy đủ và cần đúng 1 variant_id, hãy lọc lại trong variants theo sku khớp chính xác.

Note: Trước đây search_type=sku so khớp chính xác cả chuỗi SKU. Nay là khớp một phần, nên một SKU đầy đủ có thể trả về nhiều product hơn (ví dụ TS-BLK-L cũng khớp TS-BLK-LG). Code đang giả định "kết quả đầu tiên là đúng" cần đổi sang lọc theo sku như trên.


Sides (vị trí in/thêu)

Mỗi line item bắt buộc có ít nhất 1 side. Truyền dạng object { "side_code": "url_ảnh" }.

Side codes hợp lệ

CodeVị trí
front_sideMặt trước nhỏ
front_largeMặt trước lớn (full)
backMặt sau
pocket_chest_leftTúi ngực trái
pocket_chest_rightTúi ngực phải
left_sleeveTay áo trái
right_sleeveTay áo phải
special_locationVị trí đặc biệt
mockup_urlẢnh mockup sản phẩm

Note: URL phải là link ảnh hợp lệ (bắt đầu bằng http:// hoặc https://).


Printing (In ấn)

Dùng cho đơn in trên vải.

{
  "sides": { "front_large": "https://..." },
  "printing_technique": "DTG"
}
Giá trịMô tả
DTGDirect-to-Garment — in trực tiếp lên vải
DTFDirect-to-Film — in lên film rồi ép nhiệt

Embroidery (Thêu)

Dùng cho đơn thêu. Có 2 trường hợp:

Trường hợp 1: Có file thêu sẵn

Bạn đã có file thêu định dạng chuyên dụng (.dst, .pes, .jef...) và gửi kèm.

{
  "sides": { "front_large": "https://..." },
  "emb_file": "Available"
}

Chỉ cần truyền emb_file: "Available". Không cần các field khác.

Trường hợp 2: Không có file thêu (cần digitize)

Bạn chỉ có hình design, cần bên mình chuyển đổi sang file thêu.

{
  "sides": { "front_large": "https://..." },
  "emb_file": "No EMB file",
  "design_emb_type": "vector / cartoon artwork"
}

Khi emb_file = "No EMB file", bắt buộc truyền design_emb_type:

Giá trịMô tả
text onlyDesign chỉ có chữ
vector / cartoon artworkHình vector hoặc cartoon
Photo to EmbroideryẢnh chụp thực (chân dung, thú cưng...)

Photo to Embroidery

Nếu chọn "Photo to Embroidery", bắt buộc truyền thêm number_of_pets:

{
  "emb_file": "No EMB file",
  "design_emb_type": "Photo to Embroidery",
  "number_of_pets": 2
}
FieldRangeMô tả
number_of_pets1–4 (cap/hat: 1–2)Số lượng pet/người trong ảnh

Warning: Không mix in và thêu trong cùng 1 line item. Chọn printing_technique HOẶC emb_file, không cả hai.


Yarn Type (Loại chỉ thêu)

Note: Field này phụ thuộc vào product variant. Không phải tất cả sản phẩm đều cần.

Cách biết variant nào cần yarn_type

Gọi API lấy products, mỗi variant có field requires_yarn_type là mảng các yarn_type hợp lệ cho variant đó:

GET /v1/stores/{store_id}/products

// Response:
{
  "variant_id": "abc-123",
  "title": "Black / M",
  "category": "hoodie",
  "requires_yarn_type": ["yarn_6_7mm", "yarn_8_10mm", "yarn_20mm"]  // ← chọn 1 giá trị trong mảng
}
  • Mảng rỗng [] → KHÔNG ĐƯỢC truyền yarn_type (truyền vào sẽ bị reject).
  • Mảng có phần tử → BẮT BUỘC truyền yarn_type, và giá trị phải nằm trong mảng đó.

Đừng đoán theo tên sản phẩm — luôn đọc mảng requires_yarn_type của chính variant rồi chọn 1 giá trị.

Mảng hợp lệ theo category

Categoryrequires_yarn_type
hoodie, sweatshirt["yarn_6_7mm", "yarn_8_10mm", "yarn_20mm"]
cap["plat_emb", "emb_3d_puff"]
tshirt, tote[] (không truyền yarn_type)

Ý nghĩa các giá trị

Giá trịMô tả
yarn_6_7mmChỉ thêu 6-7mm
yarn_8_10mmChỉ thêu 8-10mm
yarn_20mmChỉ thêu 20mm
plat_embThêu phẳng (flat embroidery, cap)
emb_3d_puffThêu nổi 3D (3D puff, cap)

Ví dụ

{
  "variant_id": "variant-requires-yarn",
  "quantity": 1,
  "sides": { "front_large": "https://..." },
  "emb_file": "Available",
  "yarn_type": "yarn_8_10mm"
}

Add-on Service

Dịch vụ bổ sung cấp line-item (optional), tính phí theo quantity:

Giá trịMô tảPhí
fabric_appliqueFabric applique / glitter embroidery$1.50/item
lace_applique_embLace applique embroidery$2.00/item
{
  "addon_service": "lace_applique_emb"
}

Warning: Không khả dụng cho sản phẩm tote, cap/hat, hoặc sản phẩm yêu cầu yarn type.


Shipping Service

Giá trịMô tả
ecoGiao hàng tiết kiệm (mặc định)
premiumGiao hàng nhanh

Dedup (Chống trùng đơn)

Hệ thống kiểm tra trùng đơn theo reference_id:

  • Cùng reference_id + cùng store → bị reject 409 DUPLICATE_REFERENCE_ID
  • Nếu muốn bỏ qua soft dedup (content hash), truyền "force": true

Order Flow

Tạo đơn → PENDING → QUEUED → PROCESSING → SUCCESS
                                             ↓
                                           FAILED (auto retry tối đa 3 lần)

Kiểm tra trạng thái

GET /v1/orders/pod/{order_id}

Retry đơn FAILED

POST /v1/orders/pod/{order_id}/retry

Hủy đơn

POST /v1/orders/pod/{order_id}/cancel

Chỉ hủy được đơn ở trạng thái PENDING, QUEUED, hoặc FAILED.


Nhận cập nhật đơn hàng qua webhook

Thay vì poll GET /v1/orders/pod/{order_id} liên tục để biết đơn đổi trạng thái hay có tracking mới, bạn có thể đăng ký webhook: hệ thống sẽ chủ động POST sự kiện (order.created, order.status_updated, order.cancelled, tracking.created, tracking.updated) tới URL của bạn ngay khi có thay đổi.

Xem hướng dẫn Webhooks để biết quickstart, receiver mẫu (Node/Express, Python/FastAPI, PHP), cách xác thực chữ ký và troubleshooting.


Errors thường gặp

HTTPErrorNguyên nhânFix
400shipping_address is required...Thiếu địa chỉ, không có labelThêm shipping_address hoặc dùng label_link + tracking_number
400shipping_address must not be provided for label ordersTruyền cả address lẫn labelBỏ shipping_address khi dùng label
400label_link and tracking_number must both be providedTruyền 1 thiếu 1Phải truyền cả 2 hoặc bỏ cả 2
400yarn_type is required for this productVariant có requires_yarn_type không rỗng mà không truyềnChọn 1 giá trị trong mảng requires_yarn_type
400yarn_type is not allowed for this productVariant có requires_yarn_type: [] mà lại truyềnBỏ yarn_type
400yarn_type "X" not allowed for <category>Giá trị không nằm trong mảngChỉ dùng giá trị có trong requires_yarn_type
400At least one side design is requiredsides rỗngThêm ít nhất 1 side
400Invalid side codeKey saiDùng đúng side code (xem bảng trên)
400variant_id not foundID không tồn tạiCheck lại từ GET /products
400q: SKU search requires at least 3 characterssearch_type=sku với q 1–2 ký tựTruyền ít nhất 3 ký tự, hoặc bỏ q
409DUPLICATE_REFERENCE_IDref_id đã dùngĐổi reference_id hoặc "force": true

Checklist trước khi gửi đơn

  1. Lấy variant_id từ API Products (tìm theo SKU: ?q=<≥3 ký tự>&search_type=sku, xem Tìm product / variant)
  2. Check requires_yarn_type — nếu mảng không rỗng thì chọn 1 giá trị trong mảng làm yarn_type
  3. Chọn loại đơn: shipping_address HOẶC label_link + tracking_number
  4. Truyền ít nhất 1 side trong sides với URL ảnh hợp lệ
  5. Chọn technique: printing_technique HOẶC emb_file (không cả hai)
  6. Nếu emb_file = "No EMB file" → truyền design_emb_type
  7. Nếu design_emb_type = "Photo to Embroidery" → truyền number_of_pets