쇼핑몰 주문을 링크팜에 연결하기

크리에이터가 만든 매출을 집계해 커미션으로 정산합니다. 쓰는 엔드포인트는 POST /v1/events 하나입니다.

AI 에이전트에게 맡기기

Claude·Cursor 같은 코딩 에이전트를 쓰신다면 아래를 그대로 붙여넣으세요. 문서와 스펙 주소가 들어 있어 에이전트가 읽고 통합한 뒤 테스트 주문까지 넣어 확인합니다.

프롬프트
이 프로젝트에 링크팜 전환 추적을 붙여줘.

문서: https://openapi.linkfarm.ai/llms-full.txt
OpenAPI: https://openapi.linkfarm.ai/openapi.json

요구사항:
- 랜딩 URL 쿼리의 lf_click 을 서버에서 HttpOnly 쿠키로 저장(쿠키 수명 13개월.
  단, 귀속 인정은 제품별 어트리뷰션 윈도우(기본 30일)로 서버가 별도 판정)
- 결제 성공 후 서버에서 order.paid 전송
- occurred_at 을 보낼 땐 UTC 오프셋 필수(예: +09:00) — 오프셋 없으면 422
- 환불 완료 후 refund.created 전송 (refund_id 포함)
- 시크릿 키는 LINKFARM_SECRET_KEY 환경변수에서만 읽기
- 429/5xx 만 재시도, 4xx 는 재시도 금지
- 먼저 GET /v1/ping 으로 연결을 확인하고, 테스트 주문까지 넣어서 검증해줘

1. 키 확인

GET/v1/ping
https://openapi.linkfarm.ai/v1/pingsk_ · pk_

키가 유효한지, 어느 브랜드·어느 모드인지 확인합니다.

요청
curl -s https://openapi.linkfarm.ai/v1/ping \
  -H "Authorization: Bearer $LINKFARM_SECRET_KEY"
응답 · 200 OK
{
  "object": "ping",
  "ok": true,
  "brand": "글로우랩",
  "brand_id": "8c232845-32bb-40b3-8651-cff0f96f0d60",
  "livemode": false,
  "key_type": "secret",
  "api_version": "v1"
}

서버용 sk_live_ · sk_test_ — 주문·환불·취소 전부 가능

브라우저용 pk_live_ · pk_test_ page.viewed · product.viewed · cart.item_added · order.observed

공개 키로 정산 대상 주문을 만들 수 있으면 누구나 매출을 위조할 수 있어 분리했습니다. sk_test_로 보낸 데이터는 정산에 반영되지 않고 30일 뒤 지워집니다.

2. 클릭 식별자를 쿠키로 저장

크리에이터 링크로 들어오면 랜딩 URL에 ?lf_click=b_8mK3qP 가 붙습니다. 이 값을 서버에서 자사 도메인 쿠키로 저장하세요.

브라우저 JS로 굽지 마세요. Safari는 트래킹 도메인을 거쳐 들어온 페이지에 쿼리스트링이 있으면 document.cookie로 만든 쿠키를 24시간으로 잘라냅니다. 서버 Set-Cookie는 이 제한을 받지 않습니다.

Node / Express
// 랜딩 진입점(공통 미들웨어)에서 한 번만.
app.use((req, res, next) => {
  const click = req.query.lf_click;
  if (typeof click === 'string' && click) {
    res.cookie('lf_click', click, {
      httpOnly: true, secure: true, sameSite: 'lax',
      maxAge: 400 * 24 * 60 * 60 * 1000,   // 13개월(쿠키 수명 — 귀속 인정은 별도)
      domain: '.example.com',              // 서브도메인에서도 읽히게
    });
  }
  next();
});
PHP
<?php
// 공통 헤더에서 한 번만.
if (!empty($_GET['lf_click'])) {
    setcookie('lf_click', $_GET['lf_click'], [
        'expires'  => time() + 400 * 24 * 60 * 60,  // 13개월(쿠키 수명 — 귀속 인정은 별도)
        'path'     => '/',
        'domain'   => '.example.com',
        'secure'   => true,
        'httponly' => true,
        'samesite' => 'Lax',
    ]);
}

쿠키 수명 ≠ 귀속 인정 기간. 13개월은 쿠키가 저장되는 기간일 뿐입니다. 실제 귀속은 제품별 어트리뷰션 윈도우(브랜드가 7·30·60일 중 설정, 기본 30일)로 서버가 다시 판정합니다 — 기준은 해당 오퍼의 가장 최근 클릭 시각이고, 윈도우를 넘긴 클릭은 쿠키가 남아 있어도 귀속되지 않습니다. 크리에이터 할인코드 귀속은 클릭이 아니므로 이 윈도우의 영향을 받지 않습니다.

서버를 못 건드리는 솔루션이라면 쇼핑몰 연동을 보세요.

3. 결제 성공 시 주문 전송

POST/v1/events
https://openapi.linkfarm.ai/v1/eventssk_

주문·환불·취소·확정을 모두 이 하나로 보냅니다. type 이 무엇을 하는지 정합니다.

요청
curl -s -X POST https://openapi.linkfarm.ai/v1/events \
  -H "Authorization: Bearer $LINKFARM_SECRET_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "type": "order.paid",
    "data": {
      "order_id": "20260801-000123",
      "amount": 59000,
      "click_ref": "b_8mK3qP",
      "coupon_code": "SUJIN10"
    }
  }'
응답 · 200 OK
{
  "id": "evt_7c1f2a9d4b3e8a05c6d1f2",
  "object": "event",
  "type": "order.paid",
  "livemode": false,
  "status": "accepted",
  "attribution": {
    "status": "attributed",
    "via": "code"
  },
  "conversion_id": "c6a9373e-88e4-4a71-90e5-fdc55d1a83bf",
  "request_id": "req_df953ce566e74a9e91a3f6c2"
}

amount 정의 — 할인 적용 후 소비자가 실제 부담한 커미션 대상 상품 금액. 배송비·포인트 충전·상품권·비대상 상품은 빼세요. 한 주문에 대상과 비대상이 섞이면 대상분만 보냅니다. 전체 결제액을 보내면 비대상 상품에도 커미션이 붙습니다.

환불·취소·구독 갱신·외화 결제 예시는 이벤트에 있습니다.

4. 누락 복구

order.paid는 주문번호 기준 멱등입니다. 같은 주문을 다시 보내도 두 번 집계되지 않습니다. 그래서 복구가 재전송 하나로 끝납니다.

매일 밤 어제 주문 전량을 다시 보내세요. 그게 전부입니다.

POST/v1/events/batch
https://openapi.linkfarm.ai/v1/events/batchsk_

한 번에 최대 500건. 이미 반영된 주문은 그대로 두고 빠진 것만 채웁니다.

Node — 야간 대사
// 매일 밤 한 번. 이미 반영된 주문은 그대로 두고 빠진 것만 채워집니다.
const orders = await db.ordersCreatedOn(yesterday);

await fetch('https://openapi.linkfarm.ai/v1/events/batch', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
    Authorization: `Bearer ${process.env.LINKFARM_SECRET_KEY}`,
  },
  body: JSON.stringify({
    events: orders.map((o) => ({
      type: 'order.paid',
      occurred_at: o.paidAt.toISOString(),
      data: {
        order_id: o.id,
        amount: o.commissionableAmount,
        click_ref: o.lfClick,
        coupon_code: o.couponCode,
      },
    })),
  }),
});
GET/v1/orders
https://openapi.linkfarm.ai/v1/orderssk_

저희가 인식한 주문 목록. 대조용이라 조회 API를 따로 만드실 필요가 없습니다.

다음 단계

  • 이벤트 — 환불·취소·구독 갱신·외화 결제 요청/응답
  • 에러 — 코드별 대응과 재시도 규칙
  • 쇼핑몰 연동 — 카페24·스마트스토어·아임웹·고도몰

막히시면 request_id와 함께 support@linkfarm.ai 로 알려주세요.