Files
quyun/backend/providers/wepay/pay.go
2025-04-11 16:49:57 +08:00

128 lines
2.8 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
package wepay
import (
"context"
"errors"
"time"
"github.com/go-pay/gopay"
"github.com/go-pay/gopay/wechat/v3"
"go.ipao.vip/atom/container"
"go.ipao.vip/atom/opt"
)
func Provide(opts ...opt.Option) error {
o := opt.New(opts...)
var config Config
if err := o.UnmarshalConfig(&config); err != nil {
return err
}
return container.Container.Provide(func() (*Client, error) {
// NewClientV3 初始化微信客户端 v3
// mchid商户ID 或者服务商模式的 sp_mchid
// serialNo商户证书的证书序列号
// apiV3KeyapiV3Key商户平台获取
// privateKey私钥 apiclient_key.pem 读取后的内容
client, err := wechat.NewClientV3(config.MchId, config.SerialNo, config.APIv3Key, config.PrivateKey)
if err != nil {
return nil, err
}
client.DebugSwitch = gopay.DebugOff
if config.Debug {
client.DebugSwitch = gopay.DebugOn
}
return &Client{
payClient: client,
config: &config,
}, nil
}, o.DiOptions()...)
}
type Client struct {
payClient *wechat.ClientV3
config *Config
}
func (c *Client) GetClient() *wechat.ClientV3 {
return c.payClient
}
func (c *Client) V3TransactionJsapi(ctx context.Context, bm *BodyMap) (*wechat.PrepayRsp, error) {
resp, err := c.payClient.V3TransactionJsapi(ctx, bm.bm)
if err != nil {
return nil, err
}
if resp.Code != wechat.Success {
return nil, errors.New(resp.Error)
}
return resp, nil
}
func (c *Client) BodyMap() *BodyMap { return NewBodyMap(c.config) }
type BodyMap struct {
bm gopay.BodyMap
}
func NewBodyMap(c *Config) *BodyMap {
bm := make(gopay.BodyMap)
bm.Set("sp_appid", c.AppId).
Set("sp_mchid", c.MchId).
Set("notify_url", c.NotifyURL).
Set("amount", func(bm gopay.BodyMap) {
bm.Set("total", 1).
Set("currency", "CNY")
})
return &BodyMap{
bm: bm,
}
}
func (b *BodyMap) Set(key string, value interface{}) *BodyMap {
b.bm.Set(key, value)
return b
}
func (b *BodyMap) SetBodyMap(key string, f func(bm gopay.BodyMap)) *BodyMap {
b.bm.SetBodyMap(key, f)
return b
}
// Expire time
func (b *BodyMap) Expire(t time.Duration) *BodyMap {
return b.Set("time_expire", time.Now().Add(t).Format(time.RFC3339))
}
// Description
func (b *BodyMap) Description(desc string) *BodyMap {
return b.Set("description", desc)
}
// OutTradeNo
func (b *BodyMap) OutTradeNo(outTradeNo string) *BodyMap {
return b.Set("out_trade_no", outTradeNo)
}
// Amount
func (b *BodyMap) Amount(total int, currency string) *BodyMap {
return b.SetBodyMap("amount", func(bm gopay.BodyMap) {
bm.Set("total", total).Set("currency", currency)
})
}
// Payer
func (b *BodyMap) Payer(spOpenId string) *BodyMap {
return b.SetBodyMap("payer", func(bm gopay.BodyMap) {
bm.Set("sp_openid", spOpenId)
})
}
// SubMchId
func (b *BodyMap) SubMchId(subMchId string) *BodyMap {
return b.Set("sub_mchid", subMchId)
}