elf 6 months ago
parent 96cf907894
commit 6e62d1a84a

@ -6,6 +6,7 @@ import (
"gold-shop/request" "gold-shop/request"
"gold-shop/service" "gold-shop/service"
"gold-shop/utils/result" "gold-shop/utils/result"
"gold-shop/utils/tlpay"
"gold-shop/utils/weixin" "gold-shop/utils/weixin"
"net/http" "net/http"
"strconv" "strconv"
@ -115,7 +116,7 @@ func Order(c *gin.Context) (result.Data, error) {
} }
func GetWxAuthUrl(c *gin.Context) (result.Data, error) { func GetWxAuthUrl(c *gin.Context) (result.Data, error) {
authUrl := weixin.WxApi.GetAuthUrl("https://www.baidu.com") authUrl := weixin.WxApi.GetAuthUrl("http://mall.wrtcjt.com")
data := result.Data{"url": authUrl} data := result.Data{"url": authUrl}
return data, nil return data, nil
} }
@ -147,3 +148,22 @@ func TransferPayNotify(c *gin.Context) {
c.String(http.StatusOK, "success") c.String(http.StatusOK, "success")
return return
} }
func TLPay(c *gin.Context) {
param := tlpay.PayParam{}
param.PayType = "B2B"
param.OrderID = "12344565667"
param.CusID = "990581007426001"
param.AppID = "00000051"
param.TrxAmt = "0.01"
param.RetUrl = "https://www.baidu.com"
param.NotifyUrl = "https://www.baidu.com"
param.GoodsID = "123122"
param.GoodsInf = "slsdfxxx"
param.RandomStr = "sdfssss"
param.SignType = "RSA"
//c.String(http.StatusOK, "<div>nihao</div>")
c.Writer.Header().Set("content-type", "text/html")
c.Writer.WriteString("<div>nihao</div>")
return
}

@ -17,14 +17,14 @@ redis:
password: "" password: ""
db: 0 db: 0
payment: payment:
base-url: "http://api2uat.lfwin.com" base-url: "http://api2.lfwin.com"
# api-key: "00014005" # api-key: "00014005"
# sign-key: "punr8ucu" # sign-key: "punr8ucu"
api-key: "231809002" api-key: "24114801"
sign-key: "3wr2ymiz" sign-key: "88819264"
wx-pay: wx-pay:
sub-app-id: "wxb1bec7d809e7cf40" sub-app-id: "wx939c26e4e09ce9ee"
sub-app-secret: "" sub-app-secret: "0d365a525ec9bf2c055d735ced98a6c1"
jwt: jwt:
key: "I2js2oElEo82NmRru8v73Nwm" key: "I2js2oElEo82NmRru8v73Nwm"
issuer: "gold-shop" issuer: "gold-shop"

BIN
goshop

Binary file not shown.

@ -11,6 +11,7 @@ import (
"gold-shop/request" "gold-shop/request"
"gold-shop/route" "gold-shop/route"
"gold-shop/utils" "gold-shop/utils"
"gold-shop/utils/tlpay"
"net/http" "net/http"
"net/url" "net/url"
"time" "time"
@ -18,6 +19,7 @@ import (
func main() { func main() {
initial() initial()
//testPay()
runServer() runServer()
} }
@ -29,6 +31,7 @@ func initial() {
global.DB = initialize.InitDB(global.Config) global.DB = initialize.InitDB(global.Config)
global.Redis = initialize.InitRedis(global.Config) global.Redis = initialize.InitRedis(global.Config)
} }
func runServer() { func runServer() {
r := gin.Default() r := gin.Default()
s := &http.Server{ s := &http.Server{
@ -117,3 +120,21 @@ func payOrder3() {
fmt.Println(string(body)) fmt.Println(string(body))
utils.Post2("https://api.paypal.com/v2/checkout/orders", string(body), token) utils.Post2("https://api.paypal.com/v2/checkout/orders", string(body), token)
} }
func testPay() {
param := tlpay.PayParam{}
param.PayType = "B2B"
param.OrderID = "12344565667"
param.CusID = "990581007426001"
param.AppID = "00000051"
param.TrxAmt = "0.01"
param.RetUrl = "https://www.baidu.com"
param.NotifyUrl = "https://www.baidu.com"
param.GoodsID = "123122"
param.GoodsInf = "slsdfxxx"
param.RandomStr = "sdfssss"
param.SignType = "RSA"
//param.GateID = ""
//param.ValidTime = ""
tlpay.TLPay.Pay(param)
}

@ -5,6 +5,7 @@ import (
) )
func Initial(r *gin.Engine) { func Initial(r *gin.Engine) {
r.Static("/asset", "./asset")
h5RouteInit(r) h5RouteInit(r)
adminRouteInit(r) adminRouteInit(r)
} }

@ -14,6 +14,7 @@ func h5RouteInit(r *gin.Engine) {
h5Group.Match([]string{"POST", "OPTIONS"}, "/register", result.Json(h5.Register)) h5Group.Match([]string{"POST", "OPTIONS"}, "/register", result.Json(h5.Register))
h5Group.Match([]string{"GET", "OPTIONS"}, "/get-product-info", result.Json(h5.GetProductInfo)) h5Group.Match([]string{"GET", "OPTIONS"}, "/get-product-info", result.Json(h5.GetProductInfo))
h5Group.Match([]string{"POST", "OPTIONS"}, "/transfer-pay-notify", h5.TransferPayNotify) h5Group.Match([]string{"POST", "OPTIONS"}, "/transfer-pay-notify", h5.TransferPayNotify)
h5Group.Match([]string{"GET", "OPTIONS"}, "/tl-pay", h5.TLPay)
authGroup := h5Group.Group("") authGroup := h5Group.Group("")
authGroup.Use(middleware.JwtMiddleware("user")) authGroup.Use(middleware.JwtMiddleware("user"))

@ -0,0 +1,35 @@
package utils
import (
"fmt"
"net/url"
"reflect"
)
func StructToURLValues(s interface{}) (url.Values, error) {
values := url.Values{}
structValue := reflect.ValueOf(s)
structFieldValue := structValue.FieldByName
structType := reflect.TypeOf(s)
for i := 0; i < structType.NumField(); i++ {
fieldName := structType.Field(i).Name
tagName := structType.Field(i).Tag.Get("form")
valueField := fieldName
if tagName != "" {
valueField = tagName
}
fieldValue := structFieldValue(fieldName)
switch fieldValue.Kind() {
case reflect.String:
values.Set(valueField, fieldValue.String())
case reflect.Int, reflect.Int64:
str := fmt.Sprintf("%v", fieldValue.Int())
values.Set(valueField, str)
default:
return nil, fmt.Errorf("unsupported field type: %v", fieldValue.Kind())
}
}
fmt.Println(values)
return values, nil
}

@ -1,13 +1,21 @@
package utils package utils
import ( import (
"crypto"
"crypto/md5" "crypto/md5"
"crypto/rand"
"crypto/rsa"
"crypto/x509"
"encoding/base64"
"encoding/hex" "encoding/hex"
"encoding/pem"
"errors"
"fmt" "fmt"
"golang.org/x/crypto/bcrypt" "golang.org/x/crypto/bcrypt"
"io" "io"
"net/http" "net/http"
"net/url" "net/url"
"os"
"strings" "strings"
) )
@ -109,3 +117,84 @@ func Post2(url string, params string, token string) {
} }
fmt.Println(string(bodyBytes)) fmt.Println(string(bodyBytes))
} }
func RSASign(data []byte, filename string) (string, error) {
// 1、选择hash算法对需要签名的数据进行hash运算
myHash := crypto.SHA256
hashInstance := myHash.New()
hashInstance.Write(data)
hashed := hashInstance.Sum(nil)
// 2、读取私钥文件解析出私钥对象
privateKey, err := ReadParsePrivateKey(filename)
if err != nil {
return "", err
}
// 3、RSA数字签名参数是随机数、私钥对象、哈希类型、签名文件的哈希串生成bash64编码
bytes, err := rsa.SignPKCS1v15(rand.Reader, privateKey, myHash, hashed)
if err != nil {
return "", err
}
return base64.StdEncoding.EncodeToString(bytes), nil
}
func RSAVerify(data []byte, base64Sig, filename string) error {
// 1、对base64编码的签名内容进行解码返回签名字节
bytes, err := base64.StdEncoding.DecodeString(base64Sig)
if err != nil {
return err
}
// 2、选择hash算法对需要签名的数据进行hash运算
myHash := crypto.SHA256
hashInstance := myHash.New()
hashInstance.Write(data)
hashed := hashInstance.Sum(nil)
// 3、读取公钥文件解析出公钥对象
publicKey, err := ReadParsePublicKey(filename)
if err != nil {
return err
}
// 4、RSA验证数字签名参数是公钥对象、哈希类型、签名文件的哈希串、签名后的字节
return rsa.VerifyPKCS1v15(publicKey, myHash, hashed, bytes)
}
// ReadParsePublicKey 读取公钥文件,解析公钥对象
func ReadParsePublicKey(filename string) (*rsa.PublicKey, error) {
// 1、读取公钥文件获取公钥字节
publicKeyBytes, err := os.ReadFile(filename)
if err != nil {
return nil, err
}
// 2、解码公钥字节生成加密对象
block, _ := pem.Decode(publicKeyBytes)
if block == nil {
return nil, errors.New("公钥信息错误!")
}
// 3、解析DER编码的公钥生成公钥接口
publicKeyInterface, err := x509.ParsePKIXPublicKey(block.Bytes)
if err != nil {
return nil, err
}
// 4、公钥接口转型成公钥对象
publicKey := publicKeyInterface.(*rsa.PublicKey)
return publicKey, nil
}
// ReadParsePrivateKey 读取私钥文件,解析出私钥对象
func ReadParsePrivateKey(filename string) (*rsa.PrivateKey, error) {
// 1、读取私钥文件获取私钥字节
privateKeyBytes, err := os.ReadFile(filename)
if err != nil {
return nil, err
}
// 2、解码私钥字节生成加密对象
block, _ := pem.Decode(privateKeyBytes)
if block == nil {
return nil, errors.New("私钥信息错误!")
}
// 3、解析DER编码的私钥生成私钥对象
privateKey, err := x509.ParsePKCS1PrivateKey(block.Bytes)
if err != nil {
return nil, err
}
return privateKey, nil
}

@ -0,0 +1,94 @@
package tlpay
import (
"fmt"
"gold-shop/errors"
"gold-shop/global"
"gold-shop/utils"
"io"
"net/http"
"net/url"
"strings"
)
var TLPay tlPay = tlPay{}
type tlPay struct {
}
func (api *tlPay) Pay(param PayParam) (string, error) {
payment := global.Config.Payment
data, err := utils.StructToURLValues(param)
sign, err := api.sign(data)
data.Set("sign", sign)
res, err := api.post(payment.BaseUrl+"/apiweb/gateway/pay", data)
if err != nil {
return "", err
}
return string(res), nil
}
func (api *tlPay) sign(params url.Values) (string, error) {
params.Del("sign")
fmt.Println(params.Encode())
return utils.RSASign([]byte(params.Encode()), "")
}
func (api *tlPay) post(url string, data url.Values) ([]byte, error) {
client := &http.Client{}
body := strings.NewReader(data.Encode())
request, err := http.NewRequest("POST", url, body)
if err != nil {
return nil, errors.NewBusinessError("请求错误")
}
response, err := client.Do(request)
defer func(Body io.ReadCloser) {
err := Body.Close()
if err != nil {
}
}(response.Body)
bodyBytes, err := io.ReadAll(response.Body)
fmt.Println(string(bodyBytes))
if err != nil {
return nil, errors.NewBusinessError("返回内容错误")
}
return bodyBytes, nil
}
func (api *tlPay) buildHtml(param PayParam) string {
htmlBegin := `
<!DOCTYPE html>
<html>
<head>
<title></title>
<script>
window.onload = function() {
document.getElementById("auto-submit-form").submit();
};
</script>
</head>
<body>`
htmlEnd :=
`</body>
</html>
`
return htmlBegin + api.buildFormHtml(param) + htmlEnd
}
func (api *tlPay) buildFormHtml(param PayParam) string {
data, _ := utils.StructToURLValues(param)
formHtml := "<form id=\"auto-submit-form\" action=\"{{.Action}}\" method=\"{{.Method}}\">"
for key, value := range data {
formHtml += "<input type=\"hidden\" name=\"" + key + "\" value=\"" + value[0] + "\">"
}
formHtml += "</form>"
return formHtml
}

@ -0,0 +1,20 @@
package tlpay
type PayParam struct {
OrgID string `json:"orgid" form:"orgid"`
CusID string `json:"cusid" form:"cusid"`
AppID string `json:"appid" form:"appid"`
RetUrl string `json:"returl" form:"returl"`
NotifyUrl string `json:"notifyurl" form:"notifyurl"`
GoodsID string `json:"goodsid" form:"goodsid"`
GoodsInf string `json:"goodsinf" form:"goodsinf"`
TrxAmt string `json:"trxamt" form:"trxamt"`
OrderID string `json:"orderid" form:"orderid"`
RandomStr string `json:"randomstr" form:"randomstr"`
GateID string `json:"gateid" form:"gateid"`
PayType string `json:"paytype" form:"paytype"`
LimitPay string `json:"limitpay" form:"limitpay"`
ValidTime string `json:"validtime" form:"validtime"`
SignType string `json:"signtype" form:"signtype"`
Sign string `json:"sign" form:"sign"`
}

@ -0,0 +1,19 @@
<!DOCTYPE html>
<html>
<head>
<title>充值</title>
<script>
window.onload = function() {
document.getElementById("auto-submit-form").submit();
};
</script>
</head>
<body>
<form id="auto-submit-form" action="{{.Action}}" method="{{.Method}}">
<!-- Your form fields go here -->
<input type="hidden" name="paytype" value="{{.data.PayType}}">
<input type="hidden" name="field2" value="value2">
<input type="hidden" name="field2" value="value2">
</form>
</body>
</html>
Loading…
Cancel
Save