이 문서는 "위챗 미니프로그램을 어떻게 예쁘게 만들 것인가"를 다루지 않습니다.
우리가 만드는 것은 단발성 미니프로그램 하나가 아니라, 이후 한국·일본·동남아 마켓플레이스까지 이어질 다보리 공통 백엔드의 첫 번째 프론트엔드입니다. 지금 짜는 데이터 구조와 API 계약(contract)이 향후 12~18개월 사업 확장의 기반이 됩니다.
따라서 이번 위챗 미니프로그램 개발에서 절대 지켜야 할 원칙 1가지:
위챗 종속 코드와 비즈니스 로직을 분리한다. 위챗이 없어도, 다른 채널(카카오, 앱, 자체 웹)이 붙어도 백엔드는 손대지 않는다.
이 문서는 이 원칙을 실제 코드/조직 구조로 어떻게 구현할지 다룹니다.
┌─────────────────────────┐
│ WeChat Mini Program │ ← 한국 개발자 A + 베트남 개발자 담당
│ (Frontend, WXML/WXSS) │
└────────────┬─────────────┘
│ HTTPS REST/GraphQL (표준 JSON Contract)
▼
┌─────────────────────────┐
│ Dabory API Gateway │ ← 인증, 라우팅, Rate Limit, 로깅
└────────────┬─────────────┘
│
▼
┌─────────────────────────┐
│ Dabory Core Backend │ ← 한국 백엔드팀 담당
│ (Seller/Item/Order/ │
│ Stock/Payment/Member) │
└─────────────────────────┘핵심 설계 원칙: 미니프로그램은 "뷰(View)"일 뿐이다. 비즈니스 로직(가격 계산, 재고 차감, 정산)은 절대 프론트엔드(미니프로그램)에 두지 않는다. 위챗의 클라우드 함수(云函数)를 쓰더라도 이는 "게이트웨이 프록시" 역할만 하고, 실제 트랜잭션 로직은 다보리 백엔드에 둔다.
일반 웹/앱 개발과 다른 위챗 고유의 제약 3가지를 먼저 이해해야 합니다.
항목 | 일반 웹/앱 | 위챗 미니프로그램 |
|---|---|---|
실행 환경 | 브라우저/OS | 위챗 자체 런타임 (독자 JS 엔진, WXML/WXSS) |
도메인 | 자유 | 사전에 위챗에 등록한 도메인만 요청 가능 (request 화이트리스트) |
HTTPS | 선택 | 필수 (ICP 인증서 필요, 자체서명 불가) |
로그인 | OAuth 등 자유 | wx.login() → code → 서버에서 code2session 필수 |
결제 | PG사 자유 | 위챗페이만 가능, 반드시 서버 서명 필요 |
심사 | 없음/자율 | 위챗 심사(审核) 통과해야 배포, 카테고리별 자격증 요구 가능 |
배포 | 즉시 | 심사 후 반영, 재심사 리스크 상존 |
→ 개발 착수 전 반드시 확인: ICP 备案(비안) 완료 여부, 위챗 공중평台 기업 인증 완료 여부. 이게 안 되어 있으면 결제/도메인 화이트리스트 자체가 불가능합니다. 개발 착수와 별개로 이 행정 절차를 즉시 병행 착수해야 합니다 (통상 2~4주 소요).
구분 | 담당 영역 | 이유 |
|---|---|---|
한국 개발자 | API Gateway, 인증/세션, 위챗페이 연동, 데이터 모델 설계, 다보리 백엔드 연동 규격 정의 | 다보리 백엔드 구조를 이해하는 인원이 계약(Contract)을 설계해야 추후 확장(한국몰, 일본몰) 시 재설계 리스크가 없음 |
베트남 개발자 | 미니프로그램 UI(WXML/WXSS), 컴포넌트 단위 화면, 위챗 API(wx.*) 핸들링, 심사 대응용 화면 요건 처리 | 리소스 효율적 활용 + WXML/WXSS 컴포넌트 작업은 백엔드 구조 이해도가 낮아도 명세만 있으면 병렬 진행 가능 |
전술적 이유: 베트남 팀이 화면을 만들 때 백엔드 구조를 몰라도 되도록, 한국 팀이 API 명세서(OpenAPI/Swagger)를 먼저 확정해서 넘겨야 합니다. 이 명세서가 나오기 전까지 베트남 팀은 목업 데이터(mock JSON)로 화면만 먼저 개발합니다.
[Week 1]
한국팀: Dabory API 명세서 확정 (상품/주문/회원/재고)
베트남팀: 위챗 개발자 도구 세팅, 목업 데이터 기반 화면 뼈대 작업 시작
(병렬 진행 — 서로 블로킹 없음)
[Week 2-3]
한국팀: API Gateway 개발, wx.login → code2session 인증 플로우 구현
베트남팀: 목업 → 실 API 연동 시작 (상품 목록, 상세)
[Week 4]
한국팀: 위챗페이 결제 서명/콜백 처리
베트남팀: 주문/결제 화면 연동, 에러 핸들링
[Week 5]
공통: 통합 테스트, 위챗 심사 제출 준비[미니프로그램] [Dabory Gateway] [다보리 Backend]
│ │ │
│ wx.login() → code │ │
│──────────────────────────────▶ │
│ │ code + appid/secret │
│ │─────────────────────────▶│
│ │ (위챗 code2session 호출) │
│ │◀─────────────────────────│
│ │ openid, session_key 획득 │
│ │ → Dabory 자체 JWT 발급 │
│ Dabory JWT 반환 │ │
│◀────────────────────────────── │
│ 이후 모든 API에 JWT Bearer │ │
│──────────────────────────────▶ │주의 (전술적으로 매우 중요): session_key는 절대 클라이언트로 내려주지 않습니다. 위챗 openid도 미니프로그램 프론트엔드에 노출하지 않고, Dabory 자체 발급 JWT로만 통신합니다. 이렇게 해야 나중에 한국/일본 앱에서도 동일한 JWT 인증 체계를 재사용할 수 있습니다 (위챗 종속 차단).
미니프로그램이 백엔드에서 받는 상품 데이터는 중국 시장용으로 가공된 필드가 아니라 국가 중립 Master + CN Projection을 조합한 형태로 설계합니다.
json
{
"item_id": "M-000123",
"master": {
"sku": "SW-001",
"base_price_cny": 200,
"images": ["https://cdn.dabory.com/..."]
},
"market_projection": {
"country": "CN",
"name": "智能手表",
"price": 200,
"currency": "CNY",
"category_local": "电子产品",
"shipping_policy_id": "CN-STD-01"
}
}베트남 개발팀 전달 포인트: 화면 코딩 시 market_projection 객체의 필드만 바인딩하고, master 객체는 화면에 직접 노출하지 않는다 (추후 한국/일본 projection 추가 시 화면 로직 변경 없이 그대로 재사용 가능해야 함).
API | 메서드 | 설명 | 담당 |
|---|---|---|---|
| POST | code → Dabory JWT 발급 | 한국 |
| GET | 상품 목록 (market=CN projection) | 한국(설계)/베트남(연동) |
| GET | 상품 상세 | 한국(설계)/베트남(연동) |
| GET/POST | 장바구니 | 베트남 |
| POST | 주문 생성 | 한국(로직)/베트남(연동) |
| POST | 위챗페이 사전 결제 서명 생성 | 한국 (필수 서버사이드) |
| POST | 위챗 결제 콜백 수신 | 한국 (필수 서버사이드) |
| GET | 회원 정보 | 베트남 |
| GET | 주문 상태 조회 | 베트남 |
위챗 개발자 도구(微信开发者工具) 설치 및 다보리 테스트 계정으로 AppID 발급 확인
WXML(구조) / WXSS(스타일, CSS 서브셋) / JS(로직) / JSON(설정) 4종 세트 구조 숙지
Vant Weapp 또는 WeUI 같은 검증된 컴포넌트 라이브러리 사용 권장 (커스텀 UI 최소화로 심사 리스크 감소)
네트워크 요청은 반드시 wx.request()의 header에 Dabory JWT를 Bearer로 포함하고, 위챗 openid/session_key는 코드 내 어디에도 하드코딩하거나 저장하지 않는다.
로컬 저장(wx.setStorageSync)에는 민감정보(결제정보, 토큰 원문) 저장 금지 — 토큰은 만료시간 짧게 설정하고 갱신 로직으로 처리.
모든 API 응답은 명세서의 market_projection 필드 기준으로 바인딩 — 필드명을 임의로 변경하거나 프론트에서 재가공(가격 계산 등)하지 않는다.
페이지 간 상태 공유는 globalData 남용 대신 Store 패턴(예: mobx-miniprogram) 사용 — 이후 다보리 자체 렌더러로 이식할 때 재사용성 확보.
결제는 프론트에서 금액을 계산하지 않는다. 반드시 서버(/payments/wechatpay/prepay)가 내려주는 서명값을 그대로 wx.requestPayment()에 전달한다.
카테고리 선택 시 실제 판매 품목과 일치하는지 확인 (예: 화장품이면 化妆品일反 필요할 수 있음)
개인정보 처리방침(隐私政策) 페이지 필수 포함
위챗 로그인 외 과도한 권한 요청 금지 (위치정보 등은 실제 사용하는 화면에서만 요청)
위챗 전용 어댑터 계층 분리: wechat-adapter 모듈을 따로 두고, 다보리 코어 백엔드는 위챗의 존재 자체를 모르게 한다. (코어가 "채널"이라는 개념만 알고, "위챗"이라는 구체 구현을 모르게)
Core Backend (channel-agnostic)
▲
│ interface: ChannelAuthProvider, ChannelPaymentProvider
│
wechat-adapter (구현체) ← 향후 kakao-adapter, appstore-adapter 동일 패턴으로 추가위챗페이 서버사이드 로직은 반드시 별도 모듈로 캡슐화하여, 추후 한국 PG(토스페이먼츠 등) 붙일 때 동일 인터페이스(ChannelPaymentProvider)를 구현하도록 설계.
Rate limit / 로깅은 게이트웨이 레벨에서 처리하고 코어 백엔드에 위챗 관련 예외 처리 코드가 들어가지 않도록 한다.
item, seller, order 테이블에 country/channel 종속 컬럼을 직접 넣지 않는다 (→ 대신 item_market_projection, channel_binding 같은 별도 테이블로 분리)
Seller 하나가 여러 채널(위챗, 추후 한국몰)에 동시 노출될 수 있다는 전제로 FK 설계 (Seller-Channel N:M 관계)
안티패턴 | 왜 위험한가 |
|---|---|
미니프로그램 프론트에 가격/할인 계산 로직 삽입 | 위챗 앱에서만 동작 → 이후 한국/일본 프론트 이식 시 로직 중복·불일치 발생 |
| 다른 채널(한국 앱 등) 확장 시 회원 통합 불가능해짐 |
위챗 SDK 호출을 화면 컴포넌트 곳곳에 흩어서 작성 | 추후 Dabory Renderer로 이식 시 전체 재작성 필요 |
상품 데이터를 중국어/CNY로만 저장 | 국가 확장 시 전체 데이터 재구조화 필요 (마이그레이션 비용 급증) |
결제 금액을 프론트에서 계산해 서버로 전달 | 위챗 심사 반려 + 보안 취약점(금액 변조) |
베트남팀: 화면은 market_projection 데이터만 바라보고 만든다. 가격 계산, 세션 관리는 절대 프론트에서 하지 않는다.
한국팀: 위챗은 여러 채널 중 하나일 뿐이다. Adapter 패턴으로 격리하고, 코어 백엔드는 위챗을 몰라야 한다.
공통: 지금 짜는 API 계약과 데이터 스키마가 6개월 뒤 한국몰, 1년 뒤 마켓플레이스의 기반이 된다. "일단 되게만 만들자"는 이번 프로젝트에서는 특히 위험하다.
댓글쓰기