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:商户证书的证书序列号 // apiV3Key:apiV3Key,商户平台获取 // 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) }