# UPBIT API Documentation v2.1

**Version:** 2.1
**Last Updated:** 2026-04-03
**Base URL:** `https://bitupgo.com`

---

## 📋 Table of Contents

1. [서버 아키텍처](#서버-아키텍처)
2. [Authentication APIs](#1-authentication-apis)
3. [Betting APIs](#2-betting-apis)
4. [Game APIs](#3-game-apis)
5. [User APIs](#4-user-apis)
6. [Chart APIs](#5-chart-apis)
7. [WebSocket APIs](#6-websocket-apis)
8. [Partner APIs (Seamless Integration)](#7-partner-apis-seamless-integration)
9. [Seamless Wallet Callbacks](#8-seamless-wallet-callbacks)
10. [Error Handling](#error-handling)

---

## 서버 아키텍처

### 서버 구성 (2026-03-15 기준)

| 포트 | 서버 | 용도 |
|------|------|------|
| 80/443 | Apache | 웹 서버 + PHP API + WebSocket 프록시 |
| **3000** | Node.js (Nuxt) | SSR 프론트엔드 메인 페이지 |
| **3001** | Node.js (Socket.io) | 실시간 WebSocket 서버 (채팅, 배팅, 잔액) |
| **8081** | Node.js (Socket.io) | Socket.io 보조 포트 (3001과 동일 서버) |
| **9090** | Node.js (BTC Chart) | BTC Chart Server (권한 서버, 라운드 관리) |

### Game Types (게임 타입)

| Type | Duration | Betting Closes At | Result Table |
|------|----------|-------------------|--------------|
| **30s** | 30 seconds | 25s, 55s | `round_results` |
| **60s** | 60 seconds | 45s | `round_results_60` |

### 주요 변경사항 (v1.0 → v2.0)

#### ⚠️ BREAKING CHANGES:

1. **WebSocket 프로토콜 변경**
   - ~~포트 8080 (PHP Ratchet)~~ → **포트 3001 (Socket.io)**
   - ~~wss://bitupgo.com/ws~~ → **wss://bitupgo.com/socket.io/**
   - 메시지 형식: JSON 객체 → Socket.io 이벤트 기반

2. **데이터베이스 테이블명 변경**
   - ~~`bets`~~ → **`betting_history`**
   - ~~`rounds`~~ → **`game_rounds`**
   - 배팅 상태: ~~`status`~~ → **`result`** (`pending/win/lose`)

3. **가격 데이터 소스 변경**
   - ~~포트 8081 (binance-relay)~~ → **포트 9090 (BTC Chart Server)**
   - `/price-ws` 엔드포인트 → 9090 포트로 프록시

4. **프론트엔드 변경**
   - PHP 템플릿 → **Nuxt 3 SSR** (포트 3000)

---

## 1. Authentication APIs

### 1.1 Login

```
POST /api/login.php
```

**Request Body:**
```json
{
  "username": "user123",
  "password": "password123"
}
```

**변경:** 이제 `email` 또는 `username` 둘 다 지원
```json
{
  "email": "user@example.com",
  "password": "password123"
}
```

**Response:**
```json
{
  "success": true,
  "message": "로그인 성공",
  "user": {
    "id": 1,
    "nickname": "사용자",
    "email": "user@example.com",
    "balance": 1000000,
    "avatar": "avatar1.png"
  },
  "redirect": "https://bitupgo.com/main.php"
}
```

### 1.2 Token Login (SSO)

외부 파트너 시스템에서 토큰 기반 자동 로그인

```
GET /auth/token_login.php?token={TOKEN}
```

**Response:**
- 성공 시: 자동 로그인 후 main.php로 리다이렉트
- 실패 시: 에러 메시지 표시

**Token 유효기간:** 60초

**Token 생성:** Partner API 참조 ([7.1 Get Login Token](#71-get-login-token))

### 1.3 Logout

```
POST /api/logout.php
```

**Response:**
```json
{
  "success": true,
  "message": "로그아웃 되었습니다."
}
```

---

## 2. Betting APIs

Base endpoint: `/api/betting.php`

### 2.1 Server Time Sync

서버 시간 및 게임 상태 동기화

```
GET /api/betting.php?action=sync
```

**Response:**
```json
{
  "success": true,
  "server_time": 1770380000,
  "server_time_ms": 1770380000000,
  "server_datetime": "2026-03-15 12:00:00",
  "game_duration": 30,
  "seconds_into_game": 15,
  "remaining_time": 15,
  "round_id": "202603150001",
  "round_number": 1,
  "round_date": "20260315",
  "round_start_time": 1770379985,
  "round_end_time": 1770380015,
  "betting_closed": false,
  "showing_result": false
}
```

### 2.2 Place Bet

배팅하기 (로그인 필요)

```
POST /api/betting.php?action=place
```

**Request Body:**
```json
{
  "bet_type": "UP",
  "amount": 10000,
  "entry_price": 66500.00
}
```

| Field | Type | Required | Description |
|-------|------|----------|-------------|
| bet_type | string | Yes | "UP" or "DOWN" |
| amount | number | Yes | 배팅 금액 (원) |
| entry_price | number | No | 진입 가격 (참고용) |

**Response:**
```json
{
  "success": true,
  "message": "배팅이 완료되었습니다.",
  "bet_id": 123,
  "new_balance": 990000,
  "round": {
    "round_id": "202603150001",
    "start_price": 66500.00
  }
}
```

**심리스 월렛 사용자:**
- 배팅 시 파트너 서버로 `debit` 콜백 호출
- 콜백 실패 시 배팅 거부

### 2.3 Current Round Info

현재 라운드 정보

```
GET /api/betting.php?action=current_round
```

**Response:**
```json
{
  "success": true,
  "round": {
    "id": 123,
    "round_id": "202603150001",
    "round_number": 1,
    "status": "betting",
    "total_up_bet": 500000,
    "total_down_bet": 300000,
    "approved_up_bet": 450000,
    "approved_down_bet": 280000,
    "start_price": 66500.00,
    "remaining_time": 15,
    "betting_closed": false
  },
  "stats": {
    "up_count": 5,
    "down_count": 3
  }
}
```

### 2.4 My Bets

내 배팅 정보 (로그인 필요)

```
GET /api/betting.php?action=my_bets&round_id=202603150001
```

**Response:**
```json
{
  "success": true,
  "bets": [
    {
      "id": 1,
      "bet_type": "UP",
      "original_amount": 10000,
      "approved_amount": 10000,
      "result": "pending"
    }
  ]
}
```

### 2.5 Betting History

배팅 히스토리 (로그인 필요)

```
GET /api/betting.php?action=history&limit=20&offset=0
```

**변경:** 테이블명 `bets` → `betting_history`

**Response:**
```json
{
  "success": true,
  "history": [
    {
      "round_id": "202603150001",
      "bet_type": "UP",
      "original_amount": 10000,
      "approved_amount": 10000,
      "result": "win",
      "payout_amount": 19000,
      "profit": 9000,
      "settled_at": "2026-03-15 12:00:30"
    }
  ]
}
```

### 2.6 Round Result

라운드 결과 조회

```
GET /api/betting.php?action=round_result&round_id=202603150001
```

**Response:**
```json
{
  "success": true,
  "round": {
    "id": 123,
    "round_id": "202603150001",
    "status": "settled",
    "result": "UP",
    "start_price": 66500.00,
    "end_price": 66550.00
  },
  "user_bet": {
    "bet_type": "UP",
    "original_amount": 10000,
    "approved_amount": 10000,
    "result": "win",
    "payout_amount": 19000
  }
}
```

### 2.7 Recent Results

최근 게임 결과 (히스토리 닷)

```
GET /api/betting.php?action=recent_results&limit=10
```

**Response:**
```json
{
  "success": true,
  "results": [
    {
      "round_id": "202603150001",
      "round_number": 1,
      "result": "UP",
      "start_price": 66500.00,
      "end_price": 66550.00
    }
  ]
}
```

### 2.8 Balance

사용자 잔액 조회 (로그인 필요)

```
GET /api/betting.php?action=balance
```

**Response:**
```json
{
  "success": true,
  "balance": 1000000,
  "wallet_type": "local"
}
```

**wallet_type:**
- `local`: 로컬 월렛 (Admin 직하부)
- `seamless`: 심리스 월렛 (파트너 하부)

---

## 3. Game APIs

Base endpoint: `/api/game.php`

### 3.1 Game Status

```
GET /api/game.php?action=status
```

**Response:**
```json
{
  "success": true,
  "round": 2847,
  "price": 66500.50,
  "change": 0.15,
  "up_total": 1500000,
  "down_total": 1200000,
  "up_count": 8,
  "down_count": 6,
  "time_remaining": 15
}
```

### 3.2 Game History

```
GET /api/game.php?action=history&limit=20
```

### 3.3 Participants

```
GET /api/game.php?action=participants&round_id=202603150001&type=UP
```

**Response:**
```json
{
  "success": true,
  "participants": [
    {
      "user_id": 1,
      "nickname": "사용자",
      "avatar": "avatar1.png",
      "amount": 10000
    }
  ]
}
```

---

## 4. User APIs

Base endpoint: `/api/user.php`

### 4.1 Get Profile

```
GET /api/user.php?action=profile
```

### 4.2 Update Profile

```
POST /api/user.php?action=update
```

**Request Body:**
```json
{
  "nickname": "새닉네임",
  "avatar": "avatar2.png"
}
```

### 4.3 Get Balance

```
GET /api/user.php?action=balance
```

### 4.4 Betting History

```
GET /api/user.php?action=history&page=1&limit=10
```

### 4.5 Notifications

```
GET /api/user.php?action=notifications
```

---

## 5. Chart APIs

### 5.1 Price History (for Chart)

차트 초기 로딩용 가격 데이터

```
GET /api/v1/history
```

**Response:**
```json
{
  "success": true,
  "source": "database",
  "klines": [
    [1770380000000, "66500.00", "66500.00", "66500.00", "66500.00", "0.001", 1770380000000, "0", 1, "0", "0", "0"]
  ],
  "candleCount": 100,
  "tradeCount": 100,
  "roundStart": 1770380000000,
  "endTime": 1770379999999,
  "cached": false
}
```

**Kline Format (Binance 호환):**
```
[
  openTime,           // 0: 시작 시간 (ms)
  open,               // 1: 시가
  high,               // 2: 고가
  low,                // 3: 저가
  close,              // 4: 종가
  volume,             // 5: 거래량
  closeTime,          // 6: 종료 시간 (ms)
  quoteVolume,        // 7: Quote 거래량
  trades,             // 8: 거래 수
  takerBuyBaseVolume, // 9
  takerBuyQuoteVolume,// 10
  ignored             // 11
]
```

---

## 6. WebSocket APIs

### 6.1 Socket.io Connection (NEW)

**변경:** PHP Ratchet → Socket.io

```javascript
// 클라이언트 연결
const socket = io('https://bitupgo.com', {
  path: '/socket.io/',
  transports: ['websocket', 'polling']
});
```

**Connection URL:**
```
wss://bitupgo.com/socket.io/
```

**서버 포트:** 3001, 8081 (Apache가 프록시)

### 6.2 Socket.io 이벤트

#### 클라이언트 → 서버

**사용자 인증:**
```javascript
socket.emit('authenticate', {
  session_id: 'abc123',
  user_id: 1
});
```

**채팅 메시지:**
```javascript
socket.emit('chat:send', {
  message: 'Hello',
  user_id: 1
});
```

#### 서버 → 클라이언트

**가격 업데이트 (100ms 스로틀):**
```javascript
socket.on('price:update', (data) => {
  // { price: 66500.50, timestamp: 1770380000000 }
});
```

**라운드 업데이트:**
```javascript
socket.on('round:update', (data) => {
  // {
  //   round_id: "202603150001",
  //   status: "betting",
  //   start_price: 66500.00,
  //   total_up_bet: 500000,
  //   total_down_bet: 300000
  // }
});
```

**타이머:**
```javascript
socket.on('round:tick', (data) => {
  // { remaining_time: 15 }
});
```

**잔액 업데이트:**
```javascript
socket.on('balance:update', (data) => {
  // { user_id: 1, balance: 990000 }
});
```

**배팅 현황:**
```javascript
socket.on('bets:update', (data) => {
  // { up_bets: [...], down_bets: [...] }
});
```

**채팅 메시지:**
```javascript
socket.on('chat:message', (data) => {
  // { user_id: 1, nickname: "사용자", message: "Hello" }
});
```

**라운드 종료:**
```javascript
socket.on('round:settled', (data) => {
  // {
  //   round_id: "202603150001",
  //   result: "UP",
  //   start_price: 66500.00,
  //   end_price: 66550.00
  // }
});
```

### 6.3 Price WebSocket (BTC Chart Server)

**변경:** 포트 8081 → **9090**

```
wss://bitupgo.com/price-ws
```

**용도:** 실시간 BTC 가격 수신 (Binance WebSocket 중계)

**주의:** WebSocket 전용 경로 - HTTP 요청 시 404 반환

---

## 7. Partner APIs (Seamless Integration)

외부 파트너가 UPBIT 게임을 자기 사이트에 통합할 수 있는 API

Base endpoint: `/api/partner.php`

**인증:** `X-Partner-Key` 헤더 필요

```
X-Partner-Key: {YOUR_CALLBACK_SECRET_KEY}
```

### 7.1 Get Login Token

사용자 자동 로그인용 토큰 생성

```
POST /api/partner.php?action=login
```

**Request Headers:**
```
Content-Type: application/json
X-Partner-Key: your_secret_key_here
```

**Request Body:**
```json
{
  "user_id": "username",
  "user_pw": "password"
}
```

**Response:**
```json
{
  "success": true,
  "login_url": "https://bitupgo.com/auth/token_login.php?token=abc123...",
  "expires_in": 60
}
```

**사용 방법:**
```html
<!-- 파트너 사이트에서 -->
<iframe src="https://bitupgo.com/auth/token_login.php?token=abc123..."
        width="100%" height="800"></iframe>
```

### 7.2 Get Transaction Result

배팅 결과 조회 (tx_id로)

```
GET /api/partner.php?action=result&tx_id=tx_abc123
```

**Request Headers:**
```
X-Partner-Key: your_secret_key_here
```

**Response:**
```json
{
  "success": true,
  "data": {
    "tx_id": "tx_abc123",
    "user_id": "user123",
    "game_id": "202603150001",
    "bet_type": "UP",
    "amount": 10000,
    "approved_amount": 10000,
    "returned_amount": 0,
    "win_amount": 19000,
    "profit": 9000,
    "result": "win",
    "start_price": 66500.00,
    "end_price": 66550.00,
    "round_result": "UP",
    "status": "settled",
    "created_at": "2026-03-15 12:00:00",
    "settled_at": "2026-03-15 12:00:30"
  }
}
```

### 7.3 Get User Balance

사용자 잔액 조회

```
GET /api/partner.php?action=balance&user_id=username
```

**Request Headers:**
```
X-Partner-Key: your_secret_key_here
```

**Response:**
```json
{
  "success": true,
  "data": {
    "user_id": "user123",
    "nickname": "사용자",
    "balance": 1000000
  }
}
```

### 7.4 Get User Betting History

사용자 배팅 내역 조회

```
GET /api/partner.php?action=history&user_id=username&limit=20&offset=0
```

**Request Headers:**
```
X-Partner-Key: your_secret_key_here
```

**Query Parameters:**
- `user_id`: 사용자 아이디 (필수)
- `limit`: 조회 개수 (기본 20, 최대 100)
- `offset`: 오프셋 (기본 0)

**Response:**
```json
{
  "success": true,
  "data": [
    {
      "tx_id": "tx_abc123",
      "bet_type": "UP",
      "amount": 10000,
      "approved_amount": 10000,
      "win_amount": 19000,
      "profit": 9000,
      "result": "win",
      "status": "settled",
      "created_at": "2026-03-15 12:00:00",
      "settled_at": "2026-03-15 12:00:30",
      "game_id": "202603150001",
      "start_price": 66500.00,
      "end_price": 66550.00,
      "round_result": "UP"
    }
  ]
}
```

---

## 8. Seamless Wallet Callbacks

파트너 서버가 구현해야 하는 콜백 API (UPBIT → 파트너)

### 8.1 콜백 설정

파트너 페이지에서 설정:
```
https://pt.bitupgo.com/pages/callback.php
```

**설정 항목:**
- `callback_balance_url` - 잔액 조회
- `callback_debit_url` - 배팅 차감
- `callback_credit_url` - 당첨금 지급
- `callback_cancel_url` - 배팅 취소
- `callback_secret_key` - HMAC-SHA256 서명 키

### 8.2 요청 형식

**Headers:**
```
Content-Type: application/json
X-Signature: {HMAC-SHA256(request_body, secret_key)}
X-Partner-Id: {partner_id}
```

**서명 검증 (파트너 서버):**
```php
$requestBody = file_get_contents('php://input');
$signature = $_SERVER['HTTP_X_SIGNATURE'] ?? '';
$secretKey = 'your_callback_secret_key';

$expectedSignature = hash_hmac('sha256', $requestBody, $secretKey);

if (!hash_equals($expectedSignature, $signature)) {
    // 서명 불일치 - 거부
    http_response_code(401);
    echo json_encode(['success' => false, 'error' => 'Invalid signature']);
    exit;
}
```

### 8.3 Balance (잔액 조회)

```
POST {callback_balance_url}
```

**Request Body:**
```json
{
  "action": "balance",
  "user_id": "user123",
  "timestamp": 1770380000
}
```

**Response (파트너 서버):**
```json
{
  "success": true,
  "balance": 1000000
}
```

**호출 빈도:** 5초 주기 (게임 중), 35초 주기 (대기 중)

### 8.4 Debit (배팅 차감)

```
POST {callback_debit_url}
```

**Request Body:**
```json
{
  "action": "debit",
  "user_id": "user123",
  "game_id": "202603150001",
  "game_type": "30s",
  "amount": 10000,
  "tx_id": "tx_abc123",
  "timestamp": 1770380000
}
```

| Field | Type | Description |
|-------|------|-------------|
| action | string | Always "debit" |
| user_id | string | User identifier |
| game_id | string | Round ID (YYYYMMDDNNNN) |
| **game_type** | **string** | **Game type: "30s" (30-second game) or "60s" (60-second game)** |
| amount | number | Debit amount |
| tx_id | string | Transaction ID (for duplicate prevention) |
| timestamp | number | Unix timestamp |

**Response (파트너 서버):**
```json
{
  "success": true,
  "balance": 990000,
  "tx_id": "tx_abc123"
}
```

**실패 시:**
```json
{
  "success": false,
  "error": "Insufficient balance",
  "error_code": "INSUFFICIENT_FUNDS"
}
```

### 8.5 Credit (당첨금 지급)

```
POST {callback_credit_url}
```

**Request Body:**
```json
{
  "action": "credit",
  "user_id": "user123",
  "game_id": "202603150001",
  "game_type": "30s",
  "win_amount": 19000,
  "tx_id": "tx_abc123",
  "start_price": 66500.00,
  "end_price": 66550.00,
  "result": "UP",
  "timestamp": 1770380030
}
```

| Field | Type | Description |
|-------|------|-------------|
| action | string | Always "credit" |
| user_id | string | User identifier |
| game_id | string | Round ID (YYYYMMDDNNNN) |
| **game_type** | **string** | **Game type: "30s" (30-second game) or "60s" (60-second game)** |
| win_amount | number | Winning amount (bet amount × payout rate) |
| tx_id | string | Transaction ID (same as debit tx_id) |
| start_price | number | BTC price at round start |
| end_price | number | BTC price at round end |
| result | string | Round result ("UP", "DOWN", "DRAW") |
| timestamp | number | Unix timestamp |

**Response (파트너 서버):**
```json
{
  "success": true,
  "balance": 1009000,
  "tx_id": "tx_abc123"
}
```

### 8.6 Cancel (배팅 취소)

```
POST {callback_cancel_url}
```

**Request Body:**
```json
{
  "action": "cancel",
  "user_id": "user123",
  "game_id": "202603150001",
  "amount": 10000,
  "tx_id": "tx_abc123",
  "timestamp": 1770380015
}
```

**Response (파트너 서버):**
```json
{
  "success": true,
  "balance": 1000000,
  "tx_id": "tx_abc123"
}
```

### 8.7 콜백 로그 확인

파트너 페이지에서 콜백 로그 확인 가능:
```
https://pt.bitupgo.com/pages/callback_logs.php
```

**제공 정보:**
- 요청/응답 내용
- HTTP 상태 코드
- 에러 메시지
- 성공/실패 통계

---

## Error Handling

### Error Response Format

모든 API는 일관된 에러 형식 사용:

```json
{
  "success": false,
  "message": "에러 설명",
  "error_code": "ERROR_CODE"
}
```

### HTTP Status Codes

| Code | Description |
|------|-------------|
| 200 | Success |
| 400 | Bad Request (잘못된 요청) |
| 401 | Unauthorized (로그인 필요 or 인증 실패) |
| 403 | Forbidden (권한 없음) |
| 404 | Not Found |
| 405 | Method Not Allowed |
| 500 | Internal Server Error |

### Common Error Codes

| Error Code | Description |
|------------|-------------|
| `AUTH_REQUIRED` | 로그인 필요 |
| `INVALID_CREDENTIALS` | 잘못된 인증 정보 |
| `INSUFFICIENT_BALANCE` | 잔액 부족 |
| `BETTING_CLOSED` | 배팅 마감 |
| `INVALID_BET_AMOUNT` | 잘못된 배팅 금액 |
| `DUPLICATE_BET` | 중복 배팅 |
| `ROUND_NOT_FOUND` | 라운드를 찾을 수 없음 |
| `CALLBACK_FAILED` | 콜백 실패 (심리스 월렛) |
| `INVALID_SIGNATURE` | 서명 불일치 |
| `INVALID_PARTNER_KEY` | 잘못된 파트너 키 |

---

## Rate Limits

| API Type | Limit |
|----------|-------|
| General APIs | 100 req/min |
| Betting APIs | 30 req/min |
| Partner APIs | 60 req/min |
| WebSocket | No limit |

---

## 데이터베이스 테이블 (참고)

### 주요 테이블

**betting_history** (이전: bets)
```sql
- id, round_id, user_id
- bet_type (UP/DOWN)
- original_amount, approved_amount, returned_amount, payout_amount
- result (pending/win/lose)  -- 이전: status
- profit
- is_seamless, callback_tx_id
- created_at, settled_at
```

**game_rounds** (30초 게임, 이전: rounds)
```sql
- id, round_id (YYYYMMDDNNNN)
- status (betting/locked/settled)
- start_price, end_price
- total_up_bet, total_down_bet
- approved_up_bet, approved_down_bet
- result (UP/DOWN/DRAW)
- payout_rate
- btc_round_id (BTC Chart Server ID)
```

**game_rounds_60** (60초 게임)
```sql
- id, round_id (YYYYMMDDNNNN)
- status (betting/locked/settled)
- start_price, end_price
- total_up_bet, total_down_bet
- approved_up_bet, approved_down_bet
- result (UP/DOWN/DRAW)
- payout_rate
- btc_round_id (BTC Chart Server ID)
```

**round_results** (30초 게임 결과)
```sql
- id, round_id, round_number
- result (UP/DOWN/DRAW)
- start_price, end_price
- created_at
```

**round_results_60** (60초 게임 결과)
```sql
- id, round_id, round_number
- result (UP/DOWN/DRAW)
- start_price, end_price
- created_at
```

**user_partner_settings**
```sql
- user_id
- partner_code (추천인 코드)
- rolling_rate, commission_rate
- callback_enabled
- callback_balance_url
- callback_debit_url
- callback_credit_url
- callback_cancel_url
- callback_secret_key
```

**callback_logs**
```sql
- id, partner_id, user_id
- action (balance/debit/credit/cancel)
- url, request, response
- http_code, error
- created_at
```

**login_tokens**
```sql
- id, user_id, token
- partner_id
- expires_at, used_at
- created_at
```

---

## Change Log

| Version | Date | Changes |
|---------|------|---------|
| 1.0 | 2026-02-08 | Initial documentation |
| 2.0 | 2026-03-15 | Major update: |
|  |  | - WebSocket: PHP Ratchet → Socket.io (포트 3001) |
|  |  | - 테이블명 변경: bets → betting_history, rounds → game_rounds |
|  |  | - BTC Chart Server 추가 (포트 9090) |
|  |  | - Nuxt 3 Frontend 추가 (포트 3000) |
|  |  | - Seamless Wallet 시스템 완전 구현 |
|  |  | - Partner APIs 추가 (login, result, balance, history) |
|  |  | - Token 기반 SSO 로그인 추가 |
|  |  | - 배팅 상태: status → result |
| **2.1** | **2026-04-03** | **60-second game support:** |
|  |  | - **Added `game_type` parameter to debit/credit callbacks** |
|  |  | - **Values: "30s" (30-second game) or "60s" (60-second game)** |
|  |  | - 60-second game tables: `game_rounds_60`, `round_results_60` |
|  |  | - New internal APIs: `lock_round_60`, `settle_round_60` |

---

## 🔗 관련 링크

- **사용자 페이지:** https://bitupgo.com
- **관리자 페이지:** https://ad.bitupgo.com
- **파트너 페이지:** https://pt.bitupgo.com
- **서버 설정 가이드:** `/0315_서버설정법.md`

---

## 📞 기술 지원

문의사항이 있으시면 관리자에게 문의하세요.

**파트너 연동 절차:**
1. 관리자에게 파트너 계정 발급 요청
2. 파트너 페이지 로그인 (https://pt.bitupgo.com)
3. 콜백 URL 설정 (`pages/callback.php`)
4. Secret Key 확인
5. 콜백 API 구현 (Balance, Debit, Credit, Cancel)
6. 테스트 후 프로덕션 연동

---

**© 2026 UPBIT. All rights reserved.**
