diff --git a/backend/internal/service/pay_test.go b/backend/internal/service/pay_test.go index 3a2e96a..e2ea7f8 100644 --- a/backend/internal/service/pay_test.go +++ b/backend/internal/service/pay_test.go @@ -278,6 +278,35 @@ func TestCreatePurchase_HappyPath(t *testing.T) { assert.Equal(t, strconv.FormatUint(p.ID, 10), gotBizRef, "biz_ref 应为购买记录 id") } +// TestCreatePurchase_QueryOrderFailKeepsZeroAmount 覆盖 D1 金额兜底:下单 POST 成功但 +// best-effort 查单 GET 失败时,不阻断下单,金额留 0(PayURL/OutTradeNo 等仍正常落库)。 +func TestCreatePurchase_QueryOrderFailKeepsZeroAmount(t *testing.T) { + db := testutil.SetupTestDB() + shop := testutil.CreateTestShop(db, "PAY007") + + mux := http.NewServeMux() + mux.HandleFunc("POST /api/v2/orders", func(w http.ResponseWriter, r *http.Request) { + fmt.Fprint(w, `{"data":{"order_no":"pay-test-qf","session":{"render_type":"redirect","payload":{"url":"https://pay.test/cashier"}}}}`) + }) + mux.HandleFunc("GET /api/v2/orders/pay-test-qf", func(w http.ResponseWriter, r *http.Request) { + w.WriteHeader(http.StatusInternalServerError) + }) + payServer := httptest.NewServer(mux) + defer payServer.Close() + + svc := newTestPaySvc(db, payServer.URL) + res, err := svc.CreatePurchase(shop.ID, 1, "annual_standard", "mobile") + require.NoError(t, err, "查单失败不应阻断下单") + assert.Equal(t, int64(0), res.AmountMinor, "查单失败金额留 0") + assert.Equal(t, "", res.Amount, "查单失败金额留 0") + assert.Equal(t, "https://pay.test/cashier", res.PayURL) + + var p model.LicensePurchase + require.NoError(t, db.Where("out_trade_no = ?", "pay-test-qf").First(&p).Error) + assert.Equal(t, "https://pay.test/cashier", p.PayURL) + assert.Equal(t, int64(0), p.AmountMinor) +} + func TestCreatePurchase_UnknownPlanAndUnconfigured(t *testing.T) { db := testutil.SetupTestDB() svc := newTestPaySvc(db, "http://pay.invalid")