修改支付相关

This commit is contained in:
Yvan
2026-09-23 18:16:56 +08:00
parent 38d071b137
commit 5c1da5bf55
2 changed files with 117 additions and 5 deletions
+11 -4
View File
@@ -39,14 +39,21 @@ func (a *wechatV3Adapter) Create(ctx context.Context, req *bizpayment.PaymentReq
bm.SetBodyMap("amount", func(amount gopay.BodyMap) { bm.SetBodyMap("amount", func(amount gopay.BodyMap) {
amount.Set("total", req.Amount).Set("currency", strings.ToUpper(req.Currency)) amount.Set("total", req.Amount).Set("currency", strings.ToUpper(req.Currency))
}) })
tradeType := normalizeWechatV3TradeType(firstAny(req.Extra, "trade_type", "pay_type", "method"))
if tradeType == "" {
tradeType = normalizeWechatV3TradeType(firstAny(c, "trade_type", "pay_type", "method"))
}
if tradeType == "native" || tradeType == "qr" || tradeType == "qrcode" {
for _, key := range []string{"time_expire", "attach", "goods_tag", "support_fapiao", "detail", "scene_info", "settle_info"} {
if value, ok := req.Extra[key]; ok {
bm[key] = value
}
}
} else {
mergeGoPayExtras(bm, req.Extra, mergeGoPayExtras(bm, req.Extra,
"appid", "mchid", "description", "out_trade_no", "notify_url", "amount", "payer", "appid", "mchid", "description", "out_trade_no", "notify_url", "amount", "payer",
"trade_type", "pay_type", "method", "openid", "open_id", "auth_code", "authcode", "barcode", "trade_type", "pay_type", "method", "openid", "open_id", "auth_code", "authcode", "barcode",
) )
tradeType := normalizeWechatV3TradeType(firstAny(req.Extra, "trade_type", "pay_type", "method"))
if tradeType == "" {
tradeType = normalizeWechatV3TradeType(firstAny(c, "trade_type", "pay_type", "method"))
} }
switch tradeType { switch tradeType {
case "", "jsapi", "js_api", "mini", "miniapp", "mini_app", "miniprogram", "mini_program", "applet": case "", "jsapi", "js_api", "mini", "miniapp", "mini_app", "miniprogram", "mini_program", "applet":
@@ -0,0 +1,105 @@
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 TestWechatV3NativeOnlySendsSupportedExtras(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.URL.Path != "/v3/pay/transactions/native" {
t.Errorf("request path = %q", 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()
for _, test := range []struct {
name, method, configMethod string
}{
{"native", "native", "jsapi"},
{"qr alias", "qr", "jsapi"},
{"qrcode alias", "qrcode", "jsapi"},
{"config fallback", "", "native"},
} {
t.Run(test.name, func(t *testing.T) {
requestBody = nil
extra := map[string]any{
"appid": "wrong-app", "mchid": "wrong-merchant",
"amount": map[string]any{"total": 999}, "payer": map[string]any{"openid": "wrong"},
"openid": "wrong", "trade_type": test.method, "unexpected": "not-a-native-field",
"time_expire": "2026-09-24T12:00:00+08:00", "attach": "order metadata",
"goods_tag": "tag", "support_fapiao": true,
"detail": map[string]any{"cost_price": 123},
"scene_info": map[string]any{"payer_client_ip": "127.0.0.1"},
"settle_info": map[string]any{"profit_sharing": false},
}
result, err := (&wechatV3Adapter{}).Create(context.Background(), &bizpayment.PaymentRequest{
TradeNo: "T-NATIVE", Subject: "subject", Amount: 123, Currency: "cny",
NotifyURL: "https://merchant.test/payment/callback", Extra: extra,
}, 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,
"trade_type": test.configMethod, "create_url": server.URL,
})
if err != nil {
t.Fatal(err)
}
if result.Status != "created" || requestBody == nil {
t.Fatalf("result = %+v, request = %#v", result, requestBody)
}
for _, key := range []string{"unexpected", "payer", "openid", "trade_type", "method"} {
if _, exists := requestBody[key]; exists {
t.Errorf("native request unexpectedly includes %s", key)
}
}
for key, want := range map[string]any{
"appid": "wx-test", "mchid": "mch-test", "description": "subject",
"out_trade_no": "T-NATIVE", "notify_url": "https://merchant.test/payment/callback",
"amount": map[string]any{"total": float64(123), "currency": "CNY"},
} {
if !reflect.DeepEqual(requestBody[key], want) {
t.Errorf("%s = %#v, want %#v", key, requestBody[key], want)
}
}
for _, key := range []string{"time_expire", "attach", "goods_tag", "support_fapiao", "detail", "scene_info", "settle_info"} {
if _, exists := requestBody[key]; !exists {
t.Errorf("native request missing %s", key)
}
}
})
}
}