package wechat_pay import ( "context" "errors" "fmt" "github.com/wechatpay-apiv3/wechatpay-go/core" "github.com/wechatpay-apiv3/wechatpay-go/core/auth/verifiers" "github.com/wechatpay-apiv3/wechatpay-go/core/downloader" "github.com/wechatpay-apiv3/wechatpay-go/core/notify" "github.com/wechatpay-apiv3/wechatpay-go/core/option" "github.com/wechatpay-apiv3/wechatpay-go/services/payments" "github.com/wechatpay-apiv3/wechatpay-go/services/payments/jsapi" "github.com/wechatpay-apiv3/wechatpay-go/utils" "log" "net/http" ) // Config 微信支付配置 type Config struct { AppID string // 公众号ID MchID string // 商户号 APIKey string // API密钥 NotifyURL string // 支付回调通知地址 } // PayService 微信支付服务 type PayService struct { Client *core.Client notifyHandler *notify.Handler appId string mchid string } /* NewPayService 传参说明 arg1:商户号 arg2:AppId arg3:商户证书序列号 arg4:商户APIv3密钥 arg5:商户私钥 arg6:商户公钥 */ func NewPayService(arg1, arg2, arg3, arg4, arg5, arg6 string) *PayService { // 使用 utils 提供的函数从本地文件中加载商户私钥,商户私钥会用来生成请求的签名 mchPrivateKey, err := utils.LoadPrivateKeyWithPath(arg5) if err != nil { log.Fatal("load merchant private key error", err.Error()) } cert, err := utils.LoadCertificateWithPath(arg6) if err != nil { log.Fatal("load merchant private key error", err.Error()) } fmt.Println("===============") fmt.Println(cert.SerialNumber.String()) fmt.Println("===============") ctx := context.Background() // 使用商户私钥等初始化 client,并使它具有自动定时获取微信支付平台证书的能力 opts := []core.ClientOption{ option.WithWechatPayAutoAuthCipher(arg1, arg3, mchPrivateKey, arg4), } client, err := core.NewClient(ctx, opts...) if err != nil { log.Fatal(err) } //err = downloader.MgrInstance().RegisterDownloaderWithPrivateKey(ctx, mchPrivateKey, arg3, arg1, arg4) certificateVisitor := downloader.MgrInstance().GetCertificateVisitor(arg1) handler, err := notify.NewRSANotifyHandler(arg4, verifiers.NewSHA256WithRSAVerifier(certificateVisitor)) if err != nil { log.Fatal(err) } if err != nil { log.Fatal(err) } return &PayService{client, handler, arg2, arg1} } type PaymentInfo struct { Description string Attach string AmountTotal int64 OpenId string OutTradeNo string } func (p *PayService) CreatePayment(paymentInfo *PaymentInfo) (*jsapi.PrepayWithRequestPaymentResponse, error) { svc := jsapi.JsapiApiService{Client: p.Client} resp, result, err := svc.PrepayWithRequestPayment(context.Background(), jsapi.PrepayRequest{ Appid: core.String(p.appId), Mchid: core.String(p.mchid), Description: core.String(paymentInfo.Description), OutTradeNo: core.String(paymentInfo.OutTradeNo), Attach: core.String(paymentInfo.Attach), NotifyUrl: core.String("http://famyun.com/api/order/order_notify"), Amount: &jsapi.Amount{ Total: core.Int64(paymentInfo.AmountTotal), }, Payer: &jsapi.Payer{ Openid: core.String(paymentInfo.OpenId), }, }) if err != nil { return nil, err } if result.Response.StatusCode != 200 { return nil, errors.New(resp.String()) } return resp, nil } func (p *PayService) CancelPayment(orderId string) error { svc := jsapi.JsapiApiService{Client: p.Client} result, err := svc.CloseOrder(context.Background(), jsapi.CloseOrderRequest{ OutTradeNo: core.String(orderId), Mchid: core.String(p.mchid), }) if err != nil { return err } if result.Response.StatusCode == 200 { return nil } else { return errors.New("关闭订单失败") } } func (p *PayService) HandlerNotifyRequest(r *http.Request) (*payments.Transaction, error) { content := new(payments.Transaction) _, err := p.notifyHandler.ParseNotifyRequest(context.Background(), r, content) if err != nil { return nil, err } return content, nil }