한눈에 보기
- 브랜드가 부담하는 동일한 할인 비용이 Shopee에서는 'Seller Voucher', Qoo10에서는 'Cart Discount', Amazon에서는 'Promotion'이라는 서로 다른 이름으로, 서로 다른 리포트에 표시됩니다.
- 이 차이를 if-else 코드로 대응하는 방식 리포트 구조는 마켓플레이스가 규칙을 변경하는 순간 문제가 생깁니다. 오류가 겉으로 드러나지 않아 월 마감 때가 되어서야 발견되는 경우가 많습니다.
- Palantir는 Foundry에서 데이터가 '무엇을 담고 있는지'가 아니라 '무엇을 의미하는지'를 정의하는 온톨로지 계층으로 이 문제를 해결했습니다.
- 환불을 원거래의 수정이 아닌 독립된 재무 이벤트로 정의하면, 비즈니스 규칙이 개별 스크립트에 흩어지지 않고 데이터 모델 안에서 일관되게 유지됩니다.
- 포트원 클로즈는 이 온톨로지 구조를 핵심에 두고 개발되고 있습니다. 마켓플레이스가 리포트 포맷을 바꿔도 매핑 계층만 수정하면 되고, 비즈니스 로직은 영향을 받지 않습니다.
반품 요청이 접수됩니다. 마켓플레이스는 '무조건 반품' 정책에 따라 이미 환불을 완료했고, 구매자는 상품을 발송하기도 전에 환불을 받았습니다. 재무팀은 해당 주문을 매출 취소 대상으로 처리합니다.
그런데 상품은 아직 도착하지 않았습니다. K-IFRS 기준으로 매출 취소는 환불 시점이 아니라 반품 완료 시점에 인식해야 하는데, 이 두 시점은 서로 다른 정산 기간에 속할 수 있습니다. 여기에 마켓플레이스가 뒤늦게 반품 요청을 거절하면, 환불은 그대로 유지되지만 매출 취소는 되돌려야 합니다.
주문 하나를 정확히 추적하려면 여러 이벤트, 여러 시스템, 여러 시점에 걸쳐 상태 변화를 따라가야 합니다. 그러려면 각 상태가 무엇을 의미하는지에 대한 공통된 기준이 필요합니다. 문제는 마켓플레이스마다 그 기준이 전부 다르다는 점입니다.
같은 비용, 다른 이름
브랜드가 결제 시점에 부담하는 할인 비용이 Shopee에서는 'Seller Voucher'라는 이름으로 Income Report에 주문 단위로 표시됩니다.
같은 항목이 Qoo10에서는 QSM의 'Cart Discount'로 분류됩니다. Cart Discount Detail 탭에서만 조회할 수 있고, 이 화면의 수치가 API로 조회한 값과 일치하지 않는 경우도 있습니다. Amazon에서는 프로모션 할인이 Settlement Report의 Promotion 행에 표시되는데, 리포트만 봐서는 그 비용을 Amazon이 부담했는지 브랜드가 부담했는지 구분할 수 없습니다.
같은 성격의 비용인데 이름이 세 개, 확인해야 하는 리포트가 세 곳이고, 비용 부담 주체를 파악할 수 있는 수준도 제각각입니다. 공통된 정의가 없으니 이 비용을 처리하는 쿼리와 회계 규칙도 각각 다른 곳에 다른 방식으로 작성되고, 일관성을 보장할 방법이 없습니다.
코드로 처리하면 되지 않을까요?
개발자가 떠올리는 가장 자연스러운 해결책은 이 차이를 코드로 처리하는 것입니다. "마켓플레이스가 shopee이고 voucher_type이 seller_voucher면 총매출에서 차감한다" 같은 조건문을 작성하는 방식입니다.
이 방식은 Shopee가 분기 업데이트로 Income Report 구조를 변경하기 전까지는 잘 작동합니다. 하지만 구조가 바뀌면 조건문이 더 이상 동작하지 않는데, 데이터 수집 자체는 계속되기 때문에 차감이 누락되고 있다는 사실을 알아차리기 어렵습니다. 월 마감 때가 되어서야 발견되는 경우가 많습니다.
포트원 클로즈를 만들면서 30곳 이상의 브랜드와 이커머스 운영 전문 기업을 인터뷰했는데, 공통된 이야기를 들을 수 있었습니다. 자체 구축 시스템은 마켓플레이스가 안정적일 때만 유지되는데, 글로벌 마켓플레이스는 변경이 잦습니다. 리포트 포맷이나 탭 구조가 바뀔 때마다 코드 수정, 배포, 테스트를 반복해야 하고, 그 사이 잘못된 숫자가 계속 쌓입니다.
기성 솔루션도 반대 방향에서 같은 한계에 부딪힙니다. 일반적인 케이스는 폭넓게 처리하지만, 글로벌 마켓플레이스별 세부 사항까지 따라가려다 보면 결국 고객사마다 별도로 커스터마이징해야 하는 상황이 됩니다. 규칙 파일은 계속 늘어나고, 처음 만든 담당자는 퇴사하고, 결국 아무도 전체 구조를 파악하지 못하는 시스템이 됩니다.
데이터의 '이름'이 아닌 '의미'를 정의하는 방식
Palantir는 하나의 전제 위에 Foundry를 설계했습니다. 데이터는 무엇을 담고 있는지가 아니라 무엇을 의미하는지를 정의할 때 비로소 제대로 활용할 수 있다는 것입니다.
Foundry의 온톨로지는 데이터 사전이나 스키마 문서가 아닙니다. 원본 데이터 소스와 이를 사용하는 모든 애플리케이션 사이에 위치한 실행 계층이며, 어떤 애플리케이션도 원본 테이블에 직접 접근하지 않습니다. 온톨로지가 곧 데이터와 애플리케이션 사이의 계약(contract)인 셈입니다.
이 모델은 네 가지 요소로 구성됩니다.
- 객체(Object): Order, Return, Fee, SKU 같은 도메인 엔티티입니다. 데이터베이스 테이블이 아니라 재무팀이 실제로 비즈니스를 바라보는 개념 단위로 정의됩니다.
- 속성(Property): return_status, fee_type, funded_by 같은 세부 정보입니다. 타입과 제약 조건이 정의되어 있고, 원본 데이터가 불분명한 경우에는 불분명하다는 사실 자체를 기록합니다. Amazon Settlement Report는 Lightning Deal 프로모션의 부담 주체를 알려주지 않기 때문에, 잘못된 가정을 그대로 반영하는 대신 funded_by = UNKNOWN으로 기록합니다.
- 링크(Link): 객체 사이의 관계입니다. 환불과 그 대상이 되는 원 주문, 마켓플레이스 주문과 물류사의 배송 기록을 연결합니다. 링크를 한 번 정의해두면 이후 모든 시스템이 별도 작업 없이 그 관계를 그대로 활용할 수 있습니다.
- 관계(Relationship): 비즈니스 규칙이 정의되는 자리입니다.
비즈니스 규칙은 데이터 모델에 담겨야 합니다
포트원 클로즈의 온톨로지에서 환불은 원 주문 금액에서 차감하는 값이 아닙니다. refund_of 링크로 원 주문에 연결된 독립적인 RevenueEvent이며, 별도의 대사 프로세스를 거칩니다.
원래의 SALE 레코드는 검증 이력을 유지한 채 VERIFIED 상태로 남고, REFUND는 별도의 상태 관리 절차에 따라 따로 처리됩니다. '환불은 원거래의 수정이 아니라 독립된 재무 이벤트'라는 규칙이 개별 리포트 스크립트가 아니라 데이터 모델 자체에 정의되어 있기 때문에, 이 규칙을 모르는 담당자가 작성한 쿼리에 의해 임의로 덮어써지지 않습니다.
Amazon이 리저브 기간 동안 지급을 보류한 이연 정산 금액은 기준 저장소(canonical store)에 아예 기록하지 않습니다. '기록하지 않는다'는 것 자체가 매출 인식 정책이 되는 구조입니다. 적용을 잊어버릴 수 있는 필터가 애초에 존재하지 않고, 기준 저장소에 있는 데이터는 그 자체로 인식된 매출이 됩니다.
같은 원리가 3PL 데이터 연결에도 적용됩니다. K-IFRS 매출 인식의 기준이 되는 배송일 정보는 풀필먼트 파트너가 갖고 있고, 수수료 내역과 반품 상태는 마켓플레이스가 갖고 있습니다. 두 데이터를 연결하려면 마켓플레이스의 order_id와 3PL의 reference_no가 같은 주문을 가리킨다는 사실을 알아야 하는데, 이것이 바로 링크입니다. 한 번 정의해두면 매출 인식일이 필요한 모든 작업에서 필드 매핑을 처음부터 다시 확인할 필요가 없습니다.
참고로 이런 구조는 AI 에이전트가 재무 데이터를 안정적으로 다루기 위한 전제 조건이기도 합니다. 이 주제는 별도의 글에서 자세히 다루겠습니다.
포트원 클로즈가 해결합니다
포트원 클로즈 역시 위의 문제들을 직접 겪었고, 그래서 온톨로지 실행 계층을 핵심에 두고 개발하고 있습니다.
표준 데이터 모델이 Shopee, Qoo10, Amazon, Rakuten, TikTok Shop 전반의 객체, 속성, 링크, 상태 관리 규칙을 정의합니다. 마켓플레이스가 리포트 포맷을 바꾸거나 새로운 수수료 항목을 추가하더라도 수정되는 것은 매핑 계층뿐입니다. 비즈니스 로직은 그대로 유지되고, 이를 사용하는 시스템도 영향을 받지 않습니다.
PortOne Close 도입문의 →



.png&w=3840&q=75)
