diff --git a/api/h5/index.go b/api/h5/index.go
index d75b63d..4972351 100644
--- a/api/h5/index.go
+++ b/api/h5/index.go
@@ -1,6 +1,7 @@
package h5
import (
+ "encoding/json"
"fmt"
"github.com/gin-gonic/gin"
"gold-shop/errors"
@@ -8,8 +9,7 @@ import (
"gold-shop/request"
"gold-shop/service"
"gold-shop/utils/result"
- "gold-shop/utils/tlpay"
- "gold-shop/utils/tlpay/param"
+ "gold-shop/utils/tlpay/notify"
"gold-shop/utils/weixin"
"gorm.io/gorm"
"net/http"
@@ -170,15 +170,53 @@ func PaymentNotify(c *gin.Context) {
}
fmt.Println("has-data")
fmt.Println(req)
+
+ service.PaymentService.AfterPaymentNotify(req)
+ c.String(http.StatusOK, "success")
+ return
+}
+
+func BindingPayNotify(c *gin.Context) {
+ var req notify.PayAgreeNotify
+ err := c.ShouldBind(&req)
if err != nil {
+ fmt.Println("error: " + err.Error())
c.String(http.StatusOK, "fail")
return
}
- service.PaymentService.AfterPaymentNotify(req)
+ fmt.Println("has-data")
+ fmt.Println(req)
+ reqJson, err := json.Marshal(req)
+ fmt.Println(string(reqJson))
+ if err != nil {
+ c.String(http.StatusOK, "fail")
+ return
+ }
+ service.PaymentService.AfterBindingPayNotify(req)
c.String(http.StatusOK, "success")
return
}
+func GatewayPayRet(c *gin.Context) {
+ var req notify.GatewayPayRet
+ err := c.ShouldBind(&req)
+ if err != nil {
+ fmt.Println("error: " + err.Error())
+ c.String(http.StatusOK, "fail")
+ return
+ }
+ fmt.Println("has-data")
+ fmt.Println(req)
+ reqJson, err := json.Marshal(req)
+ fmt.Println(string(reqJson))
+ if err != nil {
+ c.String(http.StatusOK, "fail")
+ return
+ }
+ c.Redirect(http.StatusMovedPermanently, "http://mall.wrtcjt.com/pages/knq-detail/index")
+ return
+}
+
func TlBindingApply(c *gin.Context) (result.Data, error) {
var req request.TlBindingApplyRequest
err := c.ShouldBind(&req)
@@ -206,7 +244,7 @@ func GetUserBankCard(c *gin.Context) (result.Data, error) {
if err != nil {
return nil, err
}
- bankCard, err := service.UserService.GetBankCardByUserID(2)
+ bankCard, err := service.UserService.GetBankCardByUserID(user(c).ID)
if err != nil && errors.Is(err, gorm.ErrRecordNotFound) {
return result.Data{"bankCard": bankCard}, nil
}
@@ -228,20 +266,46 @@ func BindingPayConfirm(c *gin.Context) (result.Data, error) {
return data, err
}
-func TLPay(c *gin.Context) {
- p := param.GatewayPayParam{}
- p.OrderID = "22222222223323232"
- p.PayType = "B2B"
- p.TrxAmt = "1"
- p.RetUrl = "https://www.baidu.com"
- p.NotifyUrl = "https://www.baidu.com"
- p.GoodsID = "1"
- p.GoodsInf = "充值"
- p.Charset = "UTF-8"
+func BindingPaySms(c *gin.Context) (result.Data, error) {
+ var req request.BindingPaySmsRequest
+ err := c.ShouldBind(&req)
+ if err != nil {
+ return nil, err
+ }
+ data, err := service.PaymentService.SmsBindingPayment(req, user(c))
+ return data, err
+}
+
+func GatewayPayApply(c *gin.Context) (result.Data, error) {
+ var req request.PaymentRequest
+ err := c.ShouldBind(&req)
+ if err != nil {
+ return nil, err
+ }
+ req.PayType = "gateway"
+ return service.PaymentService.GatewayPayApply(user(c).ID, req)
+}
- str := tlpay.TLPay.GatewayPay(p)
- fmt.Println(str)
+func GatewayPay(c *gin.Context) {
c.Writer.Header().Set("content-type", "text/html")
- c.Writer.WriteString(str)
+ token := c.DefaultQuery("token", "")
+ if token == "" {
+ c.Writer.WriteString("token empty")
+ return
+ }
+ body, err := service.PaymentService.GatewayPay(token)
+ if err != nil {
+ c.Writer.WriteString(err.Error())
+ return
+ }
+ c.Writer.WriteString(body)
return
}
+
+func BankCardUnbind(c *gin.Context) (result.Data, error) {
+ err := service.UserService.BankCardUnbind(user(c))
+ if err != nil {
+ return nil, err
+ }
+ return nil, nil
+}
diff --git a/go.mod b/go.mod
index 2d4e00c..f00a13b 100644
--- a/go.mod
+++ b/go.mod
@@ -3,7 +3,6 @@ module gold-shop
go 1.21.1
require (
- github.com/fvbock/endless v0.0.0-20170109170031-447134032cb6
github.com/gin-contrib/cors v1.7.1
github.com/gin-gonic/gin v1.9.1
github.com/golang-jwt/jwt/v5 v5.2.1
diff --git a/go.sum b/go.sum
index 14a7cf6..40ea229 100644
--- a/go.sum
+++ b/go.sum
@@ -29,8 +29,6 @@ github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f/go.mod h1:cu
github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98=
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
-github.com/fvbock/endless v0.0.0-20170109170031-447134032cb6 h1:6VSn3hB5U5GeA6kQw4TwWIWbOhtvR2hmbBJnTOtqTWc=
-github.com/fvbock/endless v0.0.0-20170109170031-447134032cb6/go.mod h1:YxOVT5+yHzKvwhsiSIWmbAYM3Dr9AEEbER2dVayfBkg=
github.com/gabriel-vasile/mimetype v1.4.3 h1:in2uUcidCuFcDKtdcBxlR0rJ1+fsokWf+uqxgUFjbI0=
github.com/gabriel-vasile/mimetype v1.4.3/go.mod h1:d8uq/6HKRL6CGdk+aubisF/M5GcPfT7nKyLpA0lbSSk=
github.com/gin-contrib/cors v1.7.1 h1:s9SIppU/rk8enVvkzwiC2VK3UZ/0NNGsWfUKvV55rqs=
diff --git a/goldshop b/goldshop
index 4b9729a..c2f157c 100755
Binary files a/goldshop and b/goldshop differ
diff --git a/main.go b/main.go
index a85e45e..2f0d038 100644
--- a/main.go
+++ b/main.go
@@ -10,12 +10,14 @@ import (
"gold-shop/request"
"gold-shop/route"
"gold-shop/utils"
+ "gold-shop/utils/tlpay"
+ "gold-shop/utils/tlpay/notify"
"net/url"
)
func main() {
initial()
- //testPay()
+ //testVerify()
//runServer()
runServerInWindows()
}
@@ -123,3 +125,14 @@ func payOrder3() {
fmt.Println(string(body))
utils.Post2("https://api.paypal.com/v2/checkout/orders", string(body), token)
}
+
+func testVerify() {
+ str := "{\"cusid\":\"6603910521126XB\",\"appid\":\"00307595\",\"outTrxid\":\"2024051323201201\",\"trxcode\":\"VSP301\",\"trxid\":\"240513117804146702\",\"initamt\":\"10\",\"trxamt\":\"10\",\"trxdate\":\"20240513\",\"paytime\":\"20240513232054\",\"chnltrxid\":\"\",\"trxstatus\":\"0000\",\"termno\":\"\",\"termbatchid\":\"\",\"termtraceno\":\"0\",\"termauthno\":\"0513030178146702\",\"termrefnum\":\"2405132301010100017804146702\",\"trxreserved\":\"充值\",\"srctrxid\":\"\",\"cusorderid\":\"2024051323201201\",\"acct\":\"6226631705801444\",\"fee\":\"0\",\"cmid\":\"\",\"chnlid\":\"\",\"chnldata\":\"\",\"accttype\":\"00\",\"bankcode\":\"03030000\",\"logonid\":\"\",\"signtype\":\"RSA\",\"sign\":\"bQlu7ErUyYhmk5Atv7RWcqAnD1B7Ls0UwAaSJSXn7vJkTsl2C0NZ8pXYPpXeVxrZY7D+YWoUkHTSmtZH5V4qRtzlWDZSdOE8T3eeEs54tibr5ZUg6UuhbunUrznyTLRKsof+BvLjDp+4bYCG1+q/mesAXDOqA1fHXkc1jDvvGdQ=\"}"
+ req := notify.PayAgreeNotify{}
+ err := json.Unmarshal([]byte(str), &req)
+ fmt.Println("err1", err)
+ params, err := utils.StructToURLValues(req)
+ fmt.Println("err2", err)
+ err = tlpay.TLPay.Verify(params)
+ fmt.Println("err3", err)
+}
diff --git a/model/payment.go b/model/payment.go
index 7dc14d9..6df6500 100644
--- a/model/payment.go
+++ b/model/payment.go
@@ -15,6 +15,7 @@ type Payment struct {
PayOrderID string
UserID int
Amount float64
+ Token string
User User `gorm:"foreignKey:UserID;references:ID"`
PayType string
OpenID string
diff --git a/request/binding_pay_sms_request.go b/request/binding_pay_sms_request.go
new file mode 100644
index 0000000..32c78a9
--- /dev/null
+++ b/request/binding_pay_sms_request.go
@@ -0,0 +1,7 @@
+package request
+
+type BindingPaySmsRequest struct {
+ PaymentNo string `json:"paymentNo" form:"paymentNo"`
+ ThpInfo string `json:"thpInfo" form:"thpInfo"`
+ AgreeID string `json:"agreeId" form:"agreeId"`
+}
diff --git a/route/h5.go b/route/h5.go
index 14bba23..565a685 100644
--- a/route/h5.go
+++ b/route/h5.go
@@ -15,7 +15,10 @@ func h5RouteInit(r *gin.Engine) {
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"}, "/payment-notify", h5.PaymentNotify)
- h5Group.Match([]string{"GET", "OPTIONS"}, "/tl-pay", h5.TLPay)
+ h5Group.Match([]string{"POST", "OPTIONS"}, "/binding-pay-notify", h5.BindingPayNotify)
+ h5Group.Match([]string{"GET", "OPTIONS"}, "/test-gateway-pay", h5.GatewayPay)
+ h5Group.Match([]string{"GET", "OPTIONS"}, "/gateway-pay", h5.GatewayPay)
+ h5Group.Match([]string{"POST", "GET", "OPTIONS"}, "/gateway-pay-ret", h5.GatewayPayRet)
authGroup := h5Group.Group("")
authGroup.Use(middleware.JwtMiddleware("user"))
@@ -36,6 +39,8 @@ func h5RouteInit(r *gin.Engine) {
authGroup.Match([]string{"POST", "OPTIONS"}, "/tl-binding-confirm", result.Json(h5.TlBindingConfirm))
authGroup.Match([]string{"GET", "OPTIONS"}, "/get-user-bank-card", result.Json(h5.GetUserBankCard))
authGroup.Match([]string{"POST", "OPTIONS"}, "/binding-pay-confirm", result.Json(h5.BindingPayConfirm))
-
+ authGroup.Match([]string{"POST", "OPTIONS"}, "/binding-pay-sms", result.Json(h5.BindingPaySms))
+ authGroup.Match([]string{"POST", "OPTIONS"}, "/gateway-pay-apply", result.Json(h5.GatewayPayApply))
+ authGroup.Match([]string{"POST", "OPTIONS"}, "/bank-card-unbind", result.Json(h5.BankCardUnbind))
}
}
diff --git a/service/payment_service.go b/service/payment_service.go
index be9c478..9fd2bfe 100644
--- a/service/payment_service.go
+++ b/service/payment_service.go
@@ -15,6 +15,7 @@ import (
"gold-shop/utils/payment"
"gold-shop/utils/result"
"gold-shop/utils/tlpay"
+ "gold-shop/utils/tlpay/notify"
"gold-shop/utils/tlpay/param"
"gorm.io/gorm"
"strconv"
@@ -48,6 +49,8 @@ func (s paymentService) Payment(userID int, paymentRequest request.PaymentReques
data, err = s.transferPayment(paymentRequest, p)
} else if paymentRequest.PayType == "binding" {
data, err = s.bindingPayment(paymentRequest, p)
+ } else if paymentRequest.PayType == "gateway" {
+ data, err = s.getGatewayPayUrl(p)
} else {
err = errors.NewBusinessError("payType参数错误")
}
@@ -125,7 +128,7 @@ func (s paymentService) bindingPayment(paymentRequest request.PaymentRequest, p
payParam.Currency = "CNY"
payParam.Subject = "充值"
payParam.TrxReserve = "充值"
- payParam.NotifyUrl = "http://api.wrtcjt.com/h5/payment-notify"
+ payParam.NotifyUrl = "http://api.wrtcjt.com/h5/binding-pay-notify"
res, err := tlpay.TLPay.PayApplyAgree(payParam)
if err != nil {
return nil, err
@@ -175,7 +178,8 @@ func (s paymentService) ConfirmBindingPayment(req request.BindingPayConfirmReque
if res.RetCode != "SUCCESS" {
return nil, errors.NewBusinessError(res.RetMsg)
}
- if res.TrxStatus != "1999" {
+
+ if res.TrxStatus != "0000" {
return nil, errors.NewBusinessError(res.ErrMsg)
}
@@ -186,6 +190,38 @@ func (s paymentService) ConfirmBindingPayment(req request.BindingPayConfirmReque
return data, nil
}
+func (s paymentService) SmsBindingPayment(req request.BindingPaySmsRequest, user *model.User) (result.Data, error) {
+ pm := &model.Payment{}
+ err := global.DB.Where("user_id", user.ID).Where("payment_no", req.PaymentNo).Where("status", 0).First(&pm).Error
+ if err != nil {
+ return nil, err
+ }
+ thpInfo, err := base64.StdEncoding.DecodeString(req.ThpInfo)
+ if err != nil {
+ return nil, err
+ }
+ smsParam := param.PaySmsAgreeParam{}
+ smsParam.AgreeID = req.AgreeID
+ smsParam.ThpInfo = string(thpInfo)
+ smsParam.OrderID = req.PaymentNo
+ res, err := tlpay.TLPay.PaySmsAgree(smsParam)
+ if err != nil {
+ return nil, err
+ }
+
+ if err != nil {
+ return nil, err
+ }
+ if res.RetCode != "SUCCESS" {
+ return nil, errors.NewBusinessError(res.RetMsg)
+ }
+
+ data := result.Data{
+ "paymentNo": pm.PaymentNo,
+ }
+ return data, nil
+}
+
func (paymentService) createPayment(userID int, paymentRequest request.PaymentRequest) (*model.Payment, error) {
p := model.Payment{}
p.PaymentNo = utils.GenerateNo("payment")
@@ -309,3 +345,70 @@ func (s paymentService) AfterPaymentNotify(req request.PaymentNotifyRequest) err
return err
}
+
+func (s paymentService) AfterBindingPayNotify(req notify.PayAgreeNotify) error {
+ pm := &model.Payment{}
+ err := global.DB.Where("payment_no", req.CusOrderID).Where("status", 0).First(&pm).Error
+ if err != nil && e.Is(err, gorm.ErrRecordNotFound) {
+ return errors.NewBusinessError("记录不存在")
+ }
+
+ user := model.User{}
+ global.DB.Model(&model.User{}).Where("id", pm.UserID).Find(&user)
+
+ if req.TrxStatus == "0000" {
+ pm.Status = 1
+ global.DB.Model(&user).UpdateColumn("balance", gorm.Expr("balance + ?", pm.Amount))
+ } else {
+ pm.Status = 2
+ }
+
+ err = global.DB.Save(&pm).Error
+
+ return err
+}
+
+func (s paymentService) GatewayPay(token string) (string, error) {
+ pm := &model.Payment{}
+ err := global.DB.Where("token", token).Where("status", 0).First(&pm).Error
+
+ if err != nil {
+ return "", err
+ }
+ p := param.GatewayPayParam{}
+ p.OrderID = pm.PaymentNo
+ p.PayType = "B2B,B2C"
+ p.TrxAmt = strconv.FormatFloat(pm.Amount*100, 'f', 0, 64)
+ p.LimitPay = "no_credit"
+ p.RetUrl = "http://api.wrtcjt.com/h5/gateway-pay-ret"
+ p.NotifyUrl = "http://api.wrtcjt.com/h5/binding-pay-notify"
+ p.GoodsID = "1"
+ p.GoodsInf = "充值"
+ p.Charset = "UTF-8"
+
+ str := tlpay.TLPay.GatewayPay(p)
+ return str, nil
+}
+
+func (s paymentService) GatewayPayRet(ret notify.GatewayPayRet) (string, error) {
+ return "", nil
+}
+
+func (s paymentService) GatewayPayApply(userID int, paymentRequest request.PaymentRequest) (result.Data, error) {
+ pm, err := s.createPayment(userID, paymentRequest)
+ if err != nil {
+ return nil, err
+ }
+ return s.getGatewayPayUrl(pm)
+}
+
+func (s paymentService) getGatewayPayUrl(pm *model.Payment) (result.Data, error) {
+ token := utils.Md5(pm.PaymentNo + strconv.Itoa(pm.UserID) + "_gateway")
+ pm.Token = token
+ err := global.DB.Save(pm).Error
+ if err != nil {
+ return nil, err
+ }
+ data := result.Data{"url": "http://api.wrtcjt.com/h5/gateway-pay?token=" + token, "orderId": ""}
+ return data, nil
+}
diff --git a/service/user_service.go b/service/user_service.go
index 026dddf..93e1ba9 100644
--- a/service/user_service.go
+++ b/service/user_service.go
@@ -181,7 +181,7 @@ func (s *userService) doTlBindingApply(req request.TlBindingApplyRequest, user *
func (userService) createBankCard(req request.TlBindingApplyRequest, user *model.User) (*model.UserBankCard, error) {
c := model.UserBankCard{}
- err := global.DB.Where("user_id", user.ID).Where("account_no", req.AcctNo).Find(&c).Error
+ err := global.DB.Where("user_id", user.ID).Where("account_no", req.AcctNo).First(&c).Error
if err != nil && !errors.Is(err, gorm.ErrRecordNotFound) {
return nil, err
}
@@ -203,7 +203,7 @@ func (userService) createBankCard(req request.TlBindingApplyRequest, user *model
func (s *userService) TlBindingConfirm(req request.TlBindingConfirmRequest, user *model.User) (result.Data, error) {
c := model.UserBankCard{}
- err := global.DB.Where("user_id", user.ID).Where("account_no", req.AcctNo).Find(&c).Error
+ err := global.DB.Where("user_id", user.ID).Where("account_no", req.AcctNo).First(&c).Error
if err != nil {
return nil, err
}
@@ -272,3 +272,35 @@ func (s *userService) GetBankCardByUserID(userID int) (*model.UserBankCard, erro
}
return &c, nil
}
+
+func (s *userService) BankCardUnbind(user *model.User) error {
+ c := model.UserBankCard{}
+ err := global.DB.Where("user_id", user.ID).Where("status", 1).First(&c).Error
+ if err != nil && errors.Is(err, gorm.ErrRecordNotFound) {
+ return errors.NewBusinessError("银行卡不存在")
+ }
+
+ if err != nil {
+ return err
+ }
+
+ p := param.UnbindParam{}
+ p.AgreeID = c.AgreeID
+ p.ReqIp = "127.0.0.1"
+ p.Version = "11"
+ r, err := tlpay.TLPay.Unbind(p)
+ if err != nil {
+ return err
+ }
+
+ if r.RetCode != "SUCCESS" {
+ return errors.NewBusinessError(r.RetMsg)
+ }
+
+ c.Status = 3
+ err = global.DB.Save(&c).Error
+ if err != nil {
+ return errors.NewBusinessError("更新失败")
+ }
+ return nil
+}
diff --git a/utils/tlpay/api.go b/utils/tlpay/api.go
index 9417c45..c7b65aa 100644
--- a/utils/tlpay/api.go
+++ b/utils/tlpay/api.go
@@ -64,6 +64,28 @@ func (api *tlPay) AgreeConfirm(p param.AgreeConfirmParam) (*result.AgreeConfirmR
return &r, nil
}
+func (api *tlPay) Unbind(p param.UnbindParam) (*result.CommonResult, error) {
+ payConfig := global.Config.TlPay
+ data, err := utils.StructToURLValues(p)
+ data = api.SetCommonParams(data, true)
+ sign, err := api.sign(data)
+ if err != nil {
+ return nil, err
+ }
+ fmt.Println(sign)
+ data.Set("sign", sign)
+ res, err := api.post(payConfig.BaseUrl+"/apiweb/qpay/unbind", data)
+ if err != nil {
+ return nil, err
+ }
+ r := result.CommonResult{}
+ err = json.Unmarshal(res, &r)
+ if err != nil {
+ return nil, err
+ }
+ return &r, nil
+}
+
func (api *tlPay) PayApplyAgree(p param.PayApplyAgreeParam) (*result.PayApplyAgreeResult, error) {
payConfig := global.Config.TlPay
data, err := utils.StructToURLValues(p)
@@ -159,6 +181,26 @@ func (api *tlPay) sign(params url.Values) (string, error) {
return utils.RSASign([]byte(signStr), payConfig.PriPemFile)
}
+func (api *tlPay) Verify(params url.Values) error {
+ payConfig := global.Config.TlPay
+ sign := params.Get("sign")
+ params.Del("sign")
+ for key, value := range params {
+ if len(value) == 0 || value[0] == "" {
+ params.Del(key)
+ }
+ }
+ //signStr, err := url.QueryUnescape(params.Encode())
+ //if err != nil {
+ // return err
+ //}
+ signStr := params.Encode()
+
+ fmt.Println("sign: ", sign)
+ fmt.Println("signStr: ", signStr)
+ return utils.RSAVerify([]byte(signStr), sign, payConfig.PriPemFile)
+}
+
func (api *tlPay) post(url string, data url.Values) ([]byte, error) {
client := &http.Client{}
body := strings.NewReader(data.Encode())
@@ -181,7 +223,7 @@ func (api *tlPay) post(url string, data url.Values) ([]byte, error) {
bodyBytes, err := io.ReadAll(response.Body)
- fmt.Println(string(bodyBytes))
+ fmt.Println("res: ", string(bodyBytes))
if err != nil {
return nil, errors.NewBusinessError("返回内容错误")
@@ -207,7 +249,7 @@ func (api *tlPay) BuildForm(data url.Values) string {
@@ -228,7 +270,7 @@ func (api *tlPay) buildFormHtml(data url.Values) string {
formHtml += ""
}
- formHtml += ""
+ //formHtml += ""
formHtml += ""
return formHtml
}
diff --git a/utils/tlpay/notify/gateway_pay_ret.go b/utils/tlpay/notify/gateway_pay_ret.go
new file mode 100644
index 0000000..d6daf02
--- /dev/null
+++ b/utils/tlpay/notify/gateway_pay_ret.go
@@ -0,0 +1,16 @@
+package notify
+
+type GatewayPayRet struct {
+ CusID string `json:"cusid" form:"cusid"`
+ AppID string `json:"appid" form:"appid"`
+ TrxCode string `json:"trxcode" form:"trxcode"`
+ TrxID string `json:"trxid" form:"trxid"`
+ TrxAmt string `json:"trxamt" form:"trxamt"`
+ TrxDate string `json:"trxdate" form:"trxdate"`
+ PayTime string `json:"paytime" form:"paytime"`
+ TrxStatus string `json:"trxstatus" form:"trxstatus"`
+ TrxReserved string `json:"trxreserved" form:"trxreserved"`
+ CusOrderID string `json:"cusorderid" form:"cusorderid"`
+ SignType string `json:"signtype" form:"signtype"`
+ Sign string `json:"sign" form:"sign"`
+}
diff --git a/utils/tlpay/notify/pay_agree_notify.go b/utils/tlpay/notify/pay_agree_notify.go
new file mode 100644
index 0000000..da93127
--- /dev/null
+++ b/utils/tlpay/notify/pay_agree_notify.go
@@ -0,0 +1,36 @@
+package notify
+
+type PayAgreeNotify struct {
+ CusID string `json:"cusid" form:"cusid"`
+ AppID string `json:"appid" form:"appid"`
+ OutTrxID string `json:"outTrxid" form:"outtrxid"`
+ TrxCode string `json:"trxcode" form:"trxcode"`
+ TrxID string `json:"trxid" form:"trxid"`
+ InitAmt string `json:"initamt" form:"initamt"`
+ TrxAmt string `json:"trxamt" form:"trxamt"`
+ TrxDate string `json:"trxdate" form:"trxdate"`
+ PayTime string `json:"paytime" form:"paytime"`
+ ChannelTrxID string `json:"chnltrxid" form:"chnltrxid"`
+ TrxStatus string `json:"trxstatus" form:"trxstatus"`
+
+ TermNo string `json:"termno" form:"termno"`
+ TermBatchID string `json:"termbatchid" form:"termbatchid"`
+ TermTraceNo string `json:"termtraceno" form:"termtraceno"`
+ TermAuthNo string `json:"termauthno" form:"termauthno"`
+ TermRefNum string `json:"termrefnum" form:"termrefnum"`
+
+ TrxReserved string `json:"trxreserved" form:"trxreserved"`
+ SrcTrxID string `json:"srctrxid" form:"srctrxid"`
+ CusOrderID string `json:"cusorderid" form:"cusorderid"`
+ Acct string `json:"acct" form:"acct"`
+ Fee string `json:"fee" form:"fee"`
+ CmID string `json:"cmid" form:"cmid"`
+ ChannelID string `json:"chnlid" form:"chnlid"`
+ ChannelData string `json:"chnldata" form:"chnldata"`
+ AcctType string `json:"accttype" form:"accttype"`
+ BankCode string `json:"bankcode" form:"bankcode"`
+ LogOnID string `json:"logonid" form:"logonid"`
+
+ SignType string `json:"signtype" form:"signtype"`
+ Sign string `json:"sign" form:"sign"`
+}
diff --git a/utils/tlpay/param/unbind_param.go b/utils/tlpay/param/unbind_param.go
new file mode 100644
index 0000000..903583b
--- /dev/null
+++ b/utils/tlpay/param/unbind_param.go
@@ -0,0 +1,14 @@
+package param
+
+type UnbindParam struct {
+ CusID string `json:"cusid" form:"cusid"`
+ AppID string `json:"appid" form:"appid"`
+ ReqTime string `json:"reqtime" form:"reqtime"`
+ ReqIp string `json:"reqip" form:"reqip"`
+ Version string `json:"version" form:"version"`
+ RandomStr string `json:"randomstr" form:"randomstr"`
+ SignType string `json:"signtype" form:"signtype"`
+ Sign string `json:"sign" form:"sign"`
+
+ AgreeID string `json:"agreeid" form:"agreeid"`
+}