PaymentCenter/app/services/thirdpay/do/pay.go

272 lines
7.7 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package do
import (
"PaymentCenter/app/constants/common"
"PaymentCenter/app/constants/errorcode"
"PaymentCenter/app/http/entities/front"
"PaymentCenter/app/models/merchantmodel"
"PaymentCenter/app/models/paychannelmodel"
"PaymentCenter/app/services"
"PaymentCenter/app/third/paymentService/payCommon"
"PaymentCenter/app/utils"
"PaymentCenter/config"
"context"
"net/url"
"strconv"
"xorm.io/builder"
"PaymentCenter/app/models/ordersmodel"
"PaymentCenter/app/third/paymentService"
)
type PayParam struct {
Merchant *merchantmodel.Merchant
Channel *paychannelmodel.PayChannel
App_id int64
OutTradeNo string
Amount int
ExtJson string
Desc string
ClientIp string
ReturnUrl string
OpenId string
}
type Pay struct {
ctx *context.Context
PayParam *PayParam
RelationOrder *ordersmodel.Orders
Order *ordersmodel.Orders
PayCode int
Url string
ThirdMsg string
}
func NewPayWithPayCheck(paycheck *PayCheck) *Pay {
return &Pay{
ctx: paycheck.ctx,
PayParam: &PayParam{
Merchant: paycheck.Merchant,
Channel: paycheck.Channel,
App_id: paycheck.Reqs.AppId,
OutTradeNo: paycheck.Reqs.OutTradeNo,
Amount: paycheck.Reqs.Amount,
ExtJson: paycheck.Reqs.ExtJson,
Desc: paycheck.Reqs.Desc,
ClientIp: paycheck.AppCheck.Ip,
ReturnUrl: paycheck.Reqs.ReturnUrl,
OpenId: paycheck.Reqs.OpenId,
},
RelationOrder: paycheck.OldOrder,
PayCode: errorcode.Success,
}
}
func (w *Pay) CheckRefundOrder() bool {
cond := builder.NewCond()
cond = cond.And(builder.Eq{"app_id": w.PayParam.App_id}, builder.Eq{"order_type": common.ORDER_TYPE_REFUND}, builder.Eq{"out_trade_no": w.PayParam.OutTradeNo})
order, code := services.OrderFindOne(&ordersmodel.Orders{}, cond)
if code != errorcode.Success {
return true
}
if order.Status == common.ORDER_STATUS_FAILED {
return true
}
w.Order = order
return false
}
func (w *Pay) CreateOrder(order_type int) {
if _, ok := common.OrderTypeList[order_type]; !ok { //判断是否是支持的支付渠道
w.PayCode = errorcode.PayChannelNotFound
return
}
order := &ordersmodel.Orders{
MerchantId: w.PayParam.Merchant.Id,
PayChannelId: w.PayParam.Channel.Id,
AppId: w.PayParam.App_id,
OutTradeNo: w.PayParam.OutTradeNo,
OrderType: order_type,
Amount: w.PayParam.Amount,
ExtJson: w.PayParam.ExtJson,
Desc: w.PayParam.Desc,
Status: common.ORDER_STATUS_WAITPAY,
}
if order_type == common.ORDER_TYPE_REFUND {
order.RefundOrderId = w.RelationOrder.Id
}
w.Order, w.PayCode = services.OrderCreate(order)
}
func (w *Pay) PayUrl() (url string) {
var (
payFunc func(commonPayInfo *paymentService.PayOrderRequest, channel *paychannelmodel.PayChannel) error
ok bool
res paymentService.PayOrderResponse
)
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,
OpenId: w.PayParam.OpenId,
}
// 判断是否是支持的支付渠道,找到对应的配置
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
}
// 根据渠道类型,调用对应的支付方式
switch w.PayParam.Channel.ChannelType {
// 微信公众号支付,返回的是用户授权链接
case common.PAY_CHANNEL_WECHAT_JSAPI:
// 获取授权链接
res.Result, res.Code = GetWxAuthUrl(w.PayParam.Channel.AppId, w.Order.Id)
case common.PAY_CHANNEL_ALIPAY_WEB:
// 支付宝h5
res = paymentService.PaymentService(*w.ctx, *thirdPay)
case common.PAY_CHANNEL_WECHAT_H5:
// 微信h5支付
res = paymentService.PaymentService(*w.ctx, *thirdPay)
if res.Result != "" {
res.Result = config.GetConf().PayService.Host + "/pay/front/api/v1/brokerWechatUrl" + "?url=" + res.Result
}
case common.PAY_CHANNEL_WECHAT_MINI:
req := front.GetWxMiniSchemeRequest{
PayChannelId: strconv.Itoa(int(w.PayParam.Channel.Id)),
GenerateSchemeRequest: front.GenerateSchemeRequest{
JumpWxa: front.JumpWxa{Query: "?order_id=" + strconv.Itoa(int(w.Order.Id))},
}}
if config.GetEnv() == config.LocalEnv {
req.GenerateSchemeRequest.JumpWxa.EnvVersion = "develop"
}
// 微信小程序支付返回小程序的scheme todo 拼接订单id参数
wx := NewWxMini().WithPayChannel(w.PayParam.Channel)
url, err = wx.GetWxMiniScheme(req)
res.Result = url
if err != nil {
w.PayCode = errorcode.PayChannelExtJsonError
w.ThirdMsg = err.Error()
return
}
default:
w.PayCode = errorcode.PayChannelNotBuild
return
}
if res.Code == payCommon.PAY_SUCCESS_CODE {
w.Order.Status = common.ORDER_STATUS_PAYING
code := services.OrderUpdate(w.Order, "status")
if code != errorcode.Success {
w.PayCode = code
}
w.Url = res.Result
} else {
w.PayCode = errorcode.PrePayFail
w.ThirdMsg = res.ErrorMsg
}
return
}
func (w *Pay) Refund() {
var (
refundFunc func(commonRefundInfo *paymentService.OrderRefundRequest, channel *paychannelmodel.PayChannel) error
ok bool
)
thirdPayRefund := &paymentService.OrderRefundRequest{
OrderId: w.RelationOrder.Id,
RefundOrderId: w.Order.Id,
RefundReason: w.PayParam.Desc,
RefundAmount: int64(w.PayParam.Amount),
}
if refundFunc, ok = RefundWayList[w.PayParam.Channel.ChannelType]; !ok {
w.PayCode = errorcode.PayChannelNotBuild
return
}
err := refundFunc(thirdPayRefund, w.PayParam.Channel)
if err != nil {
w.PayCode = errorcode.PayChannelExtJsonError
return
}
res := paymentService.OrderRefund(*w.ctx, *thirdPayRefund)
if res.Code == payCommon.PAY_SUCCESS_CODE {
w.Order.Status = common.ORDER_STATUS_PAYING
code := services.OrderUpdate(w.Order, "status")
if code != errorcode.Success {
w.PayCode = code
return
}
} else {
w.PayCode = errorcode.ThirdRefundFail
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
}
// appid:微信的公众号appid
func GetWxAuthUrl(appid string, orderId int64) (targetUrl string, code int) {
var (
// 重定向地址
redirectUri = config.GetConf().PayService.Host + common.WXCodeRedirectAddress
)
baseUrl := "https://open.weixin.qq.com/connect/oauth2/authorize"
redirectUri = url.QueryEscape(redirectUri)
responseType := "code"
scope := "snsapi_base"
order := strconv.Itoa(int(orderId))
targetUrl = baseUrl + "?appid=" + appid + "&redirect_uri=" + redirectUri + "&response_type=" + responseType + "&scope=" + scope + "&state=" + order + "#wechat_redirect"
code = errorcode.Success
return
}