Compare commits
4 Commits
666527b976
...
main
Author | SHA1 | Date | |
---|---|---|---|
9f220dc025 | |||
7951f77f47 | |||
bb2a68fb61 | |||
8fd1968cf6 |
@@ -1,3 +1,131 @@
|
||||
package app
|
||||
|
||||
import (
|
||||
"git.echol.cn/loser/lckt/global"
|
||||
"git.echol.cn/loser/lckt/model/app"
|
||||
"git.echol.cn/loser/lckt/model/app/request"
|
||||
r "git.echol.cn/loser/lckt/model/common/response"
|
||||
"git.echol.cn/loser/lckt/utils/user_jwt"
|
||||
"git.echol.cn/loser/lckt/utils/wechat"
|
||||
"github.com/gin-gonic/gin"
|
||||
"go.uber.org/zap"
|
||||
)
|
||||
|
||||
type OrderApi struct{}
|
||||
|
||||
// CreateOrder APP新建订单
|
||||
func (o *OrderApi) CreateOrder(c *gin.Context) {
|
||||
var p app.Order
|
||||
if err := c.ShouldBind(&p); err != nil {
|
||||
global.GVA_LOG.Error("支付订单参数错误", zap.Error(err))
|
||||
r.FailWithMessage("支付订单参数错误", c)
|
||||
return
|
||||
}
|
||||
|
||||
order, err := orderService.Create(&p)
|
||||
if err != nil {
|
||||
global.GVA_LOG.Error("创建订单失败", zap.Error(err))
|
||||
r.FailWithMessage("创建订单失败", c)
|
||||
return
|
||||
}
|
||||
|
||||
r.OkWithData(order, c)
|
||||
}
|
||||
|
||||
func (o *OrderApi) PayOrder(context *gin.Context) {
|
||||
var p request.PayReq
|
||||
if err := context.ShouldBind(&p); err != nil {
|
||||
global.GVA_LOG.Error("支付订单参数错误", zap.Error(err))
|
||||
r.FailWithMessage("支付订单参数错误", context)
|
||||
return
|
||||
}
|
||||
|
||||
pay, err := orderService.Pay(p, context)
|
||||
if err != nil {
|
||||
global.GVA_LOG.Error("支付订单失败", zap.Error(err))
|
||||
r.FailWithMessage("支付订单失败:"+err.Error(), context)
|
||||
return
|
||||
}
|
||||
|
||||
r.OkWithDetailed(pay, "支付订单成功", context)
|
||||
}
|
||||
|
||||
// NotifyOrder 微信支付回调通知
|
||||
func (o *OrderApi) NotifyOrder(context *gin.Context) {
|
||||
err := wechat.NotifyHandle(context)
|
||||
if err != nil {
|
||||
global.GVA_LOG.Error("微信支付回调处理失败", zap.Error(err))
|
||||
r.FailWithMessage("微信支付回调处理失败:"+err.Error(), context)
|
||||
return
|
||||
}
|
||||
r.OkWithMessage("微信支付回调处理成功", context)
|
||||
}
|
||||
|
||||
func (o *OrderApi) GetOrderDetail(context *gin.Context) {
|
||||
id := context.Param("id")
|
||||
if id == "" {
|
||||
global.GVA_LOG.Error("获取订单详情参数错误: ID不能为空")
|
||||
r.FailWithMessage("获取订单详情参数错误: ID不能为空", context)
|
||||
return
|
||||
}
|
||||
|
||||
order, err := orderService.GetOrderDetail(id)
|
||||
if err != nil {
|
||||
global.GVA_LOG.Error("获取订单详情失败", zap.Error(err))
|
||||
r.FailWithMessage("获取订单详情失败", context)
|
||||
return
|
||||
}
|
||||
|
||||
r.OkWithData(order, context)
|
||||
}
|
||||
|
||||
func (o *OrderApi) GetOrderList(context *gin.Context) {
|
||||
var p request.GetOrderList
|
||||
if err := context.ShouldBind(&p); err != nil {
|
||||
global.GVA_LOG.Error("获取订单列表参数错误", zap.Error(err))
|
||||
r.FailWithMessage("获取订单列表参数错误", context)
|
||||
return
|
||||
}
|
||||
|
||||
// 获取当前用户ID
|
||||
userId := user_jwt.GetUserID(context)
|
||||
if userId == 0 {
|
||||
global.GVA_LOG.Error("获取用户ID失败")
|
||||
r.FailWithMessage("获取用户ID失败", context)
|
||||
return
|
||||
}
|
||||
|
||||
// 获取订单列表
|
||||
orders, total, err := orderService.GetOrderList(p, userId)
|
||||
if err != nil {
|
||||
global.GVA_LOG.Error("获取订单列表失败", zap.Error(err))
|
||||
r.FailWithMessage("获取订单列表失败:"+err.Error(), context)
|
||||
return
|
||||
}
|
||||
|
||||
r.OkWithDetailed(
|
||||
r.PageResult{
|
||||
List: orders,
|
||||
Total: total,
|
||||
Page: p.Page,
|
||||
PageSize: p.PageSize,
|
||||
}, "获取订单列表成功", context)
|
||||
}
|
||||
|
||||
func (o *OrderApi) BalancePay(context *gin.Context) {
|
||||
var p request.BalancePay
|
||||
if err := context.ShouldBind(&p); err != nil {
|
||||
global.GVA_LOG.Error("余额支付参数错误", zap.Error(err))
|
||||
r.FailWithMessage("余额支付参数错误", context)
|
||||
return
|
||||
}
|
||||
|
||||
err := orderService.BalancePay(p)
|
||||
if err != nil {
|
||||
global.GVA_LOG.Error("余额支付失败", zap.Error(err))
|
||||
r.FailWithMessage("余额支付失败:"+err.Error(), context)
|
||||
return
|
||||
}
|
||||
|
||||
r.OkWithMessage("余额支付成功", context)
|
||||
}
|
||||
|
@@ -117,32 +117,24 @@ func (*AppUserApi) WechatLogin(ctx *gin.Context) {
|
||||
r.FailWithMessage("获取token失败", ctx)
|
||||
return
|
||||
}
|
||||
if _, err = global.GVA_REDIS.Get(ctx, strconv.Itoa(int(user.ID))).Result(); errors.Is(err, redis.Nil) {
|
||||
// 此处过期时间等于jwt过期时间
|
||||
dr, err := utils.ParseDuration(global.GVA_CONFIG.JWT.ExpiresTime)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
timer := dr
|
||||
if err := global.GVA_REDIS.Set(ctx, strconv.Itoa(int(user.ID)), token, timer).Err(); err != nil {
|
||||
global.GVA_LOG.Error("设置登录状态失败!", zap.Error(err))
|
||||
r.FailWithMessage("设置登录状态失败", ctx)
|
||||
return
|
||||
}
|
||||
user_jwt.SetToken(ctx, token, int(claims.RegisteredClaims.ExpiresAt.Unix()-time.Now().Unix()))
|
||||
|
||||
result := map[string]interface{}{}
|
||||
result["User"] = user
|
||||
result["Token"] = token
|
||||
result["ExpiresAt"] = claims.RegisteredClaims.ExpiresAt.Unix() * 1000
|
||||
fmt.Println(result)
|
||||
|
||||
r.OkWithDetailed(gin.H{
|
||||
"User": user,
|
||||
"Token": token,
|
||||
"ExpiresAt": claims.RegisteredClaims.ExpiresAt.Unix() * 1000,
|
||||
}, "登录成功", ctx)
|
||||
// 此处过期时间等于jwt过期时间
|
||||
dr, err := utils.ParseDuration(global.GVA_CONFIG.JWT.ExpiresTime)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
timer := dr
|
||||
if err := global.GVA_REDIS.Set(ctx, strconv.Itoa(int(user.ID)), token, timer).Err(); err != nil {
|
||||
global.GVA_LOG.Error("设置登录状态失败!", zap.Error(err))
|
||||
r.FailWithMessage("设置登录状态失败", ctx)
|
||||
return
|
||||
}
|
||||
user_jwt.SetToken(ctx, token, int(claims.RegisteredClaims.ExpiresAt.Unix()-time.Now().Unix()))
|
||||
|
||||
r.OkWithDetailed(gin.H{
|
||||
"User": user,
|
||||
"Token": token,
|
||||
"ExpiresAt": claims.RegisteredClaims.ExpiresAt.Unix() * 1000,
|
||||
}, "登录成功", ctx)
|
||||
}
|
||||
|
||||
// GetUserInfo 获取用户信息
|
||||
|
12
config.yaml
12
config.yaml
@@ -249,13 +249,13 @@ wechat:
|
||||
pay-list:
|
||||
- type: wxpay
|
||||
alias-name: wxpay-1
|
||||
app-id: 1
|
||||
mch-id: 1
|
||||
app-id: wx3d21df18d7f8f9fc
|
||||
mch-id: 1646874753
|
||||
v3-key: 1a3sd8561d5179Df152D4789aD38wG9s
|
||||
cert-path: 1
|
||||
key-path: 1
|
||||
notify-url: 1
|
||||
serial-no: 1
|
||||
cert-path: /resource/cert/apiclient_cert.pem
|
||||
key-path: /resource/cert/apiclient_key.pem
|
||||
notify-url: http://lckt.hnlc5588.cn/app_order/notify
|
||||
serial-no: 59A891FB403EC7A1CF2090DB9C8EC704BD43B101
|
||||
- type: wxpay2
|
||||
alias-name: wxpay-2
|
||||
app-id: 2
|
||||
|
@@ -119,6 +119,7 @@ func Routers() *gin.Engine {
|
||||
{
|
||||
appRouter.InitAppUserRouter(AppAuthGroup, PublicGroup)
|
||||
appRouter.InitBannerRouter(PrivateGroup, PublicGroup) // Banner相关路由
|
||||
appRouter.InitOrderRouter(AppAuthGroup) // 订单相关路由
|
||||
}
|
||||
|
||||
//插件路由安装
|
||||
|
1
main.go
1
main.go
@@ -44,5 +44,6 @@ func main() {
|
||||
}
|
||||
|
||||
wechat.InitWeOfficial() // 初始化微信公众号SDK
|
||||
wechat.InitWechatPay() // 初始化微信支付SDK
|
||||
core.RunWindowsServer()
|
||||
}
|
||||
|
@@ -8,12 +8,15 @@ type Order struct {
|
||||
UserId uint64 `gorm:"column:user_id;type:bigint(20) unsigned;comment:用户ID;NOT NULL" json:"user_id"`
|
||||
OrderType int `gorm:"column:order_type;type:int(11);comment:订单类型 |1 课程|2 vip|;NOT NULL" json:"order_type"`
|
||||
ArticleId uint `gorm:"column:article_id;type:bigint(20) unsigned;default:0;comment:文章ID;NOT NULL" json:"article_id"`
|
||||
Title string `gorm:"column:title;type:varchar(255);comment:订单标题;NOT NULL" json:"title"`
|
||||
Name string `gorm:"column:name;type:varchar(255);comment:名称;NOT NULL" json:"name"`
|
||||
Price int64 `gorm:"column:price;type:int(11) unsigned;default:0;comment:订单价格;NOT NULL" json:"price"`
|
||||
Phone string `gorm:"column:phone;type:varchar(11);comment:手机号;NOT NULL" json:"phone"`
|
||||
TeacherId uint64 `gorm:"column:teacher_Id;type:bigint(20);comment:教师Id;NOT NULL" json:"teacher_Id"`
|
||||
Status int `gorm:"column:status;type:int(11);default:1;comment:订单状态 |1 未付款|2 已付款|3 已过期|;NOT NULL" json:"status"`
|
||||
Desc string `gorm:"column:desc;type:varchar(24);comment:订单描述;NOT NULL" json:"desc"`
|
||||
OpenId string `gorm:"column:open_id;type:varchar(64);comment:用户OpenId;NOT NULL" json:"open_id"`
|
||||
PayType int `gorm:"column:pay_type;type:int(11);default:1;comment:支付方式 |1 微信|2 支付宝|3 余额|;NOT NULL" json:"pay_type"`
|
||||
}
|
||||
|
||||
// TableName Order表
|
||||
|
23
model/app/request/order.go
Normal file
23
model/app/request/order.go
Normal file
@@ -0,0 +1,23 @@
|
||||
package request
|
||||
|
||||
import common "git.echol.cn/loser/lckt/model/common/request"
|
||||
|
||||
type BalancePay struct {
|
||||
UserId uint `json:"user_id" binding:"required"` // 用户ID
|
||||
OrderNo string `json:"order_no" binding:"required"` // 订单号
|
||||
OrderId uint `json:"order_id" binding:"required"` // 订单ID
|
||||
}
|
||||
|
||||
type GetOrderList struct {
|
||||
common.PageInfo
|
||||
Status int `json:"status" form:"status"` // 订单状态
|
||||
}
|
||||
|
||||
type PayReq struct {
|
||||
UserId uint64 `json:"user_id"` // 用户ID
|
||||
OrderId uint `json:"order_id"`
|
||||
Mode string `json:"mode"` // h5 jsapi
|
||||
WxCode string `json:"wx_code"`
|
||||
PayMethod int `json:"pay_method" vd:"$>0; msg:'参数不能为空'"`
|
||||
OrderNo string `json:"order_no" vd:"@:len($)>0; msg:'订单编号参数不能为空'"`
|
||||
}
|
BIN
resource/cert/apiclient_cert.p12
Normal file
BIN
resource/cert/apiclient_cert.p12
Normal file
Binary file not shown.
25
resource/cert/apiclient_cert.pem
Normal file
25
resource/cert/apiclient_cert.pem
Normal file
@@ -0,0 +1,25 @@
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIEKzCCAxOgAwIBAgIUWaiR+0A+x6HPIJDbnI7HBL1DsQEwDQYJKoZIhvcNAQEL
|
||||
BQAwXjELMAkGA1UEBhMCQ04xEzARBgNVBAoTClRlbnBheS5jb20xHTAbBgNVBAsT
|
||||
FFRlbnBheS5jb20gQ0EgQ2VudGVyMRswGQYDVQQDExJUZW5wYXkuY29tIFJvb3Qg
|
||||
Q0EwHhcNMjUwNzIzMDU1MDU5WhcNMzAwNzIyMDU1MDU5WjCBhDETMBEGA1UEAwwK
|
||||
MTY0Njg3NDc1MzEbMBkGA1UECgwS5b6u5L+h5ZWG5oi357O757ufMTAwLgYDVQQL
|
||||
DCfmtbflj6PpvpnljY7pk4HlnZrmiJDnlLXlrZDllYbliqHllYbooYwxCzAJBgNV
|
||||
BAYTAkNOMREwDwYDVQQHDAhTaGVuWmhlbjCCASIwDQYJKoZIhvcNAQEBBQADggEP
|
||||
ADCCAQoCggEBAMUD4rf7ct0zUxJKGww+8c38L/IBx9yeNpOc7lav+CEwqZvieesy
|
||||
p1I2hbY+hwOZm23//0Vxcnl6fkr5wdidE/RsN808sGkYsetJ6q7LZsgsxnbaQd7w
|
||||
rBc4GlOh1Q4teErbjNTUMuozYzikEjMjgZMxs7i5WJnFMMVvgJS4681UKH8MQG93
|
||||
BnaaD5zEyofAnOov7mvC0KZ0RpqwiLdUsMaPzYILzccOv7Tj82Z/qLw8AFcI+7L1
|
||||
mq8trZxmSPXP5Fypz+1VKLKR9MaELUuQLPouewDjXkKTBnxkhoWow6huuz3qyUUo
|
||||
i7uJtnmDn6Eu+60ch61BB5ws3rhWDpltR/0CAwEAAaOBuTCBtjAJBgNVHRMEAjAA
|
||||
MAsGA1UdDwQEAwID+DCBmwYDVR0fBIGTMIGQMIGNoIGKoIGHhoGEaHR0cDovL2V2
|
||||
Y2EuaXRydXMuY29tLmNuL3B1YmxpYy9pdHJ1c2NybD9DQT0xQkQ0MjIwRTUwREJD
|
||||
MDRCMDZBRDM5NzU0OTg0NkMwMUMzRThFQkQyJnNnPUhBQ0M0NzFCNjU0MjJFMTJC
|
||||
MjdBOUQzM0E4N0FEMUNERjU5MjZFMTQwMzcxMA0GCSqGSIb3DQEBCwUAA4IBAQBk
|
||||
WmviQM60S/l4I4/RtQWtiZS+85fk2ePVSk5gBUS27W4yTw+aXy5RYaCLcOVXTXje
|
||||
PpAfE7QvkjZxMg/k0SJR0/NbgDNF6xuCbMj78+czWVCkqHwPjY4hWRdsM9s44Orp
|
||||
lwFrG/UNRhPgXcdwNQj8MNzy3nGeO0HWbJFBWcuRhSSwXpxv3Sh6pZviL3QA+lrV
|
||||
7QB7d0fEu8sSGbwnIB0oXl7y78l2/D20p57TKHsq5IPfQfDdExNXKV60ikMt/MdP
|
||||
C4ygbeRpSAobr6qMTXcpWlbH3KfIPOUFny3nkN8C6lm//QUl7ynOXkECcmIHY6XF
|
||||
yMx70ORdoBl1DaZ369P9
|
||||
-----END CERTIFICATE-----
|
28
resource/cert/apiclient_key.pem
Normal file
28
resource/cert/apiclient_key.pem
Normal file
@@ -0,0 +1,28 @@
|
||||
-----BEGIN PRIVATE KEY-----
|
||||
MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDFA+K3+3LdM1MS
|
||||
ShsMPvHN/C/yAcfcnjaTnO5Wr/ghMKmb4nnrMqdSNoW2PocDmZtt//9FcXJ5en5K
|
||||
+cHYnRP0bDfNPLBpGLHrSequy2bILMZ22kHe8KwXOBpTodUOLXhK24zU1DLqM2M4
|
||||
pBIzI4GTMbO4uViZxTDFb4CUuOvNVCh/DEBvdwZ2mg+cxMqHwJzqL+5rwtCmdEaa
|
||||
sIi3VLDGj82CC83HDr+04/Nmf6i8PABXCPuy9ZqvLa2cZkj1z+Rcqc/tVSiykfTG
|
||||
hC1LkCz6LnsA415CkwZ8ZIaFqMOobrs96slFKIu7ibZ5g5+hLvutHIetQQecLN64
|
||||
Vg6ZbUf9AgMBAAECggEBAI4q66PQM2cj7kI4b6Q6l8sIvKBqYIr3MHL8v5CWkvuA
|
||||
XiQ7Hbd3af6NkZedL1iNs/eAz/iQkQbQOepoqFVjpE6w+OOFc9ejFmCvikZwSM8S
|
||||
YHTLstTp34Ux2u2WzmPYtAFwxQOfzM3sHyF0ZB269Xn+V65pMWJlRXhzqdmoR6B2
|
||||
YYLzHVBZAbgj7IlS+f1WPkkbrb3BIs71tYyPS3Ng6nhGgXrnqmE5fhm93wR9KR5R
|
||||
RcgzFGH/8qD2LndmJz8tYtjvlq016Pp40VrYabIrvX6apglayShLQ+2XUe8VKH2Q
|
||||
dQPIKL3R0ZeDeqwn4PTMclBYd/nXFSbIQndufTDY84ECgYEA8RTcCPOFYkoDeQIr
|
||||
yKqWo1P1cKsB/bGzvLmo+FqFQij5lmj9iDdvpSQJ58Uj+TFy5qNRT6VueF8U4pNd
|
||||
Fmcbw05cH+9NzAXji6aYWCargbmhW4L+rzub+TQmdAfqXbBknVgrLenY4LFnFFm1
|
||||
SIdJRid3vCwiRuhcjecg4FasR+kCgYEA0TTw4ZGxPCX5qt00PUFvuGpqFxFqZ7Ah
|
||||
wapwQTUY48WeC0Pg7Iq6ipnhjggkgYLkGc1klmTwJXKV0acIS5/DNclepMWZPwIc
|
||||
+GcKclQsy8MHm+L2tPGBQosRGiSrXi5LzBIQsYSyhBRDUSqu+yj7TTd2XqpUkLAw
|
||||
qdrWiIjVBvUCgYAOkh0uaVGBfEmzcZ8l1LGgE339HkjThX8AhBQjVo1BT2quXZAd
|
||||
QIR97ayvlmmzMPrp16sdbjk8Czse6pswtHCoID9PKs5/60cydJI2mbe58nc/Ka6s
|
||||
9qRZrn44exX+LaAXJnINp1mVUwOQ5k8foBWcqNwCwoQb1wVpCjQhevuUqQKBgQC1
|
||||
SA+3Fr0iprF6iqWastoxThzSEmhGowwNOjh9eJoxvOsfTdlYfzn3ojIeFhY0F4y6
|
||||
gw03eQ3TFUCXZAq/JRhNwkl9tC//tkAOS5N00FXk1wH/5aLr1h2w4LqYEdBhEvLh
|
||||
SYInoRnjc3+FlNv9jVx9Y6Lxkt0mZ1YzyQp/UzptBQKBgFTOonik05rMHGlEg9Ng
|
||||
unjDAEK+7tXhM/RKxWDs7pZeGbdl1c/NDOX4wIbuK2cCkV0v/qfg6Ex2Obf5rqM4
|
||||
R5lrs9y30rZbwmfms8G3cimTAsOcLqObKkBED+g07t+3bw44JXLwYLPm/z//bIcI
|
||||
fkxyxKL5ZJhP3/bPJJj8UAq3
|
||||
-----END PRIVATE KEY-----
|
@@ -5,7 +5,9 @@ import api "git.echol.cn/loser/lckt/api/v1"
|
||||
type RouterGroup struct {
|
||||
UserRouter
|
||||
BannerRouter
|
||||
OrderRouter
|
||||
}
|
||||
|
||||
var userApi = api.ApiGroupApp.AppApiGroup.AppUserApi
|
||||
var bannerApi = api.ApiGroupApp.AppApiGroup.BannerApi
|
||||
var orderApi = api.ApiGroupApp.AppApiGroup.OrderApi
|
||||
|
18
router/app/order.go
Normal file
18
router/app/order.go
Normal file
@@ -0,0 +1,18 @@
|
||||
package app
|
||||
|
||||
import "github.com/gin-gonic/gin"
|
||||
|
||||
type OrderRouter struct{}
|
||||
|
||||
// InitOrderRouter 初始化订单路由
|
||||
func (r *OrderRouter) InitOrderRouter(AppRouter *gin.RouterGroup) {
|
||||
appRouter := AppRouter.Group("app_order")
|
||||
{
|
||||
appRouter.POST("", orderApi.CreateOrder) // 创建订单
|
||||
appRouter.POST("/wechat/pay", orderApi.PayOrder) // 微信支付订单
|
||||
appRouter.GET("/list", orderApi.GetOrderList) // 获取订单列表
|
||||
appRouter.GET(":id", orderApi.GetOrderDetail) // 获取订单详情
|
||||
appRouter.POST("/balance/pay", orderApi.BalancePay) // 余额支付
|
||||
appRouter.POST("/notify", orderApi.NotifyOrder) // 微信支付回调通知
|
||||
}
|
||||
}
|
@@ -1,8 +1,160 @@
|
||||
package app
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"git.echol.cn/loser/lckt/global"
|
||||
"git.echol.cn/loser/lckt/model/app"
|
||||
"git.echol.cn/loser/lckt/model/app/request"
|
||||
"git.echol.cn/loser/lckt/model/user"
|
||||
"git.echol.cn/loser/lckt/utils/wechat"
|
||||
"github.com/gin-gonic/gin"
|
||||
"go.uber.org/zap"
|
||||
)
|
||||
|
||||
type OrderService struct{}
|
||||
|
||||
// Pay 发起支付
|
||||
func (s *OrderService) Pay(orderId string, userId int64) (string, error) {
|
||||
func (s *OrderService) Pay(p request.PayReq, ctx *gin.Context) (interface{}, error) {
|
||||
order := app.Order{}
|
||||
err := global.GVA_DB.Where("id = ? AND order_no = ?", p.OrderId, p.OrderNo).First(&order).Error
|
||||
if err != nil {
|
||||
global.GVA_LOG.Error("查询订单失败", zap.Error(err))
|
||||
return "", err
|
||||
}
|
||||
|
||||
if order.Status == 3 {
|
||||
global.GVA_LOG.Error("订单已过期", zap.Int64("order_id", int64(order.ID)))
|
||||
return "", fmt.Errorf("订单已过期")
|
||||
}
|
||||
|
||||
if p.Mode == "h5" {
|
||||
payConf, err := wechat.H5Pay(&order, ctx)
|
||||
if err != nil {
|
||||
global.GVA_LOG.Error("微信支付订单失败", zap.Error(err))
|
||||
return "", err
|
||||
}
|
||||
return payConf, nil
|
||||
} else if p.Mode == "jsapi" {
|
||||
payConf, err := wechat.JSAPIPay(&order, ctx)
|
||||
if err != nil {
|
||||
global.GVA_LOG.Error("微信支付订单失败", zap.Error(err))
|
||||
return "", err
|
||||
}
|
||||
return payConf, nil
|
||||
}
|
||||
|
||||
return "", nil
|
||||
}
|
||||
|
||||
func (s *OrderService) Create(o *app.Order) (*app.Order, error) {
|
||||
// 生成订单号
|
||||
o.OrderNo = wechat.GenerateOrderNum()
|
||||
|
||||
// 查询订单商品价格
|
||||
price := 0
|
||||
if o.OrderType == 1 {
|
||||
err := global.GVA_DB.Table("article").Select("price").Where("id = ?", o.ArticleId).Scan(&price).Error
|
||||
if err != nil {
|
||||
global.GVA_LOG.Error("查询商品价格失败", zap.Error(err))
|
||||
return nil, err
|
||||
}
|
||||
} else {
|
||||
err := global.GVA_DB.Table("lckt_vip").Select("price").Where("id = ?", o.ArticleId).Scan(&price).Error
|
||||
if err != nil {
|
||||
global.GVA_LOG.Error("查询VIP价格失败", zap.Error(err))
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
o.Price = int64(price)
|
||||
o.Status = 1 // 设置订单状态为未付款
|
||||
// 设置openid
|
||||
openId := ""
|
||||
err := global.GVA_DB.Table("app_user").Where("id = ?", o.UserId).Select("open_id").Scan(&openId).Error
|
||||
if err != nil {
|
||||
global.GVA_LOG.Error("查询用户OpenID失败,请检查微信是否绑定", zap.Error(err))
|
||||
return nil, fmt.Errorf("查询用户OpenID失败,请检查微信是否绑定")
|
||||
}
|
||||
o.OpenId = openId
|
||||
|
||||
err = global.GVA_DB.Create(&o).Error
|
||||
if err != nil {
|
||||
global.GVA_LOG.Error("创建订单失败", zap.Error(err))
|
||||
return nil, err
|
||||
}
|
||||
return o, nil
|
||||
}
|
||||
|
||||
func (s *OrderService) GetOrderDetail(id string) (order app.Order, err error) {
|
||||
err = global.GVA_DB.Where("id = ?", id).First(&order).Error
|
||||
if err != nil {
|
||||
global.GVA_LOG.Error("获取订单详情失败", zap.Error(err))
|
||||
return app.Order{}, err
|
||||
}
|
||||
return order, nil
|
||||
}
|
||||
|
||||
func (s *OrderService) BalancePay(p request.BalancePay) error {
|
||||
order := app.Order{}
|
||||
err := global.GVA_DB.Where("id = ? AND order_no = ?", p.OrderId, p.OrderNo).First(&order).Error
|
||||
if err != nil {
|
||||
global.GVA_LOG.Error("查询订单失败", zap.Error(err))
|
||||
return err
|
||||
}
|
||||
|
||||
if order.Status != 1 {
|
||||
global.GVA_LOG.Error("订单状态错误,无法支付", zap.Int("status", order.Status))
|
||||
return err
|
||||
}
|
||||
// 检查用户余额是否足够
|
||||
var user user.User
|
||||
err = global.GVA_DB.Where("id = ?", p.UserId).Select("id,balance").First(&user).Error
|
||||
if err != nil {
|
||||
global.GVA_LOG.Error("查询用户信息失败", zap.Error(err))
|
||||
return err
|
||||
}
|
||||
// 将user.Balance转为int64类型进行比较
|
||||
balance := int64(user.Balance)
|
||||
if balance < order.Price/100 { // 订单价格是以分为单位存储的
|
||||
global.GVA_LOG.Error("用户余额不足", zap.Int64("balance", balance), zap.Int64("order_price", order.Price))
|
||||
return fmt.Errorf("用户余额不足")
|
||||
}
|
||||
|
||||
// 扣除用户余额
|
||||
balance -= order.Price / 100
|
||||
err = global.GVA_DB.Model(&user).Where("id = ?", p.UserId).Update("balance", balance).Error
|
||||
if err != nil {
|
||||
global.GVA_LOG.Error("扣除用户余额失败", zap.Error(err))
|
||||
return err
|
||||
}
|
||||
// 更新订单状态为已付款
|
||||
order.Status = 2
|
||||
err = global.GVA_DB.Model(&order).Where("id = ?", order.ID).Update("status", 2).Error
|
||||
if err != nil {
|
||||
global.GVA_LOG.Error("更新订单状态失败", zap.Error(err))
|
||||
return err
|
||||
}
|
||||
|
||||
global.GVA_LOG.Info("余额支付成功", zap.Int64("user_id", int64(p.UserId)), zap.String("order_no", order.OrderNo))
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *OrderService) GetOrderList(p request.GetOrderList, id uint) (orders []app.Order, total int64, err error) {
|
||||
limit := p.PageSize
|
||||
offset := p.PageSize * (p.Page - 1)
|
||||
|
||||
db := global.GVA_DB.Model(&app.Order{}).Where("user_id = ?", id)
|
||||
if p.Keyword != "" {
|
||||
db = db.Where("title LIKE ? ", "%"+p.Keyword+"%")
|
||||
}
|
||||
if p.Status != 0 {
|
||||
db = db.Where("status = ?", p.Status)
|
||||
}
|
||||
|
||||
err = db.Count(&total).Error
|
||||
err = db.Limit(limit).Offset(offset).Order("created_at desc").Find(&orders).Error
|
||||
if err != nil {
|
||||
global.GVA_LOG.Error("获取订单列表失败", zap.Error(err))
|
||||
return nil, 0, err
|
||||
}
|
||||
return
|
||||
}
|
||||
|
@@ -75,13 +75,13 @@ func (s ArticleService) APPGetArticleList(pageInfo request.GetList) (list []vo.A
|
||||
return
|
||||
}
|
||||
|
||||
func (s ArticleService) APPGetArticle(id string, userId uint) (article vo.ArticleVo, err error) {
|
||||
func (s ArticleService) APPGetArticle(id string, userId uint) (article *vo.ArticleVo, err error) {
|
||||
err = global.GVA_DB.Table("article").Where("id = ?", id).First(&article).Error
|
||||
if err != nil {
|
||||
global.GVA_LOG.Error("获取文章失败", zap.Error(err))
|
||||
return
|
||||
}
|
||||
article.IsBuy = 1 // 设置为已购买
|
||||
article.IsBuy = 1
|
||||
|
||||
global.GVA_DB.Table("app_user").Select("avatar").Where("id = ?", article.TeacherId).Scan(&article.TeacherAvatar)
|
||||
|
||||
@@ -89,10 +89,10 @@ func (s ArticleService) APPGetArticle(id string, userId uint) (article vo.Articl
|
||||
if article.IsFree == 0 {
|
||||
// 如果不是免费文章,判断用户是否购买过
|
||||
var count int64
|
||||
err = global.GVA_DB.Model(&app.Order{}).Where("article_id = ? AND user_id = ?", id, userId).Count(&count).Error
|
||||
err = global.GVA_DB.Model(&app.Order{}).Where("article_id = ? AND user_id = ? AND status = 2", id, userId).Count(&count).Error
|
||||
if err != nil {
|
||||
global.GVA_LOG.Error("查询用户购买记录失败", zap.Error(err))
|
||||
return
|
||||
return nil, err
|
||||
}
|
||||
if count == 0 {
|
||||
// 用户没有购买过,隐藏Content
|
||||
|
245
utils/wechat/pay.go
Normal file
245
utils/wechat/pay.go
Normal file
@@ -0,0 +1,245 @@
|
||||
package wechat
|
||||
|
||||
import (
|
||||
gfmt "fmt"
|
||||
"git.echol.cn/loser/lckt/global"
|
||||
"git.echol.cn/loser/lckt/model/app"
|
||||
"github.com/ArtisanCloud/PowerLibs/v3/fmt"
|
||||
"github.com/ArtisanCloud/PowerWeChat/v3/src/kernel/models"
|
||||
"github.com/ArtisanCloud/PowerWeChat/v3/src/payment"
|
||||
wxRequst "github.com/ArtisanCloud/PowerWeChat/v3/src/payment/notify/request"
|
||||
"github.com/ArtisanCloud/PowerWeChat/v3/src/payment/order/request"
|
||||
"github.com/gin-gonic/gin"
|
||||
"go.uber.org/zap"
|
||||
"log"
|
||||
"math/rand"
|
||||
"time"
|
||||
)
|
||||
|
||||
var WechatPay *payment.Payment
|
||||
|
||||
// InitWechatPay 初始化微信支付
|
||||
func InitWechatPay() {
|
||||
PaymentService, err := payment.NewPayment(&payment.UserConfig{
|
||||
AppID: "wx3d21df18d7f8f9fc", // 小程序、公众号或者企业微信的appid
|
||||
MchID: global.GVA_CONFIG.Pays[0].MchId, // 商户号 appID
|
||||
MchApiV3Key: "1a3sd8561d5179Df152D4789aD38wG9s", // 微信V3接口调用必填
|
||||
Key: "57s14dFG915486Sd5617f23d45f671Ad",
|
||||
CertPath: `-----BEGIN CERTIFICATE-----
|
||||
MIIEKzCCAxOgAwIBAgIUWaiR+0A+x6HPIJDbnI7HBL1DsQEwDQYJKoZIhvcNAQEL
|
||||
BQAwXjELMAkGA1UEBhMCQ04xEzARBgNVBAoTClRlbnBheS5jb20xHTAbBgNVBAsT
|
||||
FFRlbnBheS5jb20gQ0EgQ2VudGVyMRswGQYDVQQDExJUZW5wYXkuY29tIFJvb3Qg
|
||||
Q0EwHhcNMjUwNzIzMDU1MDU5WhcNMzAwNzIyMDU1MDU5WjCBhDETMBEGA1UEAwwK
|
||||
MTY0Njg3NDc1MzEbMBkGA1UECgwS5b6u5L+h5ZWG5oi357O757ufMTAwLgYDVQQL
|
||||
DCfmtbflj6PpvpnljY7pk4HlnZrmiJDnlLXlrZDllYbliqHllYbooYwxCzAJBgNV
|
||||
BAYTAkNOMREwDwYDVQQHDAhTaGVuWmhlbjCCASIwDQYJKoZIhvcNAQEBBQADggEP
|
||||
ADCCAQoCggEBAMUD4rf7ct0zUxJKGww+8c38L/IBx9yeNpOc7lav+CEwqZvieesy
|
||||
p1I2hbY+hwOZm23//0Vxcnl6fkr5wdidE/RsN808sGkYsetJ6q7LZsgsxnbaQd7w
|
||||
rBc4GlOh1Q4teErbjNTUMuozYzikEjMjgZMxs7i5WJnFMMVvgJS4681UKH8MQG93
|
||||
BnaaD5zEyofAnOov7mvC0KZ0RpqwiLdUsMaPzYILzccOv7Tj82Z/qLw8AFcI+7L1
|
||||
mq8trZxmSPXP5Fypz+1VKLKR9MaELUuQLPouewDjXkKTBnxkhoWow6huuz3qyUUo
|
||||
i7uJtnmDn6Eu+60ch61BB5ws3rhWDpltR/0CAwEAAaOBuTCBtjAJBgNVHRMEAjAA
|
||||
MAsGA1UdDwQEAwID+DCBmwYDVR0fBIGTMIGQMIGNoIGKoIGHhoGEaHR0cDovL2V2
|
||||
Y2EuaXRydXMuY29tLmNuL3B1YmxpYy9pdHJ1c2NybD9DQT0xQkQ0MjIwRTUwREJD
|
||||
MDRCMDZBRDM5NzU0OTg0NkMwMUMzRThFQkQyJnNnPUhBQ0M0NzFCNjU0MjJFMTJC
|
||||
MjdBOUQzM0E4N0FEMUNERjU5MjZFMTQwMzcxMA0GCSqGSIb3DQEBCwUAA4IBAQBk
|
||||
WmviQM60S/l4I4/RtQWtiZS+85fk2ePVSk5gBUS27W4yTw+aXy5RYaCLcOVXTXje
|
||||
PpAfE7QvkjZxMg/k0SJR0/NbgDNF6xuCbMj78+czWVCkqHwPjY4hWRdsM9s44Orp
|
||||
lwFrG/UNRhPgXcdwNQj8MNzy3nGeO0HWbJFBWcuRhSSwXpxv3Sh6pZviL3QA+lrV
|
||||
7QB7d0fEu8sSGbwnIB0oXl7y78l2/D20p57TKHsq5IPfQfDdExNXKV60ikMt/MdP
|
||||
C4ygbeRpSAobr6qMTXcpWlbH3KfIPOUFny3nkN8C6lm//QUl7ynOXkECcmIHY6XF
|
||||
yMx70ORdoBl1DaZ369P9
|
||||
-----END CERTIFICATE-----
|
||||
`, // 微信V2接口调用必填
|
||||
KeyPath: `-----BEGIN PRIVATE KEY-----
|
||||
MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDFA+K3+3LdM1MS
|
||||
ShsMPvHN/C/yAcfcnjaTnO5Wr/ghMKmb4nnrMqdSNoW2PocDmZtt//9FcXJ5en5K
|
||||
+cHYnRP0bDfNPLBpGLHrSequy2bILMZ22kHe8KwXOBpTodUOLXhK24zU1DLqM2M4
|
||||
pBIzI4GTMbO4uViZxTDFb4CUuOvNVCh/DEBvdwZ2mg+cxMqHwJzqL+5rwtCmdEaa
|
||||
sIi3VLDGj82CC83HDr+04/Nmf6i8PABXCPuy9ZqvLa2cZkj1z+Rcqc/tVSiykfTG
|
||||
hC1LkCz6LnsA415CkwZ8ZIaFqMOobrs96slFKIu7ibZ5g5+hLvutHIetQQecLN64
|
||||
Vg6ZbUf9AgMBAAECggEBAI4q66PQM2cj7kI4b6Q6l8sIvKBqYIr3MHL8v5CWkvuA
|
||||
XiQ7Hbd3af6NkZedL1iNs/eAz/iQkQbQOepoqFVjpE6w+OOFc9ejFmCvikZwSM8S
|
||||
YHTLstTp34Ux2u2WzmPYtAFwxQOfzM3sHyF0ZB269Xn+V65pMWJlRXhzqdmoR6B2
|
||||
YYLzHVBZAbgj7IlS+f1WPkkbrb3BIs71tYyPS3Ng6nhGgXrnqmE5fhm93wR9KR5R
|
||||
RcgzFGH/8qD2LndmJz8tYtjvlq016Pp40VrYabIrvX6apglayShLQ+2XUe8VKH2Q
|
||||
dQPIKL3R0ZeDeqwn4PTMclBYd/nXFSbIQndufTDY84ECgYEA8RTcCPOFYkoDeQIr
|
||||
yKqWo1P1cKsB/bGzvLmo+FqFQij5lmj9iDdvpSQJ58Uj+TFy5qNRT6VueF8U4pNd
|
||||
Fmcbw05cH+9NzAXji6aYWCargbmhW4L+rzub+TQmdAfqXbBknVgrLenY4LFnFFm1
|
||||
SIdJRid3vCwiRuhcjecg4FasR+kCgYEA0TTw4ZGxPCX5qt00PUFvuGpqFxFqZ7Ah
|
||||
wapwQTUY48WeC0Pg7Iq6ipnhjggkgYLkGc1klmTwJXKV0acIS5/DNclepMWZPwIc
|
||||
+GcKclQsy8MHm+L2tPGBQosRGiSrXi5LzBIQsYSyhBRDUSqu+yj7TTd2XqpUkLAw
|
||||
qdrWiIjVBvUCgYAOkh0uaVGBfEmzcZ8l1LGgE339HkjThX8AhBQjVo1BT2quXZAd
|
||||
QIR97ayvlmmzMPrp16sdbjk8Czse6pswtHCoID9PKs5/60cydJI2mbe58nc/Ka6s
|
||||
9qRZrn44exX+LaAXJnINp1mVUwOQ5k8foBWcqNwCwoQb1wVpCjQhevuUqQKBgQC1
|
||||
SA+3Fr0iprF6iqWastoxThzSEmhGowwNOjh9eJoxvOsfTdlYfzn3ojIeFhY0F4y6
|
||||
gw03eQ3TFUCXZAq/JRhNwkl9tC//tkAOS5N00FXk1wH/5aLr1h2w4LqYEdBhEvLh
|
||||
SYInoRnjc3+FlNv9jVx9Y6Lxkt0mZ1YzyQp/UzptBQKBgFTOonik05rMHGlEg9Ng
|
||||
unjDAEK+7tXhM/RKxWDs7pZeGbdl1c/NDOX4wIbuK2cCkV0v/qfg6Ex2Obf5rqM4
|
||||
R5lrs9y30rZbwmfms8G3cimTAsOcLqObKkBED+g07t+3bw44JXLwYLPm/z//bIcI
|
||||
fkxyxKL5ZJhP3/bPJJj8UAq3
|
||||
-----END PRIVATE KEY-----
|
||||
`,
|
||||
SerialNo: global.GVA_CONFIG.Pays[0].SerialNo, // 商户支付证书序列号
|
||||
NotifyURL: global.GVA_CONFIG.Pays[0].NotifyUrl, // 微信支付回调地址
|
||||
HttpDebug: false,
|
||||
Log: payment.Log{
|
||||
Level: "debug",
|
||||
// 可以重定向到你的目录下,如果设置File和Error,默认会在当前目录下的wechat文件夹下生成日志
|
||||
File: "/Users/user/wechat/payment/info.log",
|
||||
Error: "/Users/user/wechat/payment/error.log",
|
||||
Stdout: false, // 是否打印在终端
|
||||
},
|
||||
Http: payment.Http{
|
||||
Timeout: 30.0,
|
||||
BaseURI: "https://api.mch.weixin.qq.com",
|
||||
},
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
log.Println("初始化微信支付 SDK失败", err)
|
||||
}
|
||||
WechatPay = PaymentService
|
||||
}
|
||||
|
||||
// H5Pay 发送订单
|
||||
func H5Pay(order *app.Order, ctx *gin.Context) (interface{}, error) {
|
||||
options := &request.RequestH5Prepay{
|
||||
Amount: &request.H5Amount{
|
||||
Total: int(order.Price),
|
||||
Currency: "CNY",
|
||||
},
|
||||
Attach: order.Desc,
|
||||
Description: order.Desc,
|
||||
OutTradeNo: order.OrderNo, // 这里是商户订单号,不能重复提交给微信
|
||||
SceneInfo: &request.H5SceneInfo{
|
||||
PayerClientIP: ctx.ClientIP(), // 用户终端IP
|
||||
H5Info: &request.H5H5Info{
|
||||
Type: "Wap",
|
||||
AppName: "老陈课堂",
|
||||
},
|
||||
},
|
||||
}
|
||||
// 下单
|
||||
response, err := WechatPay.Order.TransactionH5(ctx, options)
|
||||
|
||||
if err != nil {
|
||||
global.GVA_LOG.Error("微信支付下单失败", zap.Error(err))
|
||||
return "", err
|
||||
}
|
||||
/*
|
||||
payConf, err := WechatPay.JSSDK.BridgeConfig(response.PrepayID, true)
|
||||
if err != nil {
|
||||
global.GVA_LOG.Error("获取微信支付配置失败", zap.Error(err))
|
||||
return "", err
|
||||
}*/
|
||||
global.GVA_LOG.Info("微信支付配置", zap.Any("payConf", response))
|
||||
return response, nil
|
||||
}
|
||||
|
||||
func JSAPIPay(order *app.Order, ctx *gin.Context) (interface{}, error) {
|
||||
options := &request.RequestJSAPIPrepay{
|
||||
Amount: &request.JSAPIAmount{
|
||||
Total: int(order.Price),
|
||||
Currency: "CNY",
|
||||
},
|
||||
Attach: order.Name,
|
||||
Description: order.Desc,
|
||||
OutTradeNo: order.OrderNo, // 这里是商户订单号,不能重复提交给微信
|
||||
Payer: &request.JSAPIPayer{
|
||||
OpenID: order.OpenId, // 用户的openid, 记得也是动态的。
|
||||
},
|
||||
}
|
||||
|
||||
// 下单
|
||||
response, err := WechatPay.Order.JSAPITransaction(ctx, options)
|
||||
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
// payConf大致如下:
|
||||
// {
|
||||
// "appId": "ww16143ea0101327c7",
|
||||
// "nonceStr": "jcMfo7lsfM3LPWkLRJb7rQU6WeatStEU",
|
||||
// "package": "prepay_id=xxxxx",
|
||||
// "paySign": "hSPF2wU0aYeTq+DJ14ELM...省略部分数据...RrOmlEkZXVxqCdZmniLdA==",
|
||||
// "signType": "RSA",
|
||||
// "timeStamp": "1634305101"
|
||||
// }
|
||||
payConf, err := WechatPay.JSSDK.BridgeConfig(response.PrepayID, true)
|
||||
if err != nil {
|
||||
global.GVA_LOG.Error("获取微信支付配置失败", zap.Error(err))
|
||||
return "", err
|
||||
}
|
||||
|
||||
return payConf, nil
|
||||
}
|
||||
|
||||
// NotifyHandle 微信支付回调处理
|
||||
func NotifyHandle(ctx *gin.Context) error {
|
||||
res, err := WechatPay.HandlePaidNotify(
|
||||
ctx.Request,
|
||||
func(message *wxRequst.RequestNotify, transaction *models.Transaction, fail func(message string)) interface{} {
|
||||
// 看下支付通知事件状态
|
||||
// 这里可能是微信支付失败的通知,所以可能需要在数据库做一些记录,然后告诉微信我处理完成了。
|
||||
if message.EventType != "TRANSACTION.SUCCESS" {
|
||||
fmt.Dump(transaction)
|
||||
return true
|
||||
}
|
||||
|
||||
if transaction.OutTradeNo != "" {
|
||||
// 这里对照自有数据库里面的订单做查询以及支付状态改变
|
||||
// 更新订单状态为已支付
|
||||
order := app.Order{}
|
||||
err := global.GVA_DB.Model(&app.Order{}).Where("order_no = ?", transaction.OutTradeNo).First(&order).Error
|
||||
if err != nil {
|
||||
global.GVA_LOG.Error("查询订单失败", zap.Error(err))
|
||||
return nil
|
||||
}
|
||||
order.Status = 2 // 设置订单状态为已支付
|
||||
err = global.GVA_DB.Save(&order).Error
|
||||
if err != nil {
|
||||
global.GVA_LOG.Error("更新订单状态失败", zap.Error(err))
|
||||
return nil
|
||||
}
|
||||
log.Printf("订单号:%s 支付成功", transaction.OutTradeNo)
|
||||
} else {
|
||||
// 因为微信这个回调不存在订单号,所以可以告诉微信我还没处理成功,等会它会重新发起通知
|
||||
// 如果不需要,直接返回true即可
|
||||
fail("payment fail")
|
||||
return nil
|
||||
}
|
||||
return true
|
||||
},
|
||||
)
|
||||
|
||||
// 这里可能是因为不是微信官方调用的,无法正常解析出transaction和message,所以直接抛错。
|
||||
if err != nil {
|
||||
res.StatusCode = 502
|
||||
err = res.Write(ctx.Writer)
|
||||
return err
|
||||
//panic(err)
|
||||
}
|
||||
|
||||
// 这里根据之前返回的是true或者fail,框架这边自动会帮你回复微信
|
||||
err = res.Write(ctx.Writer)
|
||||
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
global.GVA_LOG.Info("微信支付回调处理成功", zap.Any("response", res))
|
||||
return nil
|
||||
}
|
||||
|
||||
func GenerateOrderNum() string {
|
||||
now := time.Now()
|
||||
dateStr := now.Format("060102") // 年的后2位+月+日
|
||||
seconds := int(now.Sub(time.Date(now.Year(), now.Month(), now.Day(), 0, 0, 0, 0, now.Location())).Seconds())
|
||||
secondsStr := gfmt.Sprintf("%05d", seconds)
|
||||
nanoStr := gfmt.Sprintf("%06d", now.Nanosecond()/1000) // 微秒级,6位
|
||||
rand.Seed(time.Now().UnixNano())
|
||||
randStr := gfmt.Sprintf("%03d", rand.Intn(1000)) // 3位随机数
|
||||
orderNo := gfmt.Sprintf("%s%s%s%s%s", "5258", dateStr, secondsStr, nanoStr, randStr)
|
||||
return orderNo
|
||||
}
|
@@ -3,15 +3,12 @@ package wechat
|
||||
import (
|
||||
"git.echol.cn/loser/lckt/global"
|
||||
"github.com/ArtisanCloud/PowerSocialite/v3/src/providers"
|
||||
"github.com/ArtisanCloud/PowerWeChat/v3/src/kernel"
|
||||
"github.com/ArtisanCloud/PowerWeChat/v3/src/officialAccount"
|
||||
"github.com/ArtisanCloud/PowerWeChat/v3/src/payment"
|
||||
"go.uber.org/zap"
|
||||
"log"
|
||||
)
|
||||
|
||||
var WeOfficial *officialAccount.OfficialAccount
|
||||
var WechatPay *payment.Payment
|
||||
|
||||
// InitWeOfficial 初始化微信公众号
|
||||
func InitWeOfficial() {
|
||||
@@ -37,43 +34,6 @@ func InitWeOfficial() {
|
||||
WeOfficial = OfficialAccountApp
|
||||
}
|
||||
|
||||
// InitWechatPay 初始化微信支付
|
||||
func InitWechatPay() {
|
||||
PaymentService, err := payment.NewPayment(&payment.UserConfig{
|
||||
AppID: "wx3d21df18d7f8f9fc\n", // 小程序、公众号或者企业微信的appid
|
||||
MchID: "[mch_id]", // 商户号 appID
|
||||
MchApiV3Key: "1a3sd8561d5179Df152D4789aD38wG9s", // 微信V3接口调用必填
|
||||
Key: "57s14dFG915486Sd5617f23d45f671Ad", // 微信V2接口调用必填
|
||||
CertPath: "[wx_cert_path]", // 商户后台支付的Cert证书路径
|
||||
KeyPath: "[wx_key_path]", // 商户后台支付的Key证书路径
|
||||
SerialNo: "[serial_no]", // 商户支付证书序列号
|
||||
NotifyURL: "[notify_url]", // 微信支付回调地址
|
||||
HttpDebug: true,
|
||||
Log: payment.Log{
|
||||
Level: "debug",
|
||||
// 可以重定向到你的目录下,如果设置File和Error,默认会在当前目录下的wechat文件夹下生成日志
|
||||
File: "/Users/user/wechat/payment/info.log",
|
||||
Error: "/Users/user/wechat/payment/error.log",
|
||||
Stdout: false, // 是否打印在终端
|
||||
},
|
||||
Http: payment.Http{
|
||||
Timeout: 30.0,
|
||||
BaseURI: "https://api.mch.weixin.qq.com",
|
||||
},
|
||||
// 可选,不传默认走程序内存
|
||||
Cache: kernel.NewRedisClient(&kernel.UniversalOptions{
|
||||
Addrs: []string{"127.0.0.1:6379"},
|
||||
Password: "",
|
||||
DB: 0,
|
||||
}),
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
log.Println("初始化微信支付 SDK失败", err)
|
||||
}
|
||||
WechatPay = PaymentService
|
||||
}
|
||||
|
||||
func GetUserInfo(code string) *providers.User {
|
||||
userFromCode, err := WeOfficial.OAuth.UserFromCode(code)
|
||||
if err != nil {
|
||||
|
Reference in New Issue
Block a user