Files
quyun/backend/providers/wepay/pay.go
2025-04-14 20:05:19 +08:00

136 lines
3.4 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"
w "quyun/providers/wechat"
"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(wechatConfig *w.Config) (*Client, error) {
// NewClientV3 初始化微信客户端 v3
// mchid商户ID 或者服务商模式的 sp_mchid
// serialNo商户证书的证书序列号
// apiV3KeyapiV3Key商户平台获取
// privateKey私钥 apiclient_key.pem 读取后的内容
// 1、你最多可同时使用3个有效证书为减少风险建议及时作废不使用的API证书
// 2、API证书包括私钥文件及公钥证书配对使用仅保存在申请证书的电脑本地无法从系统下载
// 3、私钥文件名为“prikey_序列号”公钥证书名为“pubkey_序列号”序列号请查看上述列表。若无法找到证书文件可申请新证书。
client, err := wechat.NewClientV3(
w.Pay.MchID, w.Pay.SerialNo, w.Pay.ApiV3Key, w.Pay.PrivateKey,
wechatConfig.MchId, wechatConfig.SerialNo, wechatConfig.APIv3Key, wechatConfig.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)
}