Merge pull request #27 from jiamovo/fix/epay-submit-form-compat
support epay submit form params
This commit is contained in:
+49
-17
@@ -75,25 +75,51 @@ func RegisterRoute(e *echo.Echo) {
|
||||
|
||||
// epay v1 routes
|
||||
epayV1 := paymentRoute.Group("/epay/v1")
|
||||
epayV1.GET("/order/create-transaction/submit.php", func(ctx echo.Context) error {
|
||||
money := ctx.QueryParam("money")
|
||||
name := ctx.QueryParam("name")
|
||||
notifyURL := ctx.QueryParam("notify_url")
|
||||
outTradeNo := ctx.QueryParam("out_trade_no")
|
||||
returnURL := ctx.QueryParam("return_url")
|
||||
signstr := ctx.QueryParam("sign")
|
||||
// signType := ctx.QueryParam("sign_type")
|
||||
|
||||
m := map[string]interface{}{
|
||||
"money": money,
|
||||
"name": name,
|
||||
"notify_url": notifyURL,
|
||||
"out_trade_no": outTradeNo,
|
||||
"pid": config.GetEpayPid(), // 注意:验签时需要包含 pid 参数
|
||||
"return_url": returnURL,
|
||||
epayV1.Match([]string{http.MethodPost, http.MethodGet}, "/order/create-transaction/submit.php", func(ctx echo.Context) error {
|
||||
params := make(map[string]interface{})
|
||||
copyParams := func(values map[string][]string) {
|
||||
for k, v := range values {
|
||||
if len(v) == 0 {
|
||||
continue
|
||||
}
|
||||
params[k] = v[0]
|
||||
}
|
||||
}
|
||||
|
||||
checkSignature, err := sign.Get(m, config.GetApiAuthToken())
|
||||
copyParams(ctx.QueryParams())
|
||||
|
||||
formParams, err := ctx.FormParams()
|
||||
if err != nil && ctx.Request().Method == http.MethodPost {
|
||||
return comm.Ctrl.FailJson(ctx, fmt.Errorf("invalid epay form params: %w", err))
|
||||
}
|
||||
if err == nil {
|
||||
copyParams(formParams)
|
||||
}
|
||||
|
||||
getString := func(m map[string]interface{}, key string) string {
|
||||
v, ok := m[key]
|
||||
if !ok {
|
||||
return ""
|
||||
}
|
||||
s, ok := v.(string)
|
||||
if !ok {
|
||||
return ""
|
||||
}
|
||||
return s
|
||||
}
|
||||
|
||||
signstr := getString(params, "sign")
|
||||
if signstr == "" {
|
||||
return constant.SignatureErr
|
||||
}
|
||||
|
||||
delete(params, "sign")
|
||||
delete(params, "sign_type")
|
||||
|
||||
// we need to add pid to params for signature verification
|
||||
params["pid"] = config.GetEpayPid()
|
||||
|
||||
checkSignature, err := sign.Get(params, config.GetApiAuthToken())
|
||||
if err != nil {
|
||||
return constant.SignatureErr
|
||||
}
|
||||
@@ -101,6 +127,12 @@ func RegisterRoute(e *echo.Echo) {
|
||||
return constant.SignatureErr
|
||||
}
|
||||
|
||||
money := getString(params, "money")
|
||||
name := getString(params, "name")
|
||||
notifyURL := getString(params, "notify_url")
|
||||
outTradeNo := getString(params, "out_trade_no")
|
||||
returnURL := getString(params, "return_url")
|
||||
|
||||
amountFloat, err := strconv.ParseFloat(money, 64)
|
||||
if err != nil {
|
||||
return comm.Ctrl.FailJson(ctx, fmt.Errorf("invalid money value: %s", money))
|
||||
|
||||
@@ -5,6 +5,7 @@ import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"net/url"
|
||||
"os"
|
||||
"strings"
|
||||
"testing"
|
||||
@@ -28,6 +29,7 @@ func setupTestEnv(t *testing.T) *echo.Echo {
|
||||
viper.Reset()
|
||||
viper.Set("db_type", "sqlite")
|
||||
viper.Set("api_auth_token", testAPIToken)
|
||||
viper.Set("epay_pid", 1)
|
||||
viper.Set("app_uri", "http://localhost:8080")
|
||||
viper.Set("order_expiration_time", 10)
|
||||
viper.Set("api_rate_url", "")
|
||||
@@ -78,6 +80,28 @@ func doPost(e *echo.Echo, path string, body map[string]interface{}) *httptest.Re
|
||||
return rec
|
||||
}
|
||||
|
||||
func signEpayValues(values url.Values) url.Values {
|
||||
signParams := make(map[string]interface{})
|
||||
for key, items := range values {
|
||||
if key == "sign" || key == "sign_type" || len(items) == 0 {
|
||||
continue
|
||||
}
|
||||
signParams[key] = items[0]
|
||||
}
|
||||
sig, _ := sign.Get(signParams, testAPIToken)
|
||||
values.Set("sign", sig)
|
||||
values.Set("sign_type", "MD5")
|
||||
return values
|
||||
}
|
||||
|
||||
func doFormPost(e *echo.Echo, path string, values url.Values) *httptest.ResponseRecorder {
|
||||
req := httptest.NewRequest(http.MethodPost, path, strings.NewReader(values.Encode()))
|
||||
req.Header.Set(echo.HeaderContentType, echo.MIMEApplicationForm)
|
||||
rec := httptest.NewRecorder()
|
||||
e.ServeHTTP(rec, req)
|
||||
return rec
|
||||
}
|
||||
|
||||
// TestCreateOrderEpusdtDefaultTron tests the epusdt compatibility route defaults to tron network.
|
||||
func TestCreateOrderEpusdtDefaultTron(t *testing.T) {
|
||||
e := setupTestEnv(t)
|
||||
@@ -401,3 +425,52 @@ func TestCreateOrderNetworkIsolation(t *testing.T) {
|
||||
t.Errorf("expected SolTestAddress001, got %v", data["receive_address"])
|
||||
}
|
||||
}
|
||||
|
||||
func TestEpaySubmitPhpGetCompatible(t *testing.T) {
|
||||
e := setupTestEnv(t)
|
||||
|
||||
values := signEpayValues(url.Values{
|
||||
"pid": {"1"},
|
||||
"name": {"epay-get-001"},
|
||||
"type": {"alipay"},
|
||||
"money": {"1.00"},
|
||||
"out_trade_no": {"epay-get-001"},
|
||||
"notify_url": {"http://localhost/notify"},
|
||||
"return_url": {"http://localhost/return"},
|
||||
})
|
||||
|
||||
req := httptest.NewRequest(http.MethodGet, "/payments/epay/v1/order/create-transaction/submit.php?"+values.Encode(), nil)
|
||||
rec := httptest.NewRecorder()
|
||||
e.ServeHTTP(rec, req)
|
||||
|
||||
if rec.Code != http.StatusFound {
|
||||
t.Fatalf("expected 302, got %d body=%s", rec.Code, rec.Body.String())
|
||||
}
|
||||
if !strings.HasPrefix(rec.Header().Get("Location"), "/pay/checkout-counter/") {
|
||||
t.Fatalf("expected checkout redirect, got %q", rec.Header().Get("Location"))
|
||||
}
|
||||
}
|
||||
|
||||
func TestEpaySubmitPhpPostFormCompatible(t *testing.T) {
|
||||
e := setupTestEnv(t)
|
||||
|
||||
values := signEpayValues(url.Values{
|
||||
"pid": {"1"},
|
||||
"name": {"epay-post-001"},
|
||||
"type": {"alipay"},
|
||||
"money": {"1.00"},
|
||||
"out_trade_no": {"epay-post-001"},
|
||||
"notify_url": {"http://localhost/notify"},
|
||||
"return_url": {"http://localhost/return"},
|
||||
"sitename": {"example-shop"},
|
||||
})
|
||||
|
||||
rec := doFormPost(e, "/payments/epay/v1/order/create-transaction/submit.php", values)
|
||||
|
||||
if rec.Code != http.StatusFound {
|
||||
t.Fatalf("expected 302, got %d body=%s", rec.Code, rec.Body.String())
|
||||
}
|
||||
if !strings.HasPrefix(rec.Header().Get("Location"), "/pay/checkout-counter/") {
|
||||
t.Fatalf("expected checkout redirect, got %q", rec.Header().Get("Location"))
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user