需要在 xjz-payment-platform 中新增"代商家开通当面付"功能。这是支付宝 ISV 服务商代商家开通当面付收单产品的标准流程,涉及 4 个 API 的顺序调用:
alipay.open.agent.create → 创建事务,获得 batch_noalipay.open.agent.facetoface.sign → 提交当面付开通申请alipay.open.agent.confirm → 确认提交事务alipay.open.agent.order.query → 轮询申请单状态SDK 验证:所有 Request/Response 类在 alipay-sdk-python-all 中可用。FacetofaceSign 无独立 Model 类,直接在 Request 上设置属性。
backend/app/plugin/module_payment/facetoface/完全复用现有 module_payment 的 model/crud/service/controller/schema 模式。
enums.py - 申请单状态枚举INIT - 初始化(本地状态,尚未提交)
SUBMITTED - 已提交到支付宝
MERCHANT_AUDITING - 审核中
MERCHANT_CONFIRM - 审核通过,等待商家确认
SUCCESS - 商家已确认,开通成功
CLOSED - 已关闭(驳回/失败/取消)
model.py - FacetofaceOrderModel表名 pay_facetoface_order,继承 PaymentModelMixin + TenantMixin。
关键字段:
batch_no (String64, unique) - 支付宝事务编号order_no (String64) - 支付宝申请单号order_status (String32) - 申请单状态(用枚举)merchant_name (String128) - 商户名称shop_name (String128) - 店铺名称shop_address (String256) - 店铺地址mcc_code (String32) - 商户类别码rate (String16) - 费率business_license_no (String64) - 营业执照号business_license_mobile (String32) - 联系手机号sign_and_auth (Boolean) - 是否同时获取授权confirm_url (Text) - 商家确认链接app_auth_token (String128) - 商家授权 tokenreject_reason (Text) - 驳回原因remark (Text) - 备注last_query_time (DateTime) - 最后查询时间next_query_time (DateTime) - 下次查询时间query_count (Integer) - 已查询次数schema.pyFacetofaceApplySchema - 申请请求(shop_name, shop_address, mcc_code, rate, business_license_no, business_license_mobile, sign_and_auth 等)FacetofaceOrderOutSchema - 详情响应FacetofaceOrderListOutSchema - 列表响应crud.pyFacetofaceCRUD 继承 CRUDBaseget_by_batch_no - 按事务编号查询get_pending_orders - 获取待轮询的申请单service.pyapply_service - 执行三步操作:create → sign → confirm,一次性完成提交query_order_service - 手动查询单个申请单状态poll_pending_orders - 定时任务调用,轮询所有待处理申请单
controller.pyFacetofaceRouter = APIRouter(prefix="/facetoface", tags=["当面付开通"])POST /facetoface/apply - 提交开通申请GET /facetoface - 查询申请单列表(分页)POST /facetoface/{id}/query - 手动刷新查询状态GET /facetoface/{id} - 查询申请单详情__init__.py导出 Router, CRUD, Model, Service 等。
backend/app/plugin/module_payment/__init__.py 的 _MODULES 列表加入 "facetoface"。
路由自动发现:discover.py 会自动扫描 module_payment/facetoface/controller.py 并注册到 /payment/facetoface。
创建 Alembic migration:backend/app/alembic/versions/c1d2e3f4g5h6_add_facetoface_order.py
在应用启动时注册一个 interval 定时任务(通过现有的 APScheduler 系统),每 30 分钟检查一次是否有需要查询状态的申请单。具体轮询间隔由 next_query_time 字段控制:
frontend/src/api/module_payment/facetoface.tsAPI 接口定义 + 状态常量映射。
frontend/src/views/module_payment/facetoface/index.vue管理页面,包含:
复用现有 CRUD 组件:PageSearch, PageContent, CrudToolbarLeft, CrudToolbarRight, PageModal。
新建:
backend/app/plugin/module_payment/facetoface/__init__.pybackend/app/plugin/module_payment/facetoface/enums.pybackend/app/plugin/module_payment/facetoface/model.pybackend/app/plugin/module_payment/facetoface/schema.pybackend/app/plugin/module_payment/facetoface/crud.pybackend/app/plugin/module_payment/facetoface/service.pybackend/app/plugin/module_payment/facetoface/controller.pybackend/app/alembic/versions/c1d2e3f4g5h6_add_facetoface_order.pyfrontend/src/api/module_payment/facetoface.tsfrontend/src/views/module_payment/facetoface/index.vue修改:
backend/app/plugin/module_payment/__init__.py - 注册模块AlipayClient.get_client() from app.core.alipay.clientPaymentModelMixin, TenantMixin from app.core.base_modelCRUDBase from app.core.base_crudCustomException from app.core.exceptionsAuthPermission, redis_getter from app.core.dependenciesOperationLogRoute from app.core.router_classResponseSchema, SuccessResponse from app.common.responsescheduler from app.core.ap_scheduler (注册轮询任务)/payment/facetoface 路由是否注册