Skip to content

결제 거래 대사 ​

원장은 확정된 잔액 변동 기록으로 사용하고, 입금·출금 상세는 업무 상태 기록으로 사용합니다.

거래고객 계정가맹점 결제 계정
외부 USDT 입금DEPOSIT / CREDIT—
고객 결제INTERNAL_OUT / DEBITINTERNAL_IN / CREDIT
외부 정산—WITHDRAW / DEBIT

거래 유형 코드는 DEPOSIT=1000, WITHDRAW=2000, INTERNAL_OUT=3000, INTERNAL_IN=4000, ADJUSTMENT=5000입니다.

양쪽 계정 원장 조회 ​

bash
wallet_request GET "/accounts/$USER_ACCOUNT_ID/ledger?asset_type_id=$ASSET_TYPE_ID&after_id=0&limit=100" | jq
wallet_request GET "/accounts/$PAYMENT_ACCOUNT_ID/ledger?asset_type_id=$ASSET_TYPE_ID&after_id=0&limit=100" | jq

고객의 INTERNAL_OUT과 가맹점의 INTERNAL_IN 항목은 공통 ref_id로 연결합니다. 상세 결제 상태가 필요하면 GET /withdrawals/{ref_id}를 조회합니다.

원장 단건 조회 ​

원장 ID는 한 계정에만 속하므로 account_id와 ledger_id를 한 쌍으로 저장합니다.

bash
export USER_LEDGER_ID='{ledger-id-from-customer-list}'
export PAYMENT_LEDGER_ID='{ledger-id-from-merchant-list}'
wallet_request GET "/accounts/$USER_ACCOUNT_ID/ledger/$USER_LEDGER_ID" | jq
wallet_request GET "/accounts/$PAYMENT_ACCOUNT_ID/ledger/$PAYMENT_LEDGER_ID" | jq

증분 동기화 ​

다음 항목마다 독립된 cursor를 관리합니다.

  • 고객 외부 입금
  • 고객이 보낸 결제
  • 가맹점이 보낸 출금
  • 고객 원장
  • 가맹점 원장

처음 전체 동기화를 시작할 때만 아래처럼 0으로 초기화합니다. 재시작할 때는 리소스·계정·필터별로 DB에 저장한 cursor를 복원하고, 다음 코드로 덮어쓰지 않습니다.

bash
export USER_DEPOSIT_CURSOR='0'
export USER_WITHDRAWAL_CURSOR='0'
export PAYMENT_WITHDRAWAL_CURSOR='0'
export USER_LEDGER_CURSOR='0'
export PAYMENT_LEDGER_CURSOR='0'
bash
wallet_request GET "/deposits?account_id=$USER_ACCOUNT_ID&type=EXTERNAL&after_id=$USER_DEPOSIT_CURSOR&limit=100" | jq
wallet_request GET "/withdrawals?account_id=$USER_ACCOUNT_ID&after_id=$USER_WITHDRAWAL_CURSOR&limit=100" | jq
wallet_request GET "/withdrawals?account_id=$PAYMENT_ACCOUNT_ID&after_id=$PAYMENT_WITHDRAWAL_CURSOR&limit=100" | jq
wallet_request GET "/accounts/$USER_ACCOUNT_ID/ledger?asset_type_id=$ASSET_TYPE_ID&after_id=$USER_LEDGER_CURSOR&limit=100" | jq
wallet_request GET "/accounts/$PAYMENT_ACCOUNT_ID/ledger?asset_type_id=$ASSET_TYPE_ID&after_id=$PAYMENT_LEDGER_CURSOR&limit=100" | jq

각 응답은 다음 순서로 처리합니다.

  1. deposit_id, withdrawal_id, ledger_id를 기준으로 멱등 저장합니다.
  2. 가능하면 같은 DB 트랜잭션에서 next_cursor를 저장합니다.
  3. has_more가 true이면 즉시 다음 묶음을 조회합니다.
  4. 다음 polling은 저장한 cursor부터 재개합니다.

원장의 참조는 ref_id만으로 구분하지 않고 ref_type과 함께 사용합니다. ref_type=1000은 입금, ref_type=2000은 출금·내부이체입니다. amount_raw는 절댓값이므로 entry_type으로 증감 방향을 적용하고, entry_code로 원금과 수수료 분개를 구분합니다. 원장 합계와 잔액 비교에는 balance_after_raw를 사용합니다.

ID cursor는 새로 생성된 레코드만 반환하며 이후 상태 변경은 다시 반환하지 않습니다. 최종 상태가 아닌 입금과 출금은 상세 API로 별도 polling합니다. Append-only 원장은 cursor만으로 증분 동기화할 수 있습니다.

다음: Digital Payment 전체 흐름 구현

OOLIN은 BPMG가 제공하는 디지털자산 운영 인프라 제품입니다.