163 lines
5.1 KiB
Go
163 lines
5.1 KiB
Go
package service
|
|
|
|
import (
|
|
"bytes"
|
|
"encoding/json"
|
|
"errors"
|
|
"fmt"
|
|
"io"
|
|
"net/http"
|
|
"strconv"
|
|
"time"
|
|
"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
|
|
}
|
|
|
|
var YSEPAYURL = "https://qrcode.ysepay.com/gateway.do" //银盛的微信小程序接口地址
|
|
|
|
// 微信小程序,扫码支付
|
|
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.Created = gtime.Now()
|
|
payOrder.Updated = payOrder.Created
|
|
|
|
err = t.payOrderRepo.CreatePayOrder(&payOrder)
|
|
if err != nil {
|
|
r.SetError(err)
|
|
return
|
|
}
|
|
|
|
jsonBytes, err := t.ysePayRequestJson(shop, &payOrder) //组织银盛请求json
|
|
if err != nil {
|
|
r.SetError(err)
|
|
return
|
|
}
|
|
//java 项目处理sign字段
|
|
jsonResp, err := t.ysePayPost(jsonBytes) //Post请求银盛接口
|
|
if err != nil {
|
|
r.SetError(err)
|
|
return
|
|
}
|
|
yseResp, err := t.yseRespHandler(jsonResp) //解析银盛应答报文
|
|
if err != nil {
|
|
r.SetError(err)
|
|
return
|
|
}
|
|
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) yseRespHandler(jsonResp []byte) (*vo.WeixinPayResp, error) {
|
|
ysePayResp := &vo.PayResp{}
|
|
err := json.Unmarshal(jsonResp, ysePayResp)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
yseWeiXinPayResp := &vo.WeixinPayResp{}
|
|
err = json.Unmarshal([]byte(ysePayResp.YsepayOnlineWeixinPayResponse), yseWeiXinPayResp)
|
|
if yseWeiXinPayResp.Code != "10000" {
|
|
return nil, errors.New("银盛应答返回错误:" + yseWeiXinPayResp.Msg)
|
|
}
|
|
return yseWeiXinPayResp, err
|
|
}
|
|
func (t *Pay) ysePayPost(jsonBytes []byte) ([]byte, error) {
|
|
resp, err := http.Post(YSEPAYURL, "application/json", bytes.NewReader(jsonBytes))
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
defer resp.Body.Close()
|
|
return io.ReadAll(resp.Body)
|
|
}
|
|
|
|
func (t *Pay) ysePayRequestJson(shop *po.Shop, payOrder *po.PayOrder) ([]byte, error) {
|
|
jsonMap := g.Map{}
|
|
//公共请求参数
|
|
jsonMap["method"] = "ysepay.online.weixin.pay" //接口名称,固定值
|
|
certId := g.Cfg().MustGet(nil, "ysepay.CERTID")
|
|
|
|
jsonMap["partner_id"] = certId //在银盛支付开设的服务商商户号
|
|
jsonMap["timestamp"] = time.Now().Format("2006-01-02 15:04:05") //发送请求的时间
|
|
jsonMap["charset"] = "UTF-8" //商户网站使用的编码格式
|
|
jsonMap["sign_type"] = "SM" //报文签名算法
|
|
//sign 需要java项目处理 todo
|
|
notifyUrl := g.Cfg().MustGet(nil, "ysepay.notifyUrl")
|
|
jsonMap["notify_url"] = notifyUrl //交易成功异步通知到商户的后台地址
|
|
jsonMap["version"] = "3.0" //接口版本
|
|
|
|
//业务请求参数
|
|
businessMap := g.Map{}
|
|
businessMap["orderId"] = payOrder.OpenId //订单编号
|
|
businessMap["shopdate"] = payOrder.Created.Format("20060102") //商户系统的交易发生日期格式
|
|
businessMap["subject"] = "余乐兑小程序订单" //订单备注
|
|
businessMap["total_amount"] = payOrder.Price //该笔订单的资金总额
|
|
businessMap["currency"] = "CNY" //默认人民币 //订单备注
|
|
businessMap["seller_id"] = shop.AccountNumber //商户ID
|
|
businessMap["seller_name"] = shop.ShopName //店铺名称
|
|
businessMap["timeout_express"] = "1h" //设置未付款交易的超时时间,一个小时
|
|
businessMap["sub_openid"] = payOrder.OpenId //微信OpenId
|
|
businessMap["is_minipg"] = "1" //微信小程序支付:1
|
|
appId := g.Cfg().MustGet(nil, "weixin.appId")
|
|
businessMap["appid"] = appId //微信小程序APPID
|
|
b, err := json.Marshal(businessMap)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
jsonMap["biz_content"] = string(b)
|
|
return json.Marshal(jsonMap)
|
|
|
|
}
|