233 lines
6.5 KiB
Go
233 lines
6.5 KiB
Go
package thirdpay
|
|
|
|
import (
|
|
"PaymentCenter/app/constants/common"
|
|
"PaymentCenter/app/constants/errorcode"
|
|
"PaymentCenter/app/http/entities/backend"
|
|
"PaymentCenter/app/http/entities/front"
|
|
"PaymentCenter/app/models/orderrequestlogmodel"
|
|
"PaymentCenter/app/models/ordersmodel"
|
|
"PaymentCenter/app/models/paychannelmodel"
|
|
"PaymentCenter/app/services"
|
|
"PaymentCenter/app/services/thirdpay/do"
|
|
"PaymentCenter/app/third/paymentService"
|
|
"PaymentCenter/app/third/paymentService/payCommon"
|
|
"PaymentCenter/app/utils"
|
|
"PaymentCenter/config"
|
|
"context"
|
|
"encoding/json"
|
|
"fmt"
|
|
"strconv"
|
|
"time"
|
|
"xorm.io/builder"
|
|
)
|
|
|
|
// 收银台获取付款链接
|
|
func GetPayLinkService(req front.GetPayLinkRequest) (result, message string, code int) {
|
|
defer func() {
|
|
if err := recover(); err != nil {
|
|
utils.Log(nil, "", "GetPayLinkService,获取支付链接失败", fmt.Sprintf("错误原因:%s", err))
|
|
code = errorcode.SystemError
|
|
}
|
|
}()
|
|
var (
|
|
payChannel = &paychannelmodel.PayChannel{}
|
|
order = &ordersmodel.Orders{}
|
|
orderPayRequest front.PayReqsV2
|
|
)
|
|
// 支付方式校验
|
|
payChannel, code = services.PayChannelFindOne(payChannel, builder.Eq{"id": req.PayChannelId})
|
|
if code != errorcode.Success {
|
|
return
|
|
}
|
|
if !payChannel.ExpireTime.IsZero() && payChannel.ExpireTime.Unix() < time.Now().Unix() {
|
|
code = errorcode.PayChannelExpired
|
|
return
|
|
}
|
|
// 订单校验
|
|
order, code = services.OrderFindOne(order, builder.Eq{"id": req.OrderId})
|
|
if code != errorcode.Success {
|
|
return
|
|
}
|
|
// 订单状态校验
|
|
code = services.OrderStatusCheck(*order)
|
|
if code != errorcode.Success {
|
|
return
|
|
}
|
|
// 订单的支付方式是否一致, 不一致则更新
|
|
if order.PayChannelId != payChannel.Id {
|
|
order.PayChannelId = payChannel.Id
|
|
code = services.OrderUpdate(order)
|
|
if code != errorcode.Success {
|
|
return
|
|
}
|
|
}
|
|
// 获取订单的请求参数
|
|
orderRequestLog := orderrequestlogmodel.OrderRequestLog{
|
|
OutTradeNo: order.OutTradeNo,
|
|
AppId: order.AppId,
|
|
}
|
|
has, err := services.OrderRequestLogs(&orderRequestLog)
|
|
if err != nil {
|
|
code = handErr(err)
|
|
return
|
|
}
|
|
if !has {
|
|
code = errorcode.OrderPayRequestLogNotExist
|
|
return
|
|
}
|
|
err = json.Unmarshal([]byte(orderRequestLog.MerchantRequest), &orderPayRequest)
|
|
if err != nil {
|
|
code = handErr(err)
|
|
return
|
|
}
|
|
// 支付方式需要用户授权
|
|
if payChannel.ChannelType == common.PAY_CHANNEL_WECHAT_JSAPI && orderPayRequest.OpenId == "" {
|
|
result, code = do.GetWxAuthUrl(payChannel.AppId, order.Id)
|
|
return
|
|
}
|
|
// 请求第三方支付获取付款链接
|
|
payParam := paymentService.PayOrderRequest{
|
|
PayChannelId: payChannel.Id,
|
|
OrderId: order.Id,
|
|
ChannelType: payChannel.ChannelType,
|
|
Description: orderPayRequest.Desc,
|
|
Amount: orderPayRequest.Amount,
|
|
PayerClientIp: req.ClientIp,
|
|
ReturnUrl: orderPayRequest.ReturnUrl,
|
|
OpenId: orderPayRequest.OpenId,
|
|
}
|
|
// 判断是否是支持的支付渠道,找到对应的配置
|
|
var payFunc func(commonPayInfo *paymentService.PayOrderRequest, channel *paychannelmodel.PayChannel) error
|
|
var ok bool
|
|
if payFunc, ok = do.PayWayList[payChannel.ChannelType]; !ok {
|
|
code = errorcode.PayChannelNotBuild
|
|
return
|
|
}
|
|
err = payFunc(&payParam, payChannel)
|
|
if err != nil {
|
|
code = errorcode.PayChannelExtJsonError
|
|
return
|
|
}
|
|
|
|
res := paymentService.PaymentService(context.Background(), payParam)
|
|
// 下单失败
|
|
if res.Code != payCommon.PAY_SUCCESS_CODE {
|
|
code = errorcode.PrePayFail
|
|
message = res.ErrorMsg
|
|
return
|
|
}
|
|
// 更新订单状态
|
|
order.Status = common.ORDER_STATUS_PAYING
|
|
code = services.OrderUpdate(order, "status")
|
|
if code != errorcode.Success {
|
|
utils.Log(nil, "成功下单,更新订单状态失败", order)
|
|
}
|
|
|
|
result = res.Result
|
|
code = res.Code
|
|
return
|
|
}
|
|
|
|
// 预支付
|
|
type payUrl struct {
|
|
ClientIp string
|
|
param front.PayReqsV2
|
|
app *services.AppCheck
|
|
result front.PayReqsV2Response
|
|
}
|
|
|
|
func NewPayUrl(param front.PayReqsV2) *payUrl {
|
|
return &payUrl{
|
|
param: param,
|
|
}
|
|
}
|
|
func (this *payUrl) WithApp(app *services.AppCheck) *payUrl {
|
|
this.app = app
|
|
return this
|
|
}
|
|
func (this *payUrl) WithClientIp(ip string) *payUrl {
|
|
this.ClientIp = ip
|
|
return this
|
|
}
|
|
|
|
func (this *payUrl) saveOrder() {
|
|
order := &ordersmodel.Orders{
|
|
MerchantId: this.app.App.MerchantId,
|
|
//PayChannelId: w.PayParam.Channel.Id,
|
|
AppId: this.app.App.Id,
|
|
OutTradeNo: this.param.OutTradeNo,
|
|
OrderType: common.ORDER_TYPE_PAY,
|
|
Amount: this.param.Amount,
|
|
ExtJson: this.param.ExtJson,
|
|
Desc: this.param.Desc,
|
|
Status: common.ORDER_STATUS_WAITPAY,
|
|
}
|
|
this.result.Order, this.result.PayCode = services.OrderCreate(order)
|
|
}
|
|
|
|
func (this *payUrl) PayUrlV2Service() (result front.PayReqsV2Response, code int) {
|
|
var (
|
|
channelList []paychannelmodel.PayChannel
|
|
order = new(ordersmodel.Orders)
|
|
)
|
|
|
|
// redis 分布式锁 订单号幂等
|
|
key := utils.GetRealKey("payUrl:" + this.param.OutTradeNo)
|
|
lockValue := fmt.Sprintf("%d", time.Now().UnixNano())
|
|
ok, err := utils.AcquireLock(key, lockValue, time.Second*time.Duration(3))
|
|
if ok {
|
|
defer utils.ReleaseLock(key, lockValue)
|
|
} else {
|
|
if err != nil {
|
|
utils.Log(nil, "", "PayUrlV2Service,获取分布式锁失败", fmt.Sprintf("错误原因:%s", err.Error()))
|
|
code = errorcode.SystemError
|
|
} else {
|
|
code = errorcode.OrderPayRequestAcquireLock
|
|
}
|
|
return
|
|
}
|
|
|
|
// 商户是否有配置支付渠道
|
|
channelList, _, code = services.PayChannelList(backend.PayChannelListRequest{MerchantId: this.app.App.MerchantId})
|
|
if code != errorcode.Success {
|
|
return
|
|
}
|
|
if len(channelList) == 0 {
|
|
code = errorcode.PayChannelNotFound
|
|
return
|
|
}
|
|
// 订单是否存在
|
|
conn := builder.NewCond()
|
|
conn = conn.And(builder.Eq{"out_trade_no": this.param.OutTradeNo})
|
|
conn = conn.And(builder.Eq{"app_id": this.param.AppId})
|
|
order, code = services.OrderFindOne(order, conn)
|
|
if code == errorcode.Success {
|
|
// 订单存在
|
|
this.result.Order = order
|
|
this.result.PayCode = services.OrderStatusCheck(*order)
|
|
} else if code == errorcode.OrdersNotFound {
|
|
// 订单不存在
|
|
this.saveOrder()
|
|
} else {
|
|
return
|
|
}
|
|
code = this.result.PayCode
|
|
if code == errorcode.Success {
|
|
this.result.Url = config.GetConf().PayService.Host + common.PayPageAddress + "?no=" + strconv.FormatInt(this.result.Order.Id, 10)
|
|
}
|
|
|
|
return this.result, code
|
|
}
|
|
|
|
func PayPageCheckOrder(orderId string) (order ordersmodel.Orders, code int) {
|
|
orderInfo := &ordersmodel.Orders{}
|
|
orderInfo, code = services.OrderFindOne(&ordersmodel.Orders{}, builder.Eq{"id": orderId})
|
|
if code != errorcode.Success {
|
|
return
|
|
}
|
|
|
|
code = services.OrderStatusCheck(*orderInfo)
|
|
return *orderInfo, code
|
|
}
|