iedc-go/vendor/gopkg.in/chanxuehong/wechat.v2/mch/pay/refundquery.go
2023-03-03 03:12:15 +08:00

183 lines
6.9 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package pay
import (
"fmt"
"strconv"
"time"
"gopkg.in/chanxuehong/wechat.v2/mch/core"
wechatutil "gopkg.in/chanxuehong/wechat.v2/util"
)
// RefundQuery 查询退款.
func RefundQuery(clt *core.Client, req map[string]string) (resp map[string]string, err error) {
return clt.PostXML(core.APIBaseURL()+"/pay/refundquery", req)
}
type RefundQueryRequest struct {
XMLName struct{} `xml:"xml" json:"-"`
// 必选参数, 四选一
TransactionId string `xml:"transaction_id"` // 微信订单号
OutTradeNo string `xml:"out_trade_no"` // 商户订单号
OutRefundNo string `xml:"out_refund_no"` // 商户退款单号
RefundId string `xml:"refund_id"` // 微信退款单号
// 可选参数
NonceStr string `xml:"nonce_str"` // 随机字符串不长于32位。NOTE: 如果为空则系统会自动生成一个随机字符串。
SignType string `xml:"sign_type"` // 签名类型目前支持HMAC-SHA256和MD5默认为MD5
}
type RefundQueryResponse struct {
XMLName struct{} `xml:"xml" json:"-"`
// 必选返回
TransactionId string `xml:"transaction_id"` // 微信订单号
OutTradeNo string `xml:"out_trade_no"` // 商户系统内部的订单号
TotalFee int64 `xml:"total_fee"` // 订单总金额,单位为分,只能为整数,详见支付金额
CashFee int64 `xml:"cash_fee"` // 现金支付金额,单位为分,只能为整数,详见支付金额
RefundCount int `xml:"refund_count"` // 退款笔数
RefundList []RefundItem `xml:"refund_list"` // 退款列表
// 下面字段都是可选返回的(详细见微信支付文档), 为空值表示没有返回, 程序逻辑里需要判断
SettlementTotalFee *int64 `xml:"settlement_total_fee"` // 应结订单金额=订单金额-非充值代金券金额,应结订单金额<=订单金额。
FeeType string `xml:"fee_type"` // 订单金额货币类型符合ISO 4217标准的三位字母代码默认人民币CNY其他值列表详见货币类型
CashFeeType string `xml:"cash_fee_type"` // 现金支付货币类型
}
type RefundItem struct {
XMLName struct{} `xml:"xml" json:"-"`
// 必选返回
OutRefundNo string `xml:"out_refund_no"` // 商户退款单号
RefundId string `xml:"refund_id"` // 微信退款单号
RefundFee int64 `xml:"refund_fee"` // 申请退款金额
RefundStatus string `xml:"refund_status"` // 退款状态
RefundRecvAccout string `xml:"refund_recv_accout"` // 退款入账账户
// 下面字段都是可选返回的(详细见微信支付文档), 为空值表示没有返回, 程序逻辑里需要判断
RefundChannel string `xml:"refund_channel"` // 退款渠道
SettlementRefundFee *int64 `xml:"settlement_refund_fee"` // 退款金额
RefundAccount string `xml:"refund_account"` // 退款资金来源
RefundSuccessTime time.Time `xml:"refund_success_time"` // 退款成功时间
}
// RefundQuery2 查询退款.
// NOTE: 该函数不支持 代金券 功能, 如果有 代金券 功能请使用 RefundQuery 函数.
func RefundQuery2(clt *core.Client, req *RefundQueryRequest) (resp *RefundQueryResponse, err error) {
m1 := make(map[string]string, 16)
if req.TransactionId != "" {
m1["transaction_id"] = req.TransactionId
}
if req.OutTradeNo != "" {
m1["out_trade_no"] = req.OutTradeNo
}
if req.OutRefundNo != "" {
m1["out_refund_no"] = req.OutRefundNo
}
if req.RefundId != "" {
m1["refund_id"] = req.RefundId
}
if req.NonceStr != "" {
m1["nonce_str"] = req.NonceStr
} else {
m1["nonce_str"] = wechatutil.NonceStr()
}
if req.SignType != "" {
m1["sign_type"] = req.SignType
}
m2, err := RefundQuery(clt, m1)
if err != nil {
return nil, err
}
resp = &RefundQueryResponse{
TransactionId: m2["transaction_id"],
OutTradeNo: m2["out_trade_no"],
FeeType: m2["fee_type"],
CashFeeType: m2["cash_fee_type"],
}
if str := m2["total_fee"]; str != "" {
if n, err := strconv.ParseInt(str, 10, 64); err != nil {
err = fmt.Errorf("parse total_fee:%q to int64 failed: %s", str, err.Error())
return nil, err
} else {
resp.TotalFee = n
}
}
if str := m2["cash_fee"]; str != "" {
if n, err := strconv.ParseInt(str, 10, 64); err != nil {
err = fmt.Errorf("parse cash_fee:%q to int64 failed: %s", str, err.Error())
return nil, err
} else {
resp.CashFee = n
}
}
if str := m2["refund_count"]; str != "" {
if n, err := strconv.ParseInt(str, 10, 64); err != nil {
err = fmt.Errorf("parse refund_count:%q to int64 failed: %s", str, err.Error())
return nil, err
} else {
resp.RefundCount = int(n)
}
}
if str := m2["settlement_total_fee"]; str != "" {
if n, err := strconv.ParseInt(str, 10, 64); err != nil {
err = fmt.Errorf("parse settlement_total_fee:%q to int64 failed: %s", str, err.Error())
return nil, err
} else {
resp.SettlementTotalFee = wechatutil.Int64(n)
}
}
resp.RefundList = make([]RefundItem, resp.RefundCount)
for i := 0; i < resp.RefundCount; i++ {
resp.RefundList[i].OutRefundNo = m2["out_refund_no_"+strconv.Itoa(i)]
resp.RefundList[i].RefundId = m2["refund_id_"+strconv.Itoa(i)]
resp.RefundList[i].RefundStatus = m2["refund_status_"+strconv.Itoa(i)]
resp.RefundList[i].RefundRecvAccout = m2["refund_recv_accout_"+strconv.Itoa(i)]
resp.RefundList[i].RefundChannel = m2["refund_channel_"+strconv.Itoa(i)]
resp.RefundList[i].RefundAccount = m2["refund_account_"+strconv.Itoa(i)]
if str := m2["refund_fee_"+strconv.Itoa(i)]; str != "" {
if n, err := strconv.ParseInt(str, 10, 64); err != nil {
err = fmt.Errorf("parse refund_fee_%d:%q to int64 failed: %s", i, str, err.Error())
return nil, err
} else {
resp.RefundList[i].RefundFee = n
}
}
if str := m2["settlement_refund_fee_"+strconv.Itoa(i)]; str != "" {
if n, err := strconv.ParseInt(str, 10, 64); err != nil {
err = fmt.Errorf("parse settlement_refund_fee_%d:%q to int64 failed: %s", i, str, err.Error())
return nil, err
} else {
resp.RefundList[i].SettlementRefundFee = wechatutil.Int64(n)
}
}
if str := m2["refund_success_time_"+strconv.Itoa(i)]; str != "" {
// 2016-07-25 15:26:26
if t, err := time.ParseInLocation("2006-01-02 15:04:05", str, wechatutil.BeijingLocation); err != nil {
err = fmt.Errorf("parse refund_success_time_%d:%q to time.Time failed: %s", i, str, err.Error())
return nil, err
} else {
resp.RefundList[i].RefundSuccessTime = t
}
}
}
// 校验返回参数
if req.TransactionId != "" && resp.TransactionId != "" && req.TransactionId != resp.TransactionId {
err = fmt.Errorf("transaction_id mismatch, have: %s, want: %s", resp.TransactionId, req.TransactionId)
return nil, err
}
if req.OutTradeNo != "" && resp.OutTradeNo != "" && req.OutTradeNo != resp.OutTradeNo {
err = fmt.Errorf("out_trade_no mismatch, have: %s, want: %s", resp.OutTradeNo, req.OutTradeNo)
return nil, err
}
return resp, nil
}