개발자 문서 · v1 (1.2.0)

파트너 API·편집기 SDK

견적·주문 앱에서 PODIZ 고객 편집기를 띄워 디자인을 받고, 공급사 제품을 내 상품에 연결하고, 결제된 주문을 PODIZ 주문함으로 보내요. 공급사가 만든 제작 상태·송장은 API로 읽어요.

API 주소
https://www.podiz.co.kr/api/partner/v1
인증
Authorization: Bearer podiz_sk_…

개요

공급사(인쇄·제작 업체)가 PODIZ 콘솔에서 파트너 앱 연결을 만들고 키를 발급하면, 파트너 앱이 그 공급사의 제품으로 견적·주문을 받을 수 있어요. 연결 하나가 앱 설치 하나예요 — 키·사이트 주소·상품 연결·주문이 연결마다 나뉘어요.

단계누가무엇
① 준비공급사PODIZ 콘솔 [판매 채널 › 파트너 앱 연결] — 편집기를 띄울 사이트 주소를 넣으면 공개 키·비밀 키·편집기 스크립트가 나와요
② 상품 연결파트너 서버GET /products로 제품을 고르고 PUT /links/{상품 번호}로 내 상품 번호에 붙여요
③ 디자인고객 (파트너 화면)[디자인하기] → PODIZ 편집기(견적 모드) → [디자인 완료] → 디자인 번호가 견적서에 들어가요
④ 견적파트너 관리자GET /designs/{번호} — 미리보기·색상·디자인한 인쇄 위치로 견적을 내요 (가격은 파트너가 정해요)
⑤ 주문파트너 서버 (결제 뒤)POST /orders — 줄마다 디자인 번호·사이즈(품목 코드)·수량 → PODIZ 주문함
⑥ 제작·발송공급사 → 파트너 서버공급사가 인쇄 파일로 만들어 발송을 기록하면, 파트너가 GET /orders로 제작 상태·송장을 읽어요
  • 디자인은 색상까지 정해요 — 사이즈·수량은 주문 줄이 정해서, 한 디자인을 여러 사이즈로 주문할 수 있어요(단체 티셔츠처럼).
  • 디자인은 확정한 날부터 기본 90일 보관해요(주문되면 계속). 견적이 길어지면 보관 연장 API를 불러요.
  • PODIZ는 주문자·수령인 개인정보를 받지 않아요 — 배송지는 파트너 앱에서 확인하고, 공급사는 작업지시서에서 파트너 앱 주문을 보라는 안내를 봐요.

시작하기

  1. 1

    공급사에게 연결 받기

    공급사가 PODIZ 콘솔에서 파트너 앱 연결을 만들고 공개 키(podiz_pk_…)·비밀 키(podiz_sk_…)·편집기 스크립트를 전해 줘요. 비밀 키는 만들 때 한 번만 보여요 — 잃어버리면 새로 발급받아요.

  2. 2

    키 확인

    서버에서 비밀 키로 연결을 확인해요. 비밀 키는 환경 변수 등에 두고 코드에 적지 마세요.

    curl
    curl "https://www.podiz.co.kr/api/partner/v1/me" \
      -H "Authorization: Bearer $PODIZ_SECRET_KEY"
  3. 3

    상품 연결

    제품 목록에서 고른 PODIZ 제품을 내 상품 번호에 붙여요. 색상·사이즈 품목은 PODIZ가 맞춰요.

    curl
    curl -X PUT "https://www.podiz.co.kr/api/partner/v1/links/1000000015" \
      -H "Authorization: Bearer $PODIZ_SECRET_KEY" \
      -H "Content-Type: application/json" \
      -d '{"product_id":"c3b25e5b-f222-43fd-a615-b5c72a978af9","name":"단체 티셔츠 (견적)","code":"ODZ-TEE-01"}'
  4. 4

    견적 화면에 편집기

    고객이 보는 견적 화면에 스크립트 한 줄과 [디자인하기] 버튼을 넣어요 — 아래 편집기 SDK.

    편집기 SDK 보기
  5. 5

    디자인 조회 → 견적

    받은 디자인 번호로 미리보기·색상·인쇄 위치를 보고 견적을 내요.

    curl
    curl "https://www.podiz.co.kr/api/partner/v1/designs/PL-7K2M9Q4XHAA" \
      -H "Authorization: Bearer $PODIZ_SECRET_KEY"
  6. 6

    결제된 주문 보내기

    줄마다 디자인 번호·사이즈·수량 — 한 디자인을 여러 사이즈로 나눠 보내요. 주문 번호가 같으면 다시 보내도 한 주문이에요.

    curl
    curl -X POST "https://www.podiz.co.kr/api/partner/v1/orders" \
      -H "Authorization: Bearer $PODIZ_SECRET_KEY" \
      -H "Content-Type: application/json" \
      -d '{"order_id":"Q20261014-0001","paid_at":"2026-10-14T12:00:00+09:00","items":[{"item_id":"1","design_no":"PL-7K2M9Q4XHAA","variant_code":"PL-064d02c3d65c40f1a97d1f20e450d73c","quantity":20},{"item_id":"2","design_no":"PL-7K2M9Q4XHAA","variant_code":"PL-10ef6ee5a7164ed9ac9b3e8fe1f47753","quantity":10}]}'
  7. 7

    제작 상태·송장 맞추기

    PODIZ는 파트너를 부르지 않아요(웹훅 없음). 변경 목록을 주기적으로(예: 10분마다) 불러 next_cursor를 저장해 두면 그 뒤에 바뀐 주문만 와요.

    curl
    curl "https://www.podiz.co.kr/api/partner/v1/orders?limit=50" \
      -H "Authorization: Bearer $PODIZ_SECRET_KEY"

인증

비밀 키 podiz_sk_…

  • 모든 API 요청의 Authorization: Bearer podiz_sk_… 헤더로만 보내요 — 주소·본문에 넣지 않아요.
  • 서버에서만 써요. 브라우저·앱 코드에 넣지 마세요 — API는 CORS를 열지 않아 브라우저에서 부를 수 없어요.
  • 연결마다 살아 있는 키 5개까지 — 서버마다 이름을 붙여 따로 발급받으면 하나만 폐기할 수 있어요. 마지막 사용 시각이 공급사 콘솔에 보여요.
  • 새거나 의심되면 공급사가 콘솔에서 폐기해요 — 바로 401이에요. 연결을 해제하면 키가 모두 폐기돼요.

공개 키 podiz_pk_…

  • 편집기 SDK에 넣는 값이에요. 비밀이 아니에요 — 연결을 가리킬 뿐이에요.
  • 편집기는 연결에 등록한 사이트 주소(출처)에서만 열려요. 사이트 주소가 바뀌면 공급사에게 등록해 달라고 하세요.
  • 디자인 미리보기 주소처럼 키 없이 부르는 공개 주소도 이 값과 디자인 번호가 열쇠예요.
키 확인 — GET /me
curl "https://www.podiz.co.kr/api/partner/v1/me" \
  -H "Authorization: Bearer $PODIZ_SECRET_KEY"

규약

주소
https://www.podiz.co.kr/api/partner/v1 — 아래 경로는 모두 이 뒤예요.
형식
JSON·snake_case. 본문은 content-type: application/json(아니면 415), 값이 없는 요청은 빈 본문이나 {}. 시각은 ISO 8601(응답은 UTC), 금액은 원 단위 정수(참고 값 — PODIZ는 공급사와 파트너 사이를 정산하지 않아요).
번호
파트너 상품 번호는 1 ~ 9007199254740991 정수, 주문·품목 번호는 영문·숫자·하이픈 40자까지(밑줄 없음). 디자인 번호는 대소문자·하이픈을 무시하고 받아 PL-XXXXXXXXXXX로 돌려줘요.
응답
성공은 { "data": … }, 오류는 { "error": { code, message, fields?, details?, request_id } } — code로 처리하고 message(한국어)는 화면에 그대로 써도 돼요. 모든 응답에 x-request-id가 있어요 — 문의할 때 알려 주세요.
다시 보내기
주문은 주문 번호가 열쇠예요 — 같은 줄로 다시 보내면 200(replayed), 다른 줄이면 409. 상품 연결(PUT)·연장·취소도 다시 불러도 같아요. 네트워크 오류면 같은 요청을 그대로 다시 보내세요.
한도
연결마다 10분에 600번, 틀린 키는 IP마다 10분에 30번. 넘으면 429와 retry-after(초).
알림
웹훅은 없어요 — 변경 목록(GET /orders?cursor=…)을 주기적으로 불러 상태·송장을 맞춰요.
버전
v1 안에서는 더하기만 해요(새 칸·새 값) — 모르는 칸·값은 무시하세요. 깨는 바꿈은 /api/partner/v2로 함께 둬요. 바뀐 것은 맨 아래에.

엔드포인트

모든 경로에 나올 수 있는 오류: 401 UNAUTHENTICATED · 403 FORBIDDEN · 429 RATE_LIMITED · 500 INTERNAL_ERROR

연결 확인

GET /me

연결·키 확인

이 비밀 키의 연결(이름·공개 키·사이트 주소·디자인 보관 일수)과 공급사 이름, 살아 있는 키를 돌려줘요. 키를 처음 받았을 때 서버에서 한 번 불러 확인하세요.

요청 예시
curl "https://www.podiz.co.kr/api/partner/v1/me" \
  -H "Authorization: Bearer $PODIZ_SECRET_KEY"
200 연결 Me
응답 본문
{
  "data": {
    "connection": {
      "id": "8efafd80-c2d0-43b0-83fe-fb7a902fc799",
      "name": "ODIZ 견적",
      "status": "active",
      "publishable_key": "podiz_pk_8efafd80c2d043b083fefb7a902fc799",
      "domains": [
        "https://shop.example.com"
      ],
      "design_ttl_days": 90,
      "connected_at": "2026-10-14T01:00:00Z"
    },
    "supplier": {
      "name": "에이프린트"
    },
    "key": {
      "id": "069cd70a-b9cb-4a6e-bdbb-8d5540419814",
      "name": "ODIZ 운영 서버"
    },
    "keys": [
      {
        "id": "069cd70a-b9cb-4a6e-bdbb-8d5540419814",
        "name": "ODIZ 운영 서버",
        "hint": "a1b2",
        "created_at": "2026-10-14T01:00:00Z",
        "last_used_at": "2026-10-14T01:05:00Z"
      }
    ]
  }
}

제품

GET /products

제품 목록

이 공급사가 게시한 제품을 이름 순으로 돌려줘요. 상품을 연결할 때 고를 목록이에요. 색상·사이즈·품목 코드·인쇄 위치가 함께 와요.

  • page
    integer · 질의
    쪽 (1부터)
  • per_page
    integer · 질의
    쪽마다 (1 ~ 100, 기본 20)
  • q
    string · 질의
    이름 검색
요청 예시
curl "https://www.podiz.co.kr/api/partner/v1/products?page=1&per_page=20&q=%ED%8B%B0%EC%85%94%EC%B8%A0" \
  -H "Authorization: Bearer $PODIZ_SECRET_KEY"
200 제품 쪽 ProductPage
응답 본문
{
  "data": {
    "products": [
      {
        "id": "c3b25e5b-f222-43fd-a615-b5c72a978af9",
        "name": "반팔 라운드 티셔츠",
        "status": "published",
        "product_mode": "mockup",
        "base_price": 8000,
        "thumbnail_url": "https://cdn.example.com/mockups/tshirt-front.webp",
        "updated_at": "2026-10-13T09:00:00Z",
        "colors": [
          {
            "id": "1e48f712-8351-4682-b38f-983ce5bf5ba7",
            "name": "화이트",
            "hex": "#FFFFFF",
            "available": true
          },
          {
            "id": "b6ca129a-59c8-4527-8cfe-4f78c4b8ead5",
            "name": "블랙",
            "hex": "#111111",
            "available": true
          }
        ],
        "sizes": [
          {
            "id": "fb189095-a238-48e4-b82e-5b255eca88ae",
            "name": "M",
            "extra_price": 0,
            "available": true
          },
          {
            "id": "17de7f5a-0d2f-4550-a261-afed17ca0cf0",
            "name": "L",
            "extra_price": 1000,
            "available": true
          }
        ],
        "variants": [
          {
            "code": "PL-064d02c3d65c40f1a97d1f20e450d73c",
            "color_id": "1e48f712-8351-4682-b38f-983ce5bf5ba7",
            "size_id": "fb189095-a238-48e4-b82e-5b255eca88ae",
            "available": true
          },
          {
            "code": "PL-10ef6ee5a7164ed9ac9b3e8fe1f47753",
            "color_id": "1e48f712-8351-4682-b38f-983ce5bf5ba7",
            "size_id": "17de7f5a-0d2f-4550-a261-afed17ca0cf0",
            "available": true
          },
          {
            "code": "PL-8f4a4da67c7c4000866499fbd6ac33f8",
            "color_id": "b6ca129a-59c8-4527-8cfe-4f78c4b8ead5",
            "size_id": "fb189095-a238-48e4-b82e-5b255eca88ae",
            "available": true
          },
          {
            "code": "PL-1b39af989ba646078eff5d34757a3ce2",
            "color_id": "b6ca129a-59c8-4527-8cfe-4f78c4b8ead5",
            "size_id": "17de7f5a-0d2f-4550-a261-afed17ca0cf0",
            "available": false
          }
        ],
        "print_areas": [
          {
            "id": "83bbf205-41ec-4881-9d9f-bbe9a6d49d19",
            "key": "front",
            "name": "앞면",
            "width_mm": 300,
            "height_mm": 400,
            "extra_price": 0
          }
        ],
        "linked_product_nos": [
          1000000015
        ]
      }
    ],
    "page": 1,
    "per_page": 20,
    "total": 1
  }
}

오류: 400 VALIDATION_FAILED

GET /products/{product_id}

제품 하나

이 공급사의 게시중·일시중지 제품 하나. 다른 공급사 제품이나 게시 전 제품은 404예요.

  • product_id*
    string · 주소
    PODIZ 제품 id
요청 예시
curl "https://www.podiz.co.kr/api/partner/v1/products/c3b25e5b-f222-43fd-a615-b5c72a978af9" \
  -H "Authorization: Bearer $PODIZ_SECRET_KEY"
200 제품 Product
응답 본문
{
  "data": {
    "id": "c3b25e5b-f222-43fd-a615-b5c72a978af9",
    "name": "반팔 라운드 티셔츠",
    "status": "published",
    "product_mode": "mockup",
    "base_price": 8000,
    "thumbnail_url": "https://cdn.example.com/mockups/tshirt-front.webp",
    "updated_at": "2026-10-13T09:00:00Z",
    "colors": [
      {
        "id": "1e48f712-8351-4682-b38f-983ce5bf5ba7",
        "name": "화이트",
        "hex": "#FFFFFF",
        "available": true
      },
      {
        "id": "b6ca129a-59c8-4527-8cfe-4f78c4b8ead5",
        "name": "블랙",
        "hex": "#111111",
        "available": true
      }
    ],
    "sizes": [
      {
        "id": "fb189095-a238-48e4-b82e-5b255eca88ae",
        "name": "M",
        "extra_price": 0,
        "available": true
      },
      {
        "id": "17de7f5a-0d2f-4550-a261-afed17ca0cf0",
        "name": "L",
        "extra_price": 1000,
        "available": true
      }
    ],
    "variants": [
      {
        "code": "PL-064d02c3d65c40f1a97d1f20e450d73c",
        "color_id": "1e48f712-8351-4682-b38f-983ce5bf5ba7",
        "size_id": "fb189095-a238-48e4-b82e-5b255eca88ae",
        "available": true
      },
      {
        "code": "PL-10ef6ee5a7164ed9ac9b3e8fe1f47753",
        "color_id": "1e48f712-8351-4682-b38f-983ce5bf5ba7",
        "size_id": "17de7f5a-0d2f-4550-a261-afed17ca0cf0",
        "available": true
      },
      {
        "code": "PL-8f4a4da67c7c4000866499fbd6ac33f8",
        "color_id": "b6ca129a-59c8-4527-8cfe-4f78c4b8ead5",
        "size_id": "fb189095-a238-48e4-b82e-5b255eca88ae",
        "available": true
      },
      {
        "code": "PL-1b39af989ba646078eff5d34757a3ce2",
        "color_id": "b6ca129a-59c8-4527-8cfe-4f78c4b8ead5",
        "size_id": "17de7f5a-0d2f-4550-a261-afed17ca0cf0",
        "available": false
      }
    ],
    "print_areas": [
      {
        "id": "83bbf205-41ec-4881-9d9f-bbe9a6d49d19",
        "key": "front",
        "name": "앞면",
        "width_mm": 300,
        "height_mm": 400,
        "extra_price": 0
      }
    ],
    "linked_product_nos": [
      1000000015
    ]
  }
}

오류: 400 VALIDATION_FAILED · 404 NOT_FOUND

상품 연결

디자인

GET /designs/{design_no}

디자인 조회

고객이 편집기에서 받은 디자인 번호로 미리보기·제품·색상·디자인한 인쇄 위치·보관 기한·인쇄 파일 요청 시각을 돌려줘요. 견적은 이것으로 내요. 주문됐거나 인쇄 파일을 요청한 디자인은 만료가 없어 expires_at이 null이에요. 다른 연결의 번호는 404예요.

  • design_no*
    string · 주소
    디자인 번호 (대소문자·하이픈 무시)
요청 예시
curl "https://www.podiz.co.kr/api/partner/v1/designs/PL-7K2M9Q4XHAA" \
  -H "Authorization: Bearer $PODIZ_SECRET_KEY"
200 디자인 Design
응답 본문
{
  "data": {
    "design_no": "PL-7K2M9Q4XHAA",
    "status": "finalized",
    "external_product_no": 1000000015,
    "product": {
      "id": "c3b25e5b-f222-43fd-a615-b5c72a978af9",
      "name": "반팔 라운드 티셔츠"
    },
    "color": {
      "id": "1e48f712-8351-4682-b38f-983ce5bf5ba7",
      "name": "화이트",
      "hex": "#FFFFFF"
    },
    "areas": [
      {
        "key": "front",
        "name": "앞면",
        "width_mm": 300,
        "height_mm": 400
      }
    ],
    "preview_url": "https://www.pod-labs.co.kr/api/embed/partner/design-preview?k=podiz_pk_8efafd80c2d043b083fefb7a902fc799&code=PL-7K2M9Q4XHAA",
    "finalized_at": "2026-10-14T02:05:00Z",
    "expires_at": "2027-01-12T02:05:00Z",
    "ordered_at": null,
    "print_requested_at": null,
    "orders": [],
    "source_design_no": null
  }
}

오류: 400 VALIDATION_FAILED · 404 NOT_FOUND

POST /designs/{design_no}/extend

디자인 보관 연장

견적이 길어질 때 보관 기한을 오늘부터 보관 일수만큼 늘려요(확정 + 365일까지, 줄지 않아요). 본문은 비우거나 {}. 주문됐거나 인쇄 파일을 요청한 디자인은 만료가 없어 expires_at이 null이고, 이미 만료됐으면 410이에요.

  • design_no*
    string · 주소
    디자인 번호 (대소문자·하이픈 무시)
요청 예시
curl -X POST "https://www.podiz.co.kr/api/partner/v1/designs/PL-7K2M9Q4XHAA/extend" \
  -H "Authorization: Bearer $PODIZ_SECRET_KEY"
200 새 보관 기한 DesignExtension
응답 본문
{
  "data": {
    "design_no": "PL-7K2M9Q4XHAA",
    "status": "finalized",
    "expires_at": "2027-01-14T03:00:00Z"
  }
}

오류: 400 VALIDATION_FAILED · 404 NOT_FOUND · 410 DESIGN_EXPIRED · 415 UNSUPPORTED_MEDIA_TYPE

POST /designs/{design_no}/print-files

인쇄 파일 요청

주문을 보내지 않는(견적용) 연동에서 이 디자인의 인쇄 파일을 요청해요. 공급사가 PODIZ 콘솔 [인쇄 파일 요청]에서 만들면(화면을 열어 두면 자동으로) GET으로 내려받아요. 같은 요청을 다시 보내도 같고(처음 요청 시각 그대로), 요청한 디자인은 만료되지 않아요. 주문된 디자인도 되고, 주문함에서 이미 만들었으면 바로 ready예요. 본문은 비우거나 {}. 만료된 디자인은 410이에요.

  • design_no*
    string · 주소
    디자인 번호 (대소문자·하이픈 무시)
요청 예시
curl -X POST "https://www.podiz.co.kr/api/partner/v1/designs/PL-7K2M9Q4XHAA/print-files" \
  -H "Authorization: Bearer $PODIZ_SECRET_KEY"
200 인쇄 파일 상태 (보통 pending) PrintFiles
응답 본문
{
  "data": {
    "design_no": "PL-7K2M9Q4XHAA",
    "status": "pending",
    "requested_at": "2026-10-14T05:00:00Z",
    "areas": [
      {
        "key": "front",
        "name": "앞면",
        "width_mm": 300,
        "height_mm": 400,
        "bleed_mm": 2,
        "dpi": 300,
        "files": [],
        "missing": [
          "print"
        ]
      }
    ],
    "urls_expire_at": null
  }
}

오류: 400 VALIDATION_FAILED · 404 NOT_FOUND · 410 DESIGN_EXPIRED · 415 UNSUPPORTED_MEDIA_TYPE

GET /designs/{design_no}/print-files

인쇄 파일 상태·내려받기

디자인한 인쇄 위치마다 만든 파일과 아직 없는 파일을 돌려줘요. ready면 모두 있어요. 파일 주소는 서명 주소라 키 없이 받고, 1시간 뒤 끝나요(urls_expire_at — 지나면 다시 GET). 규격은 PNG(RGBA·dpi 기록·블리드 포함)이고, 칼선형은 칼선 SVG와 (투명 재질이면) 화이트 레이어 PNG도 있어요. 만료된 디자인은 410이에요.

  • design_no*
    string · 주소
    디자인 번호 (대소문자·하이픈 무시)
요청 예시
curl "https://www.podiz.co.kr/api/partner/v1/designs/PL-7K2M9Q4XHAA/print-files" \
  -H "Authorization: Bearer $PODIZ_SECRET_KEY"
200 인쇄 파일 상태 PrintFiles
응답 본문
{
  "data": {
    "design_no": "PL-7K2M9Q4XHAA",
    "status": "ready",
    "requested_at": "2026-10-14T05:00:00Z",
    "areas": [
      {
        "key": "front",
        "name": "앞면",
        "width_mm": 300,
        "height_mm": 400,
        "bleed_mm": 2,
        "dpi": 300,
        "files": [
          {
            "kind": "print",
            "file_name": "PL-7K2M9Q4XHAA_front_300x400mm_300dpi.png",
            "url": "https://files.example.supabase.co/storage/v1/object/sign/channel-print-files/…?token=…&download=PL-7K2M9Q4XHAA_front_300x400mm_300dpi.png",
            "width_px": 3591,
            "height_px": 4772
          }
        ],
        "missing": []
      }
    ],
    "urls_expire_at": "2026-10-14T06:10:00Z"
  }
}

오류: 400 VALIDATION_FAILED · 404 NOT_FOUND · 410 DESIGN_EXPIRED

GET /designs/{design_no}/assets

고객 원본 이미지

고객이 편집기에 올린 원본 이미지를 내려받기 주소(서명 1시간)·크기·쓴 인쇄 위치와 함께 돌려줘요. 바로 받을 수 있어요(공급사가 만들 필요 없음). 글자·클립아트는 원본 파일이 아니라 디자인 데이터라 없어요. 만료된 디자인은 원본이 지워져 410이에요.

  • design_no*
    string · 주소
    디자인 번호 (대소문자·하이픈 무시)
요청 예시
curl "https://www.podiz.co.kr/api/partner/v1/designs/PL-7K2M9Q4XHAA/assets" \
  -H "Authorization: Bearer $PODIZ_SECRET_KEY"
200 원본 이미지 DesignAssets
응답 본문
{
  "data": {
    "design_no": "PL-7K2M9Q4XHAA",
    "assets": [
      {
        "id": "2c8e4f0a-7b1d-4c3e-9f5a-6d2b8e1c4a70",
        "file_name": "PL-7K2M9Q4XHAA_원본_1.png",
        "mime": "image/png",
        "width_px": 2400,
        "height_px": 2400,
        "bytes": 1834221,
        "areas": [
          "front"
        ],
        "url": "https://files.example.supabase.co/storage/v1/object/sign/customer-assets/…?token=…&download=PL-7K2M9Q4XHAA_%EC%9B%90%EB%B3%B8_1.png"
      }
    ],
    "urls_expire_at": "2026-10-14T06:10:00Z"
  }
}

오류: 400 VALIDATION_FAILED · 404 NOT_FOUND · 410 DESIGN_EXPIRED

주문

POST /orders

주문 보내기

결제된 주문을 PODIZ 주문함으로 보내요. 줄마다 디자인 번호·사이즈(품목 코드)·수량 — 한 디자인을 여러 사이즈로 나눠 보내면 돼요. 주문 번호가 열쇠예요: 같은 줄로 다시 보내면 200(replayed), 다른 줄이면 409 ORDER_EXISTS. 보낸 주문은 바꾸지 않아요(취소만). 수령인·주문자 정보는 받지 않아요 — 배송지는 파트너 앱에서 확인해요.

본문 OrderInput

  • order_id*
    string
    파트너 주문 번호 — 같은 번호는 한 주문(멱등 열쇠)
  • ordered_at
    string (ISO 8601)
    주문 시각 (빼면 받은 시각)
  • paid_at
    string (ISO 8601)
    결제 시각 (빼면 받은 시각)
  • items*
    OrderItemInput[]
  • items[].item_id*
    string
    주문 안에서 겹치지 않는 품목 번호
  • items[].design_no*
    string
    디자인 번호 — 받을 때는 대소문자·하이픈을 무시하고, 돌려줄 때는 이 모양
  • items[].variant_code
    string
    사이즈를 정하는 품목 코드 — 디자인과 같은 제품·색상. 빼면 그 색상의 사이즈가 하나뿐일 때만
  • items[].quantity*
    integer
요청 예시
curl -X POST "https://www.podiz.co.kr/api/partner/v1/orders" \
  -H "Authorization: Bearer $PODIZ_SECRET_KEY" \
  -H "Content-Type: application/json" \
  -d '{"order_id":"Q20261014-0001","paid_at":"2026-10-14T12:00:00+09:00","items":[{"item_id":"1","design_no":"PL-7K2M9Q4XHAA","variant_code":"PL-064d02c3d65c40f1a97d1f20e450d73c","quantity":20},{"item_id":"2","design_no":"PL-7K2M9Q4XHAA","variant_code":"PL-10ef6ee5a7164ed9ac9b3e8fe1f47753","quantity":10}]}'
201 주문함에 들어갔어요 OrderResult
응답 본문
{
  "data": {
    "order": {
      "order_id": "Q20261014-0001",
      "status": "received",
      "hold_reason": null,
      "ordered_at": "2026-10-14T03:00:00Z",
      "paid_at": "2026-10-14T03:00:00Z",
      "shipped_at": null,
      "cancelled_at": null,
      "shipment": null,
      "items": [
        {
          "item_id": "1",
          "design_no": "PL-7K2M9Q4XHAA",
          "variant_code": "PL-064d02c3d65c40f1a97d1f20e450d73c",
          "color": "화이트",
          "size": "M",
          "quantity": 20,
          "status": "active"
        },
        {
          "item_id": "2",
          "design_no": "PL-7K2M9Q4XHAA",
          "variant_code": "PL-10ef6ee5a7164ed9ac9b3e8fe1f47753",
          "color": "화이트",
          "size": "L",
          "quantity": 10,
          "status": "active"
        }
      ],
      "updated_at": "2026-10-14T03:00:00Z"
    },
    "replayed": false
  }
}
200 같은 주문을 다시 보냈어요 (그대로) OrderResult
응답 본문
{
  "data": {
    "order": {
      "order_id": "Q20261014-0001",
      "status": "received",
      "hold_reason": null,
      "ordered_at": "2026-10-14T03:00:00Z",
      "paid_at": "2026-10-14T03:00:00Z",
      "shipped_at": null,
      "cancelled_at": null,
      "shipment": null,
      "items": [
        {
          "item_id": "1",
          "design_no": "PL-7K2M9Q4XHAA",
          "variant_code": "PL-064d02c3d65c40f1a97d1f20e450d73c",
          "color": "화이트",
          "size": "M",
          "quantity": 20,
          "status": "active"
        },
        {
          "item_id": "2",
          "design_no": "PL-7K2M9Q4XHAA",
          "variant_code": "PL-10ef6ee5a7164ed9ac9b3e8fe1f47753",
          "color": "화이트",
          "size": "L",
          "quantity": 10,
          "status": "active"
        }
      ],
      "updated_at": "2026-10-14T03:00:00Z"
    },
    "replayed": true
  }
}

오류: 400 VALIDATION_FAILED · 409 ORDER_EXISTS · 422 ORDER_ITEMS_INVALID · 415 UNSUPPORTED_MEDIA_TYPE

GET /orders

바뀐 주문 목록

주문을 수정 순(오래된 것부터)으로 돌려줘요. 받은 next_cursor를 저장해 두고 다음에 그 커서로 부르면 그 뒤에 바뀐 주문(제작 시작·보류·발송·취소)만 와요 — 상태·송장을 주기적으로 맞출 때 쓰세요. has_more면 곧바로 다음 쪽을 불러요.

  • cursor
    string · 질의
    앞 응답의 next_cursor (처음엔 빼요)
  • limit
    integer · 질의
    쪽마다 (1 ~ 100, 기본 50)
요청 예시
curl "https://www.podiz.co.kr/api/partner/v1/orders?limit=50" \
  -H "Authorization: Bearer $PODIZ_SECRET_KEY"
200 주문 쪽 OrderPage
응답 본문
{
  "data": {
    "orders": [
      {
        "order_id": "Q20261014-0001",
        "status": "shipped",
        "hold_reason": null,
        "ordered_at": "2026-10-14T03:00:00Z",
        "paid_at": "2026-10-14T03:00:00Z",
        "shipped_at": "2026-10-16T08:30:00Z",
        "cancelled_at": null,
        "shipment": {
          "carrier": {
            "code": "0006",
            "name": "CJ대한통운"
          },
          "tracking_no": "640012345678"
        },
        "items": [
          {
            "item_id": "1",
            "design_no": "PL-7K2M9Q4XHAA",
            "variant_code": "PL-064d02c3d65c40f1a97d1f20e450d73c",
            "color": "화이트",
            "size": "M",
            "quantity": 20,
            "status": "shipped"
          },
          {
            "item_id": "2",
            "design_no": "PL-7K2M9Q4XHAA",
            "variant_code": "PL-10ef6ee5a7164ed9ac9b3e8fe1f47753",
            "color": "화이트",
            "size": "L",
            "quantity": 10,
            "status": "shipped"
          }
        ],
        "updated_at": "2026-10-16T08:30:00Z"
      }
    ],
    "next_cursor": "WyIyMDI2LTEwLTE2VDA4OjMwOjAwLjAwMFoiLCIyZjFjOGEzZS02YjBkLTRmNWUtOWE3Yy0zZDJiMWUwZjlhODQiXQ",
    "has_more": false
  }
}

오류: 400 VALIDATION_FAILED

GET /orders/{order_id}

주문 조회

주문 하나의 제작 상태·보류 사유·송장. 공급사가 발송 처리하면 shipment에 택배사·송장번호가 들어와요.

  • order_id*
    string · 주소
    파트너 주문 번호
요청 예시
curl "https://www.podiz.co.kr/api/partner/v1/orders/Q20261014-0001" \
  -H "Authorization: Bearer $PODIZ_SECRET_KEY"
200 주문 Order
응답 본문
{
  "data": {
    "order_id": "Q20261014-0001",
    "status": "shipped",
    "hold_reason": null,
    "ordered_at": "2026-10-14T03:00:00Z",
    "paid_at": "2026-10-14T03:00:00Z",
    "shipped_at": "2026-10-16T08:30:00Z",
    "cancelled_at": null,
    "shipment": {
      "carrier": {
        "code": "0006",
        "name": "CJ대한통운"
      },
      "tracking_no": "640012345678"
    },
    "items": [
      {
        "item_id": "1",
        "design_no": "PL-7K2M9Q4XHAA",
        "variant_code": "PL-064d02c3d65c40f1a97d1f20e450d73c",
        "color": "화이트",
        "size": "M",
        "quantity": 20,
        "status": "shipped"
      },
      {
        "item_id": "2",
        "design_no": "PL-7K2M9Q4XHAA",
        "variant_code": "PL-10ef6ee5a7164ed9ac9b3e8fe1f47753",
        "color": "화이트",
        "size": "L",
        "quantity": 10,
        "status": "shipped"
      }
    ],
    "updated_at": "2026-10-16T08:30:00Z"
  }
}

오류: 400 VALIDATION_FAILED · 404 NOT_FOUND

POST /orders/{order_id}/cancel

주문 취소

제작을 시작하기 전(접수) 주문만 취소해요 — 다시 불러도 같아요. 제작 중·보류면 409 ORDER_IN_PRODUCTION, 발송 뒤면 409 ORDER_STATUS_LOCKED예요(공급사와 직접 이야기하세요).

  • order_id*
    string · 주소
    파트너 주문 번호

본문 CancelInput (선택)

  • reason
    string | null
    취소 사유 (기록에만)
요청 예시
curl -X POST "https://www.podiz.co.kr/api/partner/v1/orders/Q20261014-0001/cancel" \
  -H "Authorization: Bearer $PODIZ_SECRET_KEY" \
  -H "Content-Type: application/json" \
  -d '{"reason":"고객 변심"}'
200 취소한 주문 Order
응답 본문
{
  "data": {
    "order_id": "Q20261014-0001",
    "status": "cancelled",
    "hold_reason": null,
    "ordered_at": "2026-10-14T03:00:00Z",
    "paid_at": "2026-10-14T03:00:00Z",
    "shipped_at": null,
    "cancelled_at": "2026-10-14T04:00:00Z",
    "shipment": null,
    "items": [
      {
        "item_id": "1",
        "design_no": "PL-7K2M9Q4XHAA",
        "variant_code": "PL-064d02c3d65c40f1a97d1f20e450d73c",
        "color": "화이트",
        "size": "M",
        "quantity": 20,
        "status": "cancelled"
      },
      {
        "item_id": "2",
        "design_no": "PL-7K2M9Q4XHAA",
        "variant_code": "PL-10ef6ee5a7164ed9ac9b3e8fe1f47753",
        "color": "화이트",
        "size": "L",
        "quantity": 10,
        "status": "cancelled"
      }
    ],
    "updated_at": "2026-10-14T04:00:00Z"
  }
}

오류: 400 VALIDATION_FAILED · 404 NOT_FOUND · 409 ORDER_IN_PRODUCTION · 409 ORDER_STATUS_LOCKED · 415 UNSUPPORTED_MEDIA_TYPE

객체 모양

*는 늘 있는 칸(값이 null일 수는 있어요). 문서에 없는 칸이 더 오면 무시하세요.

Product

게시한 제품. 색상·사이즈는 켜 둔 것만(정렬 순), 인쇄 위치는 게시로 잠긴 것만. available은 판매 중인 변형이 있는지

  • id*
    string (uuid)
  • name*
    string
  • status*
    "published" | "paused"
    목록은 게시중만, 하나 조회는 일시중지도
  • product_mode*
    "mockup" | "die_cut"
    mockup 사진 목업 · die_cut 칼선형(아크릴 굿즈 등)
  • base_price*
    integer
    공급사 기본가 (원 — 참고)
  • thumbnail_url*
    string | null
    대표 사진 (칼선형은 null)
  • updated_at*
    string (ISO 8601)
  • colors*
    object[]
  • colors[].id*
    string (uuid)
  • colors[].name*
    string
  • colors[].hex*
    string
  • colors[].available*
    boolean
  • sizes*
    object[]
  • sizes[].id*
    string (uuid)
  • sizes[].name*
    string
  • sizes[].extra_price*
    integer
    사이즈 추가금 (원 — 참고)
  • sizes[].available*
    boolean
  • variants*
    object[]
    품목 = 색상 × 사이즈. 주문 줄의 variant_code
  • variants[].code*
    string
    품목 코드 (색상 × 사이즈 — GET /products의 variants.code)
  • variants[].color_id*
    string (uuid)
  • variants[].size_id*
    string (uuid)
  • variants[].available*
    boolean
    켜짐·품절 아님
  • print_areas*
    object[]
  • print_areas[].id*
    string (uuid)
  • print_areas[].key*
    string
  • print_areas[].name*
    string
  • print_areas[].width_mm*
    number
  • print_areas[].height_mm*
    number
  • print_areas[].extra_price*
    integer
    인쇄 위치 추가금 (원 — 참고)
  • linked_product_nos*
    integer[]
    이 연결에서 이 제품에 연결한 파트너 상품 번호

Design

고객이 편집기에서 확정한 디자인 (견적 디자인은 색상까지 — 사이즈는 주문 줄이 정한다)

  • design_no*
    string
    디자인 번호 — 받을 때는 대소문자·하이픈을 무시하고, 돌려줄 때는 이 모양
  • status*
    "finalized" | "ordered" | "expired"
    finalized 확정 · ordered 주문됨(만료 없음) · expired 보관 기한 지남
  • external_product_no*
    integer
    파트너 상품 번호 (1 ~ 9007199254740991)
  • product*
    object
  • product.id*
    string (uuid)
  • product.name*
    string
  • color*
    object | null
  • color.id*
    string (uuid)
  • color.name*
    string
  • color.hex*
    string
  • areas*
    object[]
    디자인한 인쇄 위치만
  • areas[].key*
    string
  • areas[].name*
    string
  • areas[].width_mm*
    number
  • areas[].height_mm*
    number
  • preview_url*
    string | null
    미리보기 그림 주소 (키 없이 <img>로 — 만료되면 null)
  • finalized_at*
    string (ISO 8601)
  • expires_at*
    string (ISO 8601) | null
    보관 기한 — 주문됐거나 인쇄 파일을 요청한 디자인은 null (만료 없음)
  • ordered_at*
    string (ISO 8601) | null
  • print_requested_at*
    string (ISO 8601) | null
    주문 없이 인쇄 파일을 처음 요청한 시각 (POST /designs/{design_no}/print-files)
  • orders*
    string[]
    이 디자인을 쓴 이 연결의 주문 번호
  • source_design_no*
    string | null
    편집기 SDK 수정하기(openEditor({ designNo }))로 고쳐 만든 디자인이면 연 원본 번호 — 원본은 그대로 남는다

PrintFiles

디자인의 인쇄 파일 (주문 없이 요청·내려받기 — 공급사가 PODIZ 콘솔에서 만든다)

  • design_no*
    string
    디자인 번호 — 받을 때는 대소문자·하이픈을 무시하고, 돌려줄 때는 이 모양
  • status*
    "not_requested" | "pending" | "ready"
    not_requested 요청 전 · pending 요청됨(또는 주문됨) — 공급사가 만드는 중 · ready 디자인한 위치의 파일이 모두 있음
  • requested_at*
    string (ISO 8601) | null
    처음 요청한 시각
  • areas*
    PrintFileArea[]
    디자인한 인쇄 위치 (위치 순서)
  • urls_expire_at*
    string (ISO 8601) | null
    파일 주소가 끝나는 시각 (1시간 — 지나면 다시 GET). 파일이 없으면 null

PrintFileArea

  • key*
    string
  • name*
    string
  • width_mm*
    number
  • height_mm*
    number
  • bleed_mm*
    number
    재단 여유 — 인쇄 파일은 사방으로 이만큼 크다
  • dpi*
    integer
  • files*
    PrintFile[]
    만든 파일
  • missing*
    "print" | "cut" | "white"[]
    아직 없는 파일 — 공급사가 만들면 빈다

PrintFile

  • kind*
    "print" | "cut" | "white"
    print 인쇄 파일 PNG · cut 칼선 SVG (칼선형) · white 화이트 레이어 PNG (칼선형 투명 재질)
  • file_name*
    string
    내려받기 이름 — {디자인 번호}_{위치 키}_{W}x{H}mm_{dpi}dpi.png · …_칼선.svg · …_화이트.png
  • url*
    string
    내려받기 주소 (서명 주소 — 키 없이 GET, urls_expire_at까지)
  • width_px
    integer
    픽셀 크기 (인쇄 파일만 — 블리드 포함)
  • height_px
    integer
    픽셀 크기 (인쇄 파일만 — 블리드 포함)

DesignAssets

고객이 편집기에 올린 원본 이미지 (글자·클립아트는 원본 파일이 아니라 디자인 데이터라 없다)

  • design_no*
    string
    디자인 번호 — 받을 때는 대소문자·하이픈을 무시하고, 돌려줄 때는 이 모양
  • assets*
    DesignAsset[]
    올린 순서
  • urls_expire_at*
    string (ISO 8601) | null
    파일 주소가 끝나는 시각 (1시간 — 지나면 다시 GET). 이미지가 없으면 null

DesignAsset

  • id*
    string (uuid)
  • file_name*
    string
    내려받기 이름 — {디자인 번호}_원본_{순번}.{jpg|png|webp}
  • mime*
    "image/jpeg" | "image/png" | "image/webp"
  • width_px*
    integer
  • height_px*
    integer
  • bytes*
    integer
  • areas*
    string[]
    이 이미지를 쓴 인쇄 위치 키
  • url*
    string
    내려받기 주소 (서명 주소 — 키 없이 GET, urls_expire_at까지)

Order

  • order_id*
    string
  • status*
    "received" | "in_production" | "on_hold" | "shipped" | "cancelled"
    접수 · 제작 중 · 보류 · 발송 · 취소
  • hold_reason*
    string | null
    공급사가 적은 보류 사유
  • ordered_at*
    string (ISO 8601)
  • paid_at*
    string (ISO 8601) | null
  • shipped_at*
    string (ISO 8601) | null
  • cancelled_at*
    string (ISO 8601) | null
  • shipment*
    object | null
    발송 뒤 택배사·송장번호
  • shipment.carrier*
    object
  • shipment.carrier.code*
    string
  • shipment.carrier.name*
    string
  • shipment.tracking_no*
    string
  • items*
    OrderItem[]
  • updated_at*
    string (ISO 8601)

OrderItem

  • item_id*
    string
  • design_no*
    string
    디자인 번호 — 받을 때는 대소문자·하이픈을 무시하고, 돌려줄 때는 이 모양
  • variant_code*
    string
    품목 코드 (색상 × 사이즈 — GET /products의 variants.code)
  • color*
    string | null
  • size*
    string | null
  • quantity*
    integer
  • status*
    "active" | "shipped" | "cancelled"

Me

이 키의 연결·공급사와 살아 있는 키

  • connection*
    object
  • connection.id*
    string (uuid)
  • connection.name*
    string
    공급사가 정한 연결 이름
  • connection.status*
    "active" | "disconnected"
  • connection.publishable_key*
    string
    공개 키 — 편집기 SDK에 넣는 값 (비밀이 아니다)
  • connection.domains*
    string[]
    편집기를 띄울 사이트 출처
  • connection.design_ttl_days*
    integer
    디자인 보관 일수 (기본 90)
  • connection.connected_at*
    string (ISO 8601) | null
  • supplier*
    object
  • supplier.name*
    string
  • key*
    object
    이 요청에 쓴 키
  • key.id*
    string (uuid)
  • key.name*
    string
  • keys*
    object[]
    살아 있는 키 (원문 없이 끝 4자만)
  • keys[].id*
    string (uuid)
  • keys[].name*
    string
  • keys[].hint*
    string
    끝 4자
  • keys[].created_at*
    string (ISO 8601)
  • keys[].last_used_at*
    string (ISO 8601) | null

Error

  • error*
    object
  • error.code*
    string
    오류 코드 (오류 표)
  • error.message*
    string
    한국어 문구 — 화면에 그대로 써도 된다
  • error.fields
    object
    VALIDATION_FAILED — 칸 이름 → 문구 (예 items[0].quantity)
  • error.details
    object[]
    ORDER_ITEMS_INVALID — 틀린 줄
  • error.details[].index*
    integer
  • error.details[].item_id*
    string
  • error.details[].code*
    "DESIGN_NOT_FOUND" | "DESIGN_EXPIRED" | "VARIANT_REQUIRED" | "VARIANT_MISMATCH"
  • error.request_id*
    string (uuid)
    응답 헤더 x-request-id와 같다 — 문의할 때

오류 코드

오류는 HTTP 상태와 code로 알려요. 401에는 www-authenticate: Bearer, 429에는 retry-after(초)가 함께 와요. 코드는 v1 안에서 더하기만 해요 — 모르는 코드는 상태로 처리하세요.

HTTPcode언제
400VALIDATION_FAILED본문·주소·질의 값이 틀렸어요 — fields에 칸마다 문구
401UNAUTHENTICATED키가 없거나 모르는 키·폐기한 키 (연결을 해제하면 키를 모두 폐기해요)
403FORBIDDEN공급사 이용이 정지됐어요
404NOT_FOUND이 연결의 제품·연결·디자인·주문이 아니에요 (없는 경로도)
409PRODUCT_UNAVAILABLE게시하지 않은 제품을 연결하려 했어요
409LINK_IN_USE기다리는 디자인(확정·만료 전)이 있는 번호를 다른 제품으로 바꾸려 했어요
409ORDER_EXISTS같은 주문 번호에 다른 줄을 보냈어요 (같은 줄이면 200 재전송)
409ORDER_IN_PRODUCTION제작을 시작했거나 보류 중인 주문을 취소하려 했어요
409ORDER_STATUS_LOCKED발송한 주문을 취소하려 했어요
410DESIGN_EXPIRED보관 기한이 지난 디자인을 연장하려 했어요
415UNSUPPORTED_MEDIA_TYPE본문이 JSON이 아니에요
422ORDER_ITEMS_INVALID주문 줄이 틀렸어요 — details에 [{index, item_id, code}]
429RATE_LIMITED요청 한도를 넘었어요 — retry-after(초) 뒤 다시
500INTERNAL_ERROR일시적인 오류 — 계속되면 request_id와 함께 문의
400 — 칸마다 문구 (fields)
{
  "error": {
    "code": "VALIDATION_FAILED",
    "message": "요청 값이 올바르지 않아요.",
    "fields": {
      "items[0].quantity": "수량은 1 ~ 100,000 정수예요."
    },
    "request_id": "5b0f3c7e-2d41-4a8e-9a43-1f6c2b7d9e10"
  }
}
422 — 틀린 주문 줄 (details)
{
  "error": {
    "code": "ORDER_ITEMS_INVALID",
    "message": "주문 줄 중 맞지 않는 것이 있어요. 줄마다 이유를 확인해 주세요.",
    "details": [
      {
        "index": 1,
        "item_id": "2",
        "code": "VARIANT_MISMATCH"
      }
    ],
    "request_id": "5b0f3c7e-2d41-4a8e-9a43-1f6c2b7d9e10"
  }
}

주문 줄 오류 (details의 code)

  • DESIGN_NOT_FOUND — 이 연결의 디자인 번호가 아니에요
  • DESIGN_EXPIRED — 보관 기한이 지난 디자인이에요 (주문된 디자인은 다시 주문할 수 있어요)
  • VARIANT_REQUIRED — 사이즈가 여럿인데 variant_code를 빼먹었어요
  • VARIANT_MISMATCH — 품목 코드가 디자인의 제품·색상과 달라요

편집기 SDK

고객이 보는 견적 화면에 스크립트 한 줄을 넣으면, [디자인하기]를 누를 때 PODIZ 편집기가 화면 위에 열려요(견적 모드 — 사이즈·수량·장바구니 없이 [디자인 완료]). 고객이 완료하면 디자인 번호가 돌아오고 편집기는 1.2초 뒤 저절로 닫혀요. 휴대폰은 전체 화면이에요. 받은 번호로 편집기를 다시 열어 고칠 수도 있어요(수정하기).

넣는 법 — 선언형

integrity(SRI)는 파일이 바뀌지 않았음을 브라우저가 확인하는 값이에요 — 그대로 쓰세요. 공급사 콘솔 [연결 정보 › 편집기 스크립트]에는 그 연결의 공개 키까지 채운 코드가 있어요.

HTML
<script src="https://www.podiz.co.kr/embed/partner/sdk.v2.js"
        integrity="sha384-n7rzXIy7KqUK3tyd7WdrhfAQXWT0TtllTwR3XcO7hWV0HTt1P2oT7F/kC37Aselx" crossorigin="anonymous"
        data-podiz-key="podiz_pk_8efafd80c2d043b083fefb7a902fc799" defer></script>

<!-- 디자인 버튼: 누르면 편집기, 끝나면 디자인 번호가 칸에 들어간다 -->
<button type="button" data-podiz-product="1000000015"
        data-podiz-input="#design_no" data-podiz-preview="#design_img">디자인하기</button>
<!-- 수정하기: 칸의 번호로 다시 연다 — 고치면 새 번호가 같은 칸에 -->
<button type="button" data-podiz-design="#design_no"
        data-podiz-input="#design_no" data-podiz-preview="#design_img">수정하기</button>
<input type="hidden" name="design_no" id="design_no">
<img id="design_img" alt="" hidden>
속성어디에설명
data-podiz-key<script>공개 키 — 있으면 SDK가 저절로 init하고 버튼을 묶어요
data-podiz-product버튼파트너 상품 번호 (연결한 번호)
data-podiz-design버튼수정하기 — 다시 열 디자인 번호, 또는 번호가 든 칸의 선택자(#…). 고치면 새 번호가 data-podiz-input 칸에 (v2)
data-podiz-color버튼처음 고를 색상 id (선택 — GET /products의 colors.id)
data-podiz-input버튼디자인 번호를 넣을 칸의 선택자 — 넣은 뒤 input·change 이벤트
data-podiz-preview버튼미리보기를 띄울 <img>의 선택자 — 뜨면 hidden을 풀어요

코드로

JavaScript
const podiz = PODIZ.init({ key: 'podiz_pk_8efafd80c2d043b083fefb7a902fc799' });

const product = await podiz.getProduct(1000000015);
// { linked: true, productNo, name, colors: [{ id, name, hex }], originAllowed } | { linked: false }

try {
  const result = await podiz.openEditor({ productNo: 1000000015, colorId: product.colors?.[0]?.id });
  // result.designNo를 견적 요청에 넣는다
} catch (e) {
  if (e.code !== 'cancelled') alert(e.message); // PodizError — 아래 오류 코드
}

openEditor의 결과 (podiz:design-complete의 detail도 같아요):

결과
{
  "designNo": "PL-7K2M9Q4XHAA",
  "productNo": 1000000015,
  "color": {
    "id": "1e48f712-8351-4682-b38f-983ce5bf5ba7",
    "name": "화이트",
    "hex": "#FFFFFF"
  },
  "areas": [
    {
      "key": "front",
      "name": "앞면"
    }
  ],
  "previewUrl": "https://www.pod-labs.co.kr/api/embed/partner/design-preview?k=podiz_pk_8efafd80c2d043b083fefb7a902fc799&code=PL-7K2M9Q4XHAA",
  "expiresAt": "2027-01-12T02:05:00Z",
  "sourceDesignNo": null
}

수정하기

받은 디자인 번호로 편집기를 다시 열어요 — openEditor({ designNo }) 또는 버튼의 data-podiz-design. 파트너 서버를 거치지 않아요.

JavaScript
// 받아 둔 디자인 번호로 다시 연다 — 상품 번호는 디자인에서
const edited = await podiz.openEditor({ designNo: 'PL-7K2M9Q4XHAA' });
if (edited.designNo !== edited.sourceDesignNo) {
  // 고쳤다 — 견적의 번호를 새 번호로 바꾼다 (원래 디자인은 그대로 남는다)
}
  • 디자인한 색상·인쇄 위치·글·이미지·템플릿 칸까지 그대로 열려요. 다른 기기·다른 사람(예: 관리자)이 열어도 돼요 — 번호를 아는 사람만 열 수 있으니 번호는 견적 당사자에게만 보여 주세요.
  • 고쳐서 완료하면 새 디자인 번호가 와요. 원래 디자인은 고치지 않고 그대로 남아요(그 번호의 주문·인쇄 파일 요청도 그대로) — 견적의 번호만 바꾸면 돼요. 고치지 않고 완료하면 같은 번호예요(designNo === sourceDesignNo).
  • 새 디자인은 디자인 조회의 source_design_no로 원본을 가리켜요. 보관 기간이 지난 디자인은 열 수 없어요(design_expired) — 주문됐거나 인쇄 파일을 요청한 디자인은 만료되지 않아요.

이벤트

누른 버튼에서 document까지 올라가요(코드로 열면 그때 초점이 있던 요소에서).

이벤트detail언제
podiz:open{ productNo, designNo }편집기가 열렸어요 (designNo는 수정하기일 때 연 번호, 아니면 null)
podiz:design-complete결과 (openEditor와 같은 모양)고객이 [디자인 완료]를 눌렀어요 — 1.2초 뒤 저절로 닫혀요
podiz:close{ productNo, designNo }편집기가 닫혔어요 (고객이 닫은 것도 — 오류가 아니에요)
podiz:error{ code, message }열지 못했어요 (아래 오류 코드)
JavaScript
document.addEventListener('podiz:design-complete', (e) => {
  const { designNo, previewUrl } = e.detail;
  // 견적서 칸에 넣기 등
});

오류 (PodizError.code)

  • invalid_key — 공개 키 모양이 아니에요 — init이 바로 던져요
  • not_linked — 열 수 없는 상품 — 연결하지 않은 번호·해제·정지한 연결 (서버가 구별해 알리지 않아요)
  • origin_not_allowed — 이 페이지 출처가 연결의 사이트 주소에 없어요
  • busy — 편집기가 이미 열려 있어요 (한 페이지에 하나)
  • cancelled — 고객이 닫았거나 뒤로 가기·close()로 닫혔어요
  • timeout — 30초 안에 편집기가 준비되지 않았어요
  • network — PODIZ에 연결하지 못했어요
  • unsupported_browser — 이 브라우저에서는 열 수 없어요 — init이 바로 던져요
  • not_found — 수정하기 — 디자인 번호 모양이 틀리거나 이 연결에서 만든 디자인이 아니에요 (v2)
  • design_expired — 수정하기 — 보관 기간이 지나 다시 열 수 없는 디자인이에요 (v2)

알아 두기

  • 편집기는 연결에 등록한 사이트 주소에서만 열려요. 시험 서버·새 도메인도 공급사가 등록해야 해요.
  • 화면에 CSP가 있으면 https://www.podiz.co.kr을 script-src·frame-src·connect-src·img-src에 넣어 주세요.
  • 한 페이지에 편집기는 하나예요(열려 있으면 busy). 고객이 뒤로 가기를 누르면 닫혀요.
  • 디자인은 기본 90일 보관해요 — 견적이 길어지면 보관 연장을 불러요.
  • SDK 파일(sdk.v2.js)은 바뀌지 않아요 — 바꿀 일이 생기면 새 판 파일로 내고 이전 판은 그대로 둬요. 이미 넣은 sdk.v1.js도 계속 돌아요(수정하기만 v2부터).

바뀐 것

  1. 2026-10-15 v1.2

    • 편집기 SDK v2 (sdk.v2.js — SRI) — 수정하기: openEditor({ designNo })·data-podiz-design으로 받은 디자인 번호를 다시 연다. 고치면 새 번호(원본은 그대로), 고치지 않으면 같은 번호
    • SDK 결과에 sourceDesignNo, 오류 not_found·design_expired — v1(sdk.v1.js)은 그대로 계속 제공
    • 디자인에 source_design_no — 수정하기로 만든 디자인이면 연 원본 번호
  2. 2026-10-14 v1.1

    • 인쇄 파일 요청·상태·내려받기 (POST·GET /designs/{design_no}/print-files) — 주문 없이(견적용 연동), 공급사가 PODIZ 콘솔에서 만든다
    • 고객 원본 이미지 (GET /designs/{design_no}/assets) — 서명 주소 1시간
    • 디자인에 print_requested_at — 인쇄 파일을 요청한 디자인은 만료되지 않는다
  3. 2026-10-14 v1

    • 처음 공개 — 연결 확인·제품·상품 연결·디자인 조회·연장·주문 보내기·변경 목록·조회·취소
    • 편집기 SDK v1 (sdk.v1.js — SRI) — 견적 모드 편집기, 선언형 버튼·이벤트