CloudrevePlus/pkg/payment/wechat.go
2024-02-25 08:30:34 +08:00

89 lines
2.3 KiB
Go

package payment
import (
"errors"
model "github.com/cloudreve/Cloudreve/v3/models"
"github.com/cloudreve/Cloudreve/v3/pkg/cache"
"github.com/cloudreve/Cloudreve/v3/pkg/serializer"
"github.com/cloudreve/Cloudreve/v3/pkg/util"
"github.com/iGoogle-ink/gopay"
"github.com/iGoogle-ink/gopay/wechat/v3"
"net/url"
"time"
)
// Wechat 微信扫码支付接口
type Wechat struct {
Client *wechat.ClientV3
ApiV3Key string
}
// Create 创建订单
func (pay *Wechat) Create(order *model.Order, pack *serializer.PackProduct, group *serializer.GroupProducts, user *model.User) (*OrderCreateRes, error) {
gateway, _ := url.Parse("/api/v3/callback/wechat")
bm := make(gopay.BodyMap)
bm.
Set("description", order.Name).
Set("out_trade_no", order.OrderNo).
Set("notify_url", model.GetSiteURL().ResolveReference(gateway).String()).
SetBodyMap("amount", func(bm gopay.BodyMap) {
bm.Set("total", int64(order.Price*order.Num)).
Set("currency", "CNY")
})
wxRsp, err := pay.Client.V3TransactionNative(bm)
if err != nil {
return nil, ErrIssueOrder.WithError(err)
}
if wxRsp.Code == wechat.Success {
if _, err := order.Create(); err != nil {
return nil, ErrInsertOrder.WithError(err)
}
return &OrderCreateRes{
Payment: true,
QRCode: wxRsp.Response.CodeUrl,
ID: order.OrderNo,
}, nil
}
return nil, ErrIssueOrder.WithError(errors.New(wxRsp.Error))
}
// GetPlatformCert 获取微信平台证书
func (pay *Wechat) GetPlatformCert() string {
if cert, ok := cache.Get("wechat_platform_cert"); ok {
return cert.(string)
}
res, err := pay.Client.GetPlatformCerts()
if err == nil {
// 使用反馈证书中启用时间较晚的
var (
currentLatest *time.Time
currentCert string
)
for _, cert := range res.Certs {
effectiveTime, err := time.Parse("2006-01-02T15:04:05-0700", cert.EffectiveTime)
if err != nil {
if currentLatest == nil {
currentLatest = &effectiveTime
currentCert = cert.PublicKey
continue
}
if currentLatest.Before(effectiveTime) {
currentLatest = &effectiveTime
currentCert = cert.PublicKey
}
}
}
cache.Set("wechat_platform_cert", currentCert, 3600*10)
return currentCert
}
util.Log().Debug("Failed to get Wechat Pay platform certificate: %s", err)
return ""
}