# -*- coding: utf-8 -*- """支付子应用 ORM:算力充值订单 + 活动报名订单 + OPC 收款绑定 + 分账流水。 (落平台主库,alembic 统一迁移;新表由 create_all 幂等创建。) """ from __future__ import annotations from sqlalchemy import Integer, String, Text from sqlalchemy.orm import Mapped, mapped_column from ..infrastructure.db import Base class ComputeRechargeOrder(Base): """算力充值订单(微信支付 V3)。 状态机:pending → paid(支付成功,本地终态)→ credited(引擎到账完成); pending 超时未支付 → closed;到账异常 → failed(待人工/对账补单)。 """ __tablename__ = "compute_recharge_orders" id: Mapped[str] = mapped_column(String, primary_key=True) # cr_ order_no: Mapped[str] = mapped_column(String, unique=True, index=True) # CR__,微信 out_trade_no user_id: Mapped[str] = mapped_column(String, default="", index=True) # 平台 users.id username: Mapped[str] = mapped_column(String, default="", index=True) # 平台/引擎用户名(充值归集键) engine_user_id: Mapped[int] = mapped_column(Integer, default=0) # 引擎用户 id(下单时解析缓存,0=待解析) target_type: Mapped[str] = mapped_column(String, default="user", index=True) # 到账目标:user(个人配额) | company(企业余额) target_id: Mapped[str] = mapped_column(String, default="", index=True) # 到账目标 id:users.id 或 park_companies.id package_id: Mapped[str] = mapped_column(String, default="") # 套餐 id;空 = 自由金额 amount_fen: Mapped[int] = mapped_column(Integer, default=0) # 实付金额(分,微信口径) quota_micro: Mapped[int] = mapped_column(Integer, default=0) # 到账微元 = amount_fen//100 * 1_000_000 bonus_quota_micro: Mapped[int] = mapped_column(Integer, default=0) # 套餐赠送微元 client_type: Mapped[str] = mapped_column(String, default="native") # native(扫码) | jsapi(小程序) appid: Mapped[str] = mapped_column(String, default="") # 下单所用 appid(对账依据) status: Mapped[str] = mapped_column(String, default="pending", index=True) # pending|paid|credited|closed|failed prepay_id: Mapped[str] = mapped_column(String, default="") # 微信预支付单号(jsapi) transaction_id: Mapped[str] = mapped_column(String, default="", index=True) # 微信支付单号 code_url: Mapped[str] = mapped_column(String, default="") # Native 二维码内容 expires_at: Mapped[str] = mapped_column(String, default="") # 过期时刻(ISO,超时未付 → closed) paid_at: Mapped[str] = mapped_column(String, default="") credited_at: Mapped[str] = mapped_column(String, default="") # 引擎到账完成时刻 notify_payload: Mapped[str] = mapped_column(Text, default="") # 回调/查单原始报文(JSON 串,排查用) created_at: Mapped[str] = mapped_column(String, default="", index=True) updated_at: Mapped[str] = mapped_column(String, default="") class EventOrder(Base): """活动报名订单(微信支付 V3,课程/沙龙定价)。 状态机与充值订单一致:pending → paid(支付成功)→ credited(报名确认完成); pending 超时未支付 → closed;确认异常 → failed(对账补单)。 """ __tablename__ = "event_orders" id: Mapped[str] = mapped_column(String, primary_key=True) # ev_ order_no: Mapped[str] = mapped_column(String, unique=True, index=True) # EV__,微信 out_trade_no booking_id: Mapped[str] = mapped_column(String, default="", index=True) # bookings.id event_id: Mapped[str] = mapped_column(String, default="", index=True) # events.id event_title: Mapped[str] = mapped_column(String, default="") user_id: Mapped[str] = mapped_column(String, default="", index=True) # 平台 users.id username: Mapped[str] = mapped_column(String, default="", index=True) openid: Mapped[str] = mapped_column(String, default="") # JSAPI 支付 openid(下单人) amount_fen: Mapped[int] = mapped_column(Integer, default=0) # 实付金额(分) client_type: Mapped[str] = mapped_column(String, default="jsapi") appid: Mapped[str] = mapped_column(String, default="") status: Mapped[str] = mapped_column(String, default="pending", index=True) # pending|paid|credited|closed|failed prepay_id: Mapped[str] = mapped_column(String, default="") transaction_id: Mapped[str] = mapped_column(String, default="", index=True) expires_at: Mapped[str] = mapped_column(String, default="") paid_at: Mapped[str] = mapped_column(String, default="") credited_at: Mapped[str] = mapped_column(String, default="") notify_payload: Mapped[str] = mapped_column(Text, default="") created_at: Mapped[str] = mapped_column(String, default="", index=True) updated_at: Mapped[str] = mapped_column(String, default="") class PaymentBinding(Base): """OPC 收款绑定(微信服务商分账接收方)。 bind_type: - personal:个人绑定 → PERSONAL_OPENID 分账到 OPC 微信零钱 - merchant:商户绑定 → 特约商户进件生成子商户号 sub_mchid → MERCHANT_ID 接收方 状态机:applying(商户进件中)→ active(可接收分账)→ disabled / rejected。 """ __tablename__ = "payment_bindings" id: Mapped[str] = mapped_column(String, primary_key=True) # pb_ user_id: Mapped[str] = mapped_column(String, default="", index=True) # 平台 users.id(OPC 主体) bind_type: Mapped[str] = mapped_column(String, default="personal") # personal | merchant openid: Mapped[str] = mapped_column(String, default="") # personal:小程序 openid real_name: Mapped[str] = mapped_column(String, default="") # personal:实名(微信校验) sub_mchid: Mapped[str] = mapped_column(String, default="", index=True) # merchant:子商户号 applyment_id: Mapped[str] = mapped_column(String, default="") # merchant:进件申请单号 status: Mapped[str] = mapped_column(String, default="applying", index=True) # applying|active|disabled|rejected detail: Mapped[str] = mapped_column(String, default="") # 进件驳回原因/接收方状态提示 # ── 进件生命周期(applyment4sub 查询回填,前端据此展示签约/验证引导)── applyment_state: Mapped[str] = mapped_column(String, default="") # 微信 applyment_state 枚举 sign_url: Mapped[str] = mapped_column(String, default="") # 超管签约链接(扫码完成验证+授权) account_validation_json: Mapped[str] = mapped_column(Text, default="{}") # 账户验证信息(打款/法人) audit_detail_json: Mapped[str] = mapped_column(Text, default="{}") # 驳回原因/状态说明 # ── 分账授权(查询 /v3/profitsharing/merchant-configs 回填)── split_allowed: Mapped[str] = mapped_column(String, default="") # OPEN|CLOSED|WAIT_CONFIRM split_max_ratio: Mapped[int] = mapped_column(Integer, default=0) # 允许服务商分账的最大比例(%) created_at: Mapped[str] = mapped_column(String, default="", index=True) updated_at: Mapped[str] = mapped_column(String, default="") class SettlementLog(Base): """分账流水镜像(业务侧对账用,真金在微信侧)。""" __tablename__ = "settlement_logs" id: Mapped[str] = mapped_column(String, primary_key=True) # sl_ escrow_id: Mapped[str] = mapped_column(String, default="", index=True) # escrows.id task_id: Mapped[str] = mapped_column(String, default="", index=True) share_order_no: Mapped[str] = mapped_column(String, default="", index=True) # 分账单号(幂等键) channel: Mapped[str] = mapped_column(String, default="wx_split") # wx_split | manual | ... amount: Mapped[int] = mapped_column(Integer, default=0) # 分账总额(分) commission: Mapped[int] = mapped_column(Integer, default=0) # 平台佣金(分) receivers_json: Mapped[str] = mapped_column(Text, default="[]") # 接收方+金额快照 status: Mapped[str] = mapped_column(String, default="initiated", index=True) # initiated|shared|failed|returned detail: Mapped[str] = mapped_column(String, default="") created_at: Mapped[str] = mapped_column(String, default="", index=True) updated_at: Mapped[str] = mapped_column(String, default="")