<feat>支付部分

This commit is contained in:
Rzy 2024-08-05 18:45:01 +08:00
parent 71ccc46f23
commit 548491c1f1
13 changed files with 231 additions and 89 deletions

View File

@ -28,4 +28,26 @@ const (
ORDER_STATUS_PAYED = 3
ORDER_STATUS_FAILED = 4
ORDER_STATUS_CLOSE = 5
STATUS_ENABLE int32 = 1
STATUS_DISABLED int32 = 2
ORDER_TYPE_PAY int32 = 1
ORDER_TYPE_REFUND int32 = 2
)
var PayChannelList = map[int]string{
PAY_CHANNEL_WECHAT_JSAPI: "微信JSAPI",
PAY_CHANNEL_WECHAT_H5: "微信H5",
PAY_CHANNEL_WECHAT_APP: "微信app",
PAY_CHANNEL_WECHAT_NATIVE: "微信Native",
PAY_CHANNEL_WECHAT_MINI: "微信小程序",
PAY_CHANNEL_ALIPAY_WEB: "支付宝网页&移动应用",
PAY_CHANNEL_ALIPAY_MINI: "支付宝小程序",
PAY_CHANNEL_ALIPAY_JSAPI: "支付宝JSAPI",
}
var OrderTypeList = map[int32]string{
ORDER_TYPE_PAY: "付款",
ORDER_TYPE_REFUND: "退款",
}

View File

@ -48,13 +48,16 @@ const (
AppSM4EncryptFail = 1233
//渠道
PayChannelNotFound = 1300
PayChannelNotFound = 1300
PayChannelNotBuild = 1301
PayChannelExtJsonError = 1302
//订单
OrdersNotFound = 1300
OrdersNotFound = 1401
OrdersExist = 1402
OrderTypeNotFount = 1403
//网页支付
RequestLogErrors = 1400
RequestLogErrors = 1500
)
var MsgEN = map[int]string{
@ -94,9 +97,15 @@ var MsgZH = map[int]string{
AppSM4EncryptKeyNotFound: "密匙缺失无法进行sm4加密",
AppSM4EncryptFail: "sm4加密失败",
PayChannelNotFound: "支付方式不存在",
PayChannelNotFound: "支付方式不存在",
PayChannelNotBuild: "支付方式尚未开通",
PayChannelExtJsonError: "支付方式扩展参数错误",
RequestLogErrors: "请求日志错误",
OrdersNotFound: "未找到订单",
OrdersExist: "订单已存在",
OrderTypeNotFount: "未知的支付方式",
}
var MsgMap map[string]map[int]string = map[string]map[int]string{"en": MsgZH}

View File

@ -1,6 +0,0 @@
package pojo
const (
STATUS_ENABLE int32 = 1
STATUS_DISABLED int32 = 2
)

View File

@ -10,6 +10,7 @@ import (
func WebPay(c *gin.Context) {
req := controllers.GetRequest(c).(*front.PayWebReqs)
appCheckInfo := controllers.GetAppCheckInfo(c).(*services.AppCheck)
services.NewWebPay(req, appCheckInfo)
code := services.ThirdPayWeb(c.Request.Context(), req, appCheckInfo, c.ClientIP())
controllers.ErrWithCode(c, code)
return
}

View File

@ -16,6 +16,7 @@ type PayWebReqs struct {
PayChannelId int64 `json:"pay_channel_id" validate:"required" label:"支付渠道"`
OutTradeNo string `json:"out_trade_no" validate:"required" label:"外侧商户订单号"`
OrderType int32 `json:"order_type" validate:"required" label:"订单类型,支付,退款"`
Amount int64 `json:"amount" validate:"required" label:"支付金额,单位分"`
ExtJson string `json:"ext_json" validate:"required" label:"扩展参数"`
Amount int `json:"amount" validate:"required" label:"支付金额,单位分"`
ExtJson string `json:"ext_json" label:"扩展参数"`
Desc string `json:"desc" validate:"max=100" label:"商品描述"`
}

View File

@ -18,9 +18,10 @@ type Orders struct {
PayChannelId int64 `xorm:"'pay_channel_id' bigint(20)"`
AppId int64 `xorm:"'app_id' bigint(20)"`
OutTreadNo string `xorm:"'out_tread_no' varchar(50)"`
OrderType int `xorm:"'order_type' TINYINT"`
OrderType int32 `xorm:"'order_type' TINYINT"`
Amount int `xorm:"'amount' int(11)"`
ExtJson string `xorm:"'ext_json' varchar(1024)"`
Desc string `xorm:"'desc' varchar(100)"`
CreateTime time.Time `xorm:"'create_time' datetime created"`
UpdateTime time.Time `xorm:"'update_time' timestamp updated"`
Status int `xorm:"'status' TINYINT"`

View File

@ -1,8 +1,8 @@
package services
import (
"PaymentCenter/app/constants/common"
"PaymentCenter/app/constants/errorcode"
"PaymentCenter/app/constants/pojo"
"PaymentCenter/app/http/entities/front"
"PaymentCenter/app/models/appmodel"
"PaymentCenter/app/services/apicrypt"
@ -38,7 +38,7 @@ func (a *AppCheck) IpCheck(ip string) bool {
func (a *AppCheck) Check() *AppCheck {
if a.App.Status == pojo.STATUS_DISABLED {
if a.App.Status == common.STATUS_DISABLED {
a.Code = errorcode.AppDisabled
return a
}

View File

@ -81,13 +81,13 @@ func MerchantFindOne(merchant *merchantmodel.Merchant, conn builder.Cond, col ..
return merchantInfo, errorcode.Success
}
func GetAndCheckMerchant(merchant *merchantmodel.Merchant, conn builder.Cond, col ...string) (code int) {
merchantInfo, code := MerchantFindOne(merchant, conn, col...)
func GetAndCheckMerchant(merchant *merchantmodel.Merchant, conn builder.Cond, col ...string) (merchantInfo *merchantmodel.Merchant, code int) {
merchantInfo, code = MerchantFindOne(merchant, conn, col...)
if code != errorcode.Success {
return code
return nil, code
}
if merchantInfo.DeleteTime.Location() != nil {
return errorcode.MerchantNotFound
return nil, errorcode.MerchantNotFound
}
return
}

View File

@ -76,6 +76,14 @@ func OrderLogsList(req backend.OrderLogsListRequest) (requestLog []orderrequestl
return orderLogList, thirdLogList, code
}
func OrderCreate(orderIn *ordersmodel.Orders) (orderOut *ordersmodel.Orders, code int) {
repo := data.NewOrderRepo(ordersmodel.GetInstance().GetDb())
orderId, err := repo.OrderInsertOne(orderIn)
orderIn.Id = orderId
code = handErr(err)
return orderIn, code
}
func OrderFindOne(order *ordersmodel.Orders, conn builder.Cond, col ...string) (merchantInfo *ordersmodel.Orders, code int) {
repo := data.NewOrderRepo(ordersmodel.GetInstance().GetDb())
// 拼接查询条件
@ -86,7 +94,7 @@ func OrderFindOne(order *ordersmodel.Orders, conn builder.Cond, col ...string) (
}
return nil, errorcode.SystemError
}
return orderInfo, errorcode.Success
return orderInfo, errorcode.OrdersExist
}
func HadSameValueOrder(order *ordersmodel.Orders) (exist bool, code int) {

45
app/services/pay.go Normal file
View File

@ -0,0 +1,45 @@
package services
import (
"PaymentCenter/app/constants/errorcode"
"PaymentCenter/app/http/entities/front"
"PaymentCenter/app/services/thirdpay"
"context"
)
func ThirdPayWeb(ctx context.Context, req *front.PayWebReqs, appCheck *AppCheck, ip string) (code int) {
pay := thirdpay.NewWebPay(&ctx, req, appCheck, ip)
// 校验表单
pay.CheckForm()
if pay.PayCode != errorcode.Success {
code = pay.PayCode
return
}
// 校验商户
pay.CheckMerchant()
if pay.PayCode != errorcode.Success {
code = pay.PayCode
return
}
// 校验支付通道
pay.CheckPayChannel()
if pay.PayCode != errorcode.Success {
code = pay.PayCode
return
}
// 校验订单
pay.CheckOrder()
if pay.PayCode != errorcode.Success {
code = pay.PayCode
return
}
// 创建订单
pay.CreateOrder()
if pay.PayCode != errorcode.Success {
code = pay.PayCode
return
}
// 支付
pay.Pay()
return
}

View File

@ -107,13 +107,13 @@ func PayChannelFindOne(channel *paychannelmodel.PayChannel, conn builder.Cond, c
return channelInfo, errorcode.Success
}
func GetAndCheckPayChannel(channel *paychannelmodel.PayChannel, conn builder.Cond, col ...string) (code int) {
merchantInfo, code := PayChannelFindOne(channel, conn, col...)
func GetAndCheckPayChannel(channel *paychannelmodel.PayChannel, conn builder.Cond, col ...string) (merchantInfo *paychannelmodel.PayChannel, code int) {
merchantInfo, code = PayChannelFindOne(channel, conn, col...)
if code != errorcode.Success {
return code
return nil, code
}
if merchantInfo.DeleteTime.Location() != nil {
return errorcode.PayChannelNotFound
return nil, errorcode.PayChannelNotFound
}
return
}

View File

@ -0,0 +1,123 @@
package thirdpay
import (
"PaymentCenter/app/constants/common"
"PaymentCenter/app/constants/errorcode"
"PaymentCenter/app/services"
"PaymentCenter/app/http/entities/front"
"PaymentCenter/app/models/merchantmodel"
"PaymentCenter/app/models/orderrequestlogmodel"
"PaymentCenter/app/models/ordersmodel"
"PaymentCenter/app/models/paychannelmodel"
"PaymentCenter/app/third/paymentService"
"context"
"github.com/bytedance/sonic"
)
type WebPay struct {
ctx *context.Context
WebPayReqs *front.PayWebReqs
AppCheck *services.AppCheck
Order *ordersmodel.Orders
Channel *paychannelmodel.PayChannel
Merchant *merchantmodel.Merchant
PayCode int
}
func NewWebPay(ctx *context.Context, reqs *front.PayWebReqs, appCheck *services.AppCheck, ip string) *WebPay {
if appCheck == nil {
appCheck = services.AppGetAndCheck(&services.AppCheck{
AppId: reqs.AppId,
Ip: ip,
Code: errorcode.Success,
})
}
return &WebPay{
ctx: ctx,
WebPayReqs: reqs,
AppCheck: appCheck,
PayCode: appCheck.Code,
}
}
func (w *WebPay) CheckForm() {
if _, ok := common.OrderTypeList[w.WebPayReqs.OrderType]; !ok { //判断是否是支持的支付渠道
w.PayCode = errorcode.PayChannelNotFound
return
}
}
func (w *WebPay) AddPayLog() {
requestJson, err := sonic.Marshal(w.WebPayReqs)
if err != nil {
w.PayCode = errorcode.RequestLogErrors
return
}
code := services.RequestLogCreate(&orderrequestlogmodel.OrderRequestLog{
IpAddress: w.AppCheck.Ip,
MerchantRequest: string(requestJson),
})
w.PayCode = code
return
}
func (w *WebPay) CheckPayChannel() {
w.Channel, w.PayCode = services.GetAndCheckPayChannel(&paychannelmodel.PayChannel{Id: w.WebPayReqs.PayChannelId}, nil)
}
func (w *WebPay) CheckMerchant() {
w.Merchant, w.PayCode = services.GetAndCheckMerchant(&merchantmodel.Merchant{Id: w.AppCheck.App.MerchantId}, nil)
}
func (w *WebPay) CheckOrder() {
exist, code := services.HadSameValueOrder(&ordersmodel.Orders{OutTreadNo: w.WebPayReqs.OutTradeNo})
if exist {
w.PayCode = code
}
}
func (w *WebPay) CreateOrder() {
w.Order, w.PayCode = services.OrderCreate(&ordersmodel.Orders{
MerchantId: w.Merchant.Id,
PayChannelId: w.Channel.Id,
AppId: w.Channel.Id,
OutTreadNo: w.WebPayReqs.OutTradeNo,
OrderType: w.WebPayReqs.OrderType,
Amount: w.WebPayReqs.Amount,
ExtJson: w.WebPayReqs.ExtJson,
Desc: w.WebPayReqs.Desc,
},
)
}
func (w *WebPay) Pay() {
thirdPay := &paymentService.PayOrderRequest{
PayChannelId: w.WebPayReqs.PayChannelId,
OrderId: w.Order.Id,
ChannelType: w.Channel.ChannelType,
Description: w.Order.Desc,
Amount: w.Order.Amount,
PayerClientIp: w.AppCheck.Ip,
}
//{"api_v_3_key": "131231231", "app_id": "123", "mch_id": "123123", "private_key": "2131312", "serial_no": "123213213"}
switch w.WebPayReqs.OrderType {
case common.PAY_CHANNEL_WECHAT_H5:
var wx paymentService.WxPay
err := sonic.Unmarshal([]byte(w.Channel.ExtJson), &wx)
if err != nil {
w.PayCode = errorcode.PayChannelExtJsonError
return
}
wx.AppId = w.Channel.AppId
case common.PAY_CHANNEL_ALIPAY_WEB:
//{"ali_public_key": "123", "private_key_path": "123", "sign_type": "123"}
//thirdPay.Ali = &paymentService.AliPay{}
default:
w.PayCode = errorcode.PayChannelNotBuild
return
}
_ = paymentService.PaymentService(*w.ctx, *thirdPay)
return
}

View File

@ -1,62 +0,0 @@
package services
import (
"PaymentCenter/app/constants/errorcode"
"PaymentCenter/app/data"
"PaymentCenter/app/http/entities/front"
"PaymentCenter/app/models/merchantmodel"
"PaymentCenter/app/models/orderrequestlogmodel"
"PaymentCenter/app/models/ordersmodel"
"PaymentCenter/app/models/paychannelmodel"
"github.com/bytedance/sonic"
)
type WebPay struct {
WebPayReqs *front.PayWebReqs
AppCheck *AppCheck
Order *data.OrderRepo
PayCode int
}
func NewWebPay(resp *front.PayWebReqs, appCheck *AppCheck) *WebPay {
if appCheck == nil {
appCheck = AppGetAndCheck(&AppCheck{
AppId: resp.AppId,
Code: errorcode.Success,
})
}
return &WebPay{
WebPayReqs: resp,
AppCheck: appCheck,
PayCode: appCheck.Code,
}
}
func (w *WebPay) AddPayLog() {
requestJson, err := sonic.Marshal(w.WebPayReqs)
if err != nil {
w.PayCode = errorcode.RequestLogErrors
return
}
code := RequestLogCreate(&orderrequestlogmodel.OrderRequestLog{
IpAddress: w.AppCheck.Ip,
MerchantRequest: string(requestJson),
})
w.PayCode = code
return
}
func (w *WebPay) CheckMerchant() {
w.PayCode = GetAndCheckPayChannel(&paychannelmodel.PayChannel{Id: w.WebPayReqs.PayChannelId}, nil)
}
func (w *WebPay) CheckPayChannel() {
w.PayCode = GetAndCheckMerchant(&merchantmodel.Merchant{Id: w.AppCheck.App.MerchantId}, nil)
}
func (w *WebPay) CheckOrder() {
exist, code := HadSameValueOrder(&ordersmodel.Orders{OutTreadNo: w.WebPayReqs.OutTradeNo})
if exist {
w.PayCode = code
}
}