feat: add wepay

This commit is contained in:
yanghao05
2025-04-11 16:49:57 +08:00
parent 3a04c0b39d
commit 7e17cd8164
7 changed files with 223 additions and 1 deletions

View File

@@ -0,0 +1,28 @@
package wepay
import (
"go.ipao.vip/atom/container"
"go.ipao.vip/atom/opt"
)
const DefaultPrefix = "WePay"
func DefaultProvider() container.ProviderContainer {
return container.ProviderContainer{
Provider: Provide,
Options: []opt.Option{
opt.Prefix(DefaultPrefix),
},
}
}
type Config struct {
Debug bool
NotifyURL string
AppId string
MchId string
SerialNo string
APIv3Key string
PrivateKey string
}

View File

@@ -0,0 +1,127 @@
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)
}