콜백 명세
이 페이지에서는 Seamless Wallet 연동을 지원하기 위해 귀사의 서버에 구현해야 하는 4개의 HTTP 엔드포인트를 설명합니다. Ruby는 모든 게임 이벤트에 대해 이 엔드포인트들을 실시간으로 호출합니다.
개요
4개의 엔드포인트는 다음과 같은 공통 속성을 갖습니다:
- 메서드:
POST - Base URL: 귀사가 설정한
callback_url - Content-Type:
application/json(요청 및 응답) - 인증: HMAC-SHA256 서명 헤더 (콜백 인증 참조)
- 타임아웃: 5초 하드 타임아웃; 목표 3초 미만
- 성공 기준: HTTP 2xx 응답 코드
- 실패 동작: 비-2xx 또는 타임아웃 -> 즉시 오류, 자동 재시도 없음
URL 구성
Ruby는 경로를 추가하기 전에 귀사의 callback_url에서 후행 슬래시를 제거합니다:
callback_url = "https://wallet.example.com/ruby"
→ POST https://wallet.example.com/ruby/balance
→ POST https://wallet.example.com/ruby/debit
→ POST https://wallet.example.com/ruby/credit
→ POST https://wallet.example.com/ruby/rollback
callback_url은 후행 슬래시 없이 등록하는 것을 권장하지만, 어느 형태든 정상적으로 작동합니다.
POST /balance
플레이어의 현재 잔액을 조회합니다. 이것은 상태 비저장(Stateless) 읽기로, 자금 이동이나 부수 효과가 발생하지 않습니다.
요청
{
"player_id": 12345,
"username": "player_handle",
"provider_code": "evo"
}
| 필드 | 타입 | 필수 | 설명 |
|---|---|---|---|
player_id | integer | 예 | Ruby의 내부 플레이어 식별자 |
username | string | 아니오 | 플레이어의 표시 이름 (가용한 경우) |
provider_code | string | 아니오 | 게임 제공사 코드 (예: "evo", "pg") |
응답
{
"balance": "1250.00"
}
| 필드 | 타입 | 설명 |
|---|---|---|
balance | string | 소수점 문자열로 표현된 현재 플레이어 잔액 (예: "1250.00") |
참고사항
balance는 상태 비저장 조회입니다.transaction_id가 없으며 멱등성(Idempotency) 요구사항이 없습니다.- 항상 해당 플레이어의 현재 실시간 잔액을 반환하십시오.
POST /debit
플레이어의 지갑에서 자금을 차감합니다. 플레이어가 베팅할 때 호출됩니다.
요청
{
"player_id": 12345,
"amount": "100.50",
"transaction_id": "txn_bet_abc123",
"username": "player_handle",
"provider_code": "evo",
"round_id": "round_xyz",
"game_code": "baccarat_classic",
"ref_id": "external_ref_001",
"memo": "Bet on Baccarat round 7"
}
| 필드 | 타입 | 필수 | 설명 |
|---|---|---|---|
player_id | integer | 예 | Ruby의 내부 플레이어 식별자 |
amount | string | 예 | 차감할 금액, 소수점 문자열 (예: "100.50") |
transaction_id | string | 예 | 고유 트랜잭션 식별자 -- 멱등성 처리에 사용 |
username | string | 아니오 | 플레이어의 표시 이름 |
provider_code | string | 아니오 | 게임 제공사 코드 |
round_id | string | 아니오 | 게임 라운드 식별자 |
game_code | string | 아니오 | 해당 제공사 내 게임 식별자 |
ref_id | string | 아니오 | 게임 제공사의 외부 참조 ID |
memo | string | 아니오 | 트랜잭션에 대한 사람이 읽을 수 있는 설명 |
응답
{
"balance": "1149.50",
"balance_before": "1250.00"
}
| 필드 | 타입 | 설명 |
|---|---|---|
balance | string | 차감 후 플레이어 잔액 |
balance_before | string | 차감 전 플레이어 잔액 |
멱등성
이미 성공적으로 처리한 transaction_id로 POST /debit 요청을 수신한 경우, 원래 호출과 동일한 응답을 반환하십시오. 자금을 다시 차감하지 마십시오.
원래 트랜잭션이 아직 처리 중인 경우 (예: 경쟁 상태로 인해), 이중 차감을 방지하기 위해 접근을 직렬화하십시오.
오류 케이스
| 시나리오 | 권장 HTTP 상태 |
|---|---|
| 잔액 부족 | 402 Payment Required 또는 422 Unprocessable Entity |
| 플레이어 미발견 | 404 Not Found |
| 플레이어 계정 정지 | 403 Forbidden |
| 내부 서버 오류 | 500 Internal Server Error |
비-2xx 응답은 Ruby에 의해 실패로 처리됩니다.
POST /credit
플레이어의 지갑에 자금을 추가합니다. 플레이어가 당첨되거나 정산이 이루어질 때 호출됩니다.
요청
{
"player_id": 12345,
"amount": "200.00",
"transaction_id": "txn_win_def456",
"username": "player_handle",
"provider_code": "evo",
"round_id": "round_xyz",
"game_code": "baccarat_classic",
"ref_id": "external_ref_002",
"memo": "Win payout for Baccarat round 7"
}
| 필드 | 타입 | 필수 | 설명 |
|---|---|---|---|
player_id | integer | 예 | Ruby의 내부 플레이어 식별자 |
amount | string | 예 | 입금할 금액, 소수점 문자열 |
transaction_id | string | 예 | 고유 트랜잭션 식별자 -- 멱등성 처리에 사용 |
username | string | 아니오 | 플레이어의 표시 이름 |
provider_code | string | 아니오 | 게임 제공사 코드 |
round_id | string | 아니오 | 게임 라운드 식별자 |
game_code | string | 아니오 | 해당 제공사 내 게임 식별자 |
ref_id | string | 아니오 | 게임 제공사의 외부 참조 ID |
memo | string | 아니오 | 트랜잭션에 대한 사람이 읽을 수 있는 설명 |
응답
{
"balance": "1349.50",
"balance_before": "1149.50"
}
| 필드 | 타입 | 설명 |
|---|---|---|
balance | string | 입금 후 플레이어 잔액 |
balance_before | string | 입금 전 플레이어 잔액 |
멱등성
이미 성공적으로 처리한 transaction_id로 POST /credit 요청을 수신한 경우, 원래 호출과 동일한 응답을 반환하십시오. 자금을 다시 입금하지 마십시오.
POST /rollback
이전 차감(Debit) 트랜잭션을 취소합니다. 베팅이 이미 완료된 후 라운드가 무효화되거나 취소될 때 호출됩니다.
요청
{
"player_id": 12345,
"amount": "100.50",
"transaction_id": "txn_rollback_ghi789",
"username": "player_handle",
"provider_code": "evo",
"round_id": "round_xyz",
"ref_id": "external_ref_003"
}
| 필드 | 타입 | 필수 | 설명 |
|---|---|---|---|
player_id | integer | 예 | Ruby의 내부 플레이어 식별자 |
amount | string | 예 | 복원할 금액, 소수점 문자열 |
transaction_id | string | 예 | 이 롤백의 고유 트랜잭션 식별자 -- 멱등성 처리에 사용 |
username | string | 아니오 | 플레이어의 표시 이름 |
provider_code | string | 아니오 | 게임 제공사 코드 |
round_id | string | 아니오 | 게임 라운드 식별자 |
ref_id | string | 아니오 | 게임 제공사의 외부 참조 ID |
참고: game_code와 memo는 롤백 요청에 포함되지 않습니다.
응답
{
"balance": "1250.00"
}
| 필드 | 타입 | 설명 |
|---|---|---|
balance | string | 롤백 후 플레이어 잔액 |
참고: balance_before는 롤백 응답에 포함되지 않습니다.
멱등성
이미 성공적으로 처리한 transaction_id로 POST /rollback 요청을 수신한 경우, 원래 호출과 동일한 응답을 반환하십시오. 자금을 다시 복원하지 마십시오.
필드 타입 참조
| 필드 | 타입 | 비고 |
|---|---|---|
player_id | integer | 4개의 모든 콜백에 항상 포함 |
amount | string | 소수점 표현, 예: "100.50". Decimal 또는 동등한 타입으로 파싱하십시오 -- 부동소수점(Floating-point)을 사용하지 마십시오 |
balance | string | 트랜잭션 후 잔액의 소수점 표현 |
balance_before | string | 트랜잭션 전 잔액의 소수점 표현 (debit/credit에만 해당) |
transaction_id | string | 불투명한 고유 문자열; 중복 제거 키로 사용 |
username | string | 없을 수 있음; 플레이어 조회에 의존하지 마십시오 |
provider_code | string | 게임 제공사를 식별하는 짧은 코드 |
round_id | string | 게임 수준의 라운드 식별자 |
game_code | string | 제공사별 게임 식별자 (롤백에는 포함되지 않음) |
ref_id | string | 게임 제공사의 외부 참조; 없을 수 있음 |
memo | string | 사람이 읽을 수 있는 메모; 없을 수 있음 (롤백에는 포함되지 않음) |
멱등성 요약
| 엔드포인트 | transaction_id | 멱등성 필요 여부 |
|---|---|---|
/balance | 아니오 | 아니오 -- 상태 비저장 읽기 |
/debit | 예 | 예 |
/credit | 예 | 예 |
/rollback | 예 | 예 |
Ruby는 각 transaction_id에 대해 성공 응답을 기록합니다. 네트워크 불확실성으로 인해 Ruby가 동일한 transaction_id로 다시 호출하는 경우, 귀사의 서버는 원래 결과를 반환해야 합니다. Ruby는 재처리에 의존하여 안전성을 보장하지 않지만, 귀사의 서버는 독립적으로 이를 방어해야 합니다.
재시도 정책
현재 실패한 콜백에 대한 자동 재시도는 없습니다. 콜백이 비-2xx 상태 코드를 반환하거나 요청이 타임아웃(5초 초과)되면, Ruby는 즉시 게임 제공사에 오류를 전파합니다. 재시도는 수행되지 않습니다.
이에 따라 오류 처리를 계획하십시오:
- 수동으로 재시도할 것으로 예상되는 일시적 오류에 대해서만 5xx를 반환하십시오
- 영구적인 비즈니스 오류 (잔액 부족, 플레이어 정지)에 대해서는 4xx를 반환하십시오
- 부하 상태에서도 서버가 5초 이내에 응답할 수 있도록 보장하십시오