diff --git a/doc/wechat_v2.md b/doc/wechat_v2.md index cf3636a6..5022dd92 100644 --- a/doc/wechat_v2.md +++ b/doc/wechat_v2.md @@ -245,6 +245,8 @@ return c.String(http.StatusOK, rsp.ToXmlString()) * 请求单次分账(正式):`client.ProfitSharing()` * 请求多次分账(正式):`client.MultiProfitSharing()` * 查询分账结果(正式):`client.ProfitSharingQuery()` +* 查询订单待分账金额 (正式):`client.ProfitSharingOrderAmountQuery()` +* 查询最大分账比例 (正式):`client.ProfitSharingMerchantRatioQuery()` * 添加分账接收方(正式):`client.ProfitSharingAddReceiver()` * 删除分账接收方(正式):`client.ProfitSharingRemoveReceiver()` * 完结分账(正式):`client.ProfitSharingFinish()` diff --git a/wechat/constant.go b/wechat/constant.go index ba3b4424..97c0a133 100644 --- a/wechat/constant.go +++ b/wechat/constant.go @@ -14,42 +14,44 @@ const ( baseUrlUs = "https://apius.mch.weixin.qq.com" // 其他 // 正式 - microPay = "/pay/micropay" // 提交付款码支付 - unifiedOrder = "/pay/unifiedorder" // 统一下单 - orderQuery = "/pay/orderquery" // 查询订单 - closeOrder = "/pay/closeorder" // 关闭订单 - refund = "/secapi/pay/refund" // 申请退款 - reverse = "/secapi/pay/reverse" // 撤销订单 - refundQuery = "/pay/refundquery" // 查询退款 - downloadBill = "/pay/downloadbill" // 下载对账单 - downloadFundFlow = "/pay/downloadfundflow" // 下载资金账单 - report = "/payitil/report" // 交易保障 - batchQueryComment = "/billcommentsp/batchquerycomment" // 拉取订单评价数据 - transfers = "/mmpaymkttransfers/promotion/transfers" // 企业付款(企业向微信用户个人付款) - getTransferInfo = "/mmpaymkttransfers/gettransferinfo" // 查询企业付款 - sendCashRed = "/mmpaymkttransfers/sendredpack" // 发放现金红包 - sendAppletRed = "/mmpaymkttransfers/sendminiprogramhb" // 发放小程序红包 - sendGroupCashRed = "/mmpaymkttransfers/sendgroupredpack" // 发放裂变红包 - getRedRecord = "/mmpaymkttransfers/gethbinfo" // 查询红包记录 - authCodeToOpenid = "/tools/authcodetoopenid" // 授权码查询openid - entrustPublic = "/papay/entrustweb" // 公众号纯签约 - entrustApp = "/papay/preentrustweb" // APP纯签约 - entrustH5 = "/papay/h5entrustweb" // H5纯签约 - entrustPaying = "/pay/contractorder" // 支付中签约 - entrustQuery = "/papay/querycontract" // 查询签约关系 - entrustApplyPay = "/pay/pappayapply" // 申请扣款 - entrustDelete = "/papay/deletecontract" // 申请解约 - profitSharing = "/secapi/pay/profitsharing" // 请求单次分账 - multiProfitSharing = "/secapi/pay/multiprofitsharing" // 请求多次分账 - profitSharingQuery = "/pay/profitsharingquery" // 查询分账结果 - profitSharingAddReceiver = "/pay/profitsharingaddreceiver" // 添加分账接收方 - profitSharingRemoveReceiver = "/pay/profitsharingremovereceiver" // 删除分账接收方 - profitSharingFinish = "/secapi/pay/profitsharingfinish" // 完结分账 - profitSharingReturn = "/secapi/pay/profitsharingreturn" // 分账退回 - profitSharingReturnQuery = "/pay/profitsharingreturnquery" // 分账回退结果查询 - payBank = "/mmpaysptrans/pay_bank" // 企业付款到银行卡API - queryBank = "/mmpaysptrans/query_bank" // 查询企业付款到银行卡API - getPublicKey = "https://fraud.mch.weixin.qq.com/risk/getpublickey" // 获取RSA加密公钥API + microPay = "/pay/micropay" // 提交付款码支付 + unifiedOrder = "/pay/unifiedorder" // 统一下单 + orderQuery = "/pay/orderquery" // 查询订单 + closeOrder = "/pay/closeorder" // 关闭订单 + refund = "/secapi/pay/refund" // 申请退款 + reverse = "/secapi/pay/reverse" // 撤销订单 + refundQuery = "/pay/refundquery" // 查询退款 + downloadBill = "/pay/downloadbill" // 下载对账单 + downloadFundFlow = "/pay/downloadfundflow" // 下载资金账单 + report = "/payitil/report" // 交易保障 + batchQueryComment = "/billcommentsp/batchquerycomment" // 拉取订单评价数据 + transfers = "/mmpaymkttransfers/promotion/transfers" // 企业付款(企业向微信用户个人付款) + getTransferInfo = "/mmpaymkttransfers/gettransferinfo" // 查询企业付款 + sendCashRed = "/mmpaymkttransfers/sendredpack" // 发放现金红包 + sendAppletRed = "/mmpaymkttransfers/sendminiprogramhb" // 发放小程序红包 + sendGroupCashRed = "/mmpaymkttransfers/sendgroupredpack" // 发放裂变红包 + getRedRecord = "/mmpaymkttransfers/gethbinfo" // 查询红包记录 + authCodeToOpenid = "/tools/authcodetoopenid" // 授权码查询openid + entrustPublic = "/papay/entrustweb" // 公众号纯签约 + entrustApp = "/papay/preentrustweb" // APP纯签约 + entrustH5 = "/papay/h5entrustweb" // H5纯签约 + entrustPaying = "/pay/contractorder" // 支付中签约 + entrustQuery = "/papay/querycontract" // 查询签约关系 + entrustApplyPay = "/pay/pappayapply" // 申请扣款 + entrustDelete = "/papay/deletecontract" // 申请解约 + profitSharing = "/secapi/pay/profitsharing" // 请求单次分账 + multiProfitSharing = "/secapi/pay/multiprofitsharing" // 请求多次分账 + profitSharingQuery = "/pay/profitsharingquery" // 查询分账结果 + profitSharingAddReceiver = "/pay/profitsharingaddreceiver" // 添加分账接收方 + profitSharingRemoveReceiver = "/pay/profitsharingremovereceiver" // 删除分账接收方 + profitSharingFinish = "/secapi/pay/profitsharingfinish" // 完结分账 + profitSharingOrderAmountQuery = "/pay/profitsharingorderamountquery" // 查询订单待分账金额 + profitSharingMerchantRatioQuery = "/pay/profitsharingmerchantratioquery" // 查询最大分账比例 + profitSharingReturn = "/secapi/pay/profitsharingreturn" // 分账退回 + profitSharingReturnQuery = "/pay/profitsharingreturnquery" // 分账回退结果查询 + payBank = "/mmpaysptrans/pay_bank" // 企业付款到银行卡API + queryBank = "/mmpaysptrans/query_bank" // 查询企业付款到银行卡API + getPublicKey = "https://fraud.mch.weixin.qq.com/risk/getpublickey" // 获取RSA加密公钥API // 海关自助清关 customsDeclareOrder = "/cgi-bin/mch/customs/customdeclareorder" // 订单附加信息提交 diff --git a/wechat/merchant.go b/wechat/merchant.go index db802cdd..7ff81ae7 100644 --- a/wechat/merchant.go +++ b/wechat/merchant.go @@ -341,6 +341,52 @@ func (w *Client) ProfitSharingFinish(ctx context.Context, bm gopay.BodyMap) (wxR return wxRsp, nil } +// 服务商可通过调用此接口查询订单剩余待分金额 +// 接口频率:30QPS +// 微信文档:https://pay.weixin.qq.com/wiki/doc/api/allocation_sl.php?chapter=25_10&index=7 +func (w *Client) ProfitSharingOrderAmountQuery(ctx context.Context, bm gopay.BodyMap) (wxRsp *ProfitSharingOrderAmountQueryResponse, err error) { + err = bm.CheckEmptyError("mch_id", "transaction_id", "nonce_str") + if err != nil { + return nil, err + } + + // 设置签名类型,官方文档此接口只支持 HMAC_SHA256 + bm.Set("sign_type", SignType_HMAC_SHA256) + bs, err := w.doProdPostTLS(ctx, bm, profitSharingOrderAmountQuery) + if err != nil { + return nil, err + } + wxRsp = new(ProfitSharingOrderAmountQueryResponse) + if err = xml.Unmarshal(bs, wxRsp); err != nil { + return nil, fmt.Errorf("[%w]: %v, bytes: %s", gopay.UnmarshalErr, err, string(bs)) + } + return wxRsp, nil +} + +// 服务商可以查询子商户设置的允许服务商分账的最大比例 +// 接口频率:30QPS +// 微信文档:https://pay.weixin.qq.com/wiki/doc/api/allocation_sl.php?chapter=25_10&index=7 +func (w *Client) ProfitSharingMerchantRatioQuery(ctx context.Context, bm gopay.BodyMap) (wxRsp *ProfitSharingMerchanTratioQuery, err error) { + err = bm.CheckEmptyError("mch_id", "nonce_str") + if err != nil { + return nil, err + } + if (bm.GetString("sub_mch_id") == gopay.NULL) && (bm.GetString("brand_mch_id") == gopay.NULL) { + return nil, errors.New("param sub_mch_id and brand_mch_id can not be null at the same time") + } + // 设置签名类型,官方文档此接口只支持 HMAC_SHA256 + bm.Set("sign_type", SignType_HMAC_SHA256) + bs, err := w.doProdPostTLS(ctx, bm, profitSharingMerchantRatioQuery) + if err != nil { + return nil, err + } + wxRsp = new(ProfitSharingMerchanTratioQuery) + if err = xml.Unmarshal(bs, wxRsp); err != nil { + return nil, fmt.Errorf("[%w]: %v, bytes: %s", gopay.UnmarshalErr, err, string(bs)) + } + return wxRsp, nil +} + // 分账回退 // 对订单进行退款时,如果订单已经分账,可以先调用此接口将指定的金额从分账接收方(仅限商户类型的分账接收方)回退给本商户,然后再退款。 // 回退以原分账请求为依据,可以对分给分账接收方的金额进行多次回退,只要满足累计回退不超过该请求中分给接收方的金额。 diff --git a/wechat/model.go b/wechat/model.go index 80f43dc6..6db93557 100644 --- a/wechat/model.go +++ b/wechat/model.go @@ -685,6 +685,33 @@ type ProfitSharingReturnResponse struct { FinishTime string `xml:"finish_time,omitempty" json:"finish_time,omitempty"` // 完成时间 } +// ProfitSharingOrderAmountQueryResponse 查询订单待分账金额响应结果 +type ProfitSharingOrderAmountQueryResponse struct { + ReturnCode string `xml:"return_code,omitempty" json:"return_code,omitempty"` // 返回状态码 SUCCESS/FAIL 此字段是通信标识,非交易标识 + ErrCode string `xml:"err_code,omitempty" json:"err_code,omitempty"` // 错误代码 + ErrorMsg string `xml:"error_msg,omitempty" json:"error_msg,omitempty"` // 返回信息 如果返回状态码为FAIL,则本字段存在,且为失败的错误信息 + ErrCodeDes string `xml:"err_code_des,omitempty" json:"err_code_des,omitempty"` // 错误代码描述 + MchId string `xml:"mch_id,omitempty" json:"mch_id,omitempty"` //调用接口时提供的服务商户号 + TransactionId string `xml:"transaction_id,omitempty" json:"transaction_id,omitempty"` //微信支付订单号 + UnsplitAmount int `xml:"unsplit_amount,omitempty" json:"unsplit_amount,omitempty"` //订单剩余待分金额,整数,单位为分 + NonceStr string `xml:"nonce_str,omitempty" json:"nonce_str,omitempty"` //微信返回的随机字符串 + Sign string `xml:"sign,omitempty" json:"sign,omitempty"` //微信返回的签名 +} + +// ProfitSharingReturnResponse 分账退回响应结果 +type ProfitSharingMerchanTratioQuery struct { + ReturnCode string `xml:"return_code,omitempty" json:"return_code,omitempty"` // 返回状态码 SUCCESS/FAIL 此字段是通信标识,非交易标识 + ErrCode string `xml:"err_code,omitempty" json:"err_code,omitempty"` // 错误代码 + ErrorMsg string `xml:"error_msg,omitempty" json:"error_msg,omitempty"` // 返回信息 如果返回状态码为FAIL,则本字段存在,且为失败的错误信息 + ErrCodeDes string `xml:"err_code_des,omitempty" json:"err_code_des,omitempty"` // 错误代码描述 + MchId string `xml:"mch_id,omitempty" json:"mch_id,omitempty"` //调用接口时提供的服务商户号 + SubMchId string `xml:"sub_mch_id,omitempty" json:"sub_mch_id,omitempty"` //微信支付分配的子商户号,即分账的出资商户号。查询子商户号的设置的最大分账比例(普通分账)时返回此字段 + BrandMchId string `xml:"brand_mch_id,omitempty" json:"brand_mch_id,omitempty"` //调用接口时提供的品牌主商户号。查询品牌主商户设置的全局分账比例(品牌分账)时返回此字段。 + MaxRatio int `xml:"max_ratio,omitempty" json:"max_ratio,omitempty"` //子商户允许服务商分账的最大比例,单位万分比,比如2000表示20% + NonceStr string `xml:"nonce_str,omitempty" json:"nonce_str,omitempty"` //微信返回的随机字符串 + Sign string `xml:"sign,omitempty" json:"sign,omitempty"` //微信返回的签名 +} + type PayBankResponse struct { ReturnCode string `xml:"return_code,omitempty" json:"return_code,omitempty"` ReturnMsg string `xml:"return_msg,omitempty" json:"return_msg,omitempty"`