본문으로 건너뛰기
한국어 번역 진행 중한국어 문서를 완성하는 동안 일부 가이드와 API 설명은 아직 영어로 표시될 수 있습니다.

콜백 명세

이 페이지에서는 Seamless Wallet 연동을 지원하기 위해 귀사의 서버에 구현해야 하는 4개의 HTTP 엔드포인트를 설명합니다. Ruby는 모든 게임 이벤트에 대해 이 엔드포인트들을 실시간으로 호출합니다.


개요​

4개의 엔드포인트는 다음과 같은 공통 속성을 갖습니다:

  • 메서드: POST
  • Base URL: 귀사가 설정한 callback_url
  • Content-Type: application/json (요청 및 응답)
  • 인증: HMAC-SHA256 서명 헤더 (콜백 인증 참조)
  • 타임아웃: 5초 하드 타임아웃; 목표 3초 미만
  • 성공 기준: HTTP 2xx 및 아래의 유효한 JSON 응답 계약
  • 실패 동작: 비-2xx, 타임아웃, 64 KiB 초과 본문, 잘못된 JSON 또는 응답 필드 -> 즉시 오류, 애플리케이션 수준 자동 재시도 없음

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

URL은 사용자 정보, 쿼리 문자열, 프래그먼트가 없는 절대 HTTPS URL이어야 합니다. 후행 슬래시는 허용되며 Brand 저장 시 제거됩니다.

성공 응답 계약​

성공 응답은 압축되지 않은 64 KiB 이하의 JSON object여야 합니다. Ruby는 Accept-Encoding: identity를 전송하며 압축된 Content-Encoding 응답을 거부합니다. 각 엔드포인트에서 요구하는 balance 또는 balance_before는 유한하고 음수가 아닌 DECIMAL(18,2) 문자열이어야 합니다. JSON 숫자, 부호, 지수 표기, NaN, Infinity, 누락 필드 및 범위 초과 값은 거부됩니다.


POST /balance​

플레이어의 현재 잔액을 조회합니다. 이것은 상태 비저장(Stateless) 읽기로, 자금 이동이나 부수 효과가 발생하지 않습니다.

요청​

{
"player_id": 12345,
"username": "player_handle",
"external_player_id": "brand-player-guid-001",
"provider_code": "evo"
}
필드타입필수설명
player_idinteger예Ruby의 내부 플레이어 식별자
usernamestring아니오플레이어의 표시 이름 (가용한 경우)
external_player_idstring아니오게임 시작 시 전달한 귀사의 안정적인 플레이어 식별자
provider_codestring예게임 제공사 코드 (예: "evo", "pg")

응답​

{
"balance": "1250.00"
}
필드타입설명
balancestring소수점 문자열로 표현된 현재 플레이어 잔액 (예: "1250.00")

참고사항​

  • balance는 상태 비저장 조회입니다. transaction_id가 없으며 멱등성(Idempotency) 요구사항이 없습니다.
  • 항상 해당 플레이어의 현재 실시간 잔액을 반환하십시오.

POST /debit​

플레이어의 지갑에서 자금을 차감합니다. 플레이어가 베팅할 때 호출됩니다.

요청​

{
"player_id": 12345,
"amount": "100.50",
"transaction_id": "txn_bet_abc123",
"username": "player_handle",
"external_player_id": "brand-player-guid-001",
"provider_code": "evo",
"round_id": "round_xyz",
"game_code": "baccarat_classic",
"ref_id": "external_ref_001",
"memo": "Bet on Baccarat round 7"
}
필드타입필수설명
player_idinteger예Ruby의 내부 플레이어 식별자
amountstring예차감할 금액, 소수점 문자열 (예: "100.50")
transaction_idstring예고유 트랜잭션 식별자 -- 멱등성 처리에 사용
usernamestring아니오플레이어의 표시 이름
external_player_idstring아니오게임 시작 시 전달한 귀사의 안정적인 플레이어 식별자
provider_codestring예게임 제공사 코드
round_idstring아니오게임 라운드 식별자
game_codestring아니오해당 제공사 내 게임 식별자
ref_idstring아니오게임 제공사의 외부 참조 ID
memostring아니오트랜잭션에 대한 사람이 읽을 수 있는 설명

응답​

{
"balance": "1149.50",
"balance_before": "1250.00"
}
필드타입설명
balancestring차감 후 플레이어 잔액
balance_beforestring차감 전 플레이어 잔액

멱등성​

이미 성공적으로 처리한 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",
"external_player_id": "brand-player-guid-001",
"provider_code": "evo",
"round_id": "round_xyz",
"game_code": "baccarat_classic",
"bet_amount": "100.50",
"original_transaction_id": "txn_bet_abc123",
"ref_id": "external_ref_002",
"memo": "Win payout for Baccarat round 7"
}
필드타입필수설명
player_idinteger예Ruby의 내부 플레이어 식별자
amountstring예입금할 금액, 소수점 문자열
transaction_idstring예고유 트랜잭션 식별자 -- 멱등성 처리에 사용
usernamestring아니오플레이어의 표시 이름
external_player_idstring아니오게임 시작 시 전달한 귀사의 안정적인 플레이어 식별자
provider_codestring예게임 제공사 코드
round_idstring아니오게임 라운드 식별자
game_codestring아니오해당 제공사 내 게임 식별자
bet_amountstring아니오이 입금이 기존 차감을 정산할 때의 원래 베팅 금액
original_transaction_idstring아니오이 입금과 연결된 원래 지갑 거래 ID
standalone_creditboolean아니오기존 차감 없이 발생한 독립 입금이면 true로 포함되며, 그 외에는 생략
ref_idstring아니오게임 제공사의 외부 참조 ID
memostring아니오트랜잭션에 대한 사람이 읽을 수 있는 설명

응답​

{
"balance": "1349.50",
"balance_before": "1149.50"
}
필드타입설명
balancestring입금 후 플레이어 잔액
balance_beforestring입금 전 플레이어 잔액

멱등성​

이미 성공적으로 처리한 transaction_id로 POST /credit 요청을 수신한 경우, 원래 호출과 동일한 응답을 반환하십시오. 자금을 다시 입금하지 마십시오.


POST /rollback​

이전 차감(Debit) 트랜잭션을 취소합니다. 베팅이 이미 완료된 후 라운드가 무효화되거나 취소될 때 호출됩니다.

요청​

{
"player_id": 12345,
"amount": "100.50",
"transaction_id": "txn_rollback_ghi789",
"username": "player_handle",
"external_player_id": "brand-player-guid-001",
"provider_code": "evo",
"round_id": "round_xyz",
"ref_id": "external_ref_003"
}
필드타입필수설명
player_idinteger예Ruby의 내부 플레이어 식별자
amountstring예복원할 금액, 소수점 문자열
transaction_idstring예이 롤백의 고유 트랜잭션 식별자 -- 멱등성 처리에 사용
usernamestring아니오플레이어의 표시 이름
external_player_idstring아니오게임 시작 시 전달한 귀사의 안정적인 플레이어 식별자
provider_codestring예게임 제공사 코드
round_idstring아니오게임 라운드 식별자
ref_idstring아니오게임 제공사의 외부 참조 ID

참고: game_code와 memo는 롤백 요청에 포함되지 않습니다.

응답​

{
"balance": "1250.00"
}
필드타입설명
balancestring롤백 후 플레이어 잔액

참고: balance_before는 롤백 응답에 포함되지 않습니다.

멱등성​

이미 성공적으로 처리한 transaction_id로 POST /rollback 요청을 수신한 경우, 원래 호출과 동일한 응답을 반환하십시오. 자금을 다시 복원하지 마십시오.


필드 타입 참조​

필드타입비고
player_idinteger4개의 모든 콜백에 항상 포함
amountstring소수점 표현, 예: "100.50". Decimal 또는 동등한 타입으로 파싱하십시오 -- 부동소수점(Floating-point)을 사용하지 마십시오
balancestring트랜잭션 후 잔액의 소수점 표현
balance_beforestring트랜잭션 전 잔액의 소수점 표현 (debit/credit에만 해당)
transaction_idstring불투명한 고유 문자열; 중복 제거 키로 사용
usernamestring없을 수 있음; 플레이어 조회에 의존하지 마십시오
external_player_idstring게임 시작 시 전달된 귀사의 안정적인 플레이어 식별자; 없을 수 있음
provider_codestring게임 제공사를 식별하는 짧은 코드
round_idstring게임 수준의 라운드 식별자
game_codestring제공사별 게임 식별자 (롤백에는 포함되지 않음)
bet_amountstringCredit이 기존 Debit을 정산할 때의 원래 베팅 금액; 없을 수 있음
original_transaction_idstringCredit과 연결된 원래 지갑 거래 ID; 없을 수 있음
standalone_creditboolean기존 Debit 없이 발생한 Credit 여부
ref_idstring게임 제공사의 외부 참조; 없을 수 있음
memostring사람이 읽을 수 있는 메모; 없을 수 있음 (롤백에는 포함되지 않음)

멱등성 요약​

엔드포인트transaction_id멱등성 필요 여부
/balance아니오아니오 -- 상태 비저장 읽기
/debit예예
/credit예예
/rollback예예

Ruby는 각 transaction_id에 대해 성공 응답을 기록합니다. 네트워크 불확실성으로 인해 Ruby가 동일한 transaction_id로 다시 호출하는 경우, 귀사의 서버는 원래 결과를 반환해야 합니다. Ruby는 재처리에 의존하여 안전성을 보장하지 않지만, 귀사의 서버는 독립적으로 이를 방어해야 합니다.

각 키를 최초 전체 요청에 바인딩하십시오. 완전히 동일한 재시도에는 저장된 결과를 반환하고, 다른 플레이어, 제공사, 금액 또는 컨텍스트로 재사용되면 거부하고 알림을 발생시켜야 합니다.


재시도 정책​

현재 실패한 콜백에 대한 애플리케이션 수준 자동 재시도는 없습니다. 비-2xx, 잘못된 성공 응답 또는 5초 초과 타임아웃은 즉시 게임 제공사에 오류로 전달됩니다. 게임 제공사는 원래 이벤트를 독립적으로 재시도할 수 있으며, 이때 동일한 지갑 transaction_id가 사용되므로 멱등성 보장은 필수입니다.

이에 따라 오류 처리를 계획하십시오:

  • 수동으로 재시도할 것으로 예상되는 일시적 오류에 대해서만 5xx를 반환하십시오
  • 영구적인 비즈니스 오류 (잔액 부족, 플레이어 정지)에 대해서는 4xx를 반환하십시오
  • 부하 상태에서도 서버가 5초 이내에 응답할 수 있도록 보장하십시오