Compare commits

...

15 Commits

Author SHA1 Message Date
wolter cfec0f5fca feat: 微信支付成功跳转return 2024-12-07 15:09:02 +08:00
wolter 964a0808b9 feat: 微信支付错误提示,跳转return 2024-12-07 14:35:43 +08:00
wolter cacfbccbcf feat: 微信退款fix 2024-12-06 22:06:05 +08:00
wolter 24c0c6d36a feat: 微信回调fix 2024-12-06 21:57:17 +08:00
wolter c2fd9e68f9 feat: 微信支付fix1 2024-12-06 21:30:45 +08:00
wolter ebcb3a9d7f feat: 微信支付fix 2024-12-06 20:42:44 +08:00
wolter 81dfd00cf9 feat: 微信支付2 2024-12-06 19:51:52 +08:00
wolter 5c32d74165 feat: 微信支付fix1 2024-12-06 16:02:22 +08:00
wolter 7588991d54 feat: 微信支付fix 2024-12-06 15:51:29 +08:00
wolter de1f1d01fc feat: 微信支付 2024-12-06 15:23:57 +08:00
wolter a03d0947a5 feat: dockerfile 2024-12-06 09:29:15 +08:00
wolter 1d3288acca feat: 微信jsapi 2024-12-06 09:22:21 +08:00
wolter 96aa3b16da feat: 微信jsapi 2024-12-06 09:16:53 +08:00
wolter fd57130499 Merge branch 'refs/heads/dev/dev1.0' into feature/zhifu 2024-12-05 18:41:36 +08:00
wolter 99aa763357 feat:ras加密fix 2024-12-05 18:19:13 +08:00
28 changed files with 1543 additions and 69 deletions

View File

@ -36,6 +36,7 @@ WORKDIR /app
COPY /server .
#COPY --from=builder /app/server .
COPY .env .
COPY ./front ./front
ENV TZ=Asia/Shanghai

View File

@ -6,6 +6,8 @@ const (
ADMIN_V1 = "/pay/admin/api/v1"
FRONT_V1 = "/pay/front/api/v1"
WXCodeRedirectAddress = FRONT_V1 + "/wx/payurl" // 微信支付授权code后 重定向地址
// 支付渠道枚举,1微信JSAPI2微信H53微信app4微信Native5微信小程序6支付宝网页&移动应用7支付宝小程序8支付宝JSAPI
PAY_CHANNEL_UNKNOWN = 0
PAY_CHANNEL_WECHAT_JSAPI = 1

View File

@ -52,7 +52,10 @@ const (
AppAesEncryptFail = 1234
AppDeEncryptFail = 1250
// 加密方式不存在
EncryptTypeNotFound = 1241
EncryptTypeNotFound = 1241
PayChannelConfigNotFound = 1242
// 加密参数异常
PayEncryptParamFail = 1243
//渠道
PayChannelNotFound = 1300
@ -74,6 +77,7 @@ const (
OrderNotSupportRefundPart = 1413
OrderRefundAmountError = 1414
OrderPayChannelChange = 1415
OrderPayRequestLogNotExist = 1416
// 关闭订单
CloseOrderPayed = 1420
@ -93,6 +97,10 @@ const (
// 退款
RefundOutTradeNoSame = 1801
// 微信授权
WechatAuthFail = 1901
WechatAuthSignFail = 1902
)
var MsgEN = map[int]string{
@ -138,7 +146,9 @@ var MsgZH = map[int]string{
AppAesEncryptFail: "aes 加密失败",
EncryptTypeNotFound: "加密方式不存在",
EncryptTypeNotFound: "加密方式不存在",
PayChannelConfigNotFound: "secret支付方式配置不存在",
PayEncryptParamFail: "加密参数错误,解析失败",
AppDeEncryptFail: "未知原因导致解密失败请检查加密数据是和app加密配置",
@ -150,15 +160,16 @@ var MsgZH = map[int]string{
RequestLogNotFound: "未找到日志信息",
RequestResponseValid: "上游返回格式无效",
OrdersNotFound: "未找到订单",
OrdersExist: "订单已存在",
OrderTypeNotFount: "未知的支付方式",
OrderIsDelete: "订单已删除",
OrderStatusErr: "订单状态错误",
OrderClosed: "订单已关闭,无法继续支付",
OrderFailed: "订单支付失败,请重新发起",
OrderPayed: "订单已支付成功,请勿重复支付",
OrderPayChannelChange: "支付方式不一致,切换支付方式请关闭原订单生成新订单",
OrdersNotFound: "未找到订单",
OrdersExist: "订单已存在",
OrderTypeNotFount: "未知的支付方式",
OrderIsDelete: "订单已删除",
OrderStatusErr: "订单状态错误",
OrderClosed: "订单已关闭,无法继续支付",
OrderFailed: "订单支付失败,请重新发起",
OrderPayed: "订单已支付成功,请勿重复支付",
OrderPayChannelChange: "支付方式不一致,切换支付方式请关闭原订单生成新订单",
OrderPayRequestLogNotExist: "订单下单数据不存在",
NotifySendFail: "回调发送失败",
RefundOrderNotFound: "退款订单未找到",
@ -173,6 +184,9 @@ var MsgZH = map[int]string{
CloseOrderPayed: "订单已支付成功,无法关闭",
ThirdRefundFail: "第三方退款失败",
WechatAuthFail: "微信授权失败",
WechatAuthSignFail: "微信签名失败",
}
var MsgMap map[string]map[int]string = map[string]map[int]string{"en": MsgZH}

View File

@ -49,3 +49,8 @@ func (m *OrderRequestLogRepo) OrderRequestLogBackendList(conn builder.Cond, page
repo.Join("left", "orders", "orders.app_id = order_request_log.app_id and orders.out_trade_no = order_request_log.out_trade_no")
return repo.Desc("order_request_log.create_time").FindAndCount(orderLogList)
}
// 查询订单日志
func (m *OrderRequestLogRepo) OrderRequestLogGet(orderLog *orderrequestlogmodel.OrderRequestLog, conn builder.Cond) (bool, error) {
return m.repo.Where(conn).Get(orderLog)
}

View File

@ -3,9 +3,13 @@ package front
import (
"PaymentCenter/app/constants/common"
"PaymentCenter/app/constants/errorcode"
"PaymentCenter/app/http/controllers"
"PaymentCenter/app/http/entities/front"
"PaymentCenter/app/models/paychannelmodel"
"PaymentCenter/app/services"
"PaymentCenter/app/services/thirdpay"
"PaymentCenter/app/third/paymentService"
"PaymentCenter/app/utils"
"encoding/json"
"fmt"
"github.com/gin-gonic/gin"
@ -39,7 +43,7 @@ func WxCallback(c *gin.Context) {
c.String(http.StatusBadRequest, "%s", "fail")
return
}
if payChannelModel.ChannelType != common.PAY_CHANNEL_WECHAT_H5 {
if !(payChannelModel.ChannelType == common.PAY_CHANNEL_WECHAT_H5 || payChannelModel.ChannelType == common.PAY_CHANNEL_WECHAT_JSAPI) {
logger.Error(c, "WxCallback-回调数据解析支付配置错误,查询的数据不是当前渠道")
c.String(http.StatusBadRequest, "%s", "fail")
return
@ -189,3 +193,70 @@ func BrokerWechatUrl(c *gin.Context) {
return
}
}
// 拼接微信授权链接
func GetWxAuthUrl(c *gin.Context) {
req, _ := controllers.GetRequest(c).(*front.GetWxAuthUrlRequest)
url, code := thirdpay.GetWxAuthUrl(*req)
controllers.HandCodeRes(c, url, code)
}
// 通过code获取授权openid
func GetWxAuth(c *gin.Context) {
req, _ := controllers.GetRequest(c).(*front.GetWxAuthRequest)
rsp, code := thirdpay.GetWxAuth(*req)
controllers.HandCodeRes(c, rsp, code)
}
// 接收code
func GetWxCode(c *gin.Context) {
req, _ := controllers.GetRequest(c).(*front.GetWxAuthRequest)
//rsp, code := thirdpay.GetWxAuth(*req)
controllers.HandCodeRes(c, req, 200)
}
// 微信JSAPI 支付接口
/*
预支付接口实现如下功能
1.订单请求参数
2.订单信息存数据
3.返回用户授权地址
wxjsapi接口实现如下功能
4.用户授权后获取codestatu传的是订单号
5.通过code获取openid
6.通过openid请求微信下单返回支付参数
7.支付参数聚合签名返回支付参数给前端
*/
func WxJsApiPay(c *gin.Context) {
req, _ := controllers.GetRequest(c).(*front.WxJsApiPayRequest)
req.ClientIp = c.ClientIP()
rsp, code := thirdpay.WxJsApiPay(*req)
if code == errorcode.Success {
c.HTML(http.StatusOK, "success.html", gin.H{
"appId": rsp.AppId,
"timeStamp": rsp.TimeStamp,
"nonceStr": rsp.NonceStr,
"package": rsp.Package,
"signType": rsp.SignType,
"paySign": rsp.PaySign,
"returnUrl": rsp.ReturnUrl,
})
} else {
utils.Log(c, "", "WxJsApiPay,支付失败code=", code, "msg=", rsp.ThirdMsg)
errmsg := rsp.ThirdMsg
data := make(map[string]interface{})
_ = json.Unmarshal([]byte(rsp.ThirdMsg), &data)
if message, ok := data["message"]; ok {
errmsg = message.(string)
}
if errmsg == "" {
errmsg = errorcode.GetMsg(code, "")
}
c.HTML(http.StatusOK, "fail.html", gin.H{
"errmsg": errmsg,
})
}
}

View File

@ -19,6 +19,7 @@ type PayCommonReqBody struct {
ExtJson string `json:"ext_json" label:"扩展参数"`
Desc string `json:"desc" validate:"max=100" label:"商品描述"`
ReturnUrl string `json:"return_url" validate:"max=1024" label:"支付成功后跳转的地址"`
OpenId string `json:"open_id" label:"用户openid"`
}
type PayReqs struct {

View File

@ -0,0 +1,46 @@
package front
type GetWxAuthUrlRequest struct {
PayChannelId string `json:"pay_channel_id" form:"pay_channel_id" validate:"required"`
}
type GetWxAuthRequest struct {
Code string `json:"code" form:"code" `
PayChannelId string `json:"state" form:"state"`
}
// 获取微信用户信息
type GetWxAuthResponse struct {
AccessToken string `json:"access_token"` //网页授权接口调用凭证,注意此access_token与基础支持的access_token不同
ExpiresIn int `json:"expires_in"` //access_token接口调用凭证超时时间单位
RefreshToken string `json:"refresh_token"` //用户刷新access_token
Openid string `json:"openid"` //用户唯一标识请注意在未关注公众号时用户访问公众号的网页也会产生一个用户和公众号唯一的OpenID
Scope string `json:"scope"` //用户授权的作用域,使用逗号(,)分隔
IsSnapshotuser int `json:"is_snapshotuser"`
Unionid string `json:"unionid"` // 用户统一标识(针对一个微信开放平台账号下的应用,同一用户的 unionid 是唯一的只有当scope为"snsapi_userinfo"时返回
}
// jsapi支付
type WxJsApiPayRequest struct {
Code string `json:"code" form:"code" `
State string `json:"state" form:"state"` // 支付中心的订单id
ClientIp string `json:"client_ip" form:"client_ip"`
}
//// jsapi支付返回
//type WxJsApiPayResponse struct {
// Url string
// ThirdMsg string
//}
// jsapi支付返回
type WxJsApiPayResponse struct {
AppId string `json:"appId"`
TimeStamp string `json:"timeStamp"`
NonceStr string `json:"nonceStr"`
Package string `json:"package"`
SignType string `json:"signType"`
PaySign string `json:"paySign"`
ThirdMsg string `json:"third_msg"`
ReturnUrl string
}

View File

@ -107,6 +107,7 @@ func ValidateRequest() gin.HandlerFunc {
return func(c *gin.Context) {
var path = c.FullPath()
var handler func() interface{}
var logId int64
if strings.Index(path, "admin") >= 0 {
handler = requestmapping.BackendRequestMap[path]
@ -126,6 +127,17 @@ func ValidateRequest() gin.HandlerFunc {
c.Abort()
}
c.Set("request", v)
//表单验证
logHandler := requestmapping.FrontRequestMap[path]
if logHandler != nil {
_, isSaveLog := logHandler()
if isSaveLog {
logContent, _ := json.Marshal(v)
//记录请求日志
logId, _ = services.AddRequestLog(logContent, c.ClientIP(), path)
}
c.Set("log", logId)
}
c.Next()
}

View File

@ -33,10 +33,10 @@ func ServerRecovery() gin.HandlerFunc {
}
c.JSON(500, gin.H{
"code": 500,
"msg": "system error",
"request_uri": c.Request.URL.Path,
"data": make(map[string]string),
"code": 500,
"msg": "system error",
//"request_uri": c.Request.URL.Path,
//"data": make(map[string]string),
})
}
}()

View File

@ -2,6 +2,7 @@ package requestmapping
import (
"PaymentCenter/app/constants/common"
"PaymentCenter/app/http/entities"
"PaymentCenter/app/http/entities/front"
)
@ -10,12 +11,19 @@ var FrontRequestMap = map[string]func() (validForm interface{}, isSaveLog bool){
common.FRONT_V1 + "/pay/refund": func() (interface{}, bool) { return new(front.RefundReqs), true },
common.FRONT_V1 + "/pay/query": func() (interface{}, bool) { return new(front.QueryReqs), false },
common.FRONT_V1 + "/pay/close": func() (interface{}, bool) { return new(front.CloseReqs), true },
common.FRONT_V1 + "/wx/payurl": func() (interface{}, bool) { return new(front.WxJsApiPayRequest), true },
}
var FrontRequestMapBeforeDecrypt = map[string]func() interface{}{
common.FRONT_V1 + "/pay/url": func() interface{} { return new(front.RequestBody) },
common.FRONT_V1 + "/pay/refund": func() interface{} { return new(front.RequestBody) },
common.FRONT_V1 + "/pay/query": func() interface{} { return new(front.RequestBody) },
common.FRONT_V1 + "/pay/close": func() interface{} { return new(front.CloseReqs) },
common.FRONT_V1 + "/pay/url": func() interface{} { return new(front.RequestBody) },
common.FRONT_V1 + "/pay/refund": func() interface{} { return new(front.RequestBody) },
common.FRONT_V1 + "/pay/query": func() interface{} { return new(front.RequestBody) },
common.FRONT_V1 + "/pay/close": func() interface{} { return new(front.CloseReqs) },
common.FRONT_V1 + "/wx/index": func() interface{} { return new(entities.PageRequest) },
common.FRONT_V1 + "/wx/getWxAuthUrl": func() interface{} { return new(front.GetWxAuthUrlRequest) },
common.FRONT_V1 + "/wx/getWxAuth": func() interface{} { return new(front.GetWxAuthRequest) },
common.FRONT_V1 + "/wx/getCode": func() interface{} { return new(front.GetWxAuthRequest) },
common.WXCodeRedirectAddress: func() interface{} { return new(front.WxJsApiPayRequest) },
}

View File

@ -67,6 +67,18 @@ func RegisterRoute(router *gin.Engine) {
v1.GET("/brokerWechatUrl", front.BrokerWechatUrl)
}
// 微信获取授权相关
router.LoadHTMLGlob("./front/templates/*")
wx := v1.Group("/wx", middlewares.ValidateRequest())
{
wx.POST("/getWxAuthUrl", front.GetWxAuthUrl) // 获取授权codeUrl
wx.GET("/getWxAuth", front.GetWxAuth) // 获取openId
wx.GET("/getCode", front.GetWxCode) // 接收微信code
}
// 微信jsapi支付链接
router.GET(common.WXCodeRedirectAddress, middlewares.ValidateRequest(), front.WxJsApiPay)
router.GET("/swagger/*any", ginSwagger.WrapHandler(swaggerFiles.Handler))
}

View File

@ -64,7 +64,7 @@ func (a *AppCheck) Crypt() (cryptFunc func(app *appmodel.App) apicrypt.ApiCrypt)
func (a *AppCheck) ReCheckAfterDecrypt(data []byte, requestData *front.RequestBody) bool {
var requestCommonData front.ApiCommonBody
if err := sonic.Unmarshal(data, &requestCommonData); err != nil {
a.Code = errorcode.ParamError
a.Code = errorcode.PayEncryptParamFail
return false
}
if requestCommonData.AppId != requestData.AppId || requestCommonData.Timestamp != requestData.Timestamp {

View File

@ -149,3 +149,17 @@ func PayOrderCheckRepeat(order *ordersmodel.Orders, conn builder.Cond) (exist bo
}
return true, code
}
// 商户请求日志
func OrderRequestLogs(req *orderrequestlogmodel.OrderRequestLog) (bool, error) {
requestRepo := data.NewOrderRequestLogRepo(paychannelmodel.GetInstance().GetDb())
conn := builder.NewCond()
if req.OutTradeNo != "" {
conn = conn.And(builder.Eq{"out_trade_no": req.OutTradeNo})
}
if req.AppId > 0 {
conn = conn.And(builder.Eq{"app_id": req.AppId})
}
return requestRepo.OrderRequestLogGet(req, conn)
}

View File

@ -8,7 +8,10 @@ import (
"PaymentCenter/app/services"
"PaymentCenter/app/third/paymentService/payCommon"
"PaymentCenter/app/utils"
"PaymentCenter/config"
"context"
"net/url"
"strconv"
"xorm.io/builder"
"PaymentCenter/app/models/ordersmodel"
@ -25,6 +28,7 @@ type PayParam struct {
Desc string
ClientIp string
ReturnUrl string
OpenId string
}
type Pay struct {
@ -50,6 +54,7 @@ func NewPayWithPayCheck(paycheck *PayCheck) *Pay {
Desc: paycheck.Reqs.Desc,
ClientIp: paycheck.AppCheck.Ip,
ReturnUrl: paycheck.Reqs.ReturnUrl,
OpenId: paycheck.Reqs.OpenId,
},
RelationOrder: paycheck.OldOrder,
PayCode: errorcode.Success,
@ -97,6 +102,7 @@ func (w *Pay) PayUrl() (url string) {
var (
payFunc func(commonPayInfo *paymentService.PayOrderRequest, channel *paychannelmodel.PayChannel) error
ok bool
res paymentService.PayOrderResponse
)
thirdPay := &paymentService.PayOrderRequest{
PayChannelId: w.PayParam.Channel.Id,
@ -106,7 +112,9 @@ func (w *Pay) PayUrl() (url string) {
Amount: w.Order.Amount,
PayerClientIp: w.PayParam.ClientIp,
ReturnUrl: w.PayParam.ReturnUrl,
OpenId: w.PayParam.OpenId,
}
// 判断是否是支持的支付渠道,找到对应的配置
if payFunc, ok = PayWayList[w.PayParam.Channel.ChannelType]; !ok {
w.PayCode = errorcode.PayChannelNotBuild
return
@ -116,7 +124,26 @@ func (w *Pay) PayUrl() (url string) {
w.PayCode = errorcode.PayChannelExtJsonError
return
}
res := paymentService.PaymentService(*w.ctx, *thirdPay)
switch w.PayParam.Channel.ChannelType {
// 微信公众号支付,返回的是用户授权链接
case common.PAY_CHANNEL_WECHAT_JSAPI:
// 获取授权链接
res.Result, res.Code = w.GetWxAuthUrl(w.PayParam.Channel.AppId, w.Order.Id)
case common.PAY_CHANNEL_ALIPAY_WEB:
// 支付宝h5
res = paymentService.PaymentService(*w.ctx, *thirdPay)
case common.PAY_CHANNEL_WECHAT_H5:
// 微信h5支付
res = paymentService.PaymentService(*w.ctx, *thirdPay)
if res.Result != "" {
res.Result = config.GetConf().PayService.Host + "/pay/front/api/v1/brokerWechatUrl" + "?url=" + res.Result
}
default:
w.PayCode = errorcode.PayChannelNotBuild
return
}
//res := paymentService.PaymentService(*w.ctx, *thirdPay)
if res.Code == payCommon.PAY_SUCCESS_CODE {
w.Order.Status = common.ORDER_STATUS_PAYING
@ -204,3 +231,20 @@ func (w *Pay) CloseOrder() {
w.ThirdMsg = res.ErrorMsg
w.PayCode = res.Code
}
// appid:微信的公众号appid
func (w *Pay) GetWxAuthUrl(appid string, orderId int64) (targetUrl string, code int) {
var (
// 重定向地址
redirectUri = config.GetConf().PayService.Host + common.WXCodeRedirectAddress
)
baseUrl := "https://open.weixin.qq.com/connect/oauth2/authorize"
redirectUri = url.QueryEscape(redirectUri)
responseType := "code"
scope := "snsapi_base"
order := strconv.Itoa(int(orderId))
targetUrl = baseUrl + "?appid=" + appid + "&redirect_uri=" + redirectUri + "&response_type=" + responseType + "&scope=" + scope + "&state=" + order + "#wechat_redirect"
code = errorcode.Success
return
}

View File

@ -7,9 +7,11 @@ import (
"github.com/bytedance/sonic"
)
// 支持的支付方式
var PayWayList = map[int]func(commonPayInfo *paymentService.PayOrderRequest, channel *paychannelmodel.PayChannel) error{
common.PAY_CHANNEL_WECHAT_H5: WechatH5,
common.PAY_CHANNEL_ALIPAY_WEB: AlipayWeb,
common.PAY_CHANNEL_WECHAT_H5: WechatH5,
common.PAY_CHANNEL_ALIPAY_WEB: AlipayWeb,
common.PAY_CHANNEL_WECHAT_JSAPI: WechatJSAPI,
}
func WechatH5(commonPayInfo *paymentService.PayOrderRequest, channel *paychannelmodel.PayChannel) error {
@ -29,3 +31,11 @@ func AlipayWeb(commonPayInfo *paymentService.PayOrderRequest, channel *paychanne
commonPayInfo.Ali.AppId = channel.AppId
return nil
}
func WechatJSAPI(commonPayInfo *paymentService.PayOrderRequest, channel *paychannelmodel.PayChannel) error {
err := sonic.Unmarshal([]byte(channel.ExtJson), &commonPayInfo.Wx)
if err != nil {
return err
}
commonPayInfo.Wx.AppId = channel.AppId
return nil
}

View File

@ -8,8 +8,9 @@ import (
)
var RefundWayList = map[int]func(commonRefundInfo *paymentService.OrderRefundRequest, channel *paychannelmodel.PayChannel) error{
common.PAY_CHANNEL_WECHAT_H5: WechatH5Refund,
common.PAY_CHANNEL_ALIPAY_WEB: AlipayWebRefund,
common.PAY_CHANNEL_WECHAT_H5: WechatH5Refund,
common.PAY_CHANNEL_ALIPAY_WEB: AlipayWebRefund,
common.PAY_CHANNEL_WECHAT_JSAPI: WechatJSAPIRefund,
}
func WechatH5Refund(commonRefundInfo *paymentService.OrderRefundRequest, channel *paychannelmodel.PayChannel) error {
@ -31,3 +32,13 @@ func AlipayWebRefund(commonRefundInfo *paymentService.OrderRefundRequest, channe
commonRefundInfo.Ali.AppId = channel.AppId
return nil
}
func WechatJSAPIRefund(commonRefundInfo *paymentService.OrderRefundRequest, channel *paychannelmodel.PayChannel) error {
commonRefundInfo.PayChannel = common.PAY_CHANNLE_TYPE_WECHAT
err := sonic.Unmarshal([]byte(channel.ExtJson), &commonRefundInfo.Wx)
if err != nil {
return err
}
commonRefundInfo.Wx.AppId = channel.AppId
return nil
}

359
app/services/thirdpay/wx.go Normal file
View File

@ -0,0 +1,359 @@
package thirdpay
import (
"PaymentCenter/app/constants/common"
"PaymentCenter/app/constants/errorcode"
"PaymentCenter/app/http/entities/front"
"PaymentCenter/app/models/orderrequestlogmodel"
"PaymentCenter/app/models/ordersmodel"
"PaymentCenter/app/models/paychannelmodel"
"PaymentCenter/app/services"
"PaymentCenter/app/third/paymentService"
"PaymentCenter/app/third/paymentService/payCommon"
"PaymentCenter/app/utils"
"PaymentCenter/app/utils/httpclient"
"PaymentCenter/config"
"context"
"crypto"
"crypto/rsa"
"crypto/sha256"
"crypto/x509"
"encoding/base64"
"encoding/json"
"encoding/pem"
"errors"
"fmt"
"net/url"
"strconv"
"time"
"xorm.io/builder"
)
// 获取授权链接
func GetWxAuthUrl(param front.GetWxAuthUrlRequest) (targetUrl string, code int) {
var (
// 重定向地址
redirectUri = config.GetConf().PayService.Host + common.WXCodeRedirectAddress
)
baseUrl := "https://open.weixin.qq.com/connect/oauth2/authorize"
// 获取支付渠道的配置
id, err := strconv.Atoi(param.PayChannelId)
if err != nil {
code = handErr(err)
return
}
payChannel := paychannelmodel.PayChannel{Id: int64(id)}
code = services.PayChannelGet(&payChannel)
if code != 200 {
return
}
appid := payChannel.AppId
redirectUri = url.QueryEscape(redirectUri)
responseType := "code"
scope := "snsapi_base"
targetUrl = baseUrl + "?appid=" + appid + "&redirect_uri=" + redirectUri + "&response_type=" + responseType + "&scope=" + scope + "&state=" + param.PayChannelId + "#wechat_redirect"
return
}
// // 通过code换取网页授权access_tokenopenid
func GetWxAuth(param front.GetWxAuthRequest) (rsp front.GetWxAuthResponse, code int) {
// 获取支付渠道的配置
id, err := strconv.Atoi(param.PayChannelId)
if err != nil {
code = handErr(err)
return
}
payChannel := paychannelmodel.PayChannel{Id: int64(id)}
code = services.PayChannelGet(&payChannel)
if code != 200 {
return
}
//// 配置支付的解析
wxConfig := make(map[string]interface{})
err = json.Unmarshal([]byte(payChannel.ExtJson), &wxConfig)
if err != nil {
code = handErr(err)
return
}
sk := wxConfig["secret"].(string)
if sk == "" {
code = errorcode.PayChannelConfigNotFound
return
}
targetUrl := fmt.Sprintf("https://api.weixin.qq.com/sns/oauth2/access_token?appid=%s&secret=%s&code=%s&grant_type=authorization_code",
payChannel.AppId,
sk,
param.Code,
)
header := map[string]string{
"Content-Type": "application/json",
}
body := map[string]string{}
response, err := httpclient.FastHttpGet(targetUrl, header, body, 0)
if err != nil {
code = handErr(err)
return
}
utils.Log(nil, "获取微信授权信息", string(response), targetUrl)
// 解析返回数据
err = json.Unmarshal(response, &rsp)
if err != nil {
code = handErr(err)
return
}
if rsp.Openid == "" {
code = errorcode.WechatAuthFail
return
}
code = handErr(err)
return
}
// 微信JSAPI 支付接口
/*
1.获取订单请求参数
2.订单信息存数据
3.返回用户授权地址
4.用户授权后获取code
5.通过code获取openid
6.通过openid请求微信下单返回支付参数
7.支付参数聚合签名返回支付参数给前端
*/
type wxJsapiPay struct {
code int
msg string
param front.WxJsApiPayRequest
order *ordersmodel.Orders
payChannel paychannelmodel.PayChannel
wxConfig paymentService.WxPay
orderPayRequest front.PayReqs
openId string // 用户openid
}
func newWxJsapiPay(param front.WxJsApiPayRequest) *wxJsapiPay {
return &wxJsapiPay{param: param}
}
func (this *wxJsapiPay) getOrder() {
order := new(ordersmodel.Orders)
this.order, this.code = services.OrderFindOne(order, builder.Eq{"id": this.param.State})
if this.code != errorcode.Success {
return
}
switch this.order.Status {
case common.ORDER_STATUS_PAYED:
this.code = errorcode.OrderPayed
case common.ORDER_STATUS_CLOSE:
this.code = errorcode.OrderClosed
}
}
func (this *wxJsapiPay) getPayChannel() {
payChannel := paychannelmodel.PayChannel{Id: this.order.PayChannelId}
this.code = services.PayChannelGet(&payChannel)
this.payChannel = payChannel
}
// 获取下单的请求参数
func (this *wxJsapiPay) getOrderRequestLogs() {
orderRequestLog := orderrequestlogmodel.OrderRequestLog{
OutTradeNo: this.order.OutTradeNo,
AppId: this.order.AppId,
}
has, err := services.OrderRequestLogs(&orderRequestLog)
if err != nil {
this.code = handErr(err)
return
}
if !has {
this.code = errorcode.OrderPayRequestLogNotExist
return
}
err = json.Unmarshal([]byte(orderRequestLog.MerchantRequest), &this.orderPayRequest)
if err != nil {
this.code = handErr(err)
return
}
}
func (this *wxJsapiPay) getOpenId() {
var err error
//// 配置支付的解析
wxConfig := paymentService.WxPay{}
err = json.Unmarshal([]byte(this.payChannel.ExtJson), &wxConfig)
if err != nil {
this.code = handErr(err)
return
}
sk := wxConfig.Secret
if sk == "" {
this.code = errorcode.PayChannelConfigNotFound
return
}
this.wxConfig = wxConfig
targetUrl := fmt.Sprintf("https://api.weixin.qq.com/sns/oauth2/access_token?appid=%s&secret=%s&code=%s&grant_type=authorization_code",
this.payChannel.AppId,
sk,
this.param.Code,
)
header := map[string]string{
"Content-Type": "application/json",
}
body := map[string]string{}
response, err := httpclient.FastHttpGet(targetUrl, header, body, 0)
if err != nil {
this.code = handErr(err)
return
}
utils.Log(nil, "获取微信授权信息", string(response), targetUrl)
// 解析返回数据
var rsp front.GetWxAuthResponse
err = json.Unmarshal(response, &rsp)
if err != nil {
this.code = handErr(err)
return
}
if rsp.Openid == "" {
this.code = errorcode.WechatAuthFail
this.msg = string(response)
return
}
this.openId = rsp.Openid
this.code = handErr(err)
}
func (this *wxJsapiPay) Sign(AppId, TimeStamp, NonceStr, Package string) (res string, err error) {
//组装被加密的字符串
targetStr := AppId + "\n" + TimeStamp + "\n" + NonceStr + "\n" + Package + "\n"
//加密
sign, err := this.SHA256WithRsaBase64(targetStr)
return sign, err
}
func (this *wxJsapiPay) SHA256WithRsaBase64(origData string) (sign string, err error) {
//var keypath = "商户证书私钥地址"
//key, err := ioutil.ReadFile(keypath)
var key []byte
if this.wxConfig.PrivateKey == "" {
return "", errors.New("配置的私钥不存在")
}
key = []byte(this.wxConfig.PrivateKey)
blocks, _ := pem.Decode(key)
if blocks == nil || blocks.Type != "PRIVATE KEY" {
utils.Log(nil, "failed to decode PRIVATE KEY")
return
}
privateKey, err := x509.ParsePKCS8PrivateKey(blocks.Bytes)
h := sha256.New()
h.Write([]byte(origData))
digest := h.Sum(nil)
s, _ := rsa.SignPKCS1v15(nil, privateKey.(*rsa.PrivateKey), crypto.SHA256, digest)
sign = base64.StdEncoding.EncodeToString(s)
return sign, err
}
func WxJsApiPay(param front.WxJsApiPayRequest) (response front.WxJsApiPayResponse, code int) {
var ctx = context.Background()
task := newWxJsapiPay(param)
// 1 获取订单
task.getOrder()
if task.code != errorcode.Success {
return response, task.code
}
// 获取支付渠道配置
task.getPayChannel()
if task.code != errorcode.Success {
return response, task.code
}
// 获取下单的请求参数
task.getOrderRequestLogs()
if task.code != errorcode.Success {
return response, task.code
}
// 2 通过code获取openid
task.getOpenId()
if task.code != errorcode.Success {
response.ThirdMsg = task.msg
return response, task.code
}
task.wxConfig.AppId = task.payChannel.AppId
order := task.order
// 通过openid订单数据请求微信下单, 获取prepay_id
orderRequest := paymentService.PayOrderRequest{
PayChannelId: order.PayChannelId,
OrderId: order.Id,
ChannelType: task.payChannel.ChannelType,
Description: order.Desc,
Amount: order.Amount,
PayerClientIp: param.ClientIp,
ReturnUrl: task.orderPayRequest.ReturnUrl,
Wx: task.wxConfig,
Ali: paymentService.AliPay{},
OpenId: task.openId,
}
res := paymentService.PaymentService(ctx, orderRequest)
// 下单失败
if res.Code != payCommon.PAY_SUCCESS_CODE {
task.code = errorcode.PrePayFail
response.ThirdMsg = res.ErrorMsg
return response, task.code
}
// 更新订单状态
order.Status = common.ORDER_STATUS_PAYING
task.code = services.OrderUpdate(order, "status")
if task.code != errorcode.Success {
utils.Log(nil, "成功下单,更新订单状态失败", order)
}
// 3 组装返回数据
response = front.WxJsApiPayResponse{
AppId: task.payChannel.AppId,
TimeStamp: strconv.Itoa(int(time.Now().Unix())),
NonceStr: strconv.Itoa(int(time.Now().Unix())),
Package: "prepay_id=" + res.Result,
SignType: "RSA",
PaySign: "",
ThirdMsg: "",
}
// 4 签名
signValue, err := task.Sign(response.AppId, response.TimeStamp, response.NonceStr, response.Package)
if err != nil {
utils.Log(nil, "签名失败", err)
return response, errorcode.WechatAuthFail
}
response.PaySign = signValue
response.ReturnUrl = task.orderPayRequest.ReturnUrl
return response, task.code
}
func handErr(err error) int {
if err != nil {
utils.Log(nil, "sys err", err.Error())
return errorcode.SystemError
} else {
return errorcode.Success
}
}

316
app/services/wecaht.go Normal file
View File

@ -0,0 +1,316 @@
package services
//import (
// "PaymentCenter/app/constants/common"
// "PaymentCenter/app/constants/errorcode"
// "PaymentCenter/app/http/entities/front"
// "PaymentCenter/app/models/ordersmodel"
// "PaymentCenter/app/models/paychannelmodel"
// "PaymentCenter/app/third/paymentService"
// "PaymentCenter/app/third/paymentService/payCommon"
// "PaymentCenter/app/utils"
// "PaymentCenter/app/utils/httpclient"
// "PaymentCenter/config"
// "context"
// "crypto"
// "crypto/rsa"
// "crypto/sha256"
// "crypto/x509"
// "encoding/base64"
// "encoding/json"
// "encoding/pem"
// "errors"
// "fmt"
// "net/url"
// "strconv"
// "time"
// "xorm.io/builder"
//)
//
//// 获取授权链接
//func GetWxAuthUrl(param front.GetWxAuthUrlRequest) (targetUrl string, code int) {
// var (
// // 重定向地址
// redirectUri = config.GetConf().PayService.Host + common.FRONT_V1 + "/wx/getWxAuth"
// )
// baseUrl := "https://open.weixin.qq.com/connect/oauth2/authorize"
//
// // 获取支付渠道的配置
// id, err := strconv.Atoi(param.PayChannelId)
// if err != nil {
// code = handErr(err)
// return
// }
// payChannel := paychannelmodel.PayChannel{Id: int64(id)}
// code = PayChannelGet(&payChannel)
// if code != 200 {
// return
// }
// //// 配置解析
// //wxConfig := paymentService.WxPay{}
// //err = json.Unmarshal([]byte(payChannel.ExtJson), &wxConfig)
// //if err != nil {
// // code = handErr(err)
// // return
// //}
//
// appid := payChannel.AppId
// redirectUri = url.QueryEscape(redirectUri)
// responseType := "code"
// scope := "snsapi_base"
//
// targetUrl = baseUrl + "?appid=" + appid + "&redirect_uri=" + redirectUri + "&response_type=" + responseType + "&scope=" + scope + "&state=" + param.PayChannelId + "#wechat_redirect"
// return
//}
//
//// // 通过code换取网页授权access_tokenopenid
//func GetWxAuth(param front.GetWxAuthRequest) (rsp front.GetWxAuthResponse, code int) {
//
// // 获取支付渠道的配置
// id, err := strconv.Atoi(param.PayChannelId)
// if err != nil {
// code = handErr(err)
// return
// }
// payChannel := paychannelmodel.PayChannel{Id: int64(id)}
// code = PayChannelGet(&payChannel)
// if code != 200 {
// return
// }
//
// //// 配置支付的解析
// wxConfig := make(map[string]interface{})
// err = json.Unmarshal([]byte(payChannel.ExtJson), &wxConfig)
// if err != nil {
// code = handErr(err)
// return
// }
// sk := wxConfig["secret"].(string)
// if sk == "" {
// code = errorcode.PayChannelConfigNotFound
// return
// }
//
// targetUrl := fmt.Sprintf("https://api.weixin.qq.com/sns/oauth2/access_token?appid=%s&secret=%s&code=%s&grant_type=authorization_code",
// payChannel.AppId,
// sk,
// param.Code,
// )
//
// header := map[string]string{
// "Content-Type": "application/json",
// }
// body := map[string]string{}
// response, err := httpclient.FastHttpGet(targetUrl, header, body, 0)
// if err != nil {
// code = handErr(err)
// return
// }
// utils.Log(nil, "获取微信授权信息", string(response), targetUrl)
//
// // 解析返回数据
// err = json.Unmarshal(response, &rsp)
// if err != nil {
// code = handErr(err)
// return
// }
// if rsp.Openid == "" {
// code = errorcode.WechatAuthFail
// return
// }
// code = handErr(err)
// return
//}
//
//// 微信JSAPI 支付接口
///*
//1.获取订单请求参数
//2.订单信息存数据
//3.返回用户授权地址
//4.用户授权后获取code
//5.通过code获取openid
//6.通过openid请求微信下单返回支付参数
//7.支付参数聚合,签名,返回支付参数给前端
//*/
//type wxJsapiPay struct {
// code int
// msg string
// param front.WxJsApiPayRequest
// order *ordersmodel.Orders
// payChannel paychannelmodel.PayChannel
// wxConfig map[string]interface{}
//
// openId string // 用户openid
//}
//
//func newWxJsapiPay(param front.WxJsApiPayRequest) *wxJsapiPay {
// return &wxJsapiPay{param: param}
//}
//
//func (this *wxJsapiPay) getOrder() {
// order := new(ordersmodel.Orders)
// this.order, this.code = OrderFindOne(order, builder.Eq{"id": this.param.State})
//}
//func (this *wxJsapiPay) getPayChannel() {
// payChannel := paychannelmodel.PayChannel{Id: this.order.PayChannelId}
// this.code = PayChannelGet(&payChannel)
// this.payChannel = payChannel
//}
//
//func (this *wxJsapiPay) getOpenId() {
// var err error
// //// 配置支付的解析
// wxConfig := make(map[string]interface{})
// err = json.Unmarshal([]byte(this.payChannel.ExtJson), &wxConfig)
// if err != nil {
// this.code = handErr(err)
// return
// }
// sk := wxConfig["secret"].(string)
// if sk == "" {
// this.code = errorcode.PayChannelConfigNotFound
// return
// }
// this.wxConfig = wxConfig
//
// targetUrl := fmt.Sprintf("https://api.weixin.qq.com/sns/oauth2/access_token?appid=%s&secret=%s&code=%s&grant_type=authorization_code",
// this.payChannel.AppId,
// sk,
// this.param.Code,
// )
//
// header := map[string]string{
// "Content-Type": "application/json",
// }
// body := map[string]string{}
// response, err := httpclient.FastHttpGet(targetUrl, header, body, 0)
// if err != nil {
// this.code = handErr(err)
// return
// }
// utils.Log(nil, "获取微信授权信息", string(response), targetUrl)
//
// // 解析返回数据
// var rsp front.GetWxAuthResponse
// err = json.Unmarshal(response, &rsp)
// if err != nil {
// this.code = handErr(err)
// return
// }
// if rsp.Openid == "" {
// this.code = errorcode.WechatAuthFail
// return
// }
// this.openId = rsp.Openid
// this.code = handErr(err)
//}
//
//func (this *wxJsapiPay) Sign(AppId, TimeStamp, NonceStr, Package string) (res string, err error) {
// //组装被加密的字符串
//
// targetStr := AppId + "\n" + TimeStamp + "\n" + NonceStr + "\n" + Package + "\n"
// //加密
// sign, err := this.SHA256WithRsaBase64(targetStr)
//
// return sign, err
//}
//
//func (this *wxJsapiPay) SHA256WithRsaBase64(origData string) (sign string, err error) {
// //var keypath = "商户证书私钥地址"
// //key, err := ioutil.ReadFile(keypath)
// var key []byte
// if pri, ok := this.wxConfig["private_key"].(string); ok {
// key = []byte(pri)
// } else {
// return "", errors.New("配置的私钥不存在")
// }
//
// blocks, _ := pem.Decode(key)
// if blocks == nil || blocks.Type != "PRIVATE KEY" {
// utils.Log(nil, "failed to decode PRIVATE KEY")
// return
//
// }
// privateKey, err := x509.ParsePKCS8PrivateKey(blocks.Bytes)
//
// h := sha256.New()
// h.Write([]byte(origData))
// digest := h.Sum(nil)
// s, _ := rsa.SignPKCS1v15(nil, privateKey.(*rsa.PrivateKey), crypto.SHA256, digest)
// sign = base64.StdEncoding.EncodeToString(s)
//
// return sign, err
//}
//
//func WxJsApiPay(param front.WxJsApiPayRequest) (response front.WxJsApiPayResponse, code int) {
// var ctx = context.Background()
// task := newWxJsapiPay(param)
//
// // 1 获取订单
// task.getOrder()
// if task.code != errorcode.Success {
// return response, task.code
// }
//
// // 获取支付渠道配置
// task.getPayChannel()
// if task.code != errorcode.Success {
// return response, task.code
// }
//
// // 2 通过code获取openid
// task.getOpenId()
// if task.code != errorcode.Success {
// return response, task.code
// }
//
// order := task.order
// // 通过openid订单数据请求微信下单, 获取prepay_id
// orderRequest := paymentService.PayOrderRequest{
// PayChannelId: order.PayChannelId,
// OrderId: order.Id,
// ChannelType: task.payChannel.ChannelType,
// Description: order.Desc,
// Amount: order.Amount,
// PayerClientIp: param.ClientIp,
// ReturnUrl: "",
// //Wx: paymentService.WxPay{},
// //Ali: paymentService.AliPay{},
// OpenId: task.openId,
// }
// res := paymentService.PaymentService(ctx, orderRequest)
// // 下单失败
// if res.Code != payCommon.PAY_SUCCESS_CODE {
// task.code = errorcode.PrePayFail
// task.msg = res.ErrorMsg
// return response, task.code
// }
// // 更新订单状态
// order.Status = common.ORDER_STATUS_PAYING
// task.code = OrderUpdate(order, "status")
// if task.code != errorcode.Success {
// utils.Log(nil, "成功下单,更新订单状态失败", order)
// }
//
// // 3 组装返回数据
// response = front.WxJsApiPayResponse{
// AppId: task.payChannel.AppId,
// TimeStamp: strconv.Itoa(int(time.Now().Unix())),
// NonceStr: strconv.Itoa(int(time.Now().Unix())),
// Package: "prepay_id=" + res.Result,
// SignType: "RSA",
// PaySign: "",
// ThirdMsg: "",
// }
//
// // 4 签名
// // 4.1 签名数据
// signValue, err := task.Sign(response.AppId, response.TimeStamp, response.NonceStr, response.Package)
// if err != nil {
// utils.Log(nil, "签名失败", err)
// return response, errorcode.WechatAuthFail
// }
// response.PaySign = signValue
//
// return response, task.code
//}

View File

@ -14,13 +14,14 @@ import (
type PayOrderRequest struct {
PayChannelId int64 `json:"pay_channel_id"` // 支付方式ID
OrderId int64 `json:"order_id"` // 平台订单号
ChannelType int `json:"channel_type"` // 支付方式
ChannelType int `json:"channel_type"` // 支付渠道枚举,1微信JSAPI2微信H53微信app4微信Native5微信小程序6支付宝网页&移动应用7支付宝小程序8支付宝JSAPI
Description string `json:"description"` // 商品描述
Amount int `json:"amount"` // 金额单位为分
PayerClientIp string `json:"payer_client_ip"` // 终端IP
ReturnUrl string `json:"return_url"` // 支付成功后回调地址
Wx WxPay `json:"wx"`
Ali AliPay `json:"ali"`
Wx WxPay `json:"wx"` // 微信支付参数
Ali AliPay `json:"ali"` // 支付宝参数
OpenId string `json:"open_id"` // 支付者信息。 openid
}
type WxPay struct {
@ -29,6 +30,7 @@ type WxPay struct {
SerialNo string `json:"serial_no"` // 商户证书的证书序列号
ApiV3Key string `json:"api_v_3_key"` // apiV3Key商户平台获取
PrivateKey string `json:"private_key"` // 私钥 apiclient_key.pem 读取后的内容
Secret string `json:"secret"` // 商户私钥,读取后的内容
}
type AliPay struct {
@ -58,6 +60,10 @@ func PaymentService(c context.Context, payOrderRequest PayOrderRequest) PayOrder
case payCommon.PAY_CHANNEL_ALIPAY_WEB:
// 支付宝H5支付
info, err = ALiH5PayInfo(c, payOrderRequest)
case payCommon.PAY_CHANNEL_WECHAT_JSAPI:
// 微信JSAPI支付
info, err = WxJsApiPayInfo(c, payOrderRequest)
default:
payOrderResponse = PayOrderResponse{
Code: payCommon.PAY_NOT_FOUND_CODE,

File diff suppressed because one or more lines are too long

View File

@ -31,14 +31,14 @@ func InitClient(wxConfig WxPay) (*wechat.ClientV3, error) {
wxConfig.ApiV3Key,
wxConfig.PrivateKey,
)
if clientErr != nil {
return nil, clientErr
}
// 启用自动同步返回验签并定时更新微信平台API证书开启自动验签时无需单独设置微信平台API证书和序列号
clientErr = wxClient.AutoVerifySign()
if wxClient == nil {
return nil, errors.New("client not initialized")
}
if clientErr != nil {
return nil, clientErr
}
// 自定义配置http请求接收返回结果body大小默认 10MB
wxClient.SetBodySize(10) // 没有特殊需求,可忽略此配置
@ -95,6 +95,52 @@ func WxH5PayInfo(c context.Context, payOrderRequest PayOrderRequest) (string, er
return wxRsp.Response.H5Url, nil
}
// 微信JSAPI支付
func WxJsApiPayInfo(c context.Context, payOrderRequest PayOrderRequest) (string, error) {
if payOrderRequest.OpenId == "" {
return "", errors.New("jsapi方式openId不能为空")
}
// 初始化微信客户端
wxClient, err := InitClient(payOrderRequest.Wx)
if err != nil {
return "", err
}
expire := time.Now().Add(10 * time.Minute).Format(time.RFC3339)
// 初始化 BodyMap
envConfig := config.GetConf()
bm := make(gopay.BodyMap)
bm.Set("appid", payOrderRequest.Wx.AppId).
Set("mchid", payOrderRequest.Wx.MchId).
Set("description", payOrderRequest.Description).
Set("out_trade_no", strconv.FormatInt(payOrderRequest.OrderId, 10)).
Set("time_expire", expire).
Set("notify_url", fmt.Sprintf(envConfig.PayService.Host+payCommon.WX_NOTIFY_URL_TEST+"%d", payOrderRequest.PayChannelId)).
SetBodyMap("amount", func(bm gopay.BodyMap) {
bm.Set("total", payOrderRequest.Amount).
Set("currency", "CNY")
}).
SetBodyMap("payer", func(bm gopay.BodyMap) {
bm.Set("openid", payOrderRequest.OpenId)
})
wxRsp, err := wxClient.V3TransactionJsapi(c, bm)
if err != nil {
return "", err
}
if wxRsp.Code != wechat.Success || wxRsp.Response.PrepayId == "" {
logger.Error(c, "WxJsApiPayInfo 发生错误", fmt.Sprintf("错误状态码:%d, 错误信息:%s", wxRsp.Code, wxRsp.Error))
return "", errors.New(wxRsp.Error)
}
//if payOrderRequest.ReturnUrl != "" {
// values := url.Values{}
// values.Set("redirect_url", payOrderRequest.ReturnUrl)
// encodedStr := values.Encode()
// //wxRsp.Response.H5Url = wxRsp.Response.H5Url + "&" + encodedStr
//}
return wxRsp.Response.PrepayId, nil
}
// WxPayCallBack 微信支付回调
func WxPayCallBack(notifyReq *wechat.V3NotifyReq, wxConfig WxPay) error {
// 初始化微信客户端

View File

@ -8,9 +8,12 @@ import (
)
const (
PRI = "MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCmjK6SPkrP03ssex5Dxn4KZeVm9rQoJMslru13GNgoGKJAq13xwUGl6lpGlhzM9IMzg0ldOO2a0SQPPjc0fLrDjIgHPfIT6H1hDGkZdPaF4D0OfiHGzlLwXq7FyyyGc2JXILsniMBXcCxNFhbW0jAaJyYrBJb3q84a5y5AtK3IC+eDV6Bj2J4HlQVGKgW9u2ic6Jxl23sacXY6iifi+KEuoXNCJrmYlgRWTaQovLmTCLkErkzxzG9DFRDWGoz25LthDPqcCSUmWEbJ+obwIGB4r2WCbFXvaeVBQORlyVRyNUvYMItjHBQIKinDWZ6y8KzA0YKOoxEfr0KfE8Uk4PQBAgMBAAECggEABTAX0PzelN4uyvTT0sMi/R0YRKPgepP40vtBsNvF10E7Lp4ClAupHpYFSrJq178xu1/2dVBXEGM9hw8GUQd7RCjuD3cFwcp/EKU+Zy6uQ38iZRTskEDa3bC+q3EXzuFXDxqOfIhai262UTlkATw0sjUwJRdkbMxoeWHkSNuH7UBVddxFL8Bq1DKaPzRCqQ8zlkMZHy8Xbf2b8rFoi1oPBoPjHyxCo33zcnSg5xntIoA5pkD6x4z5cAnU55aBoYUiRv7jmG+MVp1jpDvAmJLfUayVZNakgX1r74bMPsl9kpA7dVdgOlWrIkbJE1plVXXswBb8QKN0/Yx2vv/YASSi0QKBgQDaO9BkRjvht/lrsQEur1wXf5ITnsVWsqlUhYQKGHihzOj7e0rGO9QICM4eQZH9ssHfxEXhmEoFdkaqo3Fo47NI+yinpWm+KruwrRFkCGejlKZ4bhn9zWPb8L1qJbN4UD1c5jUNk1B0EEdnLRFg0/O7xm602bGilvY5x2nf0v95+QKBgQDDXyiiGNV7GO4h8OQYJwq0IqenPyIanRgYI3rw//tg147mhWcxT6ms6dMUh9nEXEFali2J1En+aVvx1Xn47CuGrRmZOLaGkw9ESFA/4ngYdea+xgttbKMXm0QwIwvATq2jxxrYEKmnr/+EUUWzIWioM1zQffAhVlkLFVnImquMSQKBgDe7qNfC/A4ELwWqubOTg0BZCxRJqvoePJJiWrs9Tql7rFB1Rz5jDx5SKVmew0r4OP0Nog8gFl9YumlfvlncNPBBfDt8SgoP3ckcGeHjJ5ymHPGKpMaliogj7ivKnw/t5g3wmMHzyksp0SJvZw3Ec22UGrfDFNOCHDXbUJWhzC75AoGBALbM6rAAnH65LNcFFeajYRh69HNAVyCfrFOpnvawDPzntAVs/MjeyNvJTH8BPXjE+UFREvrLbxBkdGsqWx3VnEQ+4pzCu8XfA4HYR33+4G/CoUwO8dJIu7DyzjJcGDqvYzjCqxNPQ+5qdqHPiW+56rq2lDlgHLaUnGwKZh+U2L5BAoGAeogtSQbnZaLQofSGcUOol2fyG24NU1JK3My+N1ypkSpD+y1KiFQeM5kg7UcJB6LBKZ/lRCKcjEMaxMyj57ETMkbRVKBLvsIL5QYolJLIHYqBul0AeFJ4K51SKK2Xk5rFvyuJKkJBux26WodtCXTnEzP1KRZGlSxJeN/V1yXjSEU="
//PRI = "MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCmjK6SPkrP03ssex5Dxn4KZeVm9rQoJMslru13GNgoGKJAq13xwUGl6lpGlhzM9IMzg0ldOO2a0SQPPjc0fLrDjIgHPfIT6H1hDGkZdPaF4D0OfiHGzlLwXq7FyyyGc2JXILsniMBXcCxNFhbW0jAaJyYrBJb3q84a5y5AtK3IC+eDV6Bj2J4HlQVGKgW9u2ic6Jxl23sacXY6iifi+KEuoXNCJrmYlgRWTaQovLmTCLkErkzxzG9DFRDWGoz25LthDPqcCSUmWEbJ+obwIGB4r2WCbFXvaeVBQORlyVRyNUvYMItjHBQIKinDWZ6y8KzA0YKOoxEfr0KfE8Uk4PQBAgMBAAECggEABTAX0PzelN4uyvTT0sMi/R0YRKPgepP40vtBsNvF10E7Lp4ClAupHpYFSrJq178xu1/2dVBXEGM9hw8GUQd7RCjuD3cFwcp/EKU+Zy6uQ38iZRTskEDa3bC+q3EXzuFXDxqOfIhai262UTlkATw0sjUwJRdkbMxoeWHkSNuH7UBVddxFL8Bq1DKaPzRCqQ8zlkMZHy8Xbf2b8rFoi1oPBoPjHyxCo33zcnSg5xntIoA5pkD6x4z5cAnU55aBoYUiRv7jmG+MVp1jpDvAmJLfUayVZNakgX1r74bMPsl9kpA7dVdgOlWrIkbJE1plVXXswBb8QKN0/Yx2vv/YASSi0QKBgQDaO9BkRjvht/lrsQEur1wXf5ITnsVWsqlUhYQKGHihzOj7e0rGO9QICM4eQZH9ssHfxEXhmEoFdkaqo3Fo47NI+yinpWm+KruwrRFkCGejlKZ4bhn9zWPb8L1qJbN4UD1c5jUNk1B0EEdnLRFg0/O7xm602bGilvY5x2nf0v95+QKBgQDDXyiiGNV7GO4h8OQYJwq0IqenPyIanRgYI3rw//tg147mhWcxT6ms6dMUh9nEXEFali2J1En+aVvx1Xn47CuGrRmZOLaGkw9ESFA/4ngYdea+xgttbKMXm0QwIwvATq2jxxrYEKmnr/+EUUWzIWioM1zQffAhVlkLFVnImquMSQKBgDe7qNfC/A4ELwWqubOTg0BZCxRJqvoePJJiWrs9Tql7rFB1Rz5jDx5SKVmew0r4OP0Nog8gFl9YumlfvlncNPBBfDt8SgoP3ckcGeHjJ5ymHPGKpMaliogj7ivKnw/t5g3wmMHzyksp0SJvZw3Ec22UGrfDFNOCHDXbUJWhzC75AoGBALbM6rAAnH65LNcFFeajYRh69HNAVyCfrFOpnvawDPzntAVs/MjeyNvJTH8BPXjE+UFREvrLbxBkdGsqWx3VnEQ+4pzCu8XfA4HYR33+4G/CoUwO8dJIu7DyzjJcGDqvYzjCqxNPQ+5qdqHPiW+56rq2lDlgHLaUnGwKZh+U2L5BAoGAeogtSQbnZaLQofSGcUOol2fyG24NU1JK3My+N1ypkSpD+y1KiFQeM5kg7UcJB6LBKZ/lRCKcjEMaxMyj57ETMkbRVKBLvsIL5QYolJLIHYqBul0AeFJ4K51SKK2Xk5rFvyuJKkJBux26WodtCXTnEzP1KRZGlSxJeN/V1yXjSEU="
PUB = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEApoyukj5Kz9N7LHseQ8Z+CmXlZva0KCTLJa7tdxjYKBiiQKtd8cFBpepaRpYczPSDM4NJXTjtmtEkDz43NHy6w4yIBz3yE+h9YQxpGXT2heA9Dn4hxs5S8F6uxcsshnNiVyC7J4jAV3AsTRYW1tIwGicmKwSW96vOGucuQLStyAvng1egY9ieB5UFRioFvbtonOicZdt7GnF2Ooon4vihLqFzQia5mJYEVk2kKLy5kwi5BK5M8cxvQxUQ1hqM9uS7YQz6nAklJlhGyfqG8CBgeK9lgmxV72nlQUDkZclUcjVL2DCLYxwUCCopw1mesvCswNGCjqMRH69CnxPFJOD0AQIDAQAB"
//PUB = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEApoyukj5Kz9N7LHseQ8Z+CmXlZva0KCTLJa7tdxjYKBiiQKtd8cFBpepaRpYczPSDM4NJXTjtmtEkDz43NHy6w4yIBz3yE+h9YQxpGXT2heA9Dn4hxs5S8F6uxcsshnNiVyC7J4jAV3AsTRYW1tIwGicmKwSW96vOGucuQLStyAvng1egY9ieB5UFRioFvbtonOicZdt7GnF2Ooon4vihLqFzQia5mJYEVk2kKLy5kwi5BK5M8cxvQxUQ1hqM9uS7YQz6nAklJlhGyfqG8CBgeK9lgmxV72nlQUDkZclUcjVL2DCLYxwUCCopw1mesvCswNGCjqMRH69CnxPFJOD0AQIDAQAB"
PRI = "MIIEoAIBAAKCAQEAnSSVbidsHYZ46XcAo3eDXYKidzPZ/0W8UKZyHSLthZ0oMlkpC9gfPNKWA1DqiGH22MjRNzX2xz3WdE+bsC+MVWCWjq988PtEX/H+ahpbxKAMHHm4jWSjSLhjrnDCCbYUraG7++uiTzx/Qcef4bq9PAA64ckZLtTfywQdkzi5iWhTzggA6I1gEMKxsoJB+wljyTufmFj12/cHOSrl8wXoHJtODEwC70maH0e2SKT0ZSCFN3G7f7iLgQEDsAl9jZYrC1x9WK9kWtzm4V1ej2wn2MFa5DuE4AzLvBJDyKQN8PHI1lMuTn2QBFDtNyCb53y2qylU7azUn6yq1LNMwsjuPQIDAQABAoIBAH2kFXHYRUIqFRydUD5ivP6UBzAFniPS7ukQ26ZeGci9ybjPvtjAeOFZgiWumYZnxUS480YQeHn/ACtIxzMMIUjWDCqTNvM6AwYvZvoQjxTb3jMaQyuRrlfjTZfYgdvf4BKfgLzAPqrZtOm0ISoK82g4ytthvSfLfg9FAByIuxeXuJtzHuy7jTRqD9t7D6QBtweMEYGpjpHuMtrGTfk5fkRmvRoFIbRLhVo68hTgl/7ha5OujmRtlS45W12ayA3HceIfCyHliCMohaAkUR4AsmbFc3Sk1Fi/lQdJry+a8SfSkmGQ8Jc55d4nXldLJ1j5eLyl5/tQakqhDNleF6KFA4UCgYEAzzAVkrVJCpyQiaKEBhgFpHT/A3KCxJDRnnzE7hO8K05S4hmPgRQk0bB8iLXwdoAgelt9oJ2Epb4u7n7xQx+x/HohLUgJq7mz+gwqkiPkVi2idSQypSn6O9XXvjYNb29bjRUsIYixRZjcbvp9//TnP8W/mxuicmQme7gmwrgjFpMCgYEAwiowbUDP9ZlKeILFSXLnPWLAWX/5uqyG3i+FhUczxj7JyOSP5zXbs31OqtDmcpKChQXaCP9erDlwq8fN+U02zcLwIw8sbTAR5UCD/GjdKdTdJ+aKntoppwnCDPNszLhbCyMn6LOXh+AVKv9yFlX7Z1b/8yRbHXj2smKgzzzzme8CgYBVbh9HGgcfIAWdKuzDUn5pHHDWbA4tnQVCE3JkNLD/LlGQtzdr4vF3oQ0IlfSr+BLsQPNhGfJLIUtave8fXV9Xmsg5Up3iODVU4lVfYvtQ6Yo2QRG89r0elQNbhBAwJbubReKnhSSLbQdfn1v7AXGk4xYpj9CA2HjhxMH+wkx9jwJ/brug4q4T6/2AezoZSco+FsQ67tANnGjIge6YN2pkHKuyaN/xMeuFYNgWBVUeGDl2Nmcf8gGx/IbFuzI4RfXDS5XhXh1JOPwxOI2SuGEVwMWlWxwf8nh5SMpH4Rry8c4yHifumsfRo6woZl1Is3RV7JmxXvlc/XH/P7z/+TDJvQKBgH+yqQHTZToSc0u4X4luHfHJMT5bRRzWYCHAo1wgj9R9hsm70uFfNmXJX1YXOYJXFA43XkZSZNaAgvtaIpOcFS/G/dwHf2JqI8MRJINT9Ixf7zmo/vPjISI2ncTUeJgguvNSSlbn9hZ/guxlhz3XWY3lmTLPHAtnAFQ7OKGoqxbw"
PUB = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAnSSVbidsHYZ46XcAo3eDXYKidzPZ/0W8UKZyHSLthZ0oMlkpC9gfPNKWA1DqiGH22MjRNzX2xz3WdE+bsC+MVWCWjq988PtEX/H+ahpbxKAMHHm4jWSjSLhjrnDCCbYUraG7++uiTzx/Qcef4bq9PAA64ckZLtTfywQdkzi5iWhTzggA6I1gEMKxsoJB+wljyTufmFj12/cHOSrl8wXoHJtODEwC70maH0e2SKT0ZSCFN3G7f7iLgQEDsAl9jZYrC1x9WK9kWtzm4V1ej2wn2MFa5DuE4AzLvBJDyKQN8PHI1lMuTn2QBFDtNyCb53y2qylU7azUn6yq1LNMwsjuPQIDAQAB"
)
func TestRsaEncrypt(t *testing.T) {
@ -19,7 +22,9 @@ func TestRsaEncrypt(t *testing.T) {
func TestRsaDecrypt(t *testing.T) {
data := "pPnAPy7v2SY9Fu0LFcQH8UBA6VQ2FCfSg3nRZdMXS7mWjBwlacKHuFnh9UhobL7mxnmMyZPP100bpjCg2kvcfOpOp3ci85p+OYWINt4Fh3qgEOTG5FUyziaagGLm882t/I36KsDTVvbMZvC5sg4gZ9JQ5yAR+nuJfr0IxI0se/iD5luV1rms1kZHggd30iXdZtbkbX7xJ4xtnIiJmZU7kL+Xmvv1rDdPLxbol65QfnM1me1IHkXJapqSBnhEEmFQyBx31vp1ccNjkza8ZWbvTPCngc1k4kvlm6lKfwsG4hMuSdXUzveDm+Oo8StAKnyVoerJ202n7Vfx1XhehineQT0TPD7bO0HCEsDXXYEWwvcax8VdzYvHk7qSbH6e154qCr4LgDRSHKwAAExinTrzxx2rtSimieBLaEpDL2v5ch45HnhjRhWTRmM61W1g6sdHaVX1mQxaXvrT4v+h+f4TbIV4r4qeGJ6rXG+yKRoYseLzyGgystoOny9P0UH15W8rWPytV2eioWT7i3Cglg04BWP9mst67LQXeFH4CA6CkwVV2w9nCHrzxX2ouYSQELUEkTlIMry2AlkZubUnupGJLmLLUyZj7pM/6cLjyAgm02/gRc4wwf7JBBq/ipmKXpkhHXWLtQDWJEZTT+ug2v9EXy5dgPNPe8ZI0MILAeipjIc="
privateKeyPEM := `-----BEGIN RSA PRIVATE KEY-----
data = "UaUJQUa2leqvgS5Brd0jjlMC4JFfQqavzk8VVSuHurBzC0l0Kz0EUY2nm8QRKB6ndCQZo4ktk/row+V1L/Zjn+3gBDhh4rNr0JNSvY/C+7AHpugvN+V8M0aEkFvZkaEaQiwjTExP8lz5w6Q/1O7Srb3KjnKs9wX97viyUbhUS4diGPCFnXLsWYnf6qSXvwNQwjgr3QykF45E2bN6VxsO/60OVZNN/yYgREe+IuuUyGvm+FlymnpMADGpDaViIOhqA77DNV4JkAsAv1Zjxtg+DFaeW9CcUOczw2yeQHXeEP/vzWfmcHXOZq17NKfSeiVotvLTUcT21UygD4oAUBPRmUTuqqa2095NCiNxxqFnRtHaWeY/dwp4ymNiHLFPh1HFwjVtvlazrEiLflsP0CI6zqn/bL8YhcV2VSSWx4g2YTTc3Xl56QeXa1PhdjSZg/apBRb/mEXTo1WNy/NQ5hVdNhtydB10WtA3YSr5vOEXSIbue4GJDYNNyMQTVBnfn3PTHl89/unlkFNI9AD60IfUCfhxOfg5Ddqa+8thTEBj4yOod/2dh6z2Dl7GZ7Ak0gWy1iFvFQm/6Y4p7dA44foAg9MwbV1wYbrdGauC5o7VRg0x6Sklzu/z5LeU4YUMruT0cd/Ov2kXkqiDyMn3GzdmIIWFadXISTbr7s1yU4uovn8="
privateKeyPEM := `-----BEGIN RSA PRIVATE KEY-----
` + PRI + `
-----END RSA PRIVATE KEY-----`
res, err := Decrypt(privateKeyPEM, data)
@ -27,7 +32,7 @@ func TestRsaDecrypt(t *testing.T) {
}
func encrypt() string {
data := "{\"pay_channel_id\":8935141660703064070,\"out_trade_no\":\"refundOutTreadNo001\",\"amount\":1,\"desc\":\"退款\",\"ext_json\":\"\",\"app_id\":5476377146882523138,\"timestamp\":53612533412643,\"refund_out_trade_no\":\"asdadasdas\"}"
data := "{\"pay_channel_id\":1729382256910270476,\"out_trade_no\":\"zxp1234D56711tuikuan\",\"order_type\":1,\"amount\":1,\"desc\":\"测试支付宝退款商品zxp\",\"ext_json\":\"\",\"app_id\":8070450532247928844,\"timestamp\":1723096731}"
pub := `-----BEGIN PUBLIC KEY-----
` + PUB + `
-----END PUBLIC KEY-----`

View File

@ -1,6 +1,8 @@
package sm2
import (
"encoding/base64"
"encoding/json"
"fmt"
"testing"
)
@ -38,7 +40,7 @@ func TestSM2Encrypt(t *testing.T) {
}
func TestSM2Decrypt(t *testing.T) {
en := "MDRkZDJkYzE1ZmIyZTdjMDRiNTlhZGM5OGM1NjBjM2RhZWVkMzhkMjljYjFkMmEyNjUzMmZlZDRkMWUxMjc5MjQxM2M5OTJiMTk5OWQ4MzgwOTdjYjhhMTU4ODA3OTNmZDNiM2FjZmE2NWNjNDAzZTgyODZjZjM5Y2NkMWU2NmJjY2EwNjU0N2NlNzM3N2M3YWViMmRmN2UzNGQ3YTIyMzI1NWJiMzU5NzljMDVlNjg2MTQzMGE4Y2VmNDZmMTU4YTYxNmI5ZjE2YTcwYzc0MTRhNmNmMWE2NWE5ZTE1YWM1ODBmODk1MWNiOWNhMzBlMDNhMjQzZmZjZWY4YjQzOWUzOGM5NmU0MGQyMTc5YjY5YThhNGQ3ZTQxMjZlMzA1MGZlNWIxZDI4Mzc0YjU3MmRiODBiMjFiMWY4NGYwNDBjYTE3NTRhN2FjMDk5Y2ZmZGI5MDM3NjIxYTE0ODAzNGIyOTU4NjA4ZDM4MzNlOGIwNDE4MWQ4NGUyMWU0OTNmZjYzNzNjMGQ4Y2M0ODVkYzM4NjZlYjZlOWZiYzVjZGFmMDExNWNiYWNiODA4Y2ZkYjczODlmZmJlZDliNmQzMDdiYTczY2EyOTVlOWNhM2RhZmNlNDk1YTZiNWI4NzFhYzdlN2U2ZTJmZWFlOGU3YTllOTFhYTE4ZGY4MzVkNWI2YjFkOGFkY2NhYWM0YjMwOTU3NzUxMmZkYWVlMmVhOWJlMTkwMWUxOTUzMzFmN2UyZjU5NmFkOGRiN2Q1ZDJmYzI2MDA5NjE4YmNhNzc="
en := "TURRek1HUXlOemhqTkdNMVl6aGxPRFZpTURCalpHVmhaV1E1WkRSaVpqVTFOekJsWkdJMk4yVTRPR0ptWVRrME5tRTROMkkzWW1FM09EUm1aVFptWVRGak0yUTRaakV3WW1FMFlqVTBZMll6TVRBek9EZGxabVJoWVRRMk1HUmpNRFU0WkdReE9XSmhZelV6TkRaak5XSmxNVE14Wm1Wa1ltRTJZVE0yWWpnelpXWTBNbVl4T1RabU5EWXpNMlk1WVdNeE4yVXpOalZpT0RabU1qQXhZbU0wTXpjM01qRmtZV1U1WVdJeE5ESTVPVE00TmpabVpXRXhNelV5Tm1aaE5EVmhaRGxrTTJWaU4yUm1aR1U0T0dRNVpUQXpabUl3TmpabE16TTFOekl4TnpsaFpETXhOV05oWmpNMk4yRmlOVEl5TlRRM1lUVTVNakJqWW1Nek1HRXpOR1l3T1RKa00ySmpPV0ZsTVRBeVkyVm1ZVEZqTkRRM01EaG1aV1UzTnpSallqWmpZVEZtWTJVMVpUYzJOMlE0WmpoaE1UTXlOMkU1WWpVek5tUTBORGcyTjJaaFlqazJaRGd5T0RBME9ETmtZVFZqTUdFMk1qUmhZV1ptWTJSa09UZGlOemN4WlRaaFltSmhNR0kzT0RNNFpETXdOV1UyWTJGbU5tVmtZak5pTURCbU4yVTJaakkxTkRWa1pqWTBPR05rTURBeE5XTmxOamt5TkRJNE1tTmlORE14T0dRM01USXpaREkxWW1ZeE1qRmxPRFU0TlRkall6RTJPVFJoWTJWak9EbGxPV0kyTlRVeFpUYzJOemsxTTJJMU56VTNNall4T1dGbU1EWTBabU0yTkdOaVkyUXhaVFZsTUdGa09EUTBNVFZqTkdVNE5tWXlaakpsT1dVM09Ea3pZVEZsTmpJMllqRmlaakl5T1dFeE9USXpNR0pqWVRjeU1ERmpOV1V4TXprME9UbGtOemN6TWpReVkySm1ORGMxTVdObFpHUTJOR05tTlRjPQ=="
decrypt, err := SM2Decrypt(en, SELF_PUB, SELF_PRI)
if err != nil {
panic(err)
@ -47,10 +49,28 @@ func TestSM2Decrypt(t *testing.T) {
}
func encrypt() string {
data := "{\"order_no\":5476377146882523228,\"order_type\":1,\"out_tread_no\":\"asdadasdas\",\"amount\":1,\"desc\":\"abc\",\"status\":2,\"create_time\":\"2024-08-08 14:47:35\"}"
data := "{\"pay_channel_id\":1729382256910270476,\"out_trade_no\":\"zxp1234D56711tuikuan\",\"order_type\":1,\"amount\":1,\"desc\":\"测试支付宝退款商品zxp\",\"ext_json\":\"\",\"app_id\":1729382256910270475,\"timestamp\":1723096731}"
//data := "{\"refund_out_trade_no\":\"zxp1234D56711tuikuan\",\"pay_channel_id\":1729382256910270476,\"out_trade_no\":\"4123412341234\",\"order_type\":2,\"amount\":1,\"desc\":\"测试支付宝退款商品zxp\",\"ext_json\":\"\",\"app_id\":1729382256910270475,\"timestamp\":1723096731}"
en, err := SM2Encrypt(data, SELF_PUB)
if err != nil {
panic(err)
}
return en
}
func TestSm2Decode(t *testing.T) {
en := "TURRd1lUZGlZamt4T1RGbU9XWmhOR1pqTkRKa05HWmpORFkyTjJNd05qVmtNR1EwTTJNellUVmhPR1ZsTm1GbVpqZzFPRGMwTW1Oak5EQmtaRGszTkRrek5tRTVNREEwTkdFMFlXRXhaREl5T0RVME1ESmtObVk1TWpWaVpqYzNORGhoT1RObE0yVmtaVGc1T0dVellUZGlabU15WkRNNU1EQXpNR0ZsTm1Oa05XSTBPVEJpT1dFMU9XUTVObU15TURCaU9EVTNNR0UzWTJFNU9UYzVNalF3TnpFeVl6RTVZemd4TW1WbVpUQTNZbVV5WVRoaU1tRmtaak5tWkRjek1XVXdabVZrTlRnMVpUTXlNR0U0WldWaVlURXlNREExWWpnek1XRTBNVFk1WlRCa09ERXpaVGN6WWpJMFpEUmpOVFV5WlRRMU1HTmxNbVEwWlRkbU5tTTFaR1l5TUdZeU5XTXdNV1kwTVdFNU5EZGxaRFV3TnpjME9EWTFaVFJoWVRreU5HTm1ZVFU1WXpoa01USmxNREF3WTJOa01qRTVNell6T1RObFpXWXpNelEyTnpObU9HTTJaV00xTkdVd1ltRmhOVFZsWVRka09UQTFaRFZrTXpobVlqSTJabVEzWldFelptWmpNbU5tTldFd01tUmhOak5qTWpBeVl6azVaR0poT0RRMFpHTTJNbVJtTkdRM05Ea3dZems0TmprMk9UTmpNbVF3TnpFeE1qUmlaVFJpT1RrMk9UY3pNR0prTmpZNVpqYzFPRFJpWVRCbE5tTXdZV1JqTnpOak4yVmpaR1ExWmpJellUWmtaR1EwTVRCbE1qSTVZV1F5WW1GbFl6YzRPRGhsWXpjME5HTmlNekk0TnpRek1UZGhNak0xWVRWbFlUYzNNR1JsTVRZMU1tWmpOVEEzT1dVMllqSTNabUl5TVRNM09URmpPRFF4TXpsa09ETm1OelExWTJVNVlUTXlZams0TVRZd1pqUXdNV1k1TjJSbVpEazRZV1kxWXpZeE1USTRaREEzT0dRME5tVXlaQT09"
content, _ := base64.StdEncoding.DecodeString(en)
decrypt, err := SM2Decrypt(string(content), SELF_PUB, SELF_PRI)
if err != nil {
panic(err)
}
t.Log(decrypt)
tempMap := make(map[string]interface{})
json.Unmarshal([]byte(decrypt), &tempMap)
t.Log(tempMap)
}

View File

@ -2,8 +2,6 @@ package httpclient
import (
"PaymentCenter/app/utils"
"fmt"
"github.com/valyala/fasthttp"
"time"
)
@ -83,12 +81,11 @@ func FastHttpGet(url string, header map[string]string, body map[string]string, t
}
url = url[0 : len(url)-1]
}
fmt.Println(url)
req.SetRequestURI(url)
resp := fasthttp.AcquireResponse()
defer fasthttp.ReleaseResponse(resp) // 用完需要释放资源
var err error
if timeout == 0 {
if timeout <= 0 {
if err = fasthttp.Do(req, resp); err != nil {
utils.Log(nil, "http请求失败", err, url)
return nil, err

99
front/templates/fail.html Normal file
View File

@ -0,0 +1,99 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
<title>微信支付</title>
<style>
body,
html {
width: 100%;
height: 100%;
margin: 0;
padding: 0;
overflow: hidden;
}
.success,
.error {
width: 100%;
height: 100%;
display: none;
background: #fff;
}
#right {
width: 150px;
height: 150px;
margin: 100px auto 20px;
border-radius: 50%;
border: 5px solid rgb(104, 225, 52);
display: flex;
justify-content: center;
align-items: center;
}
#right::before {
content: "";
display: block;
width: 88px;
height: 50px;
border: 5px solid rgb(104, 225, 52);
border-right: none;
border-top: none;
transform: rotate(-45deg) translate(7px, -10px);
}
.success-txt {
display: block;
width: 100%;
text-align: center;
font-size: 18px;
color: rgb(104, 225, 52);
}
#error {
width: 150px;
height: 150px;
margin: 100px auto 20px;
border-radius: 50%;
border: 5px solid rgb(244, 57, 52);
display: flex;
justify-content: center;
align-items: center;
}
#error::before {
content: "\2715";
display: block;
color: rgb(244, 57, 52);
font-size: 100px;
}
.error-txt {
display: block;
width: 100%;
text-align: center;
font-size: 18px;
color: rgb(244, 57, 52);
}
</style>
</head>
<body>
<div class="success">
<span id="right"></span>
<span class="success-txt">支付成功</span>
</div>
<div class="error">
<span id="error"></span>
<span class="error-txt">支付失败 {{.errmsg}}</span>
</div>
<script>
document.getElementsByClassName('error')[0].style.display = 'block';
document.getElementsByClassName('success')[0].style.display = 'none';
document.getElementsByClassName('error')[0].innerHTML = res.err_msg || '支付失败';
</script>
</body>
</html>

View File

@ -0,0 +1,131 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
<title>微信支付</title>
<style>
body,
html {
width: 100%;
height: 100%;
margin: 0;
padding: 0;
overflow: hidden;
}
.success,
.error {
width: 100%;
height: 100%;
display: none;
background: #fff;
}
#right {
width: 150px;
height: 150px;
margin: 100px auto 20px;
border-radius: 50%;
border: 5px solid rgb(104, 225, 52);
display: flex;
justify-content: center;
align-items: center;
}
#right::before {
content: "";
display: block;
width: 88px;
height: 50px;
border: 5px solid rgb(104, 225, 52);
border-right: none;
border-top: none;
transform: rotate(-45deg) translate(7px, -10px);
}
.success-txt {
display: block;
width: 100%;
text-align: center;
font-size: 18px;
color: rgb(104, 225, 52);
}
#error {
width: 150px;
height: 150px;
margin: 100px auto 20px;
border-radius: 50%;
border: 5px solid rgb(244, 57, 52);
display: flex;
justify-content: center;
align-items: center;
}
#error::before {
content: "\2715";
display: block;
color: rgb(244, 57, 52);
font-size: 100px;
}
.error-txt {
display: block;
width: 100%;
text-align: center;
font-size: 18px;
color: rgb(244, 57, 52);
}
</style>
</head>
<body>
<div class="success">
<span id="right"></span>
<span class="success-txt">支付成功</span>
</div>
<div class="error">
<span id="error"></span>
<span class="error-txt">支付失败</span>
</div>
<script>
function onBridgeReady() {
WeixinJSBridge.invoke(
'getBrandWCPayRequest', {
"appId": "{{.appId}}",
"timeStamp": "{{.timeStamp}}",
"nonceStr": "{{.nonceStr}}",
"package": "{{.package}}",
"signType": "{{.signType}}",
"paySign": "{{.paySign}}"
},
function (res) {
if (res.err_msg == "get_brand_wcpay_request:ok") {
// 使用以上方式判断前端返回,微信团队郑重提示:
//res.err_msg将在用户支付成功后返回ok但并不保证它绝对可靠。
document.getElementsByClassName('success')[0].style.display = 'block';
document.getElementsByClassName('error')[0].style.display = 'none';
window.location.href = {{.returnUrl}}; // 跳转
} else {
document.getElementsByClassName('error')[0].style.display = 'block';
document.getElementsByClassName('success')[0].style.display = 'none';
document.getElementsByClassName('error')[0].innerHTML = res.err_msg || '支付失败';
}
});
}
if (typeof WeixinJSBridge == "undefined") {
if (document.addEventListener) {
document.addEventListener('WeixinJSBridgeReady', onBridgeReady, false);
} else if (document.attachEvent) {
document.attachEvent('WeixinJSBridgeReady', onBridgeReady);
document.attachEvent('onWeixinJSBridgeReady', onBridgeReady);
}
} else {
onBridgeReady();
}
</script>
</body>
</html>

17
go.mod
View File

@ -3,9 +3,7 @@ module PaymentCenter
go 1.21
require (
gitee.com/chengdu_blue_brothers/openapi-go-sdk v0.0.2
github.com/BurntSushi/toml v0.4.1
github.com/Shopify/sarama v1.19.0
github.com/ZZMarquis/gm v1.3.2
github.com/ahmetb/go-linq/v3 v3.2.0
github.com/aliyun/aliyun-oss-go-sdk v3.0.2+incompatible
@ -13,10 +11,12 @@ require (
github.com/forgoer/openssl v1.6.0
github.com/gin-gonic/gin v1.7.7
github.com/go-pay/gopay v1.5.103
github.com/go-pay/util v0.0.2
github.com/go-playground/locales v0.14.0
github.com/go-playground/universal-translator v0.18.0
github.com/go-sql-driver/mysql v1.6.0
github.com/golang-jwt/jwt/v4 v4.5.0
github.com/jinzhu/copier v0.4.0
github.com/nacos-group/nacos-sdk-go/v2 v2.2.5
github.com/nats-io/nats.go v1.9.1
github.com/openzipkin/zipkin-go v0.2.2
@ -25,12 +25,12 @@ require (
github.com/qit-team/snow-core v0.1.28
github.com/qit-team/work v0.3.11
github.com/robfig/cron v1.2.0
github.com/spf13/cobra v1.2.1
github.com/streadway/amqp v0.0.0-20190827072141-edfb9018d271
github.com/swaggo/gin-swagger v1.3.3
github.com/swaggo/swag v1.7.9
github.com/tjfoc/gmsm v1.4.1
github.com/valyala/fasthttp v1.31.0
github.com/wechatpay-apiv3/wechatpay-go v0.2.20
google.golang.org/grpc v1.56.3
google.golang.org/protobuf v1.30.0
gopkg.in/go-playground/validator.v9 v9.31.0
@ -55,13 +55,8 @@ require (
github.com/cespare/xxhash/v2 v2.2.0 // indirect
github.com/chenzhuoyu/base64x v0.0.0-20230717121745-296ad89f973d // indirect
github.com/chenzhuoyu/iasm v0.9.1 // indirect
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect
github.com/eapache/go-resiliency v1.1.0 // indirect
github.com/eapache/go-xerial-snappy v0.0.0-20180814174437-776d5712da21 // indirect
github.com/eapache/queue v1.1.0 // indirect
github.com/emirpasic/gods v1.12.0 // indirect
github.com/fvbock/endless v0.0.0-20170109170031-447134032cb6 // indirect
github.com/gin-contrib/sse v0.1.0 // indirect
github.com/go-openapi/jsonpointer v0.19.5 // indirect
github.com/go-openapi/jsonreference v0.19.6 // indirect
@ -69,7 +64,6 @@ require (
github.com/go-openapi/swag v0.19.15 // indirect
github.com/go-pay/crypto v0.0.1 // indirect
github.com/go-pay/errgroup v0.0.2 // indirect
github.com/go-pay/util v0.0.2 // indirect
github.com/go-pay/xlog v0.0.3 // indirect
github.com/go-pay/xtime v0.0.2 // indirect
github.com/go-playground/validator/v10 v10.9.0 // indirect
@ -81,8 +75,6 @@ require (
github.com/google/uuid v1.3.0 // indirect
github.com/hetiansu5/accesslog v1.0.0 // indirect
github.com/hetiansu5/cores v1.0.0 // indirect
github.com/inconshreveable/mousetrap v1.0.0 // indirect
github.com/jinzhu/copier v0.4.0 // indirect
github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af // indirect
github.com/josharian/intern v1.0.0 // indirect
github.com/json-iterator/go v1.1.12 // indirect
@ -99,14 +91,11 @@ require (
github.com/nats-io/jwt v0.3.2 // indirect
github.com/nats-io/nkeys v0.1.3 // indirect
github.com/nats-io/nuid v1.0.1 // indirect
github.com/pierrec/lz4 v2.0.5+incompatible // indirect
github.com/prometheus/client_model v0.2.0 // indirect
github.com/prometheus/common v0.32.1 // indirect
github.com/prometheus/procfs v0.7.3 // indirect
github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a // indirect
github.com/rifflock/lfshook v0.0.0-20180920164130-b9218ef580f5 // indirect
github.com/sirupsen/logrus v1.8.1 // indirect
github.com/spf13/pflag v1.0.5 // indirect
github.com/syndtr/goleveldb v1.0.0 // indirect
github.com/tidwall/gjson v1.12.1 // indirect
github.com/tidwall/match v1.1.1 // indirect

17
go.sum
View File

@ -39,8 +39,6 @@ cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9
dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU=
gitea.com/xorm/sqlfiddle v0.0.0-20180821085327-62ce714f951a h1:lSA0F4e9A2NcQSqGqTOXqu2aRi/XEQxDCBwM8yJtE6s=
gitea.com/xorm/sqlfiddle v0.0.0-20180821085327-62ce714f951a/go.mod h1:EXuID2Zs0pAQhH8yz+DNjUbjppKQzKFAn28TMYPB6IU=
gitee.com/chengdu_blue_brothers/openapi-go-sdk v0.0.2 h1:f4Rj4jVshXYX7wl7aIrd7W9DbGfqxYrZ/c7ppoVL4a4=
gitee.com/chengdu_blue_brothers/openapi-go-sdk v0.0.2/go.mod h1:OEBHFTBQOvsJGzLyMZS8K98F8aZHWg+O8Stycuh94Dk=
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
github.com/BurntSushi/toml v0.4.1 h1:GaI7EiDXDRfa8VshkTj7Fym7ha+y8/XxIgD2okUIjLw=
github.com/BurntSushi/toml v0.4.1/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ=
@ -53,14 +51,14 @@ github.com/PuerkitoBio/purell v1.1.1 h1:WEQqlqaGbrPkxLJWfBwQmfEAE1Z7ONdDLqrN38tN
github.com/PuerkitoBio/purell v1.1.1/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0=
github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578 h1:d+Bc7a5rLufV/sSk/8dngufqelfh6jnri85riMAaF/M=
github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE=
github.com/Shopify/sarama v1.19.0 h1:9oksLxC6uxVPHPVYUmq6xhr1BOF/hHobWH2UzO67z1s=
github.com/Shopify/sarama v1.19.0/go.mod h1:FVkBWblsNy7DGZRfXLU0O9RCGt5g3g3yEuWXgklEdEo=
github.com/Shopify/toxiproxy v2.1.4+incompatible h1:TKdv8HiTLgE5wdJuEML90aBgNWsokNbMijUGhmcoBJc=
github.com/Shopify/toxiproxy v2.1.4+incompatible/go.mod h1:OXgGpZ6Cli1/URJOF1DMxUHB2q5Ap20/P/eIdh4G0pI=
github.com/VividCortex/gohistogram v1.0.0/go.mod h1:Pf5mBqqDxYaXu3hDrrU+w6nw50o/4+TcAqDqk/vUH7g=
github.com/ZZMarquis/gm v1.3.2 h1:lFtpzg5zeeVMZ/gKi0gtYcKLBEo9XTqsZDHDz6s3Gow=
github.com/ZZMarquis/gm v1.3.2/go.mod h1:wWbjZYgruQVd7Bb8UkSN8ujU931kx2XUW6nZLCiDE0Q=
github.com/afex/hystrix-go v0.0.0-20180502004556-fa1af6a1f4f5/go.mod h1:SkGFH1ia65gfNATL8TAiHDNxPzPdmEL5uirI2Uyuz6c=
github.com/agiledragon/gomonkey v2.0.2+incompatible h1:eXKi9/piiC3cjJD1658mEE2o3NjkJ5vDLgYjCQu0Xlw=
github.com/agiledragon/gomonkey v2.0.2+incompatible/go.mod h1:2NGfXu1a80LLr2cmWXGBDaHEjb1idR6+FVlX5T3D9hw=
github.com/agiledragon/gomonkey/v2 v2.3.1 h1:k+UnUY0EMNYUFUAQVETGY9uUTxjMdnUkP0ARyJS1zzs=
github.com/agiledragon/gomonkey/v2 v2.3.1/go.mod h1:ap1AmDzcVOAz1YpeJ3TCzIgstoaWLA6jbbgxfB4w2iY=
github.com/ahmetb/go-linq/v3 v3.2.0 h1:BEuMfp+b59io8g5wYzNoFe9pWPalRklhlhbiU3hYZDE=
@ -161,11 +159,8 @@ github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f h1:lO4WD4F/r
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f/go.mod h1:cuUVRXasLTGF7a8hSLbxyZXjz+1KgoB3wDUb6vlszIc=
github.com/dustin/go-humanize v0.0.0-20171111073723-bb3d318650d4/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk=
github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk=
github.com/eapache/go-resiliency v1.1.0 h1:1NtRmCAqadE2FN4ZcN6g90TP3uk8cg9rn9eNK2197aU=
github.com/eapache/go-resiliency v1.1.0/go.mod h1:kFI+JgMyC7bLPUVY133qvEBtVayf5mFgVsvEsIPBvNs=
github.com/eapache/go-xerial-snappy v0.0.0-20180814174437-776d5712da21 h1:YEetp8/yCZMuEPMUDHG0CW/brkkEp8mzqk2+ODEitlw=
github.com/eapache/go-xerial-snappy v0.0.0-20180814174437-776d5712da21/go.mod h1:+020luEh2TKB4/GOp8oxxtq0Daoen/Cii55CzbTV6DU=
github.com/eapache/queue v1.1.0 h1:YOEu7KNc61ntiQlcEeUIoDTJ2o8mQznoNvUhiigpIqc=
github.com/eapache/queue v1.1.0/go.mod h1:6eCeP0CKFpHLu8blIFXhExK/dRa7WDZfr6jVFPTqq+I=
github.com/edsrzf/mmap-go v1.0.0/go.mod h1:YO35OhQPt3KJa3ryjFM5Bs14WD66h8eGKpfaBNrHW5M=
github.com/emirpasic/gods v1.12.0 h1:QAUIPSaCu4G+POclxeqb3F+WPpdKqFGlw36+yOzGlrg=
@ -188,7 +183,6 @@ github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMo
github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ=
github.com/fsnotify/fsnotify v1.5.1 h1:mZcQUHVQUQWoPXXtuf9yuEXKudkV2sx1E06UadKWpgI=
github.com/fsnotify/fsnotify v1.5.1/go.mod h1:T3375wBYaZdLLcVNkcVbzGHY7f1l/uK5T5Ai1i3InKU=
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/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
github.com/gin-contrib/gzip v0.0.3 h1:etUaeesHhEORpZMp18zoOhepboiWnFtXrBZxszWUn4k=
@ -393,7 +387,6 @@ github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpO
github.com/hudl/fargo v1.3.0/go.mod h1:y3CKSmjA+wD2gak7sUSXTAoopbhU08POFhmITJgmKTg=
github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM=
github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
github.com/influxdata/influxdb1-client v0.0.0-20191209144304-8bf82d3c094d/go.mod h1:qj24IKcXYK6Iy9ceXlo3Tc+vtHo9lIhSX5JddghvEPo=
github.com/jackc/chunkreader v1.0.0/go.mod h1:RT6O25fNZIuasFJRyZ4R/Y2BbhasbmZXF9QQ7T3kePo=
@ -609,7 +602,6 @@ github.com/pborman/uuid v1.2.0/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtP
github.com/pelletier/go-toml v1.9.3/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c=
github.com/performancecopilot/speed v3.0.0+incompatible/go.mod h1:/CLtqpZ5gBg1M9iaPbIdPPGyKcA8hKdoy6hAWba7Yac=
github.com/pierrec/lz4 v1.0.2-0.20190131084431-473cd7ce01a1/go.mod h1:3/3N9NVKO0jef7pBehbT1qWhCMrIgbYNnFAZCqQ5LRc=
github.com/pierrec/lz4 v2.0.5+incompatible h1:2xWsjqPFWcplujydGg4WmhC/6fZqK42wMM8aXeqhl0I=
github.com/pierrec/lz4 v2.0.5+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY=
github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA=
github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
@ -655,7 +647,6 @@ github.com/qit-team/snow-core v0.1.28 h1:RrX7i6GLbcMMSVzAT1lXgS/S3M2b1OrAnsoPaRG
github.com/qit-team/snow-core v0.1.28/go.mod h1:J9CNj6P2IRh72yVa7rut4T8ikq/4DjaisLqXZy40TNg=
github.com/qit-team/work v0.3.11 h1:AAtLTCOJ01WMFcvviK9rDGhHzaHE3bvunMOnSZ/80k8=
github.com/qit-team/work v0.3.11/go.mod h1:h5m1cZjn+BznChuAyMiR/+IUyWEmaMylPKRhq/AlxKw=
github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a h1:9ZKAASQSHhDYGoxY8uLVpewe1GDZ2vu2Tr/vTdVAkFQ=
github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4=
github.com/remyoudompheng/bigfft v0.0.0-20200410134404-eec4a21b6bb0 h1:OdAsTTz6OkFY5QxjkYwrChwuRruF69c169dPK26NUlk=
github.com/remyoudompheng/bigfft v0.0.0-20200410134404-eec4a21b6bb0/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo=
@ -703,11 +694,9 @@ github.com/sony/gobreaker v0.4.1/go.mod h1:ZKptC7FHNvhBz7dN2LGjPVBz2sZJmc0/PkyDJ
github.com/spf13/afero v1.6.0/go.mod h1:Ai8FlHk4v/PARR026UzYexafAt9roJ7LcLMAmO6Z93I=
github.com/spf13/cast v1.3.1/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE=
github.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ=
github.com/spf13/cobra v1.2.1 h1:+KmjbUw1hriSNMF55oPrkZcb27aECyrj8V2ytv7kWDw=
github.com/spf13/cobra v1.2.1/go.mod h1:ExllRjgxM/piMAM+3tAZvg8fsklGAf3tPfi+i8t68Nk=
github.com/spf13/jwalterweatherman v1.1.0/go.mod h1:aNWZUN0dPAAO/Ljvb5BEdw96iTZ0EXowPYD95IqWIGo=
github.com/spf13/pflag v1.0.1/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
github.com/spf13/viper v1.8.1/go.mod h1:o0Pch8wJ9BVSWGQMbra6iw0oQ5oktSIBaujf1rJH9Ns=
github.com/streadway/amqp v0.0.0-20190404075320-75d898a42a94/go.mod h1:AZpEONHx3DKn8O/DFsRAY58/XVQiIPMTMB1SddzLXVw=
@ -769,6 +758,8 @@ github.com/valyala/fasttemplate v1.0.1/go.mod h1:UQGH1tvbgY+Nz5t2n7tXsz52dQxojPU
github.com/valyala/fasttemplate v1.2.1 h1:TVEnxayobAdVkhQfrfes2IzOB6o+z4roRkPF52WA1u4=
github.com/valyala/fasttemplate v1.2.1/go.mod h1:KHLXt3tVN2HBp8eijSv/kGJopbvo7S+qRAEEKiv+SiQ=
github.com/valyala/tcplisten v1.0.0/go.mod h1:T0xQ8SeCZGxckz9qRXTfG43PvQ/mcWh7FwZEA7Ioqkc=
github.com/wechatpay-apiv3/wechatpay-go v0.2.20 h1:gS8oFn1bHGnyapR2Zb4aqTV6l4kJWgbtqjCq6k1L9DQ=
github.com/wechatpay-apiv3/wechatpay-go v0.2.20/go.mod h1:A254AUBVB6R+EqQFo3yTgeh7HtyqRRtN2w9hQSOrd4Q=
github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU=
github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=