package do import ( "PaymentCenter/app/constants/common" "PaymentCenter/app/constants/errorcode" "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 = w.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 } default: w.PayCode = errorcode.PayChannelNotBuild return } //res := paymentService.PaymentService(*w.ctx, *thirdPay) 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 (w *Pay) 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 }