이벤트 레퍼런스
모든 이벤트는 POST /v1/events 하나로 보냅니다. type 이 무엇을 하는지 정합니다.
order.paid — 결제 완료
/v1/eventssk_결제가 성공한 직후 서버에서 보냅니다. 같은 order_id 를 다시 보내도 중복 집계되지 않습니다 — 이 성질 덕분에 누락 복구가 재전송만으로 끝납니다.
POST https://openapi.linkfarm.ai/v1/events
Authorization: Bearer sk_live_…
Content-Type: application/json
{
"type": "order.paid",
"occurred_at": "2026-08-01T14:32:18+09:00",
"data": {
"order_id": "20260801-000123",
"amount": 59000,
"currency": "KRW",
"click_ref": "b_8mK3qP",
"coupon_code": "SUJIN10",
"items": [
{ "sku": "SERUM-30", "name": "글로우 세럼 30ml",
"quantity": 1, "amount": 59000 }
]
}
}{
"id": "evt_7c1f2a9d4b3e8a05c6d1f2",
"object": "event",
"type": "order.paid",
"livemode": true,
"status": "accepted",
"attribution": {
"status": "attributed",
"via": "code"
},
"conversion_id": "c6a9373e-88e4-4a71-90e5-fdc55d1a83bf",
"request_id": "req_df953ce566e74a9e91a3f6c2"
}data 필드
order_idstring필수쇼핑몰의 주문번호. 브랜드 안에서 유일해야 합니다(멱등 키로 쓰입니다).
amountinteger필수할인 적용 후 소비자가 실제 부담한 커미션 대상 상품 금액. 배송비·포인트 충전·상품권·비대상 상품 제외. currency 의 최소단위 (KRW=원, USD=센트).
click_refstring랜딩 URL 의 lf_click 값. 자사 도메인 쿠키에 저장했다가 보냅니다.
coupon_codestring크리에이터 할인코드. click_ref 와 둘 다 있으면 코드가 우선합니다.
currencystringISO 4217. 생략하면 KRW. KRW 가 아니면 fx_rate 필수.
fx_ratedecimal1 통화단위당 KRW. 주문에 고정되어 이후 환불도 같은 환율로 계산됩니다.
parent_order_idstring구독 갱신일 때 최초 결제의 order_id. 귀속을 상속하고 회차가 자동 계산됩니다.
itemsarray라인아이템(선택). sku · name · quantity · amount.
customer_hashstring구매자 식별자의 해시. 원문 개인정보는 보내지 마세요 — 이름·이메일·전화·주소는 받지 않습니다.
occurred_at 규칙 — 결제가 실제 일어난 시각(최상위 필드, 선택). 반드시 UTC 오프셋을 붙이세요(예: 2026-08-01T14:32:18+09:00). 오프셋 없는 값은 해석 기준이 없어 422 로 거절됩니다. 허용 범위는 현재 시각 기준 과거 90일 ~ 미래 5분이며, 생략하면 서버 수신 시각으로 기록됩니다.
귀속되지 않은 경우
쿠폰도 클릭 식별자도 없으면 요청은 정상 처리되고 미귀속으로 기록됩니다. 유효한 매출을 버리면 나중에 대조할 근거가 사라지기 때문에 에러로 만들지 않습니다.
{
"id": "evt_1b8e0c5a7f2d9e4a3c6b81",
"object": "event",
"type": "order.paid",
"livemode": true,
"status": "accepted",
"attribution": {
"status": "unattributed",
"via": null
},
"conversion_id": null,
"request_id": "req_a17c93be2d0f4e88b5129d4e"
}refund.created — 부분환불
/v1/eventssk_한 주문에 환불이 여러 번 들어올 수 있습니다.refund_id로 각각을 구분하며 필수입니다 — 없으면 두 번째 환불이 첫 번째와 같은 것으로 취급되어 무시됩니다.
{
"type": "refund.created",
"occurred_at": "2026-08-04T10:11:00+09:00",
"data": {
"order_id": "20260801-000123",
"refund_id": "R1",
"amount": 19000,
"reason": "부분 반품"
}
}{
"id": "evt_44a0d7e1c9b3f5028a6d14",
"object": "event",
"type": "refund.created",
"livemode": true,
"status": "accepted",
"attribution": { "status": "attributed", "via": "code" },
"conversion_id": "c6a9373e-88e4-4a71-90e5-fdc55d1a83bf",
"request_id": "req_5b2e81a4cc76d039fe117a3c"
}커미션은 환불 금액에 비례해 줄어듭니다. 59,000원 주문의 커미션 11,800원에서 19,000원을 환불하면 3,800원이 역분개됩니다. 부분환불은 주문을 종결시키지 않으며, 환불 누계가 원금에 도달할 때 종결됩니다.
order.cancelled — 전액 취소
/v1/eventssk_항상 남은 잔액 전부가 취소됩니다. amount를 보내도 무시됩니다 — 부분 금액을 취소하려면 refund.created를 쓰세요.
{
"type": "order.cancelled",
"data": {
"order_id": "20260801-000123",
"refund_id": "C1",
"reason": "고객 요청"
}
}{
"id": "evt_9f31b6d2e08c74a5b1e3d0",
"type": "order.cancelled",
"livemode": true,
"status": "accepted",
"attribution": { "status": "attributed", "via": "code" },
"conversion_id": "c6a9373e-88e4-4a71-90e5-fdc55d1a83bf",
"request_id": "req_0d7b41fa9e3c825610abe51d"
}order.confirmed — 구매 확정
/v1/eventssk_원천몰의 구매확정을 기록합니다. 상태 확인·대조용이며 지급 일정을 앞당기지 않습니다.
{
"type": "order.confirmed",
"data": { "order_id": "20260801-000123" }
}구독 갱신
/v1/eventssk_갱신 결제에는 클릭도 쿠폰도 없습니다. 최초 결제의 주문번호를 실어 보내면 그 귀속을 상속하고 회차가 자동으로 계산됩니다.
{
"type": "order.paid",
"data": {
"order_id": "20260901-000999",
"amount": 14900,
"parent_order_id": "20260801-000123"
}
}{
"id": "evt_2e5c81a09b4f7d3612ca8e",
"type": "order.paid",
"livemode": true,
"status": "accepted",
"attribution": {
"status": "attributed",
"via": "renewal"
},
"conversion_id": "8f21b0c4-15da-4e77-9c33-1a02de5b7f90",
"request_id": "req_c840be15792fa3d0e66cb8f0"
}attributed_via 가 renewal 로 돌아옵니다. 브랜드가 반복 커미션 기간을 설정했다면 그 회차를 넘긴 갱신은 커미션 0원으로 기록됩니다.
외화 결제
/v1/eventssk_KRW 가 아닌 결제는 fx_rate 가 필수입니다. 이 환율은 주문에 고정되며 이후 환불도 같은 환율로 계산됩니다.
{
"type": "order.paid",
"data": {
"order_id": "P-20260801-77",
"amount": 999,
"currency": "USD",
"fx_rate": "1385.5",
"coupon_code": "SUJIN10"
}
}{
"id": "evt_63bd0e7a15c92f4b18ad07",
"type": "order.paid",
"livemode": true,
"status": "accepted",
"attribution": { "status": "attributed", "via": "code" },
"conversion_id": "3d5f7a91-4c2e-4b08-a6d1-90ff2e4c8b17",
"request_id": "req_9ac31be07f45d2680e1b2c7d"
}환불도 원 주문과 같은 통화로 보내야 합니다. USD 주문에 EUR 환불을 보내면 422 로 거절됩니다 — 통화가 다르면 환산 기준이 없어 금액을 신뢰할 수 없습니다.
주문 상태 조회
/v1/orders/{order_id}sk_우리가 인식한 내용을 그대로 돌려줍니다. 자사 원장과 대조하거나, 통합이 제대로 붙었는지 확인할 때 씁니다.
GET https://openapi.linkfarm.ai/v1/orders/20260801-000123
Authorization: Bearer sk_live_…{
"object": "order",
"order_id": "20260801-000123",
"livemode": true,
"status": "pending",
"amount": 59000,
"currency": "KRW",
"original_amount": null,
"original_currency": null,
"fx_rate": null,
"commission_amount": 11800,
"refunded_amount": 19000,
"refunded_commission_amount": 3800,
"remaining_amount": 40000,
"attributed": true,
"attributed_via": "code",
"parent_order_id": null,
"occurred_at": "2026-08-01T05:32:18Z",
"confirm_at": "2026-09-06T15:00:00Z"
}일괄 전송 (대사)
/v1/events/batchsk_한 번에 최대 500건.
최대 500건. 야간 대사에 씁니다 — 어제 주문을 통째로 다시 보내면 됩니다. 이미 반영된 주문은 그대로 두고 누락분만 채워집니다.
POST https://openapi.linkfarm.ai/v1/events/batch
{
"events": [
{ "type": "order.paid",
"data": { "order_id": "20260801-000123", "amount": 59000,
"coupon_code": "SUJIN10" } },
{ "type": "order.paid",
"data": { "order_id": "20260801-000124", "amount": 32000,
"click_ref": "b_2pQ9zT" } }
]
}[
{ "id": "evt_7c1f2a9d4b3e8a05c6d1f2", "type": "order.paid",
"status": "accepted",
"attribution": { "status": "attributed", "via": "code" },
"conversion_id": "c6a9373e-…", "livemode": true,
"request_id": "req_1a2b3c4d5e6f7a8b9c0de0f1" },
{ "id": "evt_b04e1c7d92a5f38601ce4a", "type": "order.paid",
"status": "accepted",
"attribution": { "status": "attributed", "via": "click" },
"conversion_id": "1b77e0aa-…", "livemode": true,
"request_id": "req_1a2b3c4d5e6f7a8b9c0de0f1" }
]부분 실패 — 개별 이벤트가 실패하면 에러의 param 에 몇 번째 이벤트인지가 함께 옵니다(예: events[137].data.amount). 해당 건만 고쳐 다시 보내면 됩니다 — 멱등이라 성공한 건을 다시 보내도 중복 집계되지 않습니다. 레이트리밋은 요청 1건이 아니라 담긴 이벤트 수만큼 집계되니, 배치로 묶어도 한도는 같습니다.