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 } commReq, err := t.ysePayRequestJson(shop, &payOrder) //组织银盛请求json if err != nil { r.SetError(err) return } yseResp, err := t.ysePostUrl(commReq) //解析银盛应答报文 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) ysePostUrl(commReq *vo.PayCommonReq) (*vo.WeixinPayResp, error) { jsonBytes, err := json.Marshal(commReq) if err != nil { return nil, err } jsonResp, err := common.HttpPost(common.YSEPAYURL, jsonBytes) if err != nil { return nil, err } 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) 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) } */ func (t *Pay) ysePayRequestJson(shop *po.Shop, payOrder *po.PayOrder) (*vo.PayCommonReq, 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.AccountNumber //商户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" //接口版本 //sign 需要java项目处理 todo commonReq.BizContent = string(bjson) // bjson, err = json.Marshal(&commonReq) if err != nil { return nil, err } url := g.Cfg().MustGet(nil, "ysepay.url").String() bjson, err = common.HttpPost(url, bjson) if err != nil { return nil, err } signResp := vo.YseJavaResp{} err = json.Unmarshal(bjson, signResp) if err != nil { return nil, err } commonReq.Sign = signResp.Sign commonReq.BizContent = signResp.BizContent return &commonReq, nil }