Steam 소액결제 - FinalizeTxn

기본 정보

  1. Steam 소액결제 프로세스 중 FinalizeTxn 을 랩핑해서 제공하는 빌링 API입니다.

    1. InitTxn 부터 시작된 구매를 완료하는 API입니다.

  2. 유저가 거래를 승인하고 승인이 성공했다는 알림을 클라이언트에서 받은 후에만 호출되어야합니다.

    1. 해당 API가 성공했다면 결제가 완료되어 사용자에게 안전하게 아이템을 지급할 수 있다는 의미라서 빌링 API에 예약했었던 구매 건을 완료할 수 있습니다.

항목
내용
비고

호출주체

게임서버(s2s API)

HTTP 메소드

POST

Content-Type

application/x-www-form-urlencoded

사전 필요사항

  1. 프로젝트ID 및 서비스 ID 발급

  2. Steam works 설정 후 빌링 시스템 설정

Request

HTTP Request end point

POST https://각 환경별 빌링시스템 도메인/billing/api-game/v1/purchase/steam/microtxn/finalizeTxn

HTTP Request Header

  • 아래의 HTTP Header들을 API 요청에 포함시켜야합니다.

이름
비고

X-Req-Pjid

프로젝트ID

기술 PM 등에게 전달받은 프로젝트ID

X-Auth-Access-Key

인증용 키

기술 PM 등에게 전달받은 해당 게임용 인증 키

HTTP Request Parameter

  • Content-Type: application/x-www-form-urlencoded 으로 요청되어야 합니다.

  • 빌링 API에서 전달받은 파라미터는 Steam의 FinalizeTxn web API를 호출할 때 사용 됩니다.

    • 주의: 해당 Steam API 정의서의 내용의 주의사항 등을 꼭 확인해두는게 좋습니다.

key
type
설명

reqId

String(100)

중복 요청을 막거나 요청 추적을 위한 값

userId_UUID 등과 같은 방식으로 생성

pjid

String(20)

프로젝트ID

  • 동일 게임이라면 서비스ID가 여러개일 수 있지만 프로젝트ID는 같음

1004

boid

String(20)

빌링 시스템 구매 예약 API를 통해서 생성된 ID

  • Steam 응답에 에러가 반환시 빌링 API 예약부터 다시 진행되어야할 수 있습니다.(실제 결제 테스트 후 확인 필요). 스팀 web API 요구사항 때문

1234

playerId

String(50)

결제를 진행하는 유저의 ID

  • 게임에서 결제 스콥을 관리하고 싶은 id값으로 사용

    • 하이브 IM의 uid값이 될 수도 있음

Response

응답은 JSON형태로 전달됩니다.

Success sample

  • FinalizeTxn이 성공했습니다. 게임서버는 상품 지급을 진행 후 빌링에 최종 요청을 하시면 됩니다.

    • 완료 요청이 되기 전까지는 VERIFY_SUCCESS로 남아 있으며 재 처리 대상에 포함됩니다.

{
    "resultCode": "SUCCESS",
    "resultMessage": "FinalizeTxn success. Updated purchaseStatus to 'VERIFY_SUCCESS"
}

Error sample

  • 사용자가 아직 승인하지 않은 구매건에 대해서 FinalizeTxn 호출

    • 디버깅 목적으로 QueryTxn 응답 내용을 resultData에 응답해드립니다.

{
    "resultCode": "NOT_ALLOW_PURCHASE",
    "resultMessage": "Steam MicroTxn status not 'Approved'(See detail resultData of queryTxnResult). status: 'Init' | boid: '2' | steamTransId: '3680066791723605524' | Steam QueryTxnResponse: 'SteamQueryTxnResultDTO(result=OK, params=SteamQueryTxnResultDTO.QueryTxnResParams(orderId=17016160822, transId=3680066791723605524, steamId=76561198119773705, status=Init, currency=KRW, time=2023-12-03T15:08:02Z, country=KR, usstate=, items=[SteamQueryTxnResultDTO.Item(itemId=75, qty=1, amount=900000, vat=90000, itemStatus=Init)]), error=null)'",
    "resultData": {
        "status": "Init",
        "currency": "KRW",
        "time": "2023-12-03T15:08:02Z",
        "country": "KR",
        "usstate": "",
        "items": [
            {
                "qty": 1,
                "amount": "900000",
                "vat": "90000",
                "itemid": "75",
                "itemstatus": "Init"
            }
        ],
        "orderid": "17016160822",
        "transid": "3680066791723605524",
        "steamid": "76561198119773705"
    }
}
  • 사용자가 구매 거부한 건에 대해서 FinalizeTxn이 호출

    • 디버깅 목적으로 스팀 응답 내용을 resultData에 응답해드립니다.

{
    "resultCode": "NOT_ALLOW_PURCHASE",
    "resultMessage": "Steam MicroTxn status not 'Approved'(See detail resultData of queryTxnResult). status: 'Failed' | boid: '1' | steamTransId: '3680066791723511947' | Steam QueryTxnResponse: 'SteamQueryTxnResultDTO(result=OK, params=SteamQueryTxnResultDTO.QueryTxnResParams(orderId=17016151691, transId=3680066791723511947, steamId=76561198119773705, status=Failed, currency=KRW, time=2023-12-03T15:04:11Z, country=KR, usstate=, items=[SteamQueryTxnResultDTO.Item(itemId=75, qty=1, amount=900000, vat=90000, itemStatus=Failed)]), error=null)'",
    "resultData": {
        "status": "Failed",
        "currency": "KRW",
        "time": "2023-12-03T15:04:11Z",
        "country": "KR",
        "usstate": "",
        "items": [
            {
                "qty": 1,
                "amount": "900000",
                "vat": "90000",
                "itemid": "75",
                "itemstatus": "Failed"
            }
        ],
        "orderid": "17016151691",
        "transid": "3680066791723511947",
        "steamid": "76561198119773705"
    }
}

에러 코드 정의(resultCode부분)

  • 아래와 같은 에러코드가 resultCode에 응답될 수 있습니다. (참고 링크)

  • 아래의 에러코드들은 모든 빌링 API에서 발생 가능한 에러 코드들입니다.

    • 해당 에러코드 외에 각 API에서만 발생가능한 에러코드들도 있습니다.

    • 각 에러 코드를 바탕으로 필요시 비즈니스 로직을 작성하시면 됩니다.

에러코드
비고

SYSTEM_ERROR

빌링 API에서 발생한 시스템 에러

  • HTTP 상태코드 500 리턴

NOT_ALLOW_AUTH

API 인증 헤더 누락이거나 기타 권한이 없는 요청에서 발생

  • 아래 에러 코드들은 해당 API에서 발생 가능한 추가 에러 코드들입니다.

에러코드
비고

INVALID_PARAMETER

NOT_ALLOW_PURCHASE

구매 기능을 사용할 수 없는 상황

  • 빌링 시스템에 스토어 관련 설정 누락

  • 다른 유저의 결제 예약건을 완료 처리 시도

STEAM_RESULT_FAILURE

Steam web API 호출은 성공했지만, 결과가 실패로 리턴됨

  • 유저 비 로그인 상태에서 호출된 경우 등

EXTERNAL_API_ERROR

Steam web API 호출 자체가 실패한 경

요청 curl 샘플

  • 도메인 및 인증 헤더 등은 변경 필요

curl --location 'https://billing-game-api-dev-public.pub-dev.hybegames.io//billing/api-game/v1/purchase/steam/microtxn/finalizeTxn' \
--header 'X-Req-Pjid: 9001' \
--header 'X-Auth-Access-Key: test-auth-key' \
--header 'Content-Type: application/x-www-form-urlencoded' \
--data-urlencode 'reqId=userId_finalizeTxn_170083bf-8d85-433f-8bd2-67674b7482db-2023-12-03-01' \
--data-urlencode 'pjid=9001' \
--data-urlencode 'boid=78' \
--data-urlencode 'playerId=test_playerId'

참고

Finalize Txn 후 스팀 지갑에서 차감 후 유저가 받게되는 이메일 샘플(영수증 내용 포함)

Last updated