优化支付退款钱包链路

This commit is contained in:
yml
2026-06-03 21:47:04 +08:00
parent 04193ae687
commit c80d3f960e
26 changed files with 1342 additions and 504 deletions
@@ -72,6 +72,56 @@ type QueryPaymentResponse struct {
Raw map[string]string
}
type CreateRefundRequest struct {
ThirdOrderID string // 原支付商户订单号
LeshuaOrderID string // 原支付乐刷订单号(优先使用)
MerchantRefundID string // 商户退款单号(唯一)
RefundAmountCent int64 // 退款金额(分)
NotifyURL string
Attach string
}
type CreateRefundResponse struct {
RespCode string
ResultCode string
ErrorCode string
ErrorMessage string
MerchantID string
ThirdOrderID string
LeshuaOrderID string
MerchantRefundID string
LeshuaRefundID string
RefundAmount string
TotalAmount string
OrderBalance string
Status string
Raw map[string]string
}
type QueryRefundRequest struct {
ThirdOrderID string
LeshuaOrderID string
MerchantRefundID string
LeshuaRefundID string
}
type QueryRefundResponse struct {
RespCode string
ResultCode string
ErrorCode string
ErrorMessage string
MerchantID string
ThirdOrderID string
LeshuaOrderID string
MerchantRefundID string
LeshuaRefundID string
Status string
RefundAmount string
TotalAmount string
RefundTime string
Raw map[string]string
}
type VerifyNotifyResult struct {
OK bool
MatchedKey string
@@ -179,6 +229,100 @@ func (c *Client) QueryPayment(ctx context.Context, thirdOrderID, providerOrderID
}, nil
}
func (c *Client) CreateRefund(ctx context.Context, req CreateRefundRequest) (*CreateRefundResponse, map[string]string, error) {
if err := c.validate(); err != nil {
return nil, nil, err
}
params := map[string]string{
"service": "unified_refund",
"merchant_id": c.cfg.MerchantID,
"merchant_refund_id": req.MerchantRefundID,
"refund_amount": fmt.Sprintf("%d", req.RefundAmountCent),
"nonce_str": Nonce(32),
}
if req.LeshuaOrderID != "" {
params["leshua_order_id"] = req.LeshuaOrderID
} else if req.ThirdOrderID != "" {
params["third_order_id"] = req.ThirdOrderID
}
if req.Attach != "" {
params["attach"] = sanitizeText(req.Attach, 64)
}
if c.cfg.SignType != "" && !strings.EqualFold(c.cfg.SignType, "MD5") {
params["sign_type"] = c.cfg.SignType
}
if req.NotifyURL != "" {
params["notify_url"] = req.NotifyURL
}
params["sign"] = Sign(params, c.cfg.SignKey, SignOptions{})
raw, err := c.post(ctx, params)
if err != nil {
return nil, params, err
}
resp := &CreateRefundResponse{
RespCode: raw["resp_code"],
ResultCode: raw["result_code"],
ErrorCode: raw["error_code"],
ErrorMessage: firstNonEmpty(raw["error_msg"], raw["resp_msg"]),
MerchantID: raw["merchant_id"],
ThirdOrderID: raw["third_order_id"],
LeshuaOrderID: raw["leshua_order_id"],
MerchantRefundID: raw["merchant_refund_id"],
LeshuaRefundID: raw["leshua_refund_id"],
RefundAmount: raw["refund_amount"],
TotalAmount: raw["total_amount"],
OrderBalance: raw["order_balance"],
Status: raw["status"],
Raw: raw,
}
return resp, params, nil
}
func (c *Client) QueryRefund(ctx context.Context, req QueryRefundRequest) (*QueryRefundResponse, error) {
if err := c.validate(); err != nil {
return nil, err
}
params := map[string]string{
"service": "unified_query_refund",
"merchant_id": c.cfg.MerchantID,
"nonce_str": Nonce(32),
}
if req.LeshuaOrderID != "" {
params["leshua_order_id"] = req.LeshuaOrderID
} else if req.ThirdOrderID != "" {
params["third_order_id"] = req.ThirdOrderID
}
if req.LeshuaRefundID != "" {
params["leshua_refund_id"] = req.LeshuaRefundID
} else if req.MerchantRefundID != "" {
params["merchant_refund_id"] = req.MerchantRefundID
}
if c.cfg.SignType != "" && !strings.EqualFold(c.cfg.SignType, "MD5") {
params["sign_type"] = c.cfg.SignType
}
params["sign"] = Sign(params, c.cfg.SignKey, SignOptions{})
raw, err := c.post(ctx, params)
if err != nil {
return nil, err
}
return &QueryRefundResponse{
RespCode: raw["resp_code"],
ResultCode: raw["result_code"],
ErrorCode: raw["error_code"],
ErrorMessage: firstNonEmpty(raw["error_msg"], raw["resp_msg"]),
MerchantID: raw["merchant_id"],
ThirdOrderID: raw["third_order_id"],
LeshuaOrderID: raw["leshua_order_id"],
MerchantRefundID: raw["merchant_refund_id"],
LeshuaRefundID: raw["leshua_refund_id"],
Status: raw["status"],
RefundAmount: raw["refund_amount"],
TotalAmount: raw["total_amount"],
RefundTime: raw["refund_time"],
Raw: raw,
}, nil
}
func (c *Client) VerifyNotify(params map[string]string) bool {
return c.VerifyNotifyDetail(params).OK
}