172 lines
5.4 KiB
Go
172 lines
5.4 KiB
Go
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))
|
||
|
||
}
|