package api import ( "bytes" "encoding/json" "fmt" "github.com/gin-gonic/gin" "github.com/smartwalle/alipay/v3" "io" "jypay/errors" "jypay/global" "jypay/model" "jypay/request" "jypay/utils" "log" "net/http" "strconv" "time" ) func Index(c *gin.Context) (utils.Data, error) { return utils.Data{"hello": "elf"}, nil } func Error(c *gin.Context) (utils.Data, error) { return nil, errors.NewBusinessError("测试", "1122") } func Pay(c *gin.Context) (utils.Data, error) { req := request.OrderRequest{} err := c.BindJSON(&req) if err != nil { fmt.Printf("bind json err:%v", err) return nil, errors.NewBusinessError("参数错误") } order, err := saveOrder(req) if err != nil { return nil, err } var param = alipay.TradeWapPay{} param.OutTradeNo = order.OrderNo param.TotalAmount = strconv.FormatFloat(order.PayAmount, 'f', -1, 64) param.Subject = order.Subject token := utils.Md5(order.OrderNo + strconv.Itoa(order.UserId) + strconv.FormatInt(time.Now().Unix(), 10)) param.NotifyURL = global.Config.Server.Domain + "/notify" param.ReturnURL = global.Config.Server.Domain + "/return?token=" + token client, err := alipay.New(global.Config.Alipay.AppId, global.Config.Alipay.PrivateKey, true) if err != nil { return nil, errors.NewBusinessError("初始化支付宝失败") } result, err := client.TradeWapPay(param) if err != nil { return nil, errors.NewBusinessError("请求支付宝失败:" + err.Error()) } fmt.Println(result.String()) order.PayUrl = result.String() order.Token = token global.DB.Save(&order) data := utils.Data{ "pay_url": global.Config.Server.Domain + "/payment?token=" + token, } return data, nil } func saveOrder(req request.OrderRequest) (*model.Order, error) { if req.OrderNo == "" { return nil, errors.NewBusinessError("订单号[orderNo]不能为空") } order := model.Order{} global.DB.Where("order_no = ?", req.OrderNo).First(&order) order.OrderNo = req.OrderNo order.UserId = req.UserId order.UserAccount = req.UserAccount order.GameId = req.GameId order.GameName = req.GameName order.ServerId = req.ServerId order.ServerName = req.ServerName order.Subject = req.Subject order.RoleId = req.RoleId order.RoleName = req.RoleName order.PayAmount = float64(req.PayAmount) / 100 order.NotifyUrl = req.NotifyUrl order.ReturnUrl = req.ReturnUrl order.PromoteId = req.PromoteId order.PromoteAccount = req.PromoteAccount order.PayStatus = 0 result := global.DB.Create(&order) if result.Error != nil { return nil, errors.NewBusinessError("数据异常") } return &order, nil } func Notify(c *gin.Context) { err := c.Request.ParseForm() if err != nil { log.Printf("参数错误:%v", err) return } client, err := alipay.New(global.Config.Alipay.AppId, global.Config.Alipay.PrivateKey, true) if err != nil { log.Printf("初始化支付宝失败:%v", err) return } client.LoadAliPayPublicKey(global.Config.Alipay.AliPublicKey) notification, err := client.DecodeNotification(c.Request.Form) if err != nil { log.Printf("解析异步通知发生错误:%v", err) return } order := model.Order{} tx := global.DB.Where("order_no = ?", notification.OutTradeNo).First(&order) if tx.Error != nil { log.Printf("订单不存在:%s", notification.OutTradeNo) return } now := time.Now() if notification.TradeStatus == "TRADE_SUCCESS" || notification.TradeStatus == "TRADE_FINISHED" { order.PayStatus = 1 order.PayTime = &now tx := global.DB.Save(order) if tx.Error != nil { log.Printf("更新订单失败:%s", notification.OutTradeNo) return } } notifyData := make(map[string]interface{}) notifyData["trade_no"] = notification.TradeNo notifyData["out_trade_no"] = notification.OutTradeNo notifyData["trade_status"] = notification.TradeStatus notifyData["total_amount"] = notification.TotalAmount notifyResult := postToSdk(order.NotifyUrl, notifyData) if notifyResult == "success" { client.ACKNotification(c.Writer) } } func TestPost(c *gin.Context) (utils.Data, error) { notifyData := make(map[string]interface{}) notifyData["trade_no"] = "112233" notifyData["out_trade_no"] = "2222222" notifyData["trade_status"] = "1" notifyData["total_amount"] = "11.11" notifyResult := postToSdk("https://api.jianghuifa.cn/callback.php/Notify/kd_callback", notifyData) return utils.Data{"hello": notifyResult}, nil } func postToSdk(url string, data map[string]interface{}) string { content, err := json.Marshal(data) if err != nil { log.Fatalf("无法编码JSON数据:%v", err) return "fail" } client := &http.Client{} req, err := http.NewRequest("POST", url, bytes.NewBuffer(content)) if err != nil { log.Fatalf("无法创建新的请求:%v", err) return "fail" } req.Header.Set("Content-Type", "application/json") resp, err := client.Do(req) if err != nil { log.Fatalf("无法发送POST请求:%v", err) return "fail" } defer resp.Body.Close() body, err := io.ReadAll(resp.Body) if err != nil { log.Fatalf("无法读取响应体内容:%v", err) return "fail" } return string(body) } func Return(c *gin.Context) { token := c.Query("token") order := model.Order{} tx := global.DB.Where("token = ?", token).First(&order) if tx.Error != nil { c.Writer.WriteHeader(http.StatusOK) c.Writer.Write([]byte("订单不存在")) return } c.Redirect(http.StatusMovedPermanently, order.ReturnUrl) } func Payment(c *gin.Context) { token := c.Query("token") order := model.Order{} tx := global.DB.Where("token = ?", token).First(&order) fmt.Println(tx) if tx.Error != nil { fmt.Println(tx.Error) c.Writer.WriteHeader(http.StatusOK) c.Writer.Write([]byte("订单不存在")) return } c.Redirect(http.StatusMovedPermanently, order.PayUrl) }