주문 흐름
주문상품이 결제 뒤 거치는 상태·행동·자동 진행을 상품별로 정하는 방법
주문 흐름은 주문상품이 결제 뒤 어떤 상태를 거치고, 누가 어떤 행동으로 다음 상태로 보내는지를 정한 것입니다. 일반 배송 상품은 기본 흐름(결제 완료 → 상품 준비 → 배송 → 배송 완료 → 구매 확정)을 따르고, 주문 제작·음식 배달·티켓처럼 진행이 다른 상품은 상점이 흐름을 골라 붙입니다.
주문 흐름은 순차적으로 열립니다. 열리기 전에는 모든 주문이 기본 흐름으로 처리되고, 아래 API의 흐름 설치·게시는 그대로 할 수 있습니다.
준비
- 관리 API 스코프
flow:r(조회)·flow:rw(만들기·게시). 주문상품의 흐름 행동은order:rw입니다. - 공개 상태(
status)는 흐름과 관계없이 8개 그대로입니다. 흐름의 상태 이름은 화면 표시용이고, 분기는 공개 상태나actions로 합니다.
1. 기본 흐름(프리셋)
흐름은 프리셋을 설치해 시작합니다. 프리셋은 상태·행동·기한이 정해진 틀이고, 설치할 때 기한·횟수 같은 값을 바꿉니다.
| 프리셋 | 키 | 진행 |
|---|---|---|
| 일반 배송 | shipping-standard | 결제완료 → 배송준비중 → 배송중 → 배송완료 → 구매확정(기본 흐름) |
| 배송 없는 상품 | manual-standard | 결제완료 → 제공 처리 → 구매확정(기본 흐름) |
| 주문제작형 | custom-made | 주문 확인 → 시안 → 구매자 승인(수정 요청 횟수) → 희망 일시 전 제작 → 택배·직접 배달·방문 수령 → 구매 확정 |
| 음식 배달형 | food-delivery | 가게 접수(기한 안에 응답이 없으면 자동 거절) → 조리 → 배달·포장 → 완료. 한 주문의 메뉴를 묶어 진행 |
| 티켓형 | ticket | 결제와 함께 예매 확정(좌석 배정 API 선택) → 입장 또는 관람일 다음 날 종료 |
| 숙박 예약형 | stay | 즉시 확정 또는 호스트 확인(기한 안에 응답이 없으면 자동 거절) → 체크인 일시에 체크인 대기 → 체크인 또는 다음 날 노쇼 확인 → 체크아웃 일시에 이용 완료. 날짜별 재고 상품에 붙입니다 |
GET /v1/flow-presets
POST /v1/commerce-flows
{ "key": "cake", "name": "레터링 케이크", "presetKey": "custom-made" }새 상점에는 기본 흐름 두 개(일반 배송형·배송 없는 상품 기본형)만 있습니다. 상점을 만들 때 게시된 흐름으로 들어가고, 흐름을 지정하지 않은 상품이 이행 유형에 맞는 기본 흐름을 따릅니다. 기본 흐름은 고칠 수 없습니다(defaultFor, 초안 저장·게시는 409 FLOW_DEFAULT_LOCKED).
다른 흐름이 필요하면 상점 플랫폼의 설정 › 주문 흐름 › 흐름 만들기에서 프리셋 제안(직접 만들기 또는 프리셋)을 고릅니다. 고른 그래프가 편집기에 열리고, 상태·외부 API 노드를 끌어 배치하고 상태 이름·공개 상태, 넘어가는 조건(셀러·구매자 행동, 외부 사건, 시간 경과)을 고친 뒤 「생성」에서 이름과 키를 입력합니다. 생성하기 전에는 흐름이 저장되지 않습니다. API로는 GET /v1/flow-presets/{key}로 프리셋 그래프를 받아 고친 그래프를 POST /v1/commerce-flows의 graph로 보냅니다.
모든 흐름은 결제 완료 노드 하나인 빈 흐름에서 출발합니다. 프리셋은 빈 흐름을 미리 편집해 둔 그래프일 뿐이라 만들 때는 이름과 키만 정합니다. 기한·횟수·수수료 같은 값은 각 노드 설정 안에 있고 편집기에서 노드를 눌러 고칩니다. 흐름 데이터(예: 조리 완료 예정 시각)는 데이터 블록이 선언 없이 저장하고 셀러 화면에만 보입니다. 구매자에게는 노드의 안내문 틀({{ item.fields.readyAt | time }})로 보입니다.
설치하면 초안 1이 열립니다. 검사(POST /v1/commerce-flows/{flowId}/draft/check)로 오류를 보고 게시(POST …/draft/publish)합니다. 게시한 버전은 바뀌지 않고, 이미 들어온 주문은 결제 때 붙은 버전으로 끝까지 진행합니다. 초안을 고치면(PUT …/draft) 새 버전이 열립니다.
2. 상품에 붙이기
흐름은 상품이나 카테고리에 지정합니다. 결제할 때 상품에 지정한 흐름 → 상품 카테고리의 흐름 → 기본 흐름 순서로 정해지고, 주문이 끝날 때까지 바뀌지 않습니다.
PATCH /v1/products/{productId}
{ "flowId": "flw_…" }
PATCH /v1/categories/{categoryId}
{ "flowId": "flw_…" }- 카테고리 흐름은 맨 아래 카테고리에만 지정합니다(
400 CATEGORY_NOT_LEAF). 하위 카테고리가 생기면 지정이 풀립니다. flowId: null이면 지정을 지웁니다. 게시하지 않은 흐름은 지정할 수 없습니다(409 FLOW_NOT_PUBLISHED).- 기본 흐름은 이행 유형별 일반 배송형·배송 없는 상품 기본형이고, 상점이 고치거나 지울 수 없습니다.
GET /v1/products/{productId}/flow로 지금 붙을 흐름과 출처(PRODUCT·CATEGORY·PLATFORM)를 봅니다.
3. 진행하기
주문상품의 지금 상태와 할 수 있는 행동은 흐름 조회로 봅니다.
GET /v1/order-items/{orderItemId}/flow
POST /v1/order-items/{orderItemId}/actions/{key}
{ "input": { "cookMinutes": 20 } }flowState: 상태 이름·안내문·기한(deadlineAt)·이 상태로 오며 붙인 첨부(attachments)·앞 상태의 첨부(earlierAttachments)·앞 행동의 입력값(inputs).actions: 켜진 행동과 꺼진 이유(disabled.reason), 입력 폼(input).- 받을 수 없는 행동은
409 ACTION_NOT_AVAILABLE이고details.reason에 이유가 있습니다.Idempotency-Key로 재시도가 안전합니다. - 발주 확인·송장 등록·배송 완료·제공 처리 행동은 기존 API(
/confirm·/dispatch·/delivered·/fulfill)와 같은 처리입니다. - 여러 위치가 함께 진행 중이면(아래 하위 흐름·병렬 진행)
flowState는 가장 앞 단계의 위치이고branches에 위치마다 상태가 옵니다.actions는 모든 위치의 행동을 합친 것입니다.
주문 전체 행동
같은 행동을 주문의 주문상품마다 한 번에 실행합니다. 그 행동이 켜진 주문상품만 실행하고, 결과는 주문상품별입니다(COMPLETED·SKIPPED·FAILED). 한 주문상품이 실패해도 다른 주문상품은 되돌리지 않습니다. 켜진 주문상품이 하나도 없으면 409 ACTION_NOT_AVAILABLE입니다.
POST /v1/orders/{orderId}/actions/{key}
POST /storefront/v1/me/orders/{orderId}/actions/{key}
POST /storefront/v1/guest/orders/{orderId}/actions/{key}주문 응답의 progressStatus는 진행 중 주문상품(취소 제외) 가운데 가장 앞 단계입니다. 한 상품은 배송완료이고 다른 상품은 준비 중이면 준비 중입니다. 기존 representativeStatus(첫 주문상품의 상태)는 그대로입니다.
상태 직접 이동
조치가 필요한 주문이나 잘못 누른 행동은 흐름의 다른 상태로 직접 옮깁니다. 옮길 수 있는 상태는 흐름 조회의 moveTargets입니다.
POST /v1/order-items/{orderItemId}/flow/move
{ "to": "delivered", "reason": "택배사 연동 오류로 수동 처리" }- 연결선을 지나지 않으므로 그 사이의 실행(재고·환불·송장)은 하지 않고, 도착한 상태의 기한만 다시 겁니다.
- 취소 상태로는 옮기지 않습니다. 취소는 판매자 취소를 사용합니다.
- 진행 중인 병렬 갈래·하위 흐름이 있으면 옮기지 않습니다. 옮길 수 없으면
409 FLOW_MOVE_NOT_ALLOWED(details.reason)입니다.
실행 기록
GET /v1/order-items/{orderItemId}/flow/runs는 흐름이 지나간 기록(시작·행동·사건·시간 경과·상태 이동·버전 옮기기·취소·클레임)을 최근 것부터 50개 줍니다. 기록마다 지나간 연결선과 실행한 일(steps)이 있습니다. 하나는 GET /v1/flow-runs/{runId}로 봅니다.
구매자는 주문 상세(GET /storefront/v1/me/orders/{orderId})의 주문상품 flowState·actions를 보고 POST /storefront/v1/me/order-items/{orderItemId}/actions/{key}로 행동합니다. 비회원은 POST /storefront/v1/guest/orders/{orderId}/items/{orderItemId}/actions/{key}에 연락처·주문 조회 비밀번호를 함께 보냅니다.
구매자 화면: 지금 단계(step)
스토어프론트는 주문상품의 step 하나로 화면을 그릴 수 있습니다. 서버가 흐름을 읽어 정리한 값이라 흐름 구조를 몰라도 됩니다.
{
"type": "BUYER_ACTION",
"label": "시안 확인",
"message": "시안을 확인해 주십시오. 승인하면 제작을 시작합니다.",
"deadlineAt": "2026-10-06T09:30:00Z",
"attachments": ["https://cdn.avarlabs.com/…/proof.png"],
"actions": [
{ "key": "APPROVE", "label": "승인", "mode": "INSTANT", "enabled": true },
{ "key": "REQUEST_CHANGE", "label": "수정 요청", "mode": "INSTANT", "enabled": true,
"input": [{ "key": "note", "type": "textarea", "required": true, "label": "수정 내용" }] }
]
}type | 뜻 | 화면 |
|---|---|---|
BUYER_ACTION | 구매자 확인·입력 필요 | actions로 버튼·폼을 그립니다 |
SELLER_PROCESSING | 판매자 처리 중 | 안내문·기한 |
IN_DELIVERY | 배송 중 | data.delivery(택배사·송장·추적 링크) |
DELIVERED | 배송·제공 완료 | 구매확정·반품은 주문상품 actions |
COMPLETED | 구매확정 | |
CANCELED | 취소 | |
CLAIM_IN_PROGRESS | 취소·반품·교환 처리 중 |
type은 늘어날 수 있습니다. 모르는 값은 SELLER_PROCESSING처럼 그리십시오. 주문 취소·구매확정·반품 요청처럼 늘 있는 행동은 step.actions에 없고 주문상품 actions에 있습니다.
버튼 입력 칸
흐름의 버튼(셀러 확인 버튼, 구매자 확인의 승인·수정 요청)마다 입력 칸을 둘 수 있습니다. 행동의 input이 그 칸이고, 값은 { "input": { 칸 키: 값 } }으로 보냅니다.
type | 값 |
|---|---|
text·textarea | 문자열(maxLength까지) |
number | 정수 |
select·radio | options 중 하나 |
checkbox | options 중 고른 것의 배열 |
boolean | true·false. 필수면 true여야 합니다 |
date | YYYY-MM-DD |
datetime | 오프셋 있는 ISO 8601(예: 2026-10-12T15:00:00+09:00) |
image | https 주소 배열(maxFiles장까지). 스토어프론트는 POST /storefront/v1/uploads/order-inputs로 올린 주소를 씁니다 |
선택지는 값만 오거나 { "value": "COURIER", "label": "택배" }처럼 값·이름 쌍으로 옵니다. 보낼 때는 값입니다. when({ "key": "deliveryMethod", "in": ["COURIER", "QUICK"] })이 있는 칸은 그 조건일 때만 받습니다. 송장 등록(DISPATCH)·판매자 취소(SELLER_CANCEL)도 같은 형식으로 칸을 싣습니다.
칸과 맞지 않으면 400 FLOW_ACTION_INPUT_INVALID이고 details.issues[]에 칸 키·이름·이유(REQUIRED·INVALID·TOO_LONG)가 옵니다. 받은 값은 다음 상태의 inputs(flowState·step)에 이름과 함께 남아 셀러·구매자 모두에게 보입니다. 다음 행동이 지나가면 바뀝니다.
현장 단말·연동의 사건
입장 확인처럼 상점 밖에서 일어난 일은 사건으로 보냅니다. 이름은 custom.으로 시작합니다.
POST /v1/order-items/{orderItemId}/events/custom.CHECKED_IN지금 상태가 그 사건을 받지 않으면 409 FLOW_EVENT_NOT_ACCEPTED, 이름이 틀리면 400 FLOW_EVENT_KEY_INVALID입니다.
자동 진행
기한(시안 응답 48시간, 접수 5분)·날짜(희망 일시 하루 전, 관람일 다음 날)가 되면 흐름이 스스로 다음 상태로 갑니다. 진행 중인 취소·반품이 있으면 기한이 멈췄다가 끝난 뒤 남은 시간으로 다시 셉니다.
4. 묶음 진행
음식 배달형처럼 한 주문의 상품을 함께 진행하는 흐름은 같은 주문의 같은 흐름 상품이 하나로 움직입니다. 어느 주문상품으로 행동해도 묶음 전체에 적용되고, 응답 affectedOrderItemIds에 함께 움직인 주문상품이 옵니다. 묶음을 거절하면 상품마다 취소되고 환불은 한 번에 합니다.
진행 단위는 초안 정의의 requires.progression(ITEM 상품별, ORDER_GROUP 주문 묶음)입니다. 게시할 때 그 버전에 고정되고 흐름의 progression도 이 값으로 바뀝니다. 진행 중 주문은 결제 때 버전의 진행 단위를 따릅니다. 값이 형식에 맞지 않으면 게시 검사가 REQUIRES_INVALID로 막습니다.
묶음 중 한 상품만 취소·반품을 신청했을 때의 동작은 requires.groupClaim으로 정합니다. CONTINUE(계속 진행)는 묶음의 다른 상품을 그대로 진행하고, 승인된 상품만 묶음에서 빠집니다. PAUSE(멈춤, 기본)는 판매자가 처리할 때까지 묶음 전체의 기한과 행동을 멈춥니다. 요청 철회 같은 클레임 행동은 신청한 주문상품에만 보입니다.
5. 취소·반품·환불
각 노드(단계)의 권한 표에서 그 단계에 할 수 있는 신청과 처리를 켭니다.
| 권한 | 누가 | 하는 일 |
|---|---|---|
| 주문 취소 | 구매자 | 바로 취소합니다(클레임 접수 후 자동 처리) |
| 취소 요청 | 구매자 | 판매자가 확인한 뒤 취소됩니다 |
| 반품 요청 · 교환 요청 | 구매자 | 판매자가 승인합니다 |
| 판매자 직권취소 | 셀러 | 주문 취소와 결제 환불을 한 번에 합니다 |
| 주문 취소(환불은 따로) | 셀러 | 주문만 취소하고 결제 환불은 대기로 남깁니다 |
- 구매자 신청에는 기한(단계에 들어온 뒤 N일)과 수수료(없음 · 건당 정액 · 비율)를 화면에서 둡니다. 수수료는 접수 때 계산해 예상 환불에서 빼고, 승인에서
deductAmount를 생략하면 그 금액을 차감합니다. - 구매자 주문 상세의 단계 요약
step.claimable에 지금 신청할 수 있는 것과 기한이 옵니다. 스토어프론트는 이 목록으로 「지금 취소할 수 있습니다」 같은 안내를 그립니다. 권한을 끄면 안내도 사라집니다. - 권한 표에 켤 수 있는 행동 목록은
GET /v1/flow-node-types의platformActions입니다. - 버튼이 받는 입력 칸(거절 사유, 조리 시간 등)은 셀러 확인 노드 버튼의
input이나 연결선 조건(on.input)에 둡니다. - 신청 전 예상 환불은
POST /storefront/v1/me/order-items/{orderItemId}/claims/preview로 봅니다(취소·반품·교환). - 접수한 요청이 아직 「요청」 상태면 구매자 행동에 요청 철회(
WITHDRAW_REQUEST)가 옵니다. - 흐름이 취소 상태로 가는 행동(가게 거절, 가게 사정 취소, 접수 기한 초과)은 판매자 취소와 같이 환불·재고 복원·
ORDER.CANCELED까지 처리합니다.
주문 취소와 결제 환불 나누기
「주문 취소(환불은 따로)」로 취소하면 정산·재고 복원·적립금 반환은 바로 하고, 결제 대행사 환불만 결제 상세의 환불 이력에 HELD(환불 대기)로 남습니다. 결제 상세에서 「환불 처리」를 누르면 그때 환불합니다. API는 판매자 취소·클레임 승인 본문의 holdRefund: true와 POST /v1/payments/refunds/{refundId}/process입니다. 클레임 승인 화면에서도 「승인만 하고 결제 환불은 나중에 처리」를 고를 수 있습니다. 대기 중인 환불은 결제 목록의 refundHeld=true 조건(상점 플랫폼 홈의 「환불 대기」)으로 모아 봅니다. 환불 처리는 한 번만 됩니다(다시 부르면 409 REFUND_NOT_HELD). 매출·현금영수증 합계는 환불이 끝난 뒤에 반영됩니다.
직접 설정하는 기한·수수료 식
화면의 기한(N일)·수수료(정액·비율)로 부족하면 노드 설정의 권한에 식을 직접 넣습니다. 초안 저장(PUT /v1/commerce-flows/{flowId}/draft)으로 그래프를 보냅니다. 편집기는 이 값을 「직접 설정한 식」으로 보여 주고 그대로 둡니다.
"permissions": {
"buyer": {
"CANCEL": {
"mode": "INSTANT",
"subflow": "core.claim.cancel@1",
"until": { "expr": "atTime(item.option.showAt - duration(\"24h\"), \"17:00\")" },
"deduct": { "expr": "daysUntil(item.option.showAt) >= 7 ? 0 : pct(refundable, 30)" }
}
}
}until은 신청 마감 시각입니다.within(기간)과 함께 쓰지 않습니다.deduct는 차감액(원)입니다. 숫자면 건당 정액이고, 식은refundable(이번 수량의 환불 기준액)·claim.quantity·claim.reason·item·order를 읽습니다.- 쓸 수 있는 함수:
pct(금액, 비율),daysUntil(시각),atTime(날짜, "HH:mm"),dayOfWeek(시각),isHoliday(시각),inRanges(시각, [{"from":"MM-DD","to":"MM-DD"}]),lookupStep(단계표, 남은 일수). - 숙박 예약형 프리셋의 차감표(성수기·주말·남은 일수)가
lookupStep예시입니다. 표는 식 안의 목록·맵으로 둡니다. - 주문 입력·옵션 속성의 일시(
item.inputs.wantedAt,item.option.showAt)는 선언 없이 시각으로 읽힙니다.
6. 주문 입력·이행 방식·첨부
| 기능 | 어디서 | 안내 |
|---|---|---|
| 주문 입력(희망 일시·레터링·참고 이미지) | 상품 직접 입력의 key·type | 상품 옵션 |
| 택배·직접 배달·방문 수령 | 상품 fulfillment.methods, 주문서 fulfillmentMethod·pickupLocationId | 배송비 |
| 회차 일시 등 조합 속성 | 조합 attributes | 상품 옵션 |
| 시안 등 첨부 | POST /v1/uploads(purpose: "flow-attachment") 뒤 행동 입력 attachments | 아래 |
시안 확인처럼 첨부가 필요한 상태는 첨부 없이 들어가지 않습니다(details.reason: ATTACHMENTS_REQUIRED). 첨부는 이 상점에서 올린 주소만 받습니다(ATTACHMENTS_INVALID).
7. 외부 API 부르기
티켓 좌석 배정처럼 흐름 중간에 상점의 API를 부를 수 있습니다. 상점 플랫폼의 흐름 편집기에서 외부 API 노드를 캔버스로 끌어 놓고, 속성에서 요청 주소·인증 헤더·요청 본문·응답 매핑을 설정합니다. 결과(성공·건너뜀·실패)마다 다음 상태를 잇습니다.
- 주소와 인증 헤더는 흐름 정의와 따로 암호화해 저장하고, 헤더 값은 다시 보여 주지 않습니다. API로는
PUT /v1/commerce-flows/secrets/{name}이고 노드의secret이 그 이름입니다. - https 외부 주소만 받습니다(
400 FLOW_SECRET_URL_INVALID). - 요청에는
Idempotency-Key헤더가 실립니다. 받는 쪽은 같은 키를 한 번만 처리하십시오. - 제한 시간 안에 답하지 않거나 결과를 모르면 다시 보내지 않고 실패로 처리합니다.
- 연결 정보를 저장하지 않으면 그 단계는 건너뜁니다.
8. 알림
흐름에 알림(연결선 실행 또는 알림 노드)을 둔 단계가 지나가면 웹훅 ORDER.FLOW_NOTIFICATION이 옵니다(event에 상점이 정한 알림 이름). 구매자 알림톡·메일은 이 웹훅을 받아 보냅니다.
흐름의 상태가 바뀔 때마다 웹훅 ORDER.FLOW_STATE_CHANGED가 옵니다(from·to·label·coreStatus). 공개 상태(ORDER.*)가 같아도 상점 흐름의 단계가 바뀌면 옵니다. 웹훅
9. 하위 흐름·병렬 진행
| 노드 | 동작 |
|---|---|
| 하위 흐름 호출 | 다른 흐름(게시한 버전)을 끝까지 돌리고, 그 흐름이 끝난 종료 상태로 다음이 갈라집니다. 진행 중에는 하위 흐름의 상태와 행동이 보입니다 |
| 병렬 분기 | 갈래마다 동시에 진행합니다(예: 제작과 포장). 모든 갈래가 합류에 닿으면 다음으로 넘어갑니다 |
| 합류 | 병렬 갈래가 모이는 곳입니다 |
- 응답 기한을 두면 기한이 지날 때 진행 중인 하위 흐름·갈래를 멈추고 기한 초과로 넘어갑니다.
- 공개 상태는 진행 중인 위치 가운데 가장 앞 단계입니다.
- 게시할 때 부를 흐름이 없거나(
CALL_TARGET_MISSING), 게시 전이거나(CALL_TARGET_UNPUBLISHED), 호출이 자기 흐름으로 돌아오면(CALL_CYCLE) 게시가 막힙니다.
10. 버전과 진행 중 주문
게시하면 새 주문이 새 버전을 따르고, 진행 중 주문은 결제 때의 버전을 끝까지 따릅니다. 흐름 조회의 versions[].inProgress가 버전마다 진행 중 주문 수입니다.
GET /v1/commerce-flows/{flowId}/versions/{version}
POST /v1/commerce-flows/{flowId}/versions/{version}/migrate
{ "limit": 100 }옮기기는 지금 상태가 새 버전에도 있는 주문만 그 상태로 옮기고 기한을 새 버전 기준으로 다시 겁니다. 진행 중 클레임·하위 흐름이 있거나 외부 API 응답을 기다리는 주문은 건너뜁니다(skipped). remaining이 0이 될 때까지 다시 부릅니다.
진행 단위가 다른 버전으로는 옮길 수 없습니다(409 FLOW_PROGRESSION_MISMATCH).
11. 시뮬레이션·과거 주문 재생
게시 전에 초안을 돌려 봅니다. 실제 주문·결제·재고는 바뀌지 않습니다.
POST /v1/commerce-flows/{flowId}/draft/simulate
{ "steps": [{ "event": { "type": "start" } }, { "event": { "type": "seller.action", "key": "CONFIRM_ORDER" } }, { "advance": "P3D" }] }
POST /v1/commerce-flows/{flowId}/draft/replay
{ "orderItemId": "oitem_..." }- 시뮬레이션은 단계마다 도착 상태·지나간 연결선·실행할 일·걸린 기한을 줍니다. 식은
context(없으면 견본 주문 값)로 계산합니다. - 과거 주문 재생은 실제 주문이 지나온 기록을 초안으로 다시 돌려, 처음 다르게 가는 단계(
divergedAt)를 찾습니다. - 흐름에 쓸 수 있는 노드·실행의 종류와 설정 형식은
GET /v1/flow-node-types(JSON Schema)로 봅니다.
자주 막히는 문제
| 증상 | 해결 |
|---|---|
409 ACTION_NOT_AVAILABLE | GET …/flow의 actions에서 켜진 행동인지, disabled.reason을 봅니다 |
400 FLOW_ACTION_INPUT_INVALID | 행동의 input 칸과 details.issues를 봅니다. 일시는 오프셋이 있어야 합니다 |
| 흐름이 붙지 않음 | 상품·카테고리에 지정한 흐름이 게시됐는지 GET /v1/products/{productId}/flow로 봅니다. 흐름은 결제 때 한 번만 정해집니다 |
게시가 막힘(409 PUBLISH_BLOCKED) | 검사 결과 blocking의 위치(nodeId·edgeId)를 고칩니다 |
| 자동 진행이 늦음 | 기한은 1분 단위로 확인합니다 |