关闭二级商户充值

更新时间:2025.07.29

以下情况可调用关单接口:1、商家操作超出规定时间限制,为防止重复处理。2、系统主动终止服务不再接受新的请求

接口说明

支持商户:【平台商户】

请求方式:【POST】/v3/platsolution/ecommerce/recharges/out-recharge-no/{out_recharge_no}/close

请求域名:【主域名】https://api.mch.weixin.qq.com 使用该域名将访问就近的接入点

     【备域名】https://api2.mch.weixin.qq.com 使用该域名将访问异地的接入点 ,指引点击查看

请求参数

Header  HTTP头参数

 Authorization  必填 string

请参考签名认证生成认证信息


 Accept  必填 string

请设置为application/json


path  路径参数

 out_recharge_no  必填   string(64)

【商户充值单号】 商户系统内部的充值单号,只能由数字、大小写字母组成,在平台商户系统内部唯一


query  查询参数

 sub_mchid  必填   string(32)

【二级商户号】 二级商户号

请求示例

Java
Go
curl

需配合微信支付工具库 WXPayUtility 使用,请参考 Java 

1package com.java.demo;
2
3import com.java.utils.WXPayUtility; // 引用微信支付工具库,参考:https://pay.weixin.qq.com/doc/v3/partner/4014985777
4
5import com.google.gson.annotations.SerializedName;
6import com.google.gson.annotations.Expose;
7import okhttp3.MediaType;
8import okhttp3.OkHttpClient;
9import okhttp3.Request;
10import okhttp3.RequestBody;
11import okhttp3.Response;
12
13import java.io.IOException;
14import java.io.UncheckedIOException;
15import java.security.PrivateKey;
16import java.security.PublicKey;
17import java.util.ArrayList;
18import java.util.HashMap;
19import java.util.List;
20import java.util.Map;
21
22/**
23 * 关闭二级商户充值
24 */
25public class PlatSolutionClose {
26  private static String HOST = "https://api.mch.weixin.qq.com";
27  private static String METHOD = "POST";
28  private static String PATH = "/v3/platsolution/ecommerce/recharges/out-recharge-no/{out_recharge_no}/close";
29
30  public static void main(String[] args) {
31    // TODO: 请准备商户开发必要参数,参考:https://pay.weixin.qq.com/doc/v3/partner/4013080340
32    PlatSolutionClose client = new PlatSolutionClose(
33      "19xxxxxxxx",                    // 商户号,是由微信支付系统生成并分配给每个商户的唯一标识符,商户号获取方式参考 https://pay.weixin.qq.com/doc/v3/partner/4013080340
34      "1DDE55AD98Exxxxxxxxxx",         // 商户API证书序列号,如何获取请参考 https://pay.weixin.qq.com/doc/v3/partner/4013058924
35      "/path/to/apiclient_key.pem",    // 商户API证书私钥文件路径,本地文件路径
36      "PUB_KEY_ID_xxxxxxxxxxxxx",      // 微信支付公钥ID,如何获取请参考 https://pay.weixin.qq.com/doc/v3/partner/4013038589
37      "/path/to/wxp_pub.pem"           // 微信支付公钥文件路径,本地文件路径
38    );
39
40    PlatSolutionCloseRequest request = new PlatSolutionCloseRequest();
41    request.outRechargeNo = "cz2020042013";
42    request.subMchid = "1900102208";
43    try {
44      MchDeposit response = client.run(request);
45
46      // TODO: 请求成功,继续业务逻辑
47      System.out.println(response);
48    } catch (WXPayUtility.ApiException e) {
49      // TODO: 请求失败,根据状态码执行不同的逻辑
50      e.printStackTrace();
51    }
52  }
53
54  public MchDeposit run(PlatSolutionCloseRequest request) {
55    String uri = PATH;
56    uri = uri.replace("{out_recharge_no}", WXPayUtility.urlEncode(request.outRechargeNo));
57    Map<String, Object> args = new HashMap<>();
58    args.put("sub_mchid", request.subMchid);
59    uri = uri + "?" + WXPayUtility.urlEncode(args);
60
61    Request.Builder reqBuilder = new Request.Builder().url(HOST + uri);
62    reqBuilder.addHeader("Accept", "application/json");
63    reqBuilder.addHeader("Wechatpay-Serial", wechatPayPublicKeyId);
64    reqBuilder.addHeader("Authorization", WXPayUtility.buildAuthorization(mchid, certificateSerialNo, privateKey, METHOD, uri, null));
65    reqBuilder.addHeader("Content-Type", "application/json");
66    RequestBody emptyBody = RequestBody.create(null, "");
67    reqBuilder.method(METHOD, emptyBody);
68    Request httpRequest = reqBuilder.build();
69
70    // 发送HTTP请求
71    OkHttpClient client = new OkHttpClient.Builder().build();
72    try (Response httpResponse = client.newCall(httpRequest).execute()) {
73      String respBody = WXPayUtility.extractBody(httpResponse);
74      if (httpResponse.code() >= 200 && httpResponse.code() < 300) {
75        // 2XX 成功,验证应答签名
76        WXPayUtility.validateResponse(this.wechatPayPublicKeyId, this.wechatPayPublicKey,
77            httpResponse.headers(), respBody);
78
79        // 从HTTP应答报文构建返回数据
80        return WXPayUtility.fromJson(respBody, MchDeposit.class);
81      } else {
82        throw new WXPayUtility.ApiException(httpResponse.code(), respBody, httpResponse.headers());
83      }
84    } catch (IOException e) {
85      throw new UncheckedIOException("Sending request to " + uri + " failed.", e);
86    }
87  }
88
89  private final String mchid;
90  private final String certificateSerialNo;
91  private final PrivateKey privateKey;
92  private final String wechatPayPublicKeyId;
93  private final PublicKey wechatPayPublicKey;
94
95  public PlatSolutionClose(String mchid, String certificateSerialNo, String privateKeyFilePath, String wechatPayPublicKeyId, String wechatPayPublicKeyFilePath) {
96    this.mchid = mchid;
97    this.certificateSerialNo = certificateSerialNo;
98    this.privateKey = WXPayUtility.loadPrivateKeyFromPath(privateKeyFilePath);
99    this.wechatPayPublicKeyId = wechatPayPublicKeyId;
100    this.wechatPayPublicKey = WXPayUtility.loadPublicKeyFromPath(wechatPayPublicKeyFilePath);
101  }
102
103  public static class PlatSolutionCloseRequest {
104    @SerializedName("sub_mchid")
105    @Expose(serialize = false)
106    public String subMchid;
107  
108    @SerializedName("out_recharge_no")
109    @Expose(serialize = false)
110    public String outRechargeNo;
111  }
112  
113  public static class MchDeposit {
114    @SerializedName("sp_mchid")
115    public String spMchid;
116  
117    @SerializedName("sub_mchid")
118    public String subMchid;
119  
120    @SerializedName("recharge_id")
121    public String rechargeId;
122  
123    @SerializedName("out_recharge_no")
124    public String outRechargeNo;
125  
126    @SerializedName("recharge_channel")
127    public RechargeChannel rechargeChannel;
128  
129    @SerializedName("account_type")
130    public AccountType accountType;
131  
132    @SerializedName("recharge_state")
133    public RechargeState rechargeState;
134  
135    @SerializedName("recharge_scene")
136    public RechargeScene rechargeScene;
137  
138    @SerializedName("recharge_state_desc")
139    public String rechargeStateDesc;
140  
141    @SerializedName("recharge_amount")
142    public RechargeAmount rechargeAmount;
143  
144    @SerializedName("bank_transfer_info")
145    public BankTransferInfo bankTransferInfo;
146  
147    @SerializedName("qr_recharge_info")
148    public QrRechargeInfo qrRechargeInfo;
149  
150    @SerializedName("online_bank_recharge_info")
151    public OnlineBankRechargeInfo onlineBankRechargeInfo;
152  
153    @SerializedName("accept_time")
154    public String acceptTime;
155  
156    @SerializedName("success_time")
157    public String successTime;
158  
159    @SerializedName("close_time")
160    public String closeTime;
161  
162    @SerializedName("available_recharge_channels")
163    public List<RechargeChannel> availableRechargeChannels;
164  }
165  
166  public enum RechargeChannel {
167    @SerializedName("BANK_TRANSFER")
168    BANK_TRANSFER,
169    @SerializedName("QR_RECHARGE")
170    QR_RECHARGE,
171    @SerializedName("ONLINE_BANK")
172    ONLINE_BANK
173  }
174  
175  public enum AccountType {
176    @SerializedName("DEPOSIT")
177    DEPOSIT,
178    @SerializedName("OPERATION")
179    OPERATION
180  }
181  
182  public enum RechargeState {
183    @SerializedName("SUCCESS")
184    SUCCESS,
185    @SerializedName("RECHARGING")
186    RECHARGING,
187    @SerializedName("CLOSED")
188    CLOSED
189  }
190  
191  public enum RechargeScene {
192    @SerializedName("ECOMMERCE_DEPOSIT")
193    ECOMMERCE_DEPOSIT,
194    @SerializedName("ECOMMERCE_PAYMENT")
195    ECOMMERCE_PAYMENT
196  }
197  
198  public static class RechargeAmount {
199    @SerializedName("amount")
200    public Long amount;
201  
202    @SerializedName("currency")
203    public String currency;
204  }
205  
206  public static class BankTransferInfo {
207    @SerializedName("bill_no")
208    public String billNo;
209  
210    @SerializedName("memo")
211    public String memo;
212  
213    @SerializedName("return_time")
214    public String returnTime;
215  
216    @SerializedName("return_reason")
217    public String returnReason;
218  
219    @SerializedName("bank_name")
220    public String bankName;
221  
222    @SerializedName("bank_card_tail")
223    public String bankCardTail;
224  
225    @SerializedName("bank_account_name")
226    public String bankAccountName;
227  }
228  
229  public static class QrRechargeInfo {
230    @SerializedName("openid")
231    public String openid;
232  
233    @SerializedName("employee_type")
234    public EmployeeType employeeType;
235  }
236  
237  public static class OnlineBankRechargeInfo {
238    @SerializedName("bill_no")
239    public String billNo;
240  
241    @SerializedName("return_time")
242    public String returnTime;
243  
244    @SerializedName("return_reason")
245    public String returnReason;
246  
247    @SerializedName("bank_name")
248    public String bankName;
249  
250    @SerializedName("online_bank_type")
251    public OnlineBankType onlineBankType;
252  
253    @SerializedName("bank_card_tail")
254    public String bankCardTail;
255  
256    @SerializedName("bank_account_name")
257    public String bankAccountName;
258  }
259  
260  public enum EmployeeType {
261    @SerializedName("ADMIN")
262    ADMIN,
263    @SerializedName("STAFF")
264    STAFF,
265    @SerializedName("LEGAL_PERSON")
266    LEGAL_PERSON
267  }
268  
269  public enum OnlineBankType {
270    @SerializedName("ONLINE_BANK_TYPE_CORPORATE")
271    ONLINE_BANK_TYPE_CORPORATE,
272    @SerializedName("ONLINE_BANK_TYPE_PERSONAL")
273    ONLINE_BANK_TYPE_PERSONAL
274  }
275  
276}
277

应答参数

200 OK

 sp_mchid  必填   string(32)

【平台商户号】 微信支付分配的商户号


 sub_mchid  必填   string(32)

【二级商户号】 微信支付分配的商户号,充值商户号


 recharge_id  必填   string(27)

【微信支付充值单号】 微信支付充值单号


 out_recharge_no  必填   string(64)

【商户充值单号】 商户系统内部的充值单号,只能由数字、大小写字母组成,在平台商户系统内部唯一


 recharge_channel  选填   string

【充值渠道】 仅在“充值成功”时返回,其它状态不返回

可选取值

  • BANK_TRANSFER:  银行转账

  • QR_RECHARGE:  扫码充值

  • ONLINE_BANK:  网银充值


 account_type  必填   string

【充值入账账户】 充值入账账户

可选取值

  • DEPOSIT:  保证金账户

  • OPERATION:  运营账户


 recharge_state  必填   string

【充值状态】 充值状态

可选取值

  • SUCCESS:  充值成功

  • RECHARGING:  充值中

  • CLOSED:  已关闭


 recharge_scene  必填   string

【充值场景】 充值场景

可选取值

  • ECOMMERCE_DEPOSIT:  二级商户充值保证金

  • ECOMMERCE_PAYMENT:  二级商户充值运营资金


 recharge_state_desc  选填   string(64)

【充值状态描述】 展示关闭充值的原因,如“平台商户主动关闭充值单”、“超过时间限制,系统自动关闭充值单”等


 recharge_amount  必填   object

【充值金额】 单位为分,仅支持CNY。单笔限额规则:1、银行转账最多8亿元 2、扫码充值5万元

属性

 bank_transfer_info  选填   object

【转账充值的付款信息】 包括付款账户、银行附言等内容

属性

 qr_recharge_info  选填   object

【扫码充值的付款信息】 包括充值用户OpenID

属性

 online_bank_recharge_info  选填   object

【网银充值的付款信息】 包括付款账户、银行交易订单号等内容

属性

 accept_time  选填   string(32)

【受理充值时间】 微信支付成功受理充值时间,不代表充值已经完成,使用rfc3339标准格式


 success_time  选填   string(32)

【充值成功时间】 当状态为“充值成功”时返回,使用rfc3339标准格式


 close_time  选填   string(32)

【关闭充值时间】 当状态为“已关闭”时返回,使用rfc3339标准格式


 available_recharge_channels  选填   array[string]

【可用充值渠道列表】 申请充值时传入的可用渠道列表

可选取值

  • BANK_TRANSFER:  银行转账

  • QR_RECHARGE:  扫码充值

  • ONLINE_BANK:  网银充值

应答示例

200 OK

1{
2  "sp_mchid" : "1900001109",
3  "sub_mchid" : "1900001121",
4  "recharge_id" : "172234484162395401",
5  "out_recharge_no" : "cz2020042013",
6  "recharge_channel" : "BANK_TRANSFER",
7  "account_type" : "DEPOSIT",
8  "recharge_state" : "SUCCESS",
9  "recharge_scene" : "ECOMMERCE_DEPOSIT",
10  "recharge_state_desc" : "超过时间限制,系统自动关闭充值单",
11  "recharge_amount" : {
12    "amount" : 500000,
13    "currency" : "CNY"
14  },
15  "bank_transfer_info" : {
16    "bill_no" : "110240620400046628001252733345",
17    "memo" : "转账充值附言",
18    "return_time" : "2015-05-20T13:29:35+08:00",
19    "return_reason" : "银行转账充值金额与申请充值金额不一致",
20    "bank_name" : "中国银行",
21    "bank_card_tail" : "0722",
22    "bank_account_name" : "某某某有限公司"
23  },
24  "qr_recharge_info" : {
25    "openid" : "owYiu0WOJdGCYxoHrPabGhI39uT4",
26    "employee_type" : "STAFF"
27  },
28  "online_bank_recharge_info" : {
29    "bill_no" : "110240620400046628001252733345",
30    "return_time" : "2015-05-20T13:29:35+08:00",
31    "return_reason" : "实际付款户名与充值单要求的付款户名不一致",
32    "bank_name" : "中国银行",
33    "online_bank_type" : "ONLINE_BANK_TYPE_CORPORATE",
34    "bank_card_tail" : "0722",
35    "bank_account_name" : "某某某有限公司"
36  },
37  "accept_time" : "2015-05-20T13:29:35+08:00",
38  "success_time" : "2015-05-20T13:29:35+08:00",
39  "close_time" : "2015-05-20T13:29:35+08:00",
40  "available_recharge_channels" : [
41    "BANK_TRANSFER"
42  ]
43}
44

 

错误码

公共错误码

状态码

错误码

描述

解决方案

400

PARAM_ERROR

参数错误

请根据错误提示正确传入参数

400

INVALID_REQUEST

HTTP 请求不符合微信支付 APIv3 接口规则

请参阅 接口规则

401

SIGN_ERROR

验证不通过

请参阅 签名常见问题

500

SYSTEM_ERROR

系统异常,请稍后重试

请稍后重试

业务错误码

状态码

错误码

描述

解决方案

404

NOT_FOUND

充值单不存在

请检查业务充值单号

403

NO_AUTH

服务商未开通平台收付通

服务商开通微信支付平台收付通

429

FREQUENCY_LIMITED

频率超限

请降低请求频率

 

 

反馈
咨询
目录
置顶