HandyCafe Docs
owner

세션 요금

HandyCafe는 인터넷 카페 또는 게이밍 센터에서 세션 비용을 계산하기 위해 구간 기반 요금 엔진을 사용합니다. 전체 세션에 단일 균일 요금을 적용하는 대신 엔진이 각 세션을 구간으로 나누고, 각 구간에 고유한 요금 컨텍스트를 적용합니다. 이 방식을 통해 세션이 여러 시간대 슬롯, 요금 변경, 일시 중지 또는 연결 끊김을 경험하더라도 정확한 청구가 보장됩니다.

핵심 개념

세부 사항을 살펴보기 전에 주요 용어를 정리합니다.

용어 정의
기본 시간당 요금 배율이 적용되기 전의 시간당 가격입니다. 설정 > 요금에서 설정합니다.
요금 슬롯 특정 배율을 가진 명명된 시간대입니다. 8개의 슬롯이 있으며 각각 색상으로 구분됩니다.
배율 기본 요금에 적용되는 계수입니다. 1.0 = 표준 가격, 0.5 = 반값, 2.0 = 두 배 가격.
구간 세션 내에서 요금 컨텍스트(슬롯, 배율, 기본 가격)가 변경되지 않는 연속적인 시간대입니다.
정산 세션 종료 시 고객이 지불해야 할 금액을 결정하는 최종 계산입니다.

기본 시간당 요금

기본 시간당 요금은 모든 요금 계산의 기초입니다. 설정 > 요금에서 설정하며 PC 사용의 표준 시간당 가격을 나타냅니다.

모든 내부 계산은 최소 통화 단위(예: USD의 경우 센트, TRY의 경우 쿠루쉬)를 사용합니다. 기본 요금이 시간당 $3.00인 경우 내부 값은 300입니다. 이를 통해 부동 소수점 반올림 문제를 제거합니다.

이중 통화 지원

HandyCafe는 기본 통화와 로컬 통화를 환율(FX)과 함께 지원합니다. 국제 가격과 현지 가격이 다른 국가에서 운영하는 경우 다음과 같이 설정합니다.

  • 기본 통화. 내부 요금 계산에 사용되는 통화입니다.
  • 로컬 통화. 고객에게 표시되고 결제에 사용되는 통화입니다.
  • FX 환율. 기본 통화와 로컬 통화 간의 변환 계수입니다.

두 통화가 같은 경우 FX 환율은 1.0으로 처리되며 효과가 없습니다.

요금 슬롯

각각 다른 요금 등급을 나타내는 8개의 색상 구분 요금 슬롯이 있습니다.

슬롯 색상 일반적인 용도
블루 파란색 표준 요금
오렌지 주황색 저녁 또는 주말 할증
레드 빨간색 피크 시간대 프리미엄
그린 초록색 비수요 시간대 할인
청록색 학생 또는 회원 요금
그레이 회색 공휴일 또는 특별 요금
시안 하늘색 야간 요금
에메랄드 에메랄드색 프로모션 요금

각 슬롯에는 세 가지 속성이 있습니다.

  1. 이름. 설명적 라벨입니다(예: "피크 시간대" 또는 "야간 할인").
  2. 배율. 기본 요금을 수정하는 소수값입니다. 일반적인 값으로는 1.0(표준), 0.5(반값), 1.5(50% 할증), 2.0(두 배)이 있습니다. 배율은 0 이상이어야 합니다.
  3. 스케줄 데이터. 슬롯이 적용되는 요일과 시간을 정의하는 내부 표현입니다. 스케줄 그리드를 통해 자동으로 관리됩니다.

슬롯은 개별적으로 활성화 또는 비활성화할 수 있습니다. 비활성화된 슬롯은 요금 엔진에서 무시됩니다.

스케줄 그리드

요금 스케줄은 7일 x 24시간 행렬(총 168개의 1시간 블록)입니다. 각 블록은 하나의 요금 슬롯에 배정됩니다. 스케줄은 특정 시점에 적용되는 배율을 결정합니다.

그리드는 설정 > 요금 스케줄에서 구성합니다. 요일은 월요일부터 일요일까지, 시간은 00:00부터 23:00까지입니다. 시간 블록에 슬롯을 배정하려면 그리드에서 블록을 선택하고 원하는 슬롯 색상을 선택합니다.

엔진이 스케줄을 읽는 방식

내부적으로 각 시간 블록은 스케줄 데이터의 위치에 매핑됩니다. 엔진은 활성화된 각 슬롯의 스케줄 데이터를 확인하여 특정 요일과 시간에 활성화된 슬롯을 결정합니다.

특정 시간에 슬롯이 설정되지 않은 경우 엔진은 배율 1.0의 기본 요금으로 대체됩니다.

요금 스케줄 기능이 완전히 비활성화된 경우(설정 > 요금) 모든 세션은 시간에 관계없이 1.0 배율의 기본 요금을 사용합니다.

요금 구간

구간은 세션 내에서 요금 컨텍스트가 변경되지 않는 연속적인 시간대입니다. 요금 엔진은 다음과 같은 경계 이벤트가 발생할 때마다 새 구간을 생성합니다.

경계 트리거
session_start 새 세션이 시작됩니다
session_stop 세션이 종료됩니다
pause 캐셔가 세션을 일시 중지합니다
resume 캐셔가 일시 중지된 세션을 재개합니다
tick 시계가 다른 요금 슬롯으로 시간 경계를 넘습니다
disconnect 클라이언트 PC의 네트워크 연결이 끊깁니다
offline 클라이언트 PC가 오프라인 상태가 됩니다
load_recovery 서버가 재시작되어 실행 중인 세션을 복구합니다

각 구간은 다음을 기록합니다.

필드 설명
session_id 이 구간이 속한 세션
segment_start 구간이 시작된 Unix 타임스탬프
segment_end 구간이 종료된 Unix 타임스탬프(아직 열려 있으면 null)
pricing_slot_id 활성 요금 슬롯의 ID(예: "blue", "red" 또는 "base")
multiplier 요금 슬롯의 배율 값
base_price_snapshot 구간이 열린 시점에 캡처된 기본 시간당 요금
amount 이 구간의 계산된 비용(구간이 닫힐 때 설정)
boundary_reason 이 구간이 생성된 이유

기본 가격 스냅샷이 필요한 이유

base_price_snapshot은 구간이 열리는 정확한 시점의 기본 시간당 요금을 캡처합니다. 관리자가 세션 도중 기본 요금을 변경할 수 있기 때문에 이것이 중요합니다. 스냅샷을 통해 각 구간은 시작 시 유효했던 요금을 사용하여 공정하고 감사 가능한 청구를 보장합니다.

비용 공식

단일 구간의 비용은 다음과 같이 계산됩니다.

amount = ceil( (base_price_snapshot * multiplier * duration_seconds) / 3600 )

보다 정확하게는 엔진이 부동 소수점 오류를 방지하기 위해 스케일링된 정수 연산을 사용합니다.

  1. 배율은 고정 소수점 정수(1,000,000 곱셈)로 스케일링됩니다.
  2. 계산은 전적으로 128비트 정수로 수행됩니다.
  3. 올림 나눗셈이 사용됩니다. 결과는 항상 다음 최소 단위로 올림됩니다.

분 단위 계산

설정 > 요금에서 "분 단위 계산" 옵션이 활성화된 경우 공식이 약간 변경됩니다.

amount = ceil( (base_price_snapshot * multiplier * used_minutes) / 60 )

여기서 used_minutes = ceil(duration_seconds / 60)입니다. 즉, 부분 분이라도 1분으로 계산됩니다.

세션 총액 계산

세션 총 비용은 세 단계로 계산됩니다.

1단계: 모든 구간 합산

raw_total = 모든 닫힌 구간 금액의 합 + 열린 구간의 부분 금액

열린 구간의 부분 금액은 현재 타임스탬프를 구간 종료로 사용하여 위의 공식으로 실시간 계산됩니다.

2단계: 반올림 적용

rounded_total = round_up(raw_total, rounding_step)

반올림은 항상 올림(천장)으로 수익을 보호합니다. 반올림 단위는 설정 > 요금에서 구성할 수 있습니다. 예를 들어 반올림 단위가 50(소수점 2자리 통화에서 $0.50)이면 원시 합계 $3.27은 $3.50으로 올림됩니다.

3단계: 시작 수수료 최소값 적용

final_total = max(rounded_total, startup_fee)

시작 수수료는 세션 시간에 관계없이 모든 세션에 대한 최소 요금입니다. 올림된 합계가 시작 수수료보다 적으면 시작 수수료가 대신 청구됩니다.

정산

정산은 세션의 청구를 마무리하는 과정입니다. 두 가지 정산 단계가 있습니다.

시작 정산 (선불만 해당)

선불 세션이 시작되면 "시작" 정산 레코드가 생성됩니다. 여기에는 다음이 포함됩니다.

  • 계산된 비용. 구매한 시간에 대해 시스템이 계산한 비용입니다.
  • 청구 금액. 고객이 실제로 지불한 금액입니다(일반적으로 계산된 비용과 동일).

"구매 시 잠금" 선불 모드의 경우 이 잠긴 금액이 세션 중 요금 변경에 관계없이 세션 비용을 결정합니다.

종료 정산

세션(선불 또는 후불)이 종료되면 "종료" 정산 레코드가 생성됩니다.

필드 설명
계산된 비용 모든 요금 구간에서 시스템이 계산한 총액
청구 금액 실제로 청구된 금액(기본값은 계산된 비용)
수동 조정 금액 캐셔가 가격을 수동으로 조정한 경우 원래 계산된 비용이 여기에 보존됩니다
수수료율 결제 수단 수수료율(퍼센트)
commission_fee 계산된 수수료 금액
fixed_fee 결제 수단 고정 수수료
computed_timeline_snapshot 세션의 모든 요금 구간에 대한 JSON 기록

타임라인 스냅샷은 비용이 구간별로 정확히 어떻게 계산되었는지 보여주는 완전한 감사 추적을 제공합니다.

결제 수단 수수료

각 결제 수단에는 두 가지 유형의 수수료가 있을 수 있습니다.

수수료 (베이시스 포인트)

수수료율은 퍼센트로 표현됩니다. 수수료는 이 비율을 청구 금액에 적용하여 계산됩니다.

예시: 청구 금액이 $10.00(1000 최소 단위)이고 결제 수단의 수수료율이 2.5%인 경우, 수수료는 $0.25(25 최소 단위)입니다.

고정 수수료

금액에 관계없이 거래당 부과되는 정액 수수료입니다. 예를 들어 신용카드 처리 수수료 $0.30입니다.

두 수수료 모두 정보성입니다. 해당 결제 수단을 수용하는 데 드는 비즈니스 비용을 나타냅니다. 정산에 기록되지만 고객 청구서에 추가되지는 않습니다.

부가세 (VAT)

부가세는 설정 > 요금에서 퍼센트(0~100%)로 구성됩니다. 계산된 세션 금액에 추가로 적용됩니다.

VAT = 청구 금액 x (부가세율 / 100)

부가세 금액은 결제 대화 상자에 별도로 표시되어 캐셔가 세금 내역을 확인할 수 있습니다.

선불 요금 모드

세션 관리에서 설명한 바와 같이 선불 세션은 두 가지 요금 모드를 지원합니다.

구매 시 잠금

선불 세션이 시작되면 "시작" 정산이 청구 금액을 잠급니다. 세션 기간 동안 다음이 적용됩니다.

  • 세션 종료 시간은 구매한 시간(분)에 기반하여 고정됩니다.
  • 요금 스케줄이 변경되더라도 세션은 잠긴 시간이 만료될 때까지 계속됩니다.
  • 종료 정산은 시작 정산의 잠긴 금액을 사용합니다.

라이브 스케줄

세션이 다른 요금 슬롯을 통과할 때 비용이 실시간으로 조정됩니다.

  • 세션이 더 저렴한 슬롯에 진입하면 잔여 시간이 늘어납니다(고객이 같은 금액으로 더 많은 시간을 받음).
  • 세션이 더 비싼 슬롯에 진입하면 잔여 시간이 줄어듭니다.
  • 종료 정산은 세션 전체에 걸쳐 적용된 실제 요금을 반영합니다.

소수점 자릿수

통화 표시에 사용되는 소수점 자릿수는 구성 가능합니다(소수점 2~4자리). 이는 UI에서 금액이 표시되는 방식에 영향을 미치지만 내부 최소 단위 계산은 변경하지 않습니다.

예시: 소수점 2자리에서 $3.50은 "3.50"으로 표시됩니다. 소수점 3자리에서는 "3.500"으로 표시됩니다.

실전 예제

예제 1: 단순 후불 세션

  • 기본 요금: 시간당 $3.00 (300 최소 단위)
  • 스케줄: 표준 슬롯 (배율 1.0) 하루 종일
  • 세션: 오전 10:00 ~ 오전 11:30 (90분)
  • 시작 수수료: $0.50

계산:

구간 1: (300 * 1.0 * 5400) / 3600 = 450 최소 단위 ($4.50)
합계: max($4.50, $0.50) = $4.50

예제 2: 두 슬롯에 걸친 세션

  • 기본 요금: 시간당 $4.00 (400 최소 단위)
  • 스케줄: 표준 (1.0) 10:0012:00, 해피 아워 (0.5) 12:0014:00
  • 세션: 오전 11:00 ~ 오후 1:00 (120분)
  • 시작 수수료: $1.00

계산:

구간 1 (11:00-12:00, 표준): (400 * 1.0 * 3600) / 3600 = 400 ($4.00)
구간 2 (12:00-13:00, 해피 아워): (400 * 0.5 * 3600) / 3600 = 200 ($2.00)
합계: $4.00 + $2.00 = $6.00
최종: max($6.00, $1.00) = $6.00

예제 3: 일시 중지가 있는 세션

  • 기본 요금: 시간당 $2.00 (200 최소 단위)
  • 스케줄: 표준 슬롯 (배율 1.0) 하루 종일
  • 세션: 시작 10:00, 일시 중지 10:30, 재개 11:00, 종료 11:45
  • 시작 수수료: $0.50

계산:

구간 1 (10:00-10:30, 활성): (200 * 1.0 * 1800) / 3600 = 100 ($1.00)
일시 중지 기간 (10:30-11:00): 무료
구간 2 (11:00-11:45, 활성): (200 * 1.0 * 2700) / 3600 = 150 ($1.50)
합계: $1.00 + $1.50 = $2.50
최종: max($2.50, $0.50) = $2.50

다음 단계