feat:前台,api关闭的订单接口

This commit is contained in:
wolter 2024-08-23 14:22:48 +08:00
parent 9dac2644d4
commit e77a7622b1
8 changed files with 142 additions and 3 deletions

View File

@ -73,6 +73,8 @@ const (
OrderAppidNotEqRefundAppid = 1412
OrderNotSupportRefundPart = 1413
OrderRefundAmountError = 1414
// 关闭订单
CloseOrderPayed = 1420
//请求日志
RequestLogErrors = 1500
@ -165,6 +167,8 @@ var MsgZH = map[int]string{
OrderRefundAmountError: "退款金额错误",
RefundOutTradeNoSame: "支付商户单号和退款商户单号不能相同",
CloseOrderPayed: "订单已支付成功,无法关闭",
ThirdRefundFail: "第三方退款失败",
}
var MsgMap map[string]map[int]string = map[string]map[int]string{"en": MsgZH}

View File

@ -86,3 +86,16 @@ func QueryOrder(c *gin.Context) {
res.Order = data
controllers.ApiRes(c, res, errorcode.Success)
}
// 关闭订单
func CloseOrder(c *gin.Context) {
req := controllers.GetRequest(c).(*front.CloseReqs)
c.Set("OutTradeNo", req.OutTradeNo)
appCheckInfo := controllers.GetAppCheckInfo(c).(*services.AppCheck)
code, message := thirdpay.ThirdCloseOrder(c.Request.Context(), *req, appCheckInfo, c.ClientIP())
var res front.ApiResponse
res.Order = message
controllers.ApiRes(c, res, code)
}

View File

@ -43,8 +43,15 @@ type QueryReqs struct {
OutTradeNo string `json:"out_trade_no" validate:"required" label:"外侧商户订单号"`
}
// 关闭订单
type CloseReqs struct {
ApiCommonBody
PayChannelId int64 `json:"pay_channel_id" validate:"required" label:"支付渠道"`
OutTradeNo string `json:"out_trade_no" validate:"required" label:"外侧商户订单号"`
}
// api 接口返回数据, 统一返回结构, order数据会进行加密
type ApiResponse struct {
Order interface{} `json:"order"`
Order interface{} `json:"order,omitempty"`
Url string `json:"url,omitempty"`
}

View File

@ -9,6 +9,7 @@ var FrontRequestMap = map[string]func() (validForm interface{}, isSaveLog bool){
common.FRONT_V1 + "/pay/url": func() (interface{}, bool) { return new(front.PayReqs), true },
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 },
}
var FrontRequestMapBeforeDecrypt = map[string]func() interface{}{
@ -16,4 +17,5 @@ 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) },
}

View File

@ -61,6 +61,7 @@ func RegisterRoute(router *gin.Engine) {
pay.POST("/url", front.PayUrl)
pay.POST("/query", front.QueryOrder) //查询订单
pay.POST("/refund", front.Refund)
pay.POST("/close", front.CloseOrder)
}
// 测试微信支付唤起
v1.GET("/brokerWechatUrl", front.BrokerWechatUrl)

View File

@ -7,6 +7,7 @@ import (
"PaymentCenter/app/models/paychannelmodel"
"PaymentCenter/app/services"
"PaymentCenter/app/third/paymentService/payCommon"
"PaymentCenter/app/utils"
"context"
"xorm.io/builder"
@ -165,3 +166,41 @@ func (w *Pay) Refund() {
w.ThirdMsg = res.ErrorMsg
}
}
// 关闭订单
func (w *Pay) CloseOrder() {
var (
payFunc func(commonPayInfo *paymentService.PayOrderRequest, channel *paychannelmodel.PayChannel) error
ok bool
)
thirdPay := &paymentService.PayOrderRequest{
PayChannelId: w.PayParam.Channel.Id,
OrderId: w.Order.Id,
ChannelType: w.PayParam.Channel.ChannelType,
Description: w.Order.Desc,
Amount: w.Order.Amount,
PayerClientIp: w.PayParam.ClientIp,
ReturnUrl: w.PayParam.ReturnUrl,
}
if payFunc, ok = PayWayList[w.PayParam.Channel.ChannelType]; !ok {
w.PayCode = errorcode.PayChannelNotBuild
return
}
err := payFunc(thirdPay, w.PayParam.Channel)
if err != nil {
w.PayCode = errorcode.PayChannelExtJsonError
return
}
closeRequest := paymentService.OrderCloseRequest{
OrderId: thirdPay.OrderId,
PayChannel: utils.PayType(thirdPay.ChannelType),
Wx: thirdPay.Wx,
Ali: thirdPay.Ali,
}
res := paymentService.OrderClose(*w.ctx, closeRequest)
w.ThirdMsg = res.ErrorMsg
w.PayCode = res.Code
}

View File

@ -9,6 +9,7 @@ import (
"PaymentCenter/app/services/thirdpay/api"
thirdpay "PaymentCenter/app/services/thirdpay/do"
"PaymentCenter/app/services/thirdpay/types"
"PaymentCenter/app/third/paymentService/payCommon"
"context"
"github.com/jinzhu/copier"
)
@ -91,3 +92,54 @@ func ThirdPay(check *thirdpay.PayCheck) (pay *thirdpay.Pay) {
}
return
}
func thirdPayCloseCheck(ctx context.Context, payReq *front.CloseReqs, appCheck *services.AppCheck, ip string) (check *thirdpay.PayCheck) {
var req types.Reqs
copier.Copy(&req, payReq)
check = thirdpay.NewPayCheck(&ctx, &req, appCheck, ip)
// 校验表单
check.CheckPayInfo()
return
}
func ThirdCloseOrder(ctx context.Context, closeReq front.CloseReqs, appCheck *services.AppCheck, ip string) (code int, message string) {
check := thirdPayCloseCheck(ctx, &closeReq, appCheck, ip)
if check.CheckCode != errorcode.Success {
return
}
check.GetOldOrder(&types.OrderFindOne{
OutTradeNo: check.Reqs.OutTradeNo,
})
if check.OldOrder != nil {
switch check.OldOrder.Status {
// 1待支付,2支付中, 4支付失败
case common.ORDER_STATUS_WAITPAY, common.ORDER_STATUS_PAYING, common.ORDER_STATUS_FAILED:
// 调用上游关闭订单
client := thirdpay.NewPayWithPayCheck(check)
client.Order = check.OldOrder
client.CloseOrder()
code = client.PayCode
message = client.ThirdMsg
// 修改订单状态为已关闭
if client.PayCode == payCommon.PAY_SUCCESS_CODE {
check.OldOrder.Status = common.ORDER_STATUS_CLOSE
code = services.OrderUpdate(check.OldOrder, "status")
}
// 3支付成功
case common.ORDER_STATUS_PAYED:
code = errorcode.CloseOrderPayed
// 5已关闭
case common.ORDER_STATUS_CLOSE:
code = errorcode.Success
default:
code = errorcode.SystemError
}
} else {
code = errorcode.OrdersNotFound
}
return
}

View File

@ -47,8 +47,7 @@ func GetHostIp() string {
}
func Log(c *gin.Context, name string, msg ...interface{}) {
_, file, line, _ := runtime.Caller(1)
timeLayout := "2006-01-01 03:04:05" //转化所需模板
var datetime = time.Unix(time.Now().Unix(), 0).Format(timeLayout)
var datetime = time.Now().Format("2006-01-02 15:04:05")
fmt.Println(name, msg, file, line, datetime)
}
@ -462,3 +461,25 @@ func PayType(payChannel int) int {
return 0
}
}
// redis控制访问频率
func KeyExistsOrSet(key string, expire int) bool {
redisClient := redis.GetRedis()
// 假设Exists方法返回的是int64类型表示键是否存在0为不存在1为存在
if exists, err := redisClient.Exists(context.Background(), key).Result(); err == nil && exists == 1 {
return true
} else if err != nil {
// 处理错误情况,可以根据实际情况记录日志或返回错误
Log(nil, "redis_Exists异常", err)
return false
}
// 如果键不存在则设置键并返回false
if err := redisClient.SetEX(context.Background(), key, "", time.Duration(expire)*time.Second).Err(); err != nil {
// 处理设置键时的错误情况
Log(nil, "redis_SetEX异常", err)
return false
}
return false
}