package payment import ( "context" "encoding/json" "io" bizpayment "kra/internal/biz/payment" "net/http" "net/http/httptest" "reflect" "testing" gopayWechatV3 "github.com/go-pay/gopay/wechat/v3" ) func TestWechatV3NativeOnlySendsDocumentedFields(t *testing.T) { platformKey, _, platformPublicPEM := testRSAKeyPair(t) _, merchantPrivatePEM, _ := testRSAKeyPair(t) const ( platformSerial = "PLATFORM-SERIAL" timestamp = "1787068800" nonce = "native-response-nonce" ) response := []byte(`{"code_url":"weixin://wxpay/bizpayurl?pr=test"}`) signature := testRSA2Sign(t, platformKey, []byte(timestamp+"\n"+nonce+"\n"+string(response)+"\n")) var requestBody map[string]any server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { if r.Method != http.MethodPost || r.URL.Path != "/v3/pay/transactions/native" { t.Errorf("request = %s %s", r.Method, r.URL.Path) } body, err := io.ReadAll(r.Body) if err != nil { t.Errorf("read request: %v", err) return } if err = json.Unmarshal(body, &requestBody); err != nil { t.Errorf("decode request: %v", err) return } w.Header().Set(gopayWechatV3.HeaderTimestamp, timestamp) w.Header().Set(gopayWechatV3.HeaderNonce, nonce) w.Header().Set(gopayWechatV3.HeaderSerial, platformSerial) w.Header().Set(gopayWechatV3.HeaderSignature, signature) w.Header().Set("Content-Type", "application/json") _, _ = w.Write(response) })) defer server.Close() result, err := (&wechatV3Adapter{}).Create(context.Background(), &bizpayment.PaymentRequest{ Provider: bizpayment.PaymentWechatV3, TradeNo: "T-WECHAT-NATIVE", Subject: "subject", Amount: 123, Currency: "CNY", NotifyURL: "https://merchant.test/payment/callback", Extra: map[string]any{ "method": "qrcode", "pay_method": "native", "product_id": "item-1", "payer": map[string]any{"openid": "not-for-native"}, "attach": "order-meta", "scene_info": map[string]any{"payer_client_ip": "127.0.0.1"}, }, }, map[string]any{ "app_id": "wx-test", "merchant_id": "mch-test", "serial_no": "merchant-serial", "private_key": merchantPrivatePEM, "api_v3_key": "01234567890123456789012345678901", "platform_cert": platformPublicPEM, "platform_serial_no": platformSerial, "create_url": server.URL, }) if err != nil { t.Fatal(err) } want := map[string]any{ "appid": "wx-test", "mchid": "mch-test", "description": "subject", "out_trade_no": "T-WECHAT-NATIVE", "notify_url": "https://merchant.test/payment/callback", "amount": map[string]any{"total": float64(123), "currency": "CNY"}, "attach": "order-meta", "scene_info": map[string]any{"payer_client_ip": "127.0.0.1"}, } if !reflect.DeepEqual(requestBody, want) { t.Fatalf("native request = %#v, want %#v", requestBody, want) } if result.Status != "created" || result.TradeNo != "T-WECHAT-NATIVE" || string(result.Payload) != string(response) { t.Fatalf("native result = %+v", result) } }