437 lines
17 KiB
Go
437 lines
17 KiB
Go
|
package wechat
|
|||
|
|
|||
|
import (
|
|||
|
"context"
|
|||
|
"crypto/tls"
|
|||
|
"encoding/xml"
|
|||
|
"errors"
|
|||
|
"fmt"
|
|||
|
|
|||
|
"github.com/go-pay/gopay"
|
|||
|
"github.com/go-pay/gopay/pkg/util"
|
|||
|
"github.com/go-pay/gopay/pkg/xhttp"
|
|||
|
"github.com/go-pay/gopay/pkg/xlog"
|
|||
|
)
|
|||
|
|
|||
|
// 企业付款(企业向微信用户个人付款)
|
|||
|
// 注意:请在初始化client时,调用 client 添加证书的相关方法添加证书
|
|||
|
// 注意:此方法未支持沙箱环境,默认正式环境,转账请慎重
|
|||
|
// 文档地址:https://pay.weixin.qq.com/wiki/doc/api/tools/mch_pay.php?chapter=14_2
|
|||
|
func (w *Client) Transfer(ctx context.Context, bm gopay.BodyMap) (wxRsp *TransfersResponse, err error) {
|
|||
|
if err = bm.CheckEmptyError("nonce_str", "partner_trade_no", "openid", "check_name", "amount", "desc", "spbill_create_ip"); err != nil {
|
|||
|
return nil, err
|
|||
|
}
|
|||
|
bm.Set("mch_appid", w.AppId)
|
|||
|
bm.Set("mchid", w.MchId)
|
|||
|
var (
|
|||
|
tlsConfig *tls.Config
|
|||
|
url = baseUrlCh + transfers
|
|||
|
)
|
|||
|
if tlsConfig, err = w.addCertConfig(nil, nil, nil); err != nil {
|
|||
|
return nil, err
|
|||
|
}
|
|||
|
bm.Set("sign", w.getReleaseSign(w.ApiKey, SignType_MD5, bm))
|
|||
|
|
|||
|
httpClient := xhttp.NewClient().SetTLSConfig(tlsConfig).Type(xhttp.TypeXML)
|
|||
|
if w.BaseURL != util.NULL {
|
|||
|
w.mu.RLock()
|
|||
|
url = w.BaseURL + transfers
|
|||
|
w.mu.RUnlock()
|
|||
|
}
|
|||
|
req := GenerateXml(bm)
|
|||
|
if w.DebugSwitch == gopay.DebugOn {
|
|||
|
xlog.Debugf("Wechat_Request: %s", req)
|
|||
|
}
|
|||
|
res, bs, err := httpClient.Post(url).SendString(req).EndBytes(ctx)
|
|||
|
if err != nil {
|
|||
|
return nil, err
|
|||
|
}
|
|||
|
if w.DebugSwitch == gopay.DebugOn {
|
|||
|
xlog.Debugf("Wechat_Response: %s%d %s%s", xlog.Red, res.StatusCode, xlog.Reset, string(bs))
|
|||
|
}
|
|||
|
if res.StatusCode != 200 {
|
|||
|
return nil, fmt.Errorf("HTTP Request Error, StatusCode = %d", res.StatusCode)
|
|||
|
}
|
|||
|
wxRsp = new(TransfersResponse)
|
|||
|
if err = xml.Unmarshal(bs, wxRsp); err != nil {
|
|||
|
return nil, fmt.Errorf("[%w]: %v, bytes: %s", gopay.UnmarshalErr, err, string(bs))
|
|||
|
}
|
|||
|
return wxRsp, nil
|
|||
|
}
|
|||
|
|
|||
|
// 查询企业付款
|
|||
|
// 注意:请在初始化client时,调用 client 添加证书的相关方法添加证书
|
|||
|
// 注意:此方法未支持沙箱环境,默认正式环境
|
|||
|
// 文档地址:https://pay.weixin.qq.com/wiki/doc/api/tools/mch_pay.php?chapter=14_3
|
|||
|
func (w *Client) GetTransferInfo(ctx context.Context, bm gopay.BodyMap) (wxRsp *TransfersInfoResponse, err error) {
|
|||
|
if err = bm.CheckEmptyError("nonce_str", "partner_trade_no"); err != nil {
|
|||
|
return nil, err
|
|||
|
}
|
|||
|
bm.Set("appid", w.AppId)
|
|||
|
bm.Set("mch_id", w.MchId)
|
|||
|
var (
|
|||
|
tlsConfig *tls.Config
|
|||
|
url = baseUrlCh + getTransferInfo
|
|||
|
)
|
|||
|
if tlsConfig, err = w.addCertConfig(nil, nil, nil); err != nil {
|
|||
|
return nil, err
|
|||
|
}
|
|||
|
bm.Set("sign", w.getReleaseSign(w.ApiKey, SignType_MD5, bm))
|
|||
|
|
|||
|
httpClient := xhttp.NewClient().SetTLSConfig(tlsConfig).Type(xhttp.TypeXML)
|
|||
|
if w.BaseURL != util.NULL {
|
|||
|
w.mu.RLock()
|
|||
|
url = w.BaseURL + getTransferInfo
|
|||
|
w.mu.RUnlock()
|
|||
|
}
|
|||
|
req := GenerateXml(bm)
|
|||
|
if w.DebugSwitch == gopay.DebugOn {
|
|||
|
xlog.Debugf("Wechat_Request: %s", req)
|
|||
|
}
|
|||
|
res, bs, err := httpClient.Post(url).SendString(req).EndBytes(ctx)
|
|||
|
if err != nil {
|
|||
|
return nil, err
|
|||
|
}
|
|||
|
if w.DebugSwitch == gopay.DebugOn {
|
|||
|
xlog.Debugf("Wechat_Response: %s%d %s%s", xlog.Red, res.StatusCode, xlog.Reset, string(bs))
|
|||
|
}
|
|||
|
if res.StatusCode != 200 {
|
|||
|
return nil, fmt.Errorf("HTTP Request Error, StatusCode = %d", res.StatusCode)
|
|||
|
}
|
|||
|
wxRsp = new(TransfersInfoResponse)
|
|||
|
if err = xml.Unmarshal(bs, wxRsp); err != nil {
|
|||
|
return nil, fmt.Errorf("[%w]: %v, bytes: %s", gopay.UnmarshalErr, err, string(bs))
|
|||
|
}
|
|||
|
return wxRsp, nil
|
|||
|
}
|
|||
|
|
|||
|
// 企业付款到银行卡API(正式)
|
|||
|
// 注意:请在初始化client时,调用 client 添加证书的相关方法添加证书
|
|||
|
// 注意:此方法未支持沙箱环境,默认正式环境,转账请慎重
|
|||
|
// 注意:enc_bank_no、enc_true_name 两参数,开发者需自行获取RSA公钥,加密后再 Set 到 BodyMap,参考 client_test.go 里的 TestClient_PayBank() 方法
|
|||
|
// 文档地址:https://pay.weixin.qq.com/wiki/doc/api/tools/mch_pay.php?chapter=24_2
|
|||
|
// RSA加密文档地址:https://pay.weixin.qq.com/wiki/doc/api/tools/mch_pay.php?chapter=24_7
|
|||
|
// 银行编码查看地址:https://pay.weixin.qq.com/wiki/doc/api/tools/mch_pay.php?chapter=24_4&index=5
|
|||
|
func (w *Client) PayBank(ctx context.Context, bm gopay.BodyMap) (wxRsp *PayBankResponse, err error) {
|
|||
|
if err = bm.CheckEmptyError("partner_trade_no", "nonce_str", "enc_bank_no", "enc_true_name", "bank_code", "amount"); err != nil {
|
|||
|
return nil, err
|
|||
|
}
|
|||
|
bm.Set("mch_id", w.MchId)
|
|||
|
var (
|
|||
|
tlsConfig *tls.Config
|
|||
|
url = baseUrlCh + payBank
|
|||
|
)
|
|||
|
if tlsConfig, err = w.addCertConfig(nil, nil, nil); err != nil {
|
|||
|
return nil, err
|
|||
|
}
|
|||
|
bm.Set("sign", w.getReleaseSign(w.ApiKey, SignType_MD5, bm))
|
|||
|
|
|||
|
httpClient := xhttp.NewClient().SetTLSConfig(tlsConfig).Type(xhttp.TypeXML)
|
|||
|
if w.BaseURL != util.NULL {
|
|||
|
w.mu.RLock()
|
|||
|
url = w.BaseURL + payBank
|
|||
|
w.mu.RUnlock()
|
|||
|
}
|
|||
|
req := GenerateXml(bm)
|
|||
|
if w.DebugSwitch == gopay.DebugOn {
|
|||
|
xlog.Debugf("Wechat_Request: %s", req)
|
|||
|
}
|
|||
|
res, bs, err := httpClient.Post(url).SendString(req).EndBytes(ctx)
|
|||
|
if err != nil {
|
|||
|
return nil, err
|
|||
|
}
|
|||
|
if w.DebugSwitch == gopay.DebugOn {
|
|||
|
xlog.Debugf("Wechat_Response: %s%d %s%s", xlog.Red, res.StatusCode, xlog.Reset, string(bs))
|
|||
|
}
|
|||
|
if res.StatusCode != 200 {
|
|||
|
return nil, fmt.Errorf("HTTP Request Error, StatusCode = %d", res.StatusCode)
|
|||
|
}
|
|||
|
wxRsp = new(PayBankResponse)
|
|||
|
if err = xml.Unmarshal(bs, wxRsp); err != nil {
|
|||
|
return nil, fmt.Errorf("[%w]: %v, bytes: %s", gopay.UnmarshalErr, err, string(bs))
|
|||
|
}
|
|||
|
return wxRsp, nil
|
|||
|
}
|
|||
|
|
|||
|
// 查询企业付款到银行卡API(正式)
|
|||
|
// 注意:请在初始化client时,调用 client 添加证书的相关方法添加证书
|
|||
|
// 文档地址:https://pay.weixin.qq.com/wiki/doc/api/tools/mch_pay.php?chapter=24_3
|
|||
|
func (w *Client) QueryBank(ctx context.Context, bm gopay.BodyMap) (wxRsp *QueryBankResponse, err error) {
|
|||
|
if err = bm.CheckEmptyError("nonce_str", "partner_trade_no"); err != nil {
|
|||
|
return nil, err
|
|||
|
}
|
|||
|
bm.Set("mch_id", w.MchId)
|
|||
|
var (
|
|||
|
tlsConfig *tls.Config
|
|||
|
url = baseUrlCh + queryBank
|
|||
|
)
|
|||
|
if tlsConfig, err = w.addCertConfig(nil, nil, nil); err != nil {
|
|||
|
return nil, err
|
|||
|
}
|
|||
|
bm.Set("sign", w.getReleaseSign(w.ApiKey, SignType_MD5, bm))
|
|||
|
|
|||
|
httpClient := xhttp.NewClient().SetTLSConfig(tlsConfig).Type(xhttp.TypeXML)
|
|||
|
if w.BaseURL != util.NULL {
|
|||
|
w.mu.RLock()
|
|||
|
url = w.BaseURL + queryBank
|
|||
|
w.mu.RUnlock()
|
|||
|
}
|
|||
|
req := GenerateXml(bm)
|
|||
|
if w.DebugSwitch == gopay.DebugOn {
|
|||
|
xlog.Debugf("Wechat_Request: %s", req)
|
|||
|
}
|
|||
|
res, bs, err := httpClient.Post(url).SendString(req).EndBytes(ctx)
|
|||
|
if err != nil {
|
|||
|
return nil, err
|
|||
|
}
|
|||
|
if w.DebugSwitch == gopay.DebugOn {
|
|||
|
xlog.Debugf("Wechat_Response: %s%d %s%s", xlog.Red, res.StatusCode, xlog.Reset, string(bs))
|
|||
|
}
|
|||
|
if res.StatusCode != 200 {
|
|||
|
return nil, fmt.Errorf("HTTP Request Error, StatusCode = %d", res.StatusCode)
|
|||
|
}
|
|||
|
wxRsp = new(QueryBankResponse)
|
|||
|
if err = xml.Unmarshal(bs, wxRsp); err != nil {
|
|||
|
return nil, fmt.Errorf("[%w]: %v, bytes: %s", gopay.UnmarshalErr, err, string(bs))
|
|||
|
}
|
|||
|
return wxRsp, nil
|
|||
|
}
|
|||
|
|
|||
|
// 获取RSA加密公钥API(正式)
|
|||
|
// 注意:请在初始化client时,调用 client 添加证书的相关方法添加证书
|
|||
|
// 文档地址:https://pay.weixin.qq.com/wiki/doc/api/tools/mch_pay.php?chapter=24_7&index=4
|
|||
|
func (w *Client) GetRSAPublicKey(ctx context.Context, bm gopay.BodyMap) (wxRsp *RSAPublicKeyResponse, err error) {
|
|||
|
if err = bm.CheckEmptyError("nonce_str", "sign_type"); err != nil {
|
|||
|
return nil, err
|
|||
|
}
|
|||
|
bm.Set("mch_id", w.MchId)
|
|||
|
var (
|
|||
|
tlsConfig *tls.Config
|
|||
|
url = getPublicKey
|
|||
|
)
|
|||
|
if tlsConfig, err = w.addCertConfig(nil, nil, nil); err != nil {
|
|||
|
return nil, err
|
|||
|
}
|
|||
|
bm.Set("sign", w.getReleaseSign(w.ApiKey, bm.GetString("sign_type"), bm))
|
|||
|
|
|||
|
httpClient := xhttp.NewClient().SetTLSConfig(tlsConfig).Type(xhttp.TypeXML)
|
|||
|
req := GenerateXml(bm)
|
|||
|
if w.DebugSwitch == gopay.DebugOn {
|
|||
|
xlog.Debugf("Wechat_Request: %s", req)
|
|||
|
}
|
|||
|
res, bs, err := httpClient.Post(url).SendString(req).EndBytes(ctx)
|
|||
|
if err != nil {
|
|||
|
return nil, err
|
|||
|
}
|
|||
|
if w.DebugSwitch == gopay.DebugOn {
|
|||
|
xlog.Debugf("Wechat_Response: %s%d %s%s", xlog.Red, res.StatusCode, xlog.Reset, string(bs))
|
|||
|
}
|
|||
|
if res.StatusCode != 200 {
|
|||
|
return nil, fmt.Errorf("HTTP Request Error, StatusCode = %d", res.StatusCode)
|
|||
|
}
|
|||
|
wxRsp = new(RSAPublicKeyResponse)
|
|||
|
if err = xml.Unmarshal(bs, wxRsp); err != nil {
|
|||
|
return nil, fmt.Errorf("[%w]: %v, bytes: %s", gopay.UnmarshalErr, err, string(bs))
|
|||
|
}
|
|||
|
return wxRsp, nil
|
|||
|
}
|
|||
|
|
|||
|
// 请求单次分账
|
|||
|
// 单次分账请求按照传入的分账接收方账号和资金进行分账,
|
|||
|
// 同时会将订单剩余的待分账金额解冻给本商户。
|
|||
|
// 故操作成功后,订单不能再进行分账,也不能进行分账完结。
|
|||
|
// 注意:请在初始化client时,调用 client 添加证书的相关方法添加证书
|
|||
|
// 文档地址:https://pay.weixin.qq.com/wiki/doc/api/allocation.php?chapter=27_1&index=1
|
|||
|
func (w *Client) ProfitSharing(ctx context.Context, bm gopay.BodyMap) (wxRsp *ProfitSharingResponse, err error) {
|
|||
|
return w.profitSharing(ctx, bm, profitSharing)
|
|||
|
}
|
|||
|
|
|||
|
// 请求多次分账
|
|||
|
// 微信订单支付成功后,商户发起分账请求,将结算后的钱分到分账接收方。多次分账请求仅会按照传入的分账接收方进行分账,不会对剩余的金额进行任何操作。
|
|||
|
// 故操作成功后,在待分账金额不等于零时,订单依旧能够再次进行分账。
|
|||
|
// 多次分账,可以将本商户作为分账接收方直接传入,实现释放资金给本商户的功能
|
|||
|
// 对同一笔订单最多能发起20次多次分账请求
|
|||
|
// 注意:请在初始化client时,调用 client 添加证书的相关方法添加证书
|
|||
|
// 文档地址:https://pay.weixin.qq.com/wiki/doc/api/allocation.php?chapter=27_1&index=1
|
|||
|
func (w *Client) MultiProfitSharing(ctx context.Context, bm gopay.BodyMap) (wxRsp *ProfitSharingResponse, err error) {
|
|||
|
return w.profitSharing(ctx, bm, multiProfitSharing)
|
|||
|
}
|
|||
|
|
|||
|
func (w *Client) profitSharing(ctx context.Context, bm gopay.BodyMap, uri string) (wxRsp *ProfitSharingResponse, err error) {
|
|||
|
err = bm.CheckEmptyError("nonce_str", "transaction_id", "out_order_no", "receivers")
|
|||
|
if err != nil {
|
|||
|
return nil, err
|
|||
|
}
|
|||
|
|
|||
|
// 设置签名类型,官方文档此接口只支持 HMAC_SHA256
|
|||
|
bm.Set("sign_type", SignType_HMAC_SHA256)
|
|||
|
tlsConfig, err := w.addCertConfig(nil, nil, nil)
|
|||
|
if err != nil {
|
|||
|
return nil, err
|
|||
|
}
|
|||
|
bs, err := w.doProdPost(ctx, bm, uri, tlsConfig)
|
|||
|
if err != nil {
|
|||
|
return nil, err
|
|||
|
}
|
|||
|
wxRsp = new(ProfitSharingResponse)
|
|||
|
if err = xml.Unmarshal(bs, wxRsp); err != nil {
|
|||
|
return nil, fmt.Errorf("[%w]: %v, bytes: %s", gopay.UnmarshalErr, err, string(bs))
|
|||
|
}
|
|||
|
return wxRsp, nil
|
|||
|
}
|
|||
|
|
|||
|
// 查询分账结果
|
|||
|
// 发起分账请求后,可调用此接口查询分账结果;发起分账完结请求后,可调用此接口查询分账完结的执行结果。
|
|||
|
// 微信文档:https://pay.weixin.qq.com/wiki/doc/api/allocation.php?chapter=27_2&index=3
|
|||
|
func (w *Client) ProfitSharingQuery(ctx context.Context, bm gopay.BodyMap) (wxRsp *ProfitSharingQueryResponse, err error) {
|
|||
|
err = bm.CheckEmptyError("transaction_id", "out_order_no", "nonce_str")
|
|||
|
if err != nil {
|
|||
|
return nil, err
|
|||
|
}
|
|||
|
// 设置签名类型,官方文档此接口只支持 HMAC_SHA256
|
|||
|
bm.Set("sign_type", SignType_HMAC_SHA256)
|
|||
|
bm.Set("mch_id", w.MchId)
|
|||
|
if bm.GetString("sign") == util.NULL {
|
|||
|
sign := w.getReleaseSign(w.ApiKey, bm.GetString("sign_type"), bm)
|
|||
|
bm.Set("sign", sign)
|
|||
|
}
|
|||
|
bs, err := w.doProdPostPure(ctx, bm, profitSharingQuery, nil)
|
|||
|
if err != nil {
|
|||
|
return nil, err
|
|||
|
}
|
|||
|
wxRsp = new(ProfitSharingQueryResponse)
|
|||
|
if err = xml.Unmarshal(bs, wxRsp); err != nil {
|
|||
|
return nil, fmt.Errorf("[%w]: %v, bytes: %s", gopay.UnmarshalErr, err, string(bs))
|
|||
|
}
|
|||
|
return wxRsp, nil
|
|||
|
}
|
|||
|
|
|||
|
// 添加分账接收方
|
|||
|
// 商户发起添加分账接收方请求,后续可通过发起分账请求将结算后的钱分到该分账接收方。
|
|||
|
// 微信文档:https://pay.weixin.qq.com/wiki/doc/api/allocation.php?chapter=27_3&index=4
|
|||
|
func (w *Client) ProfitSharingAddReceiver(ctx context.Context, bm gopay.BodyMap) (wxRsp *ProfitSharingAddReceiverResponse, err error) {
|
|||
|
err = bm.CheckEmptyError("nonce_str", "receiver")
|
|||
|
if err != nil {
|
|||
|
return nil, err
|
|||
|
}
|
|||
|
// 设置签名类型,官方文档此接口只支持 HMAC_SHA256
|
|||
|
bm.Set("sign_type", SignType_HMAC_SHA256)
|
|||
|
bs, err := w.doProdPost(ctx, bm, profitSharingAddReceiver, nil)
|
|||
|
if err != nil {
|
|||
|
return nil, err
|
|||
|
}
|
|||
|
wxRsp = new(ProfitSharingAddReceiverResponse)
|
|||
|
if err = xml.Unmarshal(bs, wxRsp); err != nil {
|
|||
|
return nil, fmt.Errorf("[%w]: %v, bytes: %s", gopay.UnmarshalErr, err, string(bs))
|
|||
|
}
|
|||
|
return wxRsp, nil
|
|||
|
}
|
|||
|
|
|||
|
// 删除分账接收方
|
|||
|
// 商户发起删除分账接收方请求,删除后不支持将结算后的钱分到该分账接收方
|
|||
|
// 微信文档:https://pay.weixin.qq.com/wiki/doc/api/allocation.php?chapter=27_4&index=5
|
|||
|
func (w *Client) ProfitSharingRemoveReceiver(ctx context.Context, bm gopay.BodyMap) (wxRsp *ProfitSharingAddReceiverResponse, err error) {
|
|||
|
err = bm.CheckEmptyError("nonce_str", "receiver")
|
|||
|
if err != nil {
|
|||
|
return nil, err
|
|||
|
}
|
|||
|
// 设置签名类型,官方文档此接口只支持 HMAC_SHA256
|
|||
|
bm.Set("sign_type", SignType_HMAC_SHA256)
|
|||
|
bs, err := w.doProdPost(ctx, bm, profitSharingRemoveReceiver, nil)
|
|||
|
if err != nil {
|
|||
|
return nil, err
|
|||
|
}
|
|||
|
wxRsp = new(ProfitSharingAddReceiverResponse)
|
|||
|
if err = xml.Unmarshal(bs, wxRsp); err != nil {
|
|||
|
return nil, fmt.Errorf("[%w]: %v, bytes: %s", gopay.UnmarshalErr, err, string(bs))
|
|||
|
}
|
|||
|
return wxRsp, nil
|
|||
|
}
|
|||
|
|
|||
|
// 完结分账
|
|||
|
// 1、不需要进行分账的订单,可直接调用本接口将订单的金额全部解冻给本商户
|
|||
|
// 2、调用多次分账接口后,需要解冻剩余资金时,调用本接口将剩余的分账金额全部解冻给特约商户
|
|||
|
// 3、已调用请求单次分账后,剩余待分账金额为零,不需要再调用此接口。
|
|||
|
// 注意:请在初始化client时,调用 client 添加证书的相关方法添加证书
|
|||
|
// 微信文档:https://pay.weixin.qq.com/wiki/doc/api/allocation.php?chapter=27_5&index=6
|
|||
|
func (w *Client) ProfitSharingFinish(ctx context.Context, bm gopay.BodyMap) (wxRsp *ProfitSharingResponse, err error) {
|
|||
|
err = bm.CheckEmptyError("nonce_str", "transaction_id", "out_order_no", "description")
|
|||
|
if err != nil {
|
|||
|
return nil, err
|
|||
|
}
|
|||
|
// 设置签名类型,官方文档此接口只支持 HMAC_SHA256
|
|||
|
bm.Set("sign_type", SignType_HMAC_SHA256)
|
|||
|
tlsConfig, err := w.addCertConfig(nil, nil, nil)
|
|||
|
if err != nil {
|
|||
|
return nil, err
|
|||
|
}
|
|||
|
bs, err := w.doProdPost(ctx, bm, profitSharingFinish, tlsConfig)
|
|||
|
if err != nil {
|
|||
|
return nil, err
|
|||
|
}
|
|||
|
wxRsp = new(ProfitSharingResponse)
|
|||
|
if err = xml.Unmarshal(bs, wxRsp); err != nil {
|
|||
|
return nil, fmt.Errorf("[%w]: %v, bytes: %s", gopay.UnmarshalErr, err, string(bs))
|
|||
|
}
|
|||
|
return wxRsp, nil
|
|||
|
}
|
|||
|
|
|||
|
// 分账回退
|
|||
|
// 对订单进行退款时,如果订单已经分账,可以先调用此接口将指定的金额从分账接收方(仅限商户类型的分账接收方)回退给本商户,然后再退款。
|
|||
|
// 回退以原分账请求为依据,可以对分给分账接收方的金额进行多次回退,只要满足累计回退不超过该请求中分给接收方的金额。
|
|||
|
// 此接口采用同步处理模式,即在接收到商户请求后,会实时返回处理结果
|
|||
|
// 此功能需要接收方在商户平台-交易中心-分账-分账接收设置下,开启同意分账回退后,才能使用。
|
|||
|
// 注意:请在初始化client时,调用 client 添加证书的相关方法添加证书
|
|||
|
// 微信文档:https://pay.weixin.qq.com/wiki/doc/api/allocation.php?chapter=27_7&index=7
|
|||
|
func (w *Client) ProfitSharingReturn(ctx context.Context, bm gopay.BodyMap) (wxRsp *ProfitSharingReturnResponse, err error) {
|
|||
|
err = bm.CheckEmptyError("nonce_str", "out_return_no", "return_account_type", "return_account", "return_amount", "description")
|
|||
|
if err != nil {
|
|||
|
return nil, err
|
|||
|
}
|
|||
|
|
|||
|
if (bm.GetString("order_id") == util.NULL) && (bm.GetString("out_order_no") == util.NULL) {
|
|||
|
return nil, errors.New("param order_id and out_order_no can not be null at the same time")
|
|||
|
}
|
|||
|
// 设置签名类型,官方文档此接口只支持 HMAC_SHA256
|
|||
|
bm.Set("sign_type", SignType_HMAC_SHA256)
|
|||
|
tlsConfig, err := w.addCertConfig(nil, nil, nil)
|
|||
|
if err != nil {
|
|||
|
return nil, err
|
|||
|
}
|
|||
|
bs, err := w.doProdPost(ctx, bm, profitSharingReturn, tlsConfig)
|
|||
|
if err != nil {
|
|||
|
return nil, err
|
|||
|
}
|
|||
|
wxRsp = new(ProfitSharingReturnResponse)
|
|||
|
if err = xml.Unmarshal(bs, wxRsp); err != nil {
|
|||
|
return nil, fmt.Errorf("[%w]: %v, bytes: %s", gopay.UnmarshalErr, err, string(bs))
|
|||
|
}
|
|||
|
return wxRsp, nil
|
|||
|
}
|
|||
|
|
|||
|
// 回退结果查询
|
|||
|
// 商户需要核实回退结果,可调用此接口查询回退结果。
|
|||
|
// 如果分账回退接口返回状态为处理中,可调用此接口查询回退结果
|
|||
|
// 微信文档:https://pay.weixin.qq.com/wiki/doc/api/allocation.php?chapter=27_8&index=8
|
|||
|
func (w *Client) ProfitSharingReturnQuery(ctx context.Context, bm gopay.BodyMap) (wxRsp *ProfitSharingReturnResponse, err error) {
|
|||
|
err = bm.CheckEmptyError("nonce_str", "out_return_no")
|
|||
|
if err != nil {
|
|||
|
return nil, err
|
|||
|
}
|
|||
|
|
|||
|
if (bm.GetString("order_id") == util.NULL) && (bm.GetString("out_order_no") == util.NULL) {
|
|||
|
return nil, errors.New("param order_id and out_order_no can not be null at the same time")
|
|||
|
}
|
|||
|
// 设置签名类型,官方文档此接口只支持 HMAC_SHA256
|
|||
|
bm.Set("sign_type", SignType_HMAC_SHA256)
|
|||
|
bs, err := w.doProdPost(ctx, bm, profitSharingReturnQuery, nil)
|
|||
|
if err != nil {
|
|||
|
return nil, err
|
|||
|
}
|
|||
|
wxRsp = new(ProfitSharingReturnResponse)
|
|||
|
if err = xml.Unmarshal(bs, wxRsp); err != nil {
|
|||
|
return nil, fmt.Errorf("[%w]: %v, bytes: %s", gopay.UnmarshalErr, err, string(bs))
|
|||
|
}
|
|||
|
return wxRsp, nil
|
|||
|
}
|