185 lines
6.0 KiB
Go
185 lines
6.0 KiB
Go
|
package service
|
|||
|
|
|||
|
import (
|
|||
|
"encoding/json"
|
|||
|
"errors"
|
|||
|
"fmt"
|
|||
|
"strconv"
|
|||
|
"time"
|
|||
|
"yuleduiPay/common"
|
|||
|
"yuleduiPay/repo"
|
|||
|
"yuleduiPay/service/po"
|
|||
|
"yuleduiPay/service/vo"
|
|||
|
|
|||
|
"github.com/gogf/gf/v2/frame/g"
|
|||
|
"github.com/gogf/gf/v2/net/ghttp"
|
|||
|
"github.com/gogf/gf/v2/os/gtime"
|
|||
|
"github.com/gogf/gf/v2/util/guid"
|
|||
|
)
|
|||
|
|
|||
|
type Pay struct {
|
|||
|
payOrderRepo repo.PayOrder
|
|||
|
shopRepo repo.Shop
|
|||
|
}
|
|||
|
|
|||
|
// 微信小程序,扫码支付
|
|||
|
func (t *Pay) PayQrCode(r *ghttp.Request) {
|
|||
|
g.Log().Line().Print(nil, r.Request) //todo
|
|||
|
req := vo.PayQrCodeReq{}
|
|||
|
err := r.Parse(&req)
|
|||
|
if err != nil {
|
|||
|
r.SetError(err)
|
|||
|
return
|
|||
|
}
|
|||
|
g.Log().Line().Printf(nil, "%+v", req)
|
|||
|
//获取订单信息
|
|||
|
shop, err := t.shopRepo.GetShopById(req.ShopId)
|
|||
|
if err != nil {
|
|||
|
r.SetError(err)
|
|||
|
return
|
|||
|
}
|
|||
|
//创建订单记录
|
|||
|
payOrder := po.PayOrder{}
|
|||
|
payOrder.OrderId = guid.S()
|
|||
|
payOrder.Price, err = strconv.ParseFloat(req.Price, 64)
|
|||
|
if err != nil {
|
|||
|
r.SetError(err)
|
|||
|
return
|
|||
|
}
|
|||
|
payOrder.Amount, err = strconv.ParseFloat(req.Amount, 64)
|
|||
|
if err != nil {
|
|||
|
r.SetError(err)
|
|||
|
return
|
|||
|
}
|
|||
|
payOrder.Bean, err = strconv.ParseFloat(req.Bean, 64)
|
|||
|
if err != nil {
|
|||
|
r.SetError(err)
|
|||
|
return
|
|||
|
}
|
|||
|
payOrder.OpenId = req.OpenId
|
|||
|
payOrder.Mobile = req.Mobile
|
|||
|
payOrder.ShopId = req.ShopId
|
|||
|
payOrder.Channel = req.Channel
|
|||
|
payOrder.Created = gtime.Now()
|
|||
|
payOrder.Updated = payOrder.Created
|
|||
|
|
|||
|
err = t.payOrderRepo.CreatePayOrder(&payOrder)
|
|||
|
if err != nil {
|
|||
|
r.SetError(err)
|
|||
|
return
|
|||
|
}
|
|||
|
|
|||
|
yseRespBytes, err := t.ysePayRequestJson(shop, &payOrder) //访问java项目,获取银盛返回的结果
|
|||
|
if err != nil {
|
|||
|
r.SetError(err)
|
|||
|
return
|
|||
|
}
|
|||
|
fmt.Println("------:", string(yseRespBytes))
|
|||
|
|
|||
|
yseResp, err := t.yseParseResp(payOrder.Channel, yseRespBytes) //解析报文返回的报文
|
|||
|
if err != nil {
|
|||
|
r.SetError(err)
|
|||
|
return
|
|||
|
}
|
|||
|
fmt.Println(yseResp)
|
|||
|
if yseResp.OutTradeNo != payOrder.OpenId {
|
|||
|
errStr := fmt.Sprintf("银盛返回订单号错误,银盛订单号:%s,余乐兑订单号:%s", yseResp.OutTradeNo, payOrder.OpenId)
|
|||
|
r.SetError(errors.New(errStr))
|
|||
|
return
|
|||
|
}
|
|||
|
//更新支付订单表字段
|
|||
|
updates := g.Map{"ysePayStatus": yseResp.TradeStatus, "updated": time.Now()}
|
|||
|
err = t.payOrderRepo.UpdatePayOrderByOrderId(updates, payOrder.OpenId)
|
|||
|
if err != nil {
|
|||
|
r.SetError(err)
|
|||
|
}
|
|||
|
return
|
|||
|
}
|
|||
|
func (t *Pay) yseParseResp(channel int, respBytes []byte) (*vo.BusPayResp, error) {
|
|||
|
yepayOnlineWeixinPayResponse := &vo.BusPayResp{}
|
|||
|
if channel == 1 { //微信
|
|||
|
ysePayResp := &vo.WxPayResp{}
|
|||
|
err := json.Unmarshal(respBytes, ysePayResp)
|
|||
|
if err != nil {
|
|||
|
return nil, err
|
|||
|
}
|
|||
|
fmt.Println("银盛返回的应答:", ysePayResp)
|
|||
|
yepayOnlineWeixinPayResponse = &ysePayResp.YsepayOnlineWeixinPayResponse
|
|||
|
} else { //支付宝
|
|||
|
ysePayResp := &vo.ZfbPayResp{}
|
|||
|
err := json.Unmarshal(respBytes, ysePayResp)
|
|||
|
if err != nil {
|
|||
|
return nil, err
|
|||
|
}
|
|||
|
fmt.Println("银盛返回的应答:", ysePayResp)
|
|||
|
yepayOnlineWeixinPayResponse = &ysePayResp.YsepayOnlineAlijsapiPayResponse
|
|||
|
|
|||
|
}
|
|||
|
if yepayOnlineWeixinPayResponse.Code != "10000" {
|
|||
|
return nil, errors.New("银盛应答返回错误:" + yepayOnlineWeixinPayResponse.Msg)
|
|||
|
}
|
|||
|
return yepayOnlineWeixinPayResponse, nil
|
|||
|
}
|
|||
|
|
|||
|
func (t *Pay) ysePayRequestJson(shop *po.Shop, payOrder *po.PayOrder) ([]byte, error) {
|
|||
|
//业务请求参数
|
|||
|
busReq := vo.PayBusReq{}
|
|||
|
busReq.OutTradeNo = payOrder.OrderId //订单编号
|
|||
|
busReq.Shopdate = payOrder.Created.Format("20060102") //商户系统的交易发生日期格式
|
|||
|
busReq.Subject = "余乐兑小程序订单" //订单备注
|
|||
|
busReq.TotalAmount = fmt.Sprintf("%.2f", payOrder.Price) //该笔订单的资金总额,保留两位小数
|
|||
|
busReq.Currency = "CNY" //默认人民币
|
|||
|
busReq.SellerId = shop.ChildAccountNumber //银盛商户ID //订单备注
|
|||
|
busReq.SellerName = shop.ShopName //店铺名称
|
|||
|
busReq.TimeoutExpress = "1h" //设置未付款交易的超时时间,一个小时
|
|||
|
busReq.BusinessCode = g.Cfg().MustGet(nil, "ysepay.busCode").String() //业务代码
|
|||
|
|
|||
|
var bjson []byte
|
|||
|
var err error
|
|||
|
if payOrder.Channel == 1 { //微信渠道
|
|||
|
wxBusReq := vo.PayWxBusReq{PayBusReq: busReq}
|
|||
|
wxBusReq.SubOpenid = payOrder.OpenId //微信用户ID
|
|||
|
wxBusReq.IsMinipg = "1" //微信小程序支付:1
|
|||
|
wxBusReq.Appid = g.Cfg().MustGet(nil, "weixin.appId").String() //微信小程序APPID
|
|||
|
bjson, err = json.Marshal(wxBusReq)
|
|||
|
if err != nil {
|
|||
|
return nil, err
|
|||
|
}
|
|||
|
} else { //支付宝渠道
|
|||
|
zfBusReq := vo.PayZfBusReq{PayBusReq: busReq}
|
|||
|
zfBusReq.BuyerId = payOrder.OpenId //支付宝用户ID
|
|||
|
bjson, err = json.Marshal(zfBusReq)
|
|||
|
if err != nil {
|
|||
|
return nil, err
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
commonReq := vo.PayCommonReq{}
|
|||
|
if payOrder.Channel == 1 { //微信渠道
|
|||
|
commonReq.Method = "ysepay.online.weixin.pay"
|
|||
|
} else { //支付宝渠道
|
|||
|
commonReq.Method = "ysepay.online.alijsapi.pay"
|
|||
|
}
|
|||
|
commonReq.PartnerId = g.Cfg().MustGet(nil, "ysepay.CERTID").String() //在银盛支付开设的服务商商户号
|
|||
|
commonReq.Timestamp = time.Now().Format("2006-01-02 15:04:05") //发送请求的时间
|
|||
|
commonReq.Charset = "UTF-8" //商户网站使用的编码格式
|
|||
|
commonReq.SignType = "SM" //报文签名算法
|
|||
|
commonReq.NotifyUrl = g.Cfg().MustGet(nil, "ysepay.notifyUrl").String() //交易成功异步通知到商户的后台地址
|
|||
|
commonReq.Version = "3.0" //接口版本
|
|||
|
|
|||
|
commonReq.BizContent = string(bjson)
|
|||
|
bjson, err = json.Marshal(&commonReq)
|
|||
|
if err != nil {
|
|||
|
return nil, err
|
|||
|
}
|
|||
|
url := g.Cfg().MustGet(nil, "ysepay.url").String()
|
|||
|
xxx := string(bjson)
|
|||
|
fmt.Println(xxx)
|
|||
|
//发送给java项目,让其访问银盛接口
|
|||
|
bjson, err = common.HttpPost(url, "application/json", bjson)
|
|||
|
if err != nil {
|
|||
|
return nil, err
|
|||
|
}
|
|||
|
return bjson, err
|
|||
|
}
|