Ver código fonte

fix: renderPay 校验支付宝响应成功,失败不落库不返回错误 JSON

支付宝业务失败时 pageExecute 返回错误 JSON body(非 HTML 表单),
原代码只判 null 即当 pay_url 返回,前端新窗口 document.write 出整页 JSON。
补 isSuccess 校验(同文件其他 5 处支付宝调用同款),失败抛错由全局处理器提示。
测试: renderPay_alipayBusinessError_throwsAndNotPersists,55/55 Service 全绿
alphaH 4 dias atrás
pai
commit
c93261c89a

+ 4 - 0
java/src/main/java/com/payment/platform/module/payment/batch/service/AlipayBatchPayService.java

@@ -436,6 +436,10 @@ public class AlipayBatchPayService {
                     alipayClientFactory.getClient(enterpriseId, BIZ_TYPE).pageExecute(request);
             if (response == null || response.getBody() == null)
                 throw new BusinessException(400, "生成支付页面失败: 无响应");
+            // 支付宝业务失败时 pageExecute 返回错误 JSON 而非 HTML 表单——若当 pay_url 返回,
+            // 前端新窗口会 document.write 出整页 JSON(用户实测)。必须先校验成功再给前端,同文件其他 5 处调用同款。
+            if (!response.isSuccess())
+                throw new BusinessException(400, "生成支付页面失败: " + response.getMsg() + " (" + response.getSubCode() + ")");
             order.setPayUrl(response.getBody());
             batchOrderMapper.updateById(order);
             return Map.of("pay_url", response.getBody());

+ 24 - 0
java/src/test/java/com/payment/platform/module/payment/batch/service/AlipayBatchPayServiceTest.java

@@ -350,6 +350,30 @@ class AlipayBatchPayServiceTest {
         assertEquals("SHORT_URL", model.getInitializeCodeType());
     }
 
+    @Test
+    void renderPay_alipayBusinessError_throwsAndNotPersists() throws AlipayApiException {
+        // 支付宝业务失败时 pageExecute 返回错误 JSON body(非 HTML 表单)——
+        // 必须 isSuccess 校验后抛错,否则错误 JSON 会被当 pay_url 返回、前端 document.write 出整页 JSON(用户实测路径)
+        BatchOrderEntity order = new BatchOrderEntity();
+        order.setEnterpriseId("E100");
+        order.setOutBatchNo("B1");
+        order.setBatchTransId("BT1");
+        order.setStatus("INIT");
+        when(batchOrderMapper.selectOne(any())).thenReturn(order);
+        AlipayFundTransRenderPayResponse resp = new AlipayFundTransRenderPayResponse();
+        resp.setCode("40004");
+        resp.setSubCode("INVALID_PARAMETER");
+        resp.setSubMsg("参数[target_terminal_type]错误, 原因: 必须传入参数[target_terminal_type]");
+        resp.setBody("{\"alipay_fund_trans_render_pay_response\":{\"code\":\"40004\"}}");
+        when(alipayClient.pageExecute(any(AlipayFundTransRenderPayRequest.class))).thenReturn(resp);
+
+        BusinessException ex = assertThrows(BusinessException.class, () -> service.renderPay("E100", "B1"));
+
+        assertEquals(400, ex.getCode());
+        assertTrue(ex.getMessage().contains("INVALID_PARAMETER"), ex.getMessage());
+        verify(batchOrderMapper, never()).updateById(any());
+    }
+
     @Test
     void batchQuery_syncsBatchStatus() throws AlipayApiException {
         BatchOrderEntity order = new BatchOrderEntity();