109 lines
2.2 KiB
Go
109 lines
2.2 KiB
Go
package weixin
|
|
|
|
import (
|
|
"bytes"
|
|
"errors"
|
|
"fmt"
|
|
"io"
|
|
"net/http"
|
|
)
|
|
|
|
var (
|
|
ErrUserPaying = errors.New("USERPAYING")
|
|
)
|
|
|
|
type WxpayPartnerConfig struct {
|
|
MchId string
|
|
AppId string
|
|
ApiKeyV2 string
|
|
}
|
|
|
|
type WxpayPartner struct {
|
|
config *WxpayPartnerConfig
|
|
stdClient *http.Client
|
|
}
|
|
|
|
type MicroPayRequest struct {
|
|
SubMchId string
|
|
SubAppId string
|
|
GoodsName string
|
|
OutTradeNo string
|
|
TotalFee int64
|
|
AuthCode string
|
|
ServerIp string
|
|
Attach string
|
|
}
|
|
|
|
func NewWxpayPartner(cfg *WxpayPartnerConfig) *WxpayPartner {
|
|
return &WxpayPartner{
|
|
config: cfg,
|
|
stdClient: &http.Client{},
|
|
}
|
|
}
|
|
|
|
func (p *WxpayPartner) MicroPay(req *MicroPayRequest) error {
|
|
params := make(Params)
|
|
params.Set("appid", p.config.AppId)
|
|
params.Set("mch_id", p.config.MchId)
|
|
params.Set("sub_mch_id", req.SubMchId)
|
|
params.Set("nonce_str", randomStr(32))
|
|
params.Set("body", req.GoodsName)
|
|
params.Set("out_trade_no", req.OutTradeNo)
|
|
params.Set("total_fee", req.TotalFee)
|
|
params.Set("auth_code", req.AuthCode)
|
|
|
|
if req.ServerIp == "" {
|
|
params.Set("spbill_create_ip", "113.248.223.215")
|
|
} else {
|
|
params.Set("spbill_create_ip", req.ServerIp)
|
|
}
|
|
|
|
if req.Attach != "" {
|
|
params.Set("attach", req.Attach)
|
|
}
|
|
if req.SubAppId != "" {
|
|
params.Set("sub_appid", req.SubAppId)
|
|
}
|
|
|
|
params.Set("sign", params.SignMd5(p.config.ApiKeyV2))
|
|
reqUrl := "https://api.mch.weixin.qq.com/pay/micropay"
|
|
body, err := p.post(reqUrl, params)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
result := make(Params)
|
|
result.Decode(body)
|
|
|
|
if result.GetString("return_code") != "SUCCESS" {
|
|
return errors.New(string(body))
|
|
}
|
|
|
|
if result.GetString("result_code") != "SUCCESS" {
|
|
if result.GetString("err_code") == "USERPAYING" {
|
|
return ErrUserPaying
|
|
}
|
|
return fmt.Errorf("%s:%s",
|
|
result.GetString("err_code"), result.GetString("err_code_des"))
|
|
}
|
|
return nil
|
|
}
|
|
|
|
// 发送请求
|
|
func (c *WxpayPartner) post(url string, params Params) ([]byte, error) {
|
|
var httpc *http.Client
|
|
|
|
httpc = c.stdClient
|
|
|
|
buf := bytes.NewBuffer(params.Encode())
|
|
resp, err := httpc.Post(url, "application/xml; charset=utf-8", buf)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
body, err := io.ReadAll(resp.Body)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return body, nil
|
|
}
|