# API Contracts: 商家 ezPay 发票开通管理 **Phase**: Phase 1 — REST 接口契约 **Date**: 2026-06-15 > 平台后台接口走若依鉴权 `@PreAuthorize("@ss.hasPermi('chanting:storeEzpay:*')")`;商家端接口走 `@Auth`+JWT。返回统一 `AjaxResult`/`TableDataInfo`。 ## 一、平台后台(PosStoreEzpayController,`/system/storeEzpay`) ### 1. 列表(分页 + 筛选) `GET /system/storeEzpay/list` | 参数 | 类型 | 说明 | |------|------|------| | pageNum / pageSize | int | 分页 | | ezpayStatus | int | 可选:0未申请/1申请中/2已开通;不传=全部(含免用) | | invoiceExempt | int | 可选:0需开票/1免用发票 | | quickFilter | string | 可选:`notEnabled`=还没开通、`needApply`=还要去开通 | | posName | string | 可选:门店名模糊 | | isStall | int | 可选:0店铺/1摊位 | **返回** `TableDataInfo`,每行含:门店基础信息(id/posName/userId/userName/isStall/invoiceExempt)+ ezPay 信息(ezpayStatus/isEnabled/ubn/merchantId 是否已填/applyTime/approvedTime/lastVerifyResult)。无 ezPay 行的门店 ezpayStatus 视为 0。 ### 2. 详情 `GET /system/storeEzpay/{storeId}` → `AjaxResult`,门店 + ezPay 配置(凭证字段是否回显由权限决定,建议列表/详情回显,敏感字段不下发商家端)。 ### 3. 发起申请(0→1) `PUT /system/storeEzpay/apply/{storeId}` - 前置:`ezpay_status=0`;建议校验 `ubn` 已填(未填则提示商家先补统编)。 - 效果:`ezpay_status=1`、`apply_time=now`。 ### 4. 录入凭证并验证(→2) `PUT /system/storeEzpay/saveCredentials` ```json { "storeId": 123, "merchantId": "3482911", "hashKey": "...", "hashIv": "...", "companyId": null } ``` - 后端:构造 `EzPayConfig` → 调 `EzPay.doPost(BASE_TEST + URL_SEARCH, cfg, {假发票号+随机码})`。 - 判读:回应含 `KEY1xxxx` → 凭证无效,**保持 status 不变**,`last_verify_result` 记错误码,返回 error(含中文说明)。回应业务错误或成功 → `ezpay_status=2`、`is_enabled=1`、`approved_time=now`、保存凭证、`last_verify_result` 记通过。 - 网络异常:返回 error 可重试,不改状态。 ### 5. 切换启用开关 `PUT /system/storeEzpay/toggleEnable/{storeId}` - 前置:`ezpay_status=2`。翻转 `is_enabled`(1↔0)。返回新状态。 ### 6. 标记/恢复免用发票 `PUT /system/storeEzpay/markExempt/{storeId}` ```json { "invoiceExempt": 1 } // 1=免用发票, 0=恢复需开票 ``` - 效果:更新 `pos_store.invoice_exempt`。免用后该门店退出待办过滤(已有 ezPay 行保留)。 ### 7. 重置状态(可选) `PUT /system/storeEzpay/reset/{storeId}` - 将 `ezpay_status` 回退到 0 或 1(凭证作废/重新申请场景),清 `approved_time`。 ## 二、商家端(上传统编) 挂在门店设置流程。两种实现选一(实现时定): **方案 A(推荐,最少改动)**:复用 `POST /chanting/store/addmendian`(已 `saveOrUpdate` 整个 PosStore)——前端门店表单加"统一编号"字段,提交时一并写入 `pos_store_ezpay.ubn`(后端在保存门店时 upsert ezPay 行的 ubn)。 **方案 B**:新增 `POST /chanting/store/saveUbn` `{ storeId, ubn }`,仅商家本人门店(JWT 校验 storeId 归属)。 > 无论哪种:商家端只能写 `ubn`,不能改 ezPay 状态/凭证/免用标记。 ## 三、权限菜单 新增菜单/权限键(写入 `sys_menu`,SQL 进 `updatesql/sql.md`): - `chanting:storeEzpay:list` / `:query` / `:apply` / `:saveCredentials` / `:toggleEnable` / `:markExempt` / `:reset` ## 四、错误约定 | 场景 | HTTP | 业务码/消息 | |------|------|-------------| | 凭证金钥错误 | 200 | error,`last_verify_result` 记 KEY1xxxx,消息"ezPay 凭证无效,请检查 HashKey/HashIV" | | 验证网络超时 | 200 | error,"ezPay 验证服务暂不可用,请稍后重试",状态不变 | | 非法状态迁移 | 200 | error,"当前状态不允许此操作" | | 商家越权改门店 | 200 | error,"无权操作该门店" |