新增了支付中心-获取订单支付数据
This commit is contained in:
parent
2ad676f9b1
commit
6b505f9b6c
@ -14,4 +14,5 @@ type Api struct {
|
|||||||
SystemMember // 会员配置
|
SystemMember // 会员配置
|
||||||
OrderMember // 订单-会员
|
OrderMember // 订单-会员
|
||||||
CallBack // 回调
|
CallBack // 回调
|
||||||
|
Pay // 支付中心
|
||||||
}
|
}
|
||||||
|
|||||||
169
api/controller/Pay.go
Normal file
169
api/controller/Pay.go
Normal file
@ -0,0 +1,169 @@
|
|||||||
|
package controller
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"github.com/gin-gonic/gin"
|
||||||
|
"hepa-calc-api/api/dao"
|
||||||
|
"hepa-calc-api/api/model"
|
||||||
|
"hepa-calc-api/api/responses"
|
||||||
|
"hepa-calc-api/config"
|
||||||
|
"hepa-calc-api/extend/app"
|
||||||
|
"hepa-calc-api/global"
|
||||||
|
"hepa-calc-api/utils"
|
||||||
|
"net/http"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Pay struct{}
|
||||||
|
|
||||||
|
// GetPayOrder 获取订单支付数据
|
||||||
|
func (r *Pay) GetPayOrder(c *gin.Context) {
|
||||||
|
req := app.PayOrderRequest{}
|
||||||
|
if err := c.ShouldBindJSON(&req); err != nil {
|
||||||
|
responses.FailWithMessage(err.Error(), c)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// 参数验证
|
||||||
|
if err := global.Validate.Struct(req); err != nil {
|
||||||
|
responses.FailWithMessage(utils.Translate(err), c)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取header签名
|
||||||
|
requestSign := c.Request.Header.Get("sign")
|
||||||
|
if requestSign == "" {
|
||||||
|
responses.FailWithMessage("缺少签名", c)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// 验证签名
|
||||||
|
err := app.VerifySignature(req, requestSign)
|
||||||
|
if err != nil {
|
||||||
|
responses.FailWithMessage(err.Error(), c)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
var payStatus int // 支付状态(1:未支付 2:已支付 3:支付中 4:支付失败 5:支付超时 6:支付关闭 7:已撤销 8:转入退款)
|
||||||
|
var orderStatus int // 订单状态(1:待支付 2:已完成 3:已取消)
|
||||||
|
var paymentAmountTotal int // 实际付款金额
|
||||||
|
var userId int64 // 用户id
|
||||||
|
var orderNo string // 订单编号
|
||||||
|
var goodName string // 商品名称
|
||||||
|
var createdAt model.LocalTime // 订单创建时间
|
||||||
|
var notifyUrl string // 回调通知地址
|
||||||
|
|
||||||
|
// 获取订单数据-单项
|
||||||
|
orderSingleDao := dao.OrderSingleDao{}
|
||||||
|
maps := make(map[string]interface{})
|
||||||
|
maps["order_no"] = req.OrderId
|
||||||
|
orderSingle, _ := orderSingleDao.GetOrderSingle(maps)
|
||||||
|
if orderSingle != nil {
|
||||||
|
payStatus = orderSingle.PayStatus
|
||||||
|
orderStatus = orderSingle.OrderStatus
|
||||||
|
paymentAmountTotal = int(orderSingle.PaymentAmountTotal * 100)
|
||||||
|
userId = orderSingle.UserId
|
||||||
|
orderNo = orderSingle.OrderNo
|
||||||
|
createdAt = orderSingle.CreatedAt
|
||||||
|
notifyUrl = config.C.Wechat.NotifyDomain + config.C.Wechat.SingleRefundNotifyUrl
|
||||||
|
|
||||||
|
// 获取单项数据
|
||||||
|
questionDao := dao.QuestionDao{}
|
||||||
|
question, err := questionDao.GetQuestionById(orderSingle.QuestionId)
|
||||||
|
if err != nil {
|
||||||
|
responses.FailWithMessage(err.Error(), c)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
goodName = question.QuestionTitle
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取订单数据-会员
|
||||||
|
orderMemberDao := dao.OrderMemberDao{}
|
||||||
|
maps = make(map[string]interface{})
|
||||||
|
maps["order_no"] = req.OrderId
|
||||||
|
orderMember, _ := orderMemberDao.GetOrderMember(maps)
|
||||||
|
if orderMember != nil {
|
||||||
|
payStatus = orderMember.PayStatus
|
||||||
|
orderStatus = orderMember.OrderStatus
|
||||||
|
paymentAmountTotal = int(orderMember.PaymentAmountTotal * 100)
|
||||||
|
userId = orderMember.UserId
|
||||||
|
orderNo = orderMember.OrderNo
|
||||||
|
createdAt = orderMember.CreatedAt
|
||||||
|
notifyUrl = config.C.Wechat.NotifyDomain + config.C.Wechat.MemberRefundNotifyUrl
|
||||||
|
|
||||||
|
// 获取对应数据
|
||||||
|
systemMemberDao := dao.SystemMemberDao{}
|
||||||
|
systemMember, err := systemMemberDao.GetSystemMemberById(orderMember.SystemMemberId)
|
||||||
|
if err != nil {
|
||||||
|
responses.FailWithMessage(err.Error(), c)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
memberDays := fmt.Sprintf("%d", systemMember.MemberDays)
|
||||||
|
goodName = "肝病算一算" + memberDays + "会员"
|
||||||
|
}
|
||||||
|
|
||||||
|
if orderSingle == nil && orderMember == nil {
|
||||||
|
c.JSON(http.StatusOK, gin.H{"code": 90002, "message": "订单不存在", "data": nil})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// 检测订单支付状态
|
||||||
|
if payStatus == 2 {
|
||||||
|
c.JSON(http.StatusOK, gin.H{"code": 90000, "message": "订单已支付,请勿重新支付", "data": nil})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if payStatus == 3 {
|
||||||
|
c.JSON(http.StatusOK, gin.H{"code": 90003, "message": "订单支付中", "data": nil})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if payStatus != 1 {
|
||||||
|
c.JSON(http.StatusOK, gin.H{"code": 90004, "message": "订单支付失败", "data": nil})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// 检测订单取消状态
|
||||||
|
if orderStatus == 3 {
|
||||||
|
c.JSON(http.StatusOK, gin.H{"code": 90001, "message": "订单已关闭", "data": nil})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if orderStatus == 2 {
|
||||||
|
c.JSON(http.StatusOK, gin.H{"code": 90004, "message": "订单支付失败", "data": nil})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// 验证订单过期支付时间
|
||||||
|
now := time.Now()
|
||||||
|
validTime := time.Time(createdAt).Add(30 * time.Minute)
|
||||||
|
if validTime.Before(now) {
|
||||||
|
c.JSON(http.StatusOK, gin.H{"code": 90001, "message": "订单已关闭", "data": nil})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取用户数据
|
||||||
|
userDao := dao.UserDao{}
|
||||||
|
user, err := userDao.GetUserById(userId)
|
||||||
|
if err != nil {
|
||||||
|
responses.FailWithMessage(err.Error(), c)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// 处理返回数据
|
||||||
|
g := app.PayOrderDataResponse{
|
||||||
|
AppId: config.C.Wechat.AppId,
|
||||||
|
Total: paymentAmountTotal,
|
||||||
|
Description: "肝病算一算",
|
||||||
|
OpenId: user.OpenId,
|
||||||
|
OutTradeNo: orderNo,
|
||||||
|
Attach: "",
|
||||||
|
NotifyUrl: notifyUrl,
|
||||||
|
GoodName: goodName,
|
||||||
|
}
|
||||||
|
|
||||||
|
responses.OkWithData(g, c)
|
||||||
|
return
|
||||||
|
}
|
||||||
@ -123,6 +123,13 @@ func publicRouter(r *gin.Engine, api controller.Api) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 支付中心
|
||||||
|
payGroup := r.Group("/pay")
|
||||||
|
{
|
||||||
|
// 获取订单支付数据
|
||||||
|
payGroup.POST("/order", api.Pay.GetPayOrder)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// adminRouter 公共路由-验证权限
|
// adminRouter 公共路由-验证权限
|
||||||
|
|||||||
53
extend/app/pay.go
Normal file
53
extend/app/pay.go
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
package app
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
)
|
||||||
|
|
||||||
|
// PayOrderRequest 获取订单支付请求数据
|
||||||
|
type PayOrderRequest struct {
|
||||||
|
OrderId string `json:"orderId" label:"订单编号" validate:"required"` // 订单id
|
||||||
|
}
|
||||||
|
|
||||||
|
// PayOrderDataResponse 获取订单支付返回数据-data
|
||||||
|
type PayOrderDataResponse struct {
|
||||||
|
AppId string `json:"appid"` // 公众号id
|
||||||
|
Total int `json:"total"` // 订单总金额(精确到分)
|
||||||
|
Description string `json:"description"` // 订单描述
|
||||||
|
OpenId string `json:"openid"` // 下单用户
|
||||||
|
OutTradeNo string `json:"out_trade_no"` // 商户订单
|
||||||
|
Attach string `json:"attach"` // 附加信息
|
||||||
|
NotifyUrl string `json:"notify_url"` // 异步接收微信支付结果通知的回调地址
|
||||||
|
GoodName string `json:"goodName"` // 商品名称
|
||||||
|
}
|
||||||
|
|
||||||
|
// VerifySignature 验证签名
|
||||||
|
func VerifySignature(req PayOrderRequest, requestSign string) error {
|
||||||
|
// 将 JSON 数据编码为字节数组
|
||||||
|
jsonData, err := json.Marshal(req)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
maps := make(map[string]interface{})
|
||||||
|
err = json.Unmarshal(jsonData, &maps)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// 生成签名
|
||||||
|
sign, err := GenSignature(maps)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Println(sign)
|
||||||
|
// 对比签名
|
||||||
|
if sign != requestSign {
|
||||||
|
return errors.New("签名错误")
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
@ -1,13 +1,15 @@
|
|||||||
package utils
|
package utils
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"errors"
|
||||||
"github.com/go-playground/validator/v10"
|
"github.com/go-playground/validator/v10"
|
||||||
"hepa-calc-api/global"
|
"hepa-calc-api/global"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Translate 检验并返回检验错误信息
|
// Translate 检验并返回检验错误信息
|
||||||
func Translate(err error) (errMsg string) {
|
func Translate(err error) (errMsg string) {
|
||||||
errs := err.(validator.ValidationErrors)
|
var errs validator.ValidationErrors
|
||||||
|
errors.As(err, &errs)
|
||||||
for _, err := range errs {
|
for _, err := range errs {
|
||||||
errMsg = err.Translate(global.Trans)
|
errMsg = err.Translate(global.Trans)
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user