You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

138 lines
3.9 KiB
Go

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

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
}