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 }