주문은 100건인데 정산은 98건이다 · 정산 대사와 수수료 · 실습
정산 파일을 대사하고 지급액 내기
목표
우리 매출 기록과 결제대행사가 보내 온 정산 파일을 맞춰 보고, 어긋난 건을 네 가지 모양으로 갈라냅니다. 그다음 수수료를 빼고 판매자에게 나갈 돈과 지급을 멈춰야 할 돈을 계산합니다.
왜 중요한가
정산은 "우리가 받을 돈" 을 확정하는 일입니다. 그런데 우리 기록과 결제대행사 기록은 절대 저절로 일치하지 않습니다. 서로 다른 시스템이 서로 다른 시각에 서로 다른 사건을 적기 때문입니다. 그래서 매일 두 파일을 맞춰 보는 대사 를 하고, 어긋난 건만 사람이 봅니다. 대사가 없으면 틀린 금액이 그대로 판매자에게 나가고, 그 돈은 회수하기가 대단히 어렵습니다.
어긋남에는 몇 가지 정해진 모양이 있고, 모양마다 원인과 처방이 다릅니다. 우리에만 있으면 매출을 잘못 올렸거나 상대가 아직 안 보낸 것이고, 상대에만 있으면 통지를 놓쳤거나 같은 주문이 두 번 처리된 것이고, 금액만 다르면 부분 취소가 한쪽에만 반영된 것이고, 날짜가 다르면 자정을 걸친 것입니다. 이 네 가지를 한 덩어리로 "불일치 N건" 이라고 보고하면 아무도 무엇을 해야 할지 모릅니다.
날짜 문제는 특히 조용합니다. 자정 직전 주문은 우리 쪽에서는 어제 매출이고 결제대행사 쪽에서는 오늘 승인입니다. 하루치만 놓고 대사하면 한쪽에만 있는 것처럼 보여서 "누락" 으로 잡히지만, 다음 날 파일을 함께 보면 짝이 맞습니다. 진짜 없는 것과 하루 늦게 오는 것을 구별하지 못하면 매일 같은 건을 다시 조사하게 됩니다.
마지막은 돈의 방향입니다. 우리가 플랫폼이면 고객이 낸 돈 전부가 우리 것이 아닙니다. 판매 수수료와 결제 수수료를 빼고 나머지를 판매자에게 지급합니다. 그래서 화면에 찍히는 거래액과 우리 장부의 매출은 다른 숫자이고, 세금계산서 관점에서도 다릅니다. 중개만 하는 플랫폼은 상품 판매액 전체가 아니라 받은 수수료를 자기 매출로 보는 것이 보통이지만, 총액으로 볼지 순액으로 볼지는 회계 기준과 계약 내용이 정합니다. 시스템이 할 일은 두 숫자를 모두 남겨 두는 것 입니다. 거래액만 남기고 수수료를 남기지 않으면 나중에 어느 쪽으로도 다시 계산할 수 없습니다.
이 실습이 정한 값
수수료율·지급 주기·보류 기준은 계약과 회사 정책이 정합니다. 이 실습에서는 아래로 못 박습니다.
- 대사의 열쇠는
pg_tid와txn_type두 개를 함께 쓴 것입니다. 승인번호만으로는 결제와 취소가 한 덩어리가 됩니다. - 짝이 있고 금액도 같으면
matched, 짝은 있는데 금액이 다르면amount_diff, 우리에만 있으면only_ours, 결제대행사에만 있으면only_pg. only_ours는 9/2 파일을 함께 보고 다시 가릅니다. 거기 있으면date_shift, 없으면unresolved.only_pg는 거래 종류로 가릅니다.CANCEL이면MISSING_CANCEL(취소가 우리에게 닿지 않음),PAY인데 그 주문에 이미 짝이 맞은 결제가 있으면DUP_AUTH(같은 주문의 두 번째 승인).- 수수료율은 1,000분율 정수입니다.
sellers.csv의commission_permille이 100이면 10.0% 입니다. 결제 수수료는 25, 즉 2.5% 입니다. - 판매 수수료 = 판매자 순매출 ×
commission_permille÷ 1000, 원 미만 버림. 결제 수수료 = 판매자 순매출 × 25 ÷ 1000, 원 미만 버림. 지급 예정액 = 순매출 − 판매 수수료 − 결제 수수료. - 순매출은 결제 금액에서 취소 금액을 뺀 값입니다. 대사가 어긋난 주문(
amount_diff·unresolved·only_pg에 걸린 주문)은 보류 로 빼고, 날짜만 갈린 주문은 다음 회차 이월 로 뺍니다. 한 주문이 둘 다에 걸리면 보류가 이깁니다.
단계
1. 오른쪽 예시의 생성기를 /root/com/make_settle.py 로 저장하고 python3 make_settle.py 로 실행하세요. sales.csv(우리 기록 30줄), pg_0901.csv(29줄), pg_0902.csv(6줄), sellers.csv(판매자 5명)가 만들어집니다.
2. /root/com/recon_count.txt 에 sales_rows=, sales_pay=, sales_cancel=, pg_rows=, pg_pay=, pg_cancel=, sales_net=, pg_net=, net_gap= 아홉 줄을 적으세요. 순매출은 결제 합에서 취소 합을 뺀 값입니다.
3. 짝이 맞은 거래를 /root/com/matched.csv 에 pg_tid,txn_type,amount 머리글로 적으세요.
4. 우리 기록에만 있는 거래를 /root/com/only_ours.csv 에 row_id,pg_tid,order_id,txn_type,amount 머리글로 적으세요.
5. 결제대행사 파일에만 있는 거래를 /root/com/only_pg.csv 에 pg_tid,order_id,txn_type,amount,kind 머리글로 적으세요. kind 는 MISSING_CANCEL 또는 DUP_AUTH 입니다.
6. 금액이 다른 거래를 /root/com/amount_diff.csv 에 pg_tid,order_id,ours,pg,gap 머리글로 적으세요. gap 은 우리 금액에서 결제대행사 금액을 뺀 값입니다.
7. 9/2 파일에서 짝을 찾은 거래를 /root/com/date_shift.csv 에 pg_tid,order_id,amount,pg_date 머리글로, 어느 파일에도 없는 거래를 /root/com/unresolved.csv 에 pg_tid,order_id,amount 머리글로 적으세요.
8. 판매자별 지급 예정액을 /root/com/payout.csv 에 seller_id,net_amount,commission,pg_fee,payout 머리글로 적고, /root/com/payout.txt 에 settled_orders=, hold_orders=, defer_orders=, commission_total=, pg_fee_total=, payout_total=, hold_total=, defer_total= 여덟 줄을 적으세요.
9. /root/com/settle_report.md 에 ## 대사 결과, ## 어긋남의 네 가지 모양, ## 날짜가 갈린 거래, ## 수수료와 지급, ## 재발 방지 다섯 절로 보고서를 쓰세요.
참고
- 두 파일을 각각
{(pg_tid, txn_type): 행}사전으로 만들어 두면 나머지는 집합 연산입니다. - 흔한 실수 1: 승인번호만으로 짝짓는 것. 같은 승인번호에 결제와 취소가 각각 오므로 거래 종류를 함께 열쇠로 써야 합니다.
- 흔한 실수 2: 어긋난 건을 한 덩어리로 세는 것. 모양마다 다음에 할 일이 다르므로 따로 세어야 보고가 됩니다.
- 흔한 실수 3: 수수료율을 실수로 계산하는 것.
0.08은 이진 부동소수점으로 정확히 표현되지 않습니다. 1,000분율 정수와//로 계산하세요.
단계 9개
- 우리 기록과 결제대행사 파일 만들기
- 대사 전에 얼마나 벌어져 있는지 재기
- 승인번호와 거래 종류로 짝짓기
- 우리에만 있는 거래 뽑기
- 결제대행사에만 있는 거래 가르기
- 금액만 다른 거래 뽑기
- 다음 날 파일까지 넓혀 짝 찾기
- 수수료를 빼고 지급 예정액 내기
- 정산 대사 보고서 쓰기