> ## Documentation Index
> Fetch the complete documentation index at: https://docs.tryaeris.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Server API

## 주문 Report: server API

Base URL: 당신의 `s2s_endpoint_base` (예: `https://realry.com/api/v1/direct`). 모든 request 는 JSON body 와 아래 3개 signature header 를 포함한 `POST`.

### Request 서명

모든 호출에 3개 header:

| Header                  | Value                                                |
| ----------------------- | ---------------------------------------------------- |
| `X-Merchant-Key`        | 당신의 `api_key`                                        |
| `X-Signature-Timestamp` | 현재 unix time (**초 단위의 정수**)                          |
| `X-Signature`           | `HMAC_SHA256(timestamp + body, hmac_secret)`, hex 형식 |

Signature 만들기: timestamp 를 취하고, **정확한 JSON body** 를 어떤 공백이나 구분자도 없이 바로 뒤에 붙여서, 그 string 을 `hmac_secret` 으로 HMAC-SHA256.

<Warning>
  **JSON body 를 한 번 serialize 하고, 그 exact text 를 서명하고, 그 exact text 를 보내세요.** 서명 후 body 를 다시 encode 하면 (key 순서만 바꿔도) signature 가 맞지 않음.
</Warning>

서버가 check 하는 것 — 실패 시 `401`:

* 3개 header 전부 포함.
* Timestamp 는 정수이며 우리 서버 clock 과 **5분** 이내.
* `api_key` 가 active.
* Signature 매칭.

당신의 key 는 계정에 tied 되어 있어서 body 에 seller 를 많이하지 않음 — 우리는 이미 당신음을 압니다.

### 4개 Event

주문의 생애을 이 호출들로 report. 모두 `merchant_order_id` (당신의 order id) 와 unique `event_id` (아래 *Safe retries* 참고) 가 필요.

#### 1. 주문 완료 — `POST /conversions`

결제 완료 순간 전송 (card capture, 또는 가상계좌 주문의 경우 입금 확인 — 아래 *가상계좌 주문* 참고).

```json theme={"dark"}
{
  "merchant_order_id": "order-1",
  "event_id": "evt-1",
  "amount": 49900,
  "currency": "KRW",
  "cb_aev": "ABC123",
  "product_name": "Silk Blouse",
  "items": [{ "item_id": "sku-7", "name": "Silk Blouse", "price": 49900, "quantity": 1 }]
}
```

| Field               | 필수  | Note                                                           |
| ------------------- | --- | -------------------------------------------------------------- |
| `merchant_order_id` | yes | 당신의 order id (pixel `transaction_id` 과 동일)                     |
| `event_id`          | yes | 호출당 unique; retry 에 안전하게                                       |
| `amount`            | yes | 주문 총액; 0 이상의 숫자                                                |
| `currency`          | yes | 3자리 코드, 예: `KRW`                                               |
| `cb_aev`            | no  | 저장해둔 click id; 빼면 크리에이터에게 credit 되지 않음                         |
| `product_name`      | no  | 크리에이터 dashboard 에 표시; 없으면 `items[0].name`, 그것도 없으면 빈칸          |
| `items`             | no  | Line item, 당신의 기록용                                             |
| `sub_id`            | no  | 당신의 click/tracking ref — 우리가 어디서나 echo 하므로 reconciliation 에 유용 |

Response:

```json theme={"dark"}
{
  "data": {
    "merchant_order_id": "order-1",
    "transaction_id": "stylmatch:<your_seller_id>:order-1",
    "status": "CONFIRMED",
    "net_amount": 49900,
    "refunded_amount": 0,
    "currency": "KRW"
  }
}
```

`net_amount` 은 주문 총액 에서 refund 를 뭐 직수. `transaction_id` 는 우리 내부 reference — parse 할 필요 없으메; 항상 당신의 `merchant_order_id` 로 주문 매칭.

#### 2. Partial refund — `POST /conversions/partial`

주문을 `refund_amount` 만큼 감소 (부분 취소 또는 반품).

```json theme={"dark"}
{ "merchant_order_id": "order-1", "event_id": "evt-2", "refund_amount": 10000 }
```

Status 는 `PARTIALLY_CANCELLED` 로 바뀌고 `net_amount` 감소. `refund_amount` 는 0 과 현재 `net_amount` 사이의 숫자여야 함.

#### 3. Full cancel — `POST /conversions/cancel`

```json theme={"dark"}
{ "merchant_order_id": "order-1", "event_id": "evt-3" }
```

`net_amount` 를 0 으로, status `CANCELLED`, commission reverse.

#### 4. 이 주문은 credit 하지 마 — `POST /conversions/decline`

**당신**이 자체 유료 채널이 실제로 판매를 이김 (크리에이터가 아니라) 를 판단했을 때 사용. Declined 주문은 settlement 에서 떨어지며 invoice 안 됨.

```json theme={"dark"}
{ "merchant_order_id": "order-1", "event_id": "evt-4", "reason": "own_google_ads_last_click" }
```

Status 는 `DECLINED`, `net_amount` 0. `reason` 은 당신 기록용 free-text.

### Safe retries — `event_id`

<Tip>
  모든 호출에 unique `event_id` 사용. Request timeout 이서 retry 하면 **같은 `event_id` 재사용** — 우리가 인지하고 double-count 하지 않음. Retry 는 항상 안전.
</Tip>

### 가상계좌 주문

가상계좌 (bank transfer) 결제는 고객이 입금해야 진짜가 됨:

* 주문 *생성* 시점에서는 order report 보내지 말 것.
* **PG 의 입금 확인 webhook** (PortOne / Toss / NICE) fire 될 때 보내세요. 그 순간이 `POST /conversions` 호출 타이밍.
* 기한이 지나도 입금이 없으면 그냥 보내지 마세요. Cancel 호출 불필요 — 우리가 모르는 주문은 절대 settle 되지 않음.
