package utils import ( "fmt" "github.com/bwmarrin/snowflake" "github.com/dgb8901/go-wechat-miniapp-sdk/config" "github.com/dgb8901/go-wechat-miniapp-sdk/models/response" "github.com/dgb8901/go-wechat-miniapp-sdk/service" "github.com/spf13/viper" "github.com/wechatpay-apiv3/wechatpay-go/core" "github.com/wechatpay-apiv3/wechatpay-go/core/option" "github.com/wechatpay-apiv3/wechatpay-go/services/refunddomestic" "github.com/wechatpay-apiv3/wechatpay-go/utils" "go.uber.org/zap" "golang.org/x/net/context" "log" "pet-house.com/core/g" "pet-house.com/core/server/viper_server" "pet-house.com/core/server/web" "pet-house.com/core/server/zap_server" ) var CONFIG = WxConfig{ AppId: "", Secret: "", Token: "", AesKey: "", MsgDataFormat: "", MchId: "", MchCertificateSerialNumber: "", MchAPIv3Key: "", PrivateKeyPath: "", WechatCert: "", } type WxConfig struct { AppId string `mapstructure:"appId" json:"appId" yaml:"appId"` Secret string `mapstructure:"secret" json:"secret" yaml:"secret"` Token string `mapstructure:"token" json:"token" yaml:"token"` AesKey string `mapstructure:"aesKey" json:"aesKey" yaml:"aesKey"` MsgDataFormat string `mapstructure:"msgDataFormat" json:"msgDataFormat" yaml:"msgDataFormat"` MchId string `mapstructure:"mchId" json:"mchId" yaml:"mchId"` MchCertificateSerialNumber string `mapstructure:"mchCertificateSerialNumber" json:"mchCertificateSerialNumber" yaml:"mchCertificateSerialNumber"` MchAPIv3Key string `mapstructure:"mchAPIv3Key" json:"mchAPIv3Key" yaml:"mchAPIv3Key"` PrivateKeyPath string `mapstructure:"privateKeyPath" json:"privateKeyPath" yaml:"privateKeyPath"` WechatCert string `mapstructure:"wechatCert" json:"wechatCert" yaml:"wechatCert"` } // getViperConfig get viper config func getViperConfig() viper_server.ViperConfig { configName := "wxconfig" return viper_server.ViperConfig{ Debug: true, Directory: g.ConfigDir, Name: configName, Type: g.ConfigType, Watch: func(vi *viper.Viper) error { if err := vi.Unmarshal(&CONFIG); err != nil { return fmt.Errorf("get Unarshal error: %v", err) } // watch config file change vi.SetConfigName(configName) return nil }, Default: []byte(` { "appId": ` + CONFIG.AppId + `, "secret": "` + CONFIG.Secret + `", "token": "` + CONFIG.Token + `", "aesKey": "` + CONFIG.AesKey + `", "msgDataFormat": ` + CONFIG.MsgDataFormat + ` "mchId": ` + CONFIG.MchId + ` "mchCertificateSerialNumber": ` + CONFIG.MchCertificateSerialNumber + ` "mchAPIv3Key": ` + CONFIG.MchAPIv3Key + ` "privateKeyPath": ` + CONFIG.PrivateKeyPath + ` "wechatCert": ` + CONFIG.WechatCert + ` }`), } } type WechatHelper struct { wechatService *service.WxaService wechatPayClient *core.Client } var wxHelper = &WechatHelper{} func WechatInit() { viper_server.Init(getViperConfig()) cfg := &config.Cfg{ AppId: CONFIG.AppId, Secret: CONFIG.Secret, Token: CONFIG.Token, AesKey: CONFIG.AesKey, MsgDataFormat: CONFIG.MsgDataFormat, } wxaConfig := config.NewInMemory(cfg) wxaService := service.NewService(wxaConfig) wxHelper.wechatService = wxaService getPayApi() } func getPayApi() { // 使用 utils 提供的函数从本地文件中加载商户私钥,商户私钥会用来生成请求的签名 mchPrivateKey, err := utils.LoadPrivateKeyWithPath(CONFIG.PrivateKeyPath) if err != nil { log.Fatal("load merchant private key error") } ctx := context.Background() // 使用商户私钥等初始化 client,并使它具有自动定时获取微信支付平台证书的能力 opts := []core.ClientOption{ option.WithWechatPayAutoAuthCipher(CONFIG.MchId, CONFIG.MchCertificateSerialNumber, mchPrivateKey, CONFIG.MchAPIv3Key), } client, err := core.NewClient(ctx, opts...) if err != nil { log.Fatalf("new wechat pay client err:%s", err) } wxHelper.wechatPayClient = client } func getWxaService() *service.WxaService { return wxHelper.wechatService } func GetWxPayService() *core.Client { return wxHelper.wechatPayClient } type WxUserInfo struct { OpenId string UnionId string } func GetWxUserInfo(code string) (*response.JsCode2SessionResult, error) { info, err := getWxaService().GetUserService().Jscode2Session(code) if err != nil { return nil, err } return info, nil } func WxPayRefund(payId string, payOrderId string, orderAmount int64, ctx context.Context) { ras := refunddomestic.RefundsApiService{Client: wxHelper.wechatPayClient} var refundNo = new(string) reason := "取消订单" currency := "CNY" notifyUrl := web.CONFIG.System.Domain + "/pet-house/pay/payNotify" amount := refunddomestic.AmountReq{ Refund: &orderAmount, Total: &orderAmount, Currency: ¤cy, } var NextId, _ = snowflake.NewNode(1) *refundNo = NextId.Generate().String() var req = refunddomestic.CreateRequest{ TransactionId: &payId, OutTradeNo: &payOrderId, OutRefundNo: refundNo, Reason: &reason, NotifyUrl: ¬ifyUrl, Amount: &amount, } createResult, _, err := ras.Create(ctx, req) if err != nil { return } zap_server.ZAPLOG.Info("WxPayRefund", zap.Any("request", req), zap.Any("response", createResult)) }