210 lines
7.1 KiB
Go
210 lines
7.1 KiB
Go
package third_party
|
||
|
||
import (
|
||
"context"
|
||
"gateway/internal/models/merchant"
|
||
"gateway/internal/models/order"
|
||
"gateway/internal/models/payfor"
|
||
"gateway/internal/models/road"
|
||
"gateway/internal/models/supply_model"
|
||
"gateway/internal/otelTrace"
|
||
|
||
"gateway/internal/service"
|
||
"gateway/internal/service/supplier"
|
||
"gateway/internal/utils"
|
||
"net/http"
|
||
"strconv"
|
||
"strings"
|
||
|
||
"github.com/beego/beego/v2/client/httplib"
|
||
"github.com/beego/beego/v2/core/logs"
|
||
"github.com/duke-git/lancet/v2/convertor"
|
||
"go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp"
|
||
"go.opentelemetry.io/otel/attribute"
|
||
"go.opentelemetry.io/otel/trace"
|
||
"go.uber.org/zap"
|
||
|
||
"github.com/beego/beego/v2/server/web"
|
||
"github.com/rs/xid"
|
||
"github.com/widuu/gojson"
|
||
)
|
||
|
||
type DaiLiImpl struct {
|
||
web.Controller
|
||
}
|
||
|
||
const (
|
||
NOTITY_URL = "http://localhost:12306/accept/notify"
|
||
URL = "http://zhaoyin.lfwin.com/payapi/pay/jspay3"
|
||
)
|
||
|
||
// HasDependencyHTML 是否有单独的支付页面
|
||
func (c *DaiLiImpl) HasDependencyHTML() bool {
|
||
return false
|
||
}
|
||
|
||
func (c *DaiLiImpl) Scan(ctx context.Context, orderInfo order.OrderInfo, roadInfo road.RoadInfo, merchantInfo merchant.MerchantInfo) supplier.ScanData {
|
||
ctx, cancel := otelTrace.Span(ctx, "DaiLiImpl", "Scan", trace.WithAttributes(
|
||
attribute.String("BankOrderId", orderInfo.BankOrderId),
|
||
attribute.String("MerchantUid", orderInfo.MerchantUid),
|
||
attribute.String("ExValue", orderInfo.ExValue),
|
||
))
|
||
defer cancel()
|
||
// 从boss后台获取数据
|
||
service2 := gojson.Json(roadInfo.Params).Get("service2").Tostring()
|
||
apiKey := gojson.Json(roadInfo.Params).Get("apikey").Tostring()
|
||
signKey := gojson.Json(roadInfo.Params).Get("signkey").Tostring()
|
||
|
||
params := make(map[string]any)
|
||
params["service2"] = service2
|
||
params["apikey"] = apiKey
|
||
params["money"] = strconv.FormatFloat(orderInfo.OrderAmount, 'f', 2, 32)
|
||
params["nonce_str"] = xid.New().String()
|
||
params["mch_orderid"] = orderInfo.BankOrderId
|
||
params["notify_url"] = NOTITY_URL
|
||
|
||
waitStr := utils.MapToString(utils.SortMapByKeys(params))
|
||
waitStr = waitStr + "&signkey=" + signKey
|
||
sign := utils.GetMD5LOWER(waitStr)
|
||
params["sign"] = sign
|
||
|
||
request := URL + "?" + utils.MapToString(params)
|
||
|
||
otelTrace.Logger.WithContext(ctx).Info("代丽请求字符串 = " + request)
|
||
|
||
var scanData supplier.ScanData
|
||
scanData.Status = "00"
|
||
req := httplib.NewBeegoRequestWithCtx(ctx, request, "POST")
|
||
req.SetTransport(otelhttp.NewTransport(http.DefaultTransport))
|
||
req.Retries(3)
|
||
response, err := req.String()
|
||
if err != nil {
|
||
otelTrace.Logger.WithContext(ctx).Error("代丽支付请求失败:" + err.Error())
|
||
scanData.Status = "-1"
|
||
scanData.Msg = "请求失败:" + err.Error()
|
||
} else {
|
||
/*otel.Logger.WithContext(ctx).Info("代丽支付返回 = " + response)
|
||
status := gojson.Json(response).Get("status").Tostring()
|
||
message := gojson.Json(response).Get("message").Tostring()
|
||
if "10000" != status {
|
||
scanData.Status = "-1"
|
||
scanData.Msg = message
|
||
} else {*/
|
||
codeUrl := gojson.Json(response).Get("url").Tostring()
|
||
codeUrl = "http://www.baidu.com"
|
||
scanData.PayUrl = codeUrl
|
||
scanData.OrderNo = orderInfo.BankOrderId
|
||
scanData.OrderPrice = strconv.FormatFloat(orderInfo.OrderAmount, 'f', 2, 64)
|
||
//}
|
||
}
|
||
|
||
return scanData
|
||
}
|
||
|
||
func (c *DaiLiImpl) PayNotify() {
|
||
ctx := c.Ctx.Request.Context()
|
||
|
||
orderNo := strings.TrimSpace(c.GetString("orderNo"))
|
||
orderInfo := order.GetOrderByBankOrderId(ctx, orderNo)
|
||
if orderInfo.BankOrderId == "" || len(orderInfo.BankOrderId) == 0 {
|
||
otelTrace.Logger.WithContext(ctx).Error("快付回调的订单号不存在,订单号=", zap.String("orderNo", orderNo))
|
||
c.StopRun()
|
||
}
|
||
roadInfo := road.GetRoadInfoByRoadUid(ctx, orderInfo.RoadUid)
|
||
if roadInfo.RoadUid == "" || len(roadInfo.RoadUid) == 0 {
|
||
otelTrace.Logger.WithContext(ctx).Error("支付通道已经关系或者删除,不进行回调")
|
||
c.StopRun()
|
||
}
|
||
merchantUid := orderInfo.MerchantUid
|
||
merchantInfo := merchant.GetMerchantByUid(ctx, merchantUid)
|
||
if merchantInfo.MerchantUid == "" || len(merchantInfo.MerchantUid) == 0 {
|
||
otelTrace.Logger.WithContext(ctx).Error("快付回调失败,该商户不存在或者已经删除,商户uid=", zap.String("merchantUid", merchantUid))
|
||
c.StopRun()
|
||
}
|
||
paySecret := merchantInfo.MerchantSecret
|
||
|
||
params := make(map[string]any)
|
||
params["orderNo"] = orderNo
|
||
params["orderPrice"] = strings.TrimSpace(c.GetString("orderPrice"))
|
||
params["orderTime"] = strings.TrimSpace(c.GetString("orderTime"))
|
||
params["trxNo"] = strings.TrimSpace(c.GetString("trxNo"))
|
||
params["statusCode"] = strings.TrimSpace(c.GetString("statusCode"))
|
||
params["tradeStatus"] = strings.TrimSpace(c.GetString("tradeStatus"))
|
||
params["field1"] = strings.TrimSpace(c.GetString("field1"))
|
||
params["payKey"] = strings.TrimSpace(c.GetString("payKey"))
|
||
// 对参数进行验签
|
||
keys := utils.SortMap(params)
|
||
tmpSign := utils.GetMD5Sign(params, keys, paySecret)
|
||
sign := strings.TrimSpace(c.GetString("sign"))
|
||
if tmpSign != sign {
|
||
otelTrace.Logger.WithContext(ctx).Error("代丽回调签名异常,回调失败")
|
||
// c.StopRun()
|
||
}
|
||
// 实际支付金额
|
||
factAmount, err := strconv.ParseFloat(convertor.ToString(params["orderPrice"]), 64)
|
||
if err != nil {
|
||
orderInfo.FactAmount = 0
|
||
}
|
||
orderInfo.FactAmount = factAmount
|
||
orderInfo.BankTransId = convertor.ToString(params["trxNo"])
|
||
tradeStatus := params["tradeStatus"]
|
||
|
||
// paySolveController := new(service.PaySolveController)
|
||
if tradeStatus == "FAILED" {
|
||
if !service.SolvePayFail(ctx, orderInfo.BankOrderId, "", "") {
|
||
otelTrace.Logger.WithContext(ctx).Error("solve order fail fail")
|
||
}
|
||
} else if tradeStatus == "CANCELED" {
|
||
if !service.SolvePayFail(ctx, orderInfo.BankOrderId, "", "") {
|
||
otelTrace.Logger.WithContext(ctx).Error("solve order cancel fail")
|
||
}
|
||
} else if tradeStatus == "WAITING_PAYMENT" {
|
||
logs.Notice("快付回调,该订单还处于等待支付,订单id=", orderNo)
|
||
} else if tradeStatus == "SUCCESS" {
|
||
// 订单支付成功,需要搞很多事情 TODO
|
||
service.SolvePaySuccess(ctx, orderInfo.BankOrderId, orderInfo.FactAmount, c.GetString("trxNo"), "支付成功")
|
||
}
|
||
c.Ctx.WriteString("success")
|
||
}
|
||
|
||
func (c *DaiLiImpl) PayQuery(orderInfo order.OrderInfo, roadInfo road.RoadInfo) bool {
|
||
ctx := c.Ctx.Request.Context()
|
||
|
||
tradeStatus := "SUCCESS"
|
||
trxNo := orderInfo.BankOrderId
|
||
factAmount := 100.00
|
||
if tradeStatus == "SUCCESS" {
|
||
// 调用支付成功的接口,做加款更新操作,需要把实际支付金额传入
|
||
if !service.SolvePaySuccess(ctx, orderInfo.BankOrderId, factAmount, trxNo, "支付成功") {
|
||
return false
|
||
}
|
||
} else if tradeStatus == "FAILED" {
|
||
if !service.SolvePayFail(ctx, orderInfo.BankOrderId, "", "") {
|
||
return false
|
||
}
|
||
} else {
|
||
otelTrace.Logger.WithContext(ctx).Info("订单状态处于:" + tradeStatus + ";bankOrderId:" + orderInfo.BankOrderId)
|
||
}
|
||
return true
|
||
}
|
||
|
||
func (c *DaiLiImpl) PayQueryV2(orderInfo order.OrderInfo, roadInfo road.RoadInfo) supply_model.MsgModel {
|
||
return ""
|
||
}
|
||
|
||
func (c *DaiLiImpl) PayFor(info payfor.PayforInfo) string {
|
||
return ""
|
||
}
|
||
|
||
func (c *DaiLiImpl) PayForNotify() string {
|
||
return ""
|
||
}
|
||
|
||
func (c *DaiLiImpl) PayForQuery(payFor payfor.PayforInfo) (string, string) {
|
||
return "", ""
|
||
}
|
||
|
||
func (c *DaiLiImpl) BalanceQuery(roadInfo road.RoadInfo) float64 {
|
||
return 0.00
|
||
}
|