package plant // //import ( // "context" // "errors" // "net/http" // "sundynix-go/global" // "sundynix-go/model/plant" // "sundynix-go/model/system" // "sundynix-go/utils/wechat" // // "github.com/gin-gonic/gin" // "github.com/wechatpay-apiv3/wechatpay-go/core" // "github.com/wechatpay-apiv3/wechatpay-go/core/auth/verifiers" // "github.com/wechatpay-apiv3/wechatpay-go/core/notify" // "github.com/wechatpay-apiv3/wechatpay-go/services/payments" // "github.com/wechatpay-apiv3/wechatpay-go/services/payments/jsapi" // "github.com/wechatpay-apiv3/wechatpay-go/utils" // "go.uber.org/zap" // "gorm.io/gorm" //) // //type PayService struct{} // //var PayServiceApp = new(PayService) // //// PrePay 预支付 //func (s *PayService) PrePay(orderId, userId string) (resp *jsapi.PrepayWithRequestPaymentResponse, err error) { // //1.查询订单和 用户 // var order plant.Order // err = global.DB.Where("id = ?", orderId).First(&order).Error // if err != nil { // return nil, err // } // var user system.User // err = global.DB.Where("id = ?", userId).First(&user).Error // if err != nil { // return nil, err // } // payClient, err := wechat.GetWxPayClient() // if err != nil { // return nil, err // } // // svc := jsapi.JsapiApiService{Client: payClient} // result, _, err := svc.PrepayWithRequestPayment(context.Background(), // jsapi.PrepayRequest{ // Appid: core.String(global.Config.MiniProgram.AppId), // Mchid: core.String(global.Config.WechatPay.MchId), // Description: core.String(order.Name), // OutTradeNo: core.String(order.OutTradeNo), // //TimeExpire: core.Time(time.Now()), //选填 // //Attach: core.String("自定义数据说明"), //选填 // NotifyUrl: core.String(global.Config.WechatPay.NotifyUrl), // //GoodsTag: core.String("WXG"), //选填 // //SupportFapiao: core.Bool(false), //选填 // Amount: &jsapi.Amount{ // Currency: core.String("CNY"), // Total: core.Int64(int64(order.Amount)), // }, // Payer: &jsapi.Payer{ // Openid: core.String(user.MiniOpenId), // }, // //Detail: &jsapi.Detail{ // // CostPrice: core.Int64(608800), // // GoodsDetail: []jsapi.GoodsDetail{jsapi.GoodsDetail{ // // GoodsName: core.String("iPhoneX 256G"), // // MerchantGoodsId: core.String("ABC"), // // Quantity: core.Int64(1), // // UnitPrice: core.Int64(828800), // // WechatpayGoodsId: core.String("1001"), // // }}, // // InvoiceId: core.String("wx123"), // //}, //选填 // //SceneInfo: &jsapi.SceneInfo{ // // DeviceId: core.String("013467007045764"), // // PayerClientIp: core.String("14.23.150.211"), // // StoreInfo: &jsapi.StoreInfo{ // // Address: core.String("广东省深圳市南山区科技中一道10000号"), // // AreaCode: core.String("440305"), // // Id: core.String("0001"), // // Name: core.String("腾讯大厦分店"), // // }, // //}, // //SettleInfo: &jsapi.SettleInfo{ // // ProfitSharing: core.Bool(false), // //}, //选填 // }) // if err != nil { // return nil, err // } // // return result, nil // //} // //// PayCallback 支付回调 //func (s *PayService) PayCallback(c *gin.Context) error { // //1.加载共钥 // mchPublicKeyPath := global.Config.WechatPay.PublicKeyPath // mchPublicKey, err := utils.LoadPublicKeyWithPath(mchPublicKeyPath) // if err != nil { // return err // } // ctx := context.Background() // //2.创建客户端 // handler, err := notify.NewRSANotifyHandler(global.Config.WechatPay.MchAPIv3Key, // verifiers.NewSHA256WithRSAPubkeyVerifier(global.Config.WechatPay.PublicKeyId, *mchPublicKey)) // if err != nil { // return err // } // //3.验签 解密 // //将支付回调通知中的内容,解析为 payments.Transaction。 // transaction := new(payments.Transaction) // notifyReq, err := handler.ParseNotifyRequest(ctx, c.Request, transaction) // // 4.如果验签未通过,或者解密失败 // if err != nil { // //应答微信 // c.AbortWithStatusJSON(http.StatusBadRequest, gin.H{ // "code": "FAIL", // "message": "失败", // }) // global.Logger.Error("wxPay回调-验签或解密:", zap.Error(err)) // return err // } // //5.应答微信 // c.Status(http.StatusOK) // // 6.处理通知内容 // global.Logger.Info("wxPay回调-成功:", zap.Any("notifyReq", notifyReq.Summary)) // //7. 异步处理数据 // go func() { // payNotify := plant.PayNotify{ // Amount: *transaction.Amount.Total, // Currency: *transaction.Amount.Currency, // PayerCurrency: *transaction.Amount.PayerCurrency, // PayerTotal: *transaction.Amount.PayerTotal, // Appid: *transaction.Appid, // Mchid: *transaction.Mchid, // OutTradeNo: *transaction.OutTradeNo, // Attach: *transaction.Attach, // BankType: *transaction.BankType, // Payer: *transaction.Payer.Openid, // SuccessTime: *transaction.SuccessTime, // TradeState: *transaction.TradeState, // TradeStateDesc: *transaction.TradeStateDesc, // TradeType: *transaction.TradeType, // TransactionId: *transaction.TransactionId, // } // //7.1 回调记录 // err = global.DB.Create(&payNotify).Error // if err != nil { // global.Logger.Error("wxPay回调-存储数据异常:", zap.Error(err)) // } // if payNotify.TradeState == "SUCCESS" { // //7.2 扣商品库存 // var order plant.Order // err = global.DB.Where("out_trade_no = ?", *transaction.OutTradeNo).First(&order).Error // if err != nil { // if errors.Is(err, gorm.ErrRecordNotFound) { // global.Logger.Error("wxPay回调-订单不存在:", zap.Error(err)) // } // } // //根据订单找到领取记录 // var record plant.ClaimPlantRecord // err = global.DB.Where("order_id = ?", order.Id).First(&record).Error // if err != nil { // if errors.Is(err, gorm.ErrRecordNotFound) { // global.Logger.Error("wxPay回调-领取记录不存在:", zap.Error(err)) // } // } // //根据领取记录找到植物 // var claimPlant plant.ClaimPlant // err = global.DB.Where("id = ?", record.ClaimPlantId).First(&claimPlant).Error // if err != nil { // if errors.Is(err, gorm.ErrRecordNotFound) { // global.Logger.Error("wxPay回调-植物不存在:", zap.Error(err)) // } // } // err = global.DB.Transaction(func(tx *gorm.DB) error { // //扣库存 // if err = tx.Model(&claimPlant).Update("stock", gorm.Expr("stock - ?", 1)).Error; err != nil { // return err // } // //订单状态 // if err = tx.Model(&order).Update("pay_status", "SUCCESS").Error; err != nil { // return err // } // //修改领取记录为成功 // if err = tx.Model(&record).Update("status", 1).Error; err != nil { // return err // } // //减用户积分 // if err = tx.Model(&plant.Personal{}).Where("user_id = ?", order.UserId).Update("points_count", gorm.Expr("points_count - ?", claimPlant.Points)).Error; err != nil { // return err // } // return nil // }) // } // if err != nil { // return // } // }() // return nil // //}