Эта статья является восьмой частью серии [Анализ платежей WeChat]. В ней в основном объясняется, как продавцы обрабатывают возвраты средств через приложение WeChat, обратные вызовы возврата средств и интерфейсы запроса возврата средств. Есть некоторые подводные камни, на которых будет сделан акцент.
Серия платежей WeChat пополнилась семью статьями~, те, кто не читал, могут ознакомиться.
Анализ оплаты WeChat: запрос заказов и закрытие заказов
Анализ оплаты WeChat: уведомление о результате платежа
Анализ оплаты WeChat: единый интерфейс заказа
В реальных сценариях приложение для возврата и интерфейс обратного вызова возврата являются наиболее часто используемыми платежными интерфейсами WeChat.Здесь мы поговорим о原路返回
Способы возврата, есть использование непосредственно для пользователя付款到零钱
,现金红包
и другие способы возврата, эта ситуация в основном возникает, когда служба поддержки клиентов возвращает деньги, а не все возвраты, а некоторые из них появляются при использовании微信代金券-单品券
В то время, поскольку купон на один продукт не может быть частично возмещен, он может быть оплачен только предприятием.Здесь мы в основном говорим о原路返回
Возвращать деньги.
PS: возврат означает, что от ассоциации, чтобы заплатить один заряд, когда вы платите, микро-канал будет записывать соответствующие данные, которые могут отображаться в уведомлении клиента.
1. Заявка на интерфейс возврата
Ниже приведен официальный WeChat.申请退款
Документация:
https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=9_4
1.1 Сценарии применения
Когда требуется возврат средств в течение определенного периода времени после совершения транзакции по вине покупателя или продавца, продавец может вернуть платеж покупателю через интерфейс возврата. WeChat Pay получит запрос на возврат средств и проверит успешность в соответствии с метод возврата.Согласно правилам оплаты, платеж будет возвращен на счет покупателя в соответствии с первоначальным маршрутом.
注意:
1、交易时间超过一年的订单无法提交退款
2、微信支付退款支持单笔交易分多次退款,多次退款需要提交原支付订单的商户订单号和设置不同的退款单号。申请退款总金额不能超过订单金额。 一笔退款失败后重新提交,请不要更换退款单号,请使用原商户退款单号
3、请求频率限制:150qps,即每秒钟正常的申请退款请求次数不超过150次
错误或无效请求频率限制:6qps,即每秒钟异常或错误的退款申请请求不超过6次
4、每个支付订单的部分退款次数不能超过50次
P.S. Вышеуказанные ограничения не проявляются в общем, но их тоже надо прописать в обработку аномальных сценариев в системе.Частота запросов может быть обработана за счет очередей или увеличенных задержек.Частичные возвраты не должны превышать лимит WeChat В настоящее время.
1.2 Ссылка на интерфейс
https://api.mch.weixin.qq.com/secapi/pay/refund
1.3 Требуется ли сертификат?
Для запроса требуется двусторонний сертификат.
PS: Что касается сертификата WeChat, вы можете загрузить его в [Платформа продавца-Account Center-API Security]. Этот сертификат должен использоваться многими платежными интерфейсами. Пожалуйста, настройте адрес сертификата как постоянный. Для конкретной реализации, пожалуйста, обратитесь к исходному коду автора на github.
1.4 Вызов интерфейса
Сначала посмотрите на исходный код, как показано ниже:
/**
* [微信退款接口] - 保存调用的相关记录
* @param refundPayment 退款订单的支付记录
* @param tradePayment 历史付款单
* @return map
* @throws Exception e
*
* @author yclimb
* @date 2018/6/21
*/
public Map<String,String> saveWxPayRefund(Payment refundPayment, Payment tradePayment) throws Exception {
if (refundPayment == null || tradePayment == null) {
return null;
}
// 微信订单号/商户订单号,必须传入其中一个,此处默认传入商户订单号
// 微信订单号,微信生成的订单号,在支付通知中有返回
// String transaction_id = null;
// 商户订单号,商户系统内部订单号,要求32个字符内,只能是数字、大小写字母_-|*@ ,且在同一个商户号下唯一。
String out_trade_no = tradePayment.getFlowNumer();
// 商户退款单号,商户系统内部的退款单号,商户系统内部唯一,只能是数字、大小写字母_-|*@ ,同一退款单号多次请求只退一笔。
String out_refund_no = refundPayment.getFlowNumer();
// 订单总金额,传入参数单位为:元
String total_fee = String.valueOf(tradePayment.getAmount());
// 退款总金额,订单总金额,传入参数单位为:元
String refund_fee = String.valueOf(refundPayment.getAmount());
// 退款原因,若商户传入,会在下发给用户的退款消息中体现退款原因
String refund_desc = refundPayment.getBody();
// 微信支付对象
WXPay wxPay = new WXPay(WXPayConfigImpl.getInstance());
// 微信退款接口
Map<String, String> resultMap = wxPay.refund(refundUrl, null, out_trade_no, out_refund_no, total_fee, refund_fee, refund_desc);
logger.info("saveWxPayRefund:resultMap:" + resultMap.toString());
// 记录付款流水
// 下单失败,进行处理
if (WXPayConstants.FAIL.equals(resultMap.get(WXPayConstants.RETURN_CODE)) ||
WXPayConstants.FAIL.equals(resultMap.get(WXPayConstants.RESULT_CODE))) {
// 处理结果返回,无需继续执行
resultMap.put(WXPayConstants.RESULT_CODE, WXPayConstants.FAIL);
resultMap.put(WXPayConstants.ERR_CODE_DES, resultMap.get(WXPayConstants.RETURN_MSG));
return resultMap;
}
return resultMap;
}
Выше приведен пример кода для вызова возврата SDK, Есть несколько параметров, на которые нам нужно обратить внимание:
имя поля | имя переменной | необходимые | тип | описывать |
---|---|---|---|---|
Номер заказа WeChat | transaction_id | да | String(32) | Номер заказа, сгенерированный WeChat, будет возвращен в платежном уведомлении. |
Номер заказа продавца | out_trade_no | да | String(32) | Внутренний номер заказа торговой системы, до 32 символов, только цифры и прописные и строчные буквы_- |
Номер заказа продавца на возврат | out_refund_no | да | String(64) | Номер заказа на возврат в системе мерчанта, уникальный в системе мерчанта, может состоять только из цифр и прописных и строчных букв_- |
Сумма возмещения | refund_fee | да | Int | Общая сумма возврата, общая сумма заказа, единица измерения - центы, может быть только целым числом |
URL-адрес уведомления о результатах возврата | notify_url | нет | String(256) | Адрес обратного вызова для асинхронного получения уведомления о результатах возврата WeChat Pay. URL-адрес уведомления должен быть URL-адресом, доступным из внешней сети, а параметры не разрешены. Если в параметре передается notify_url, адрес обратного вызова, настроенный на платформе продавца, не будет приниматься. эффект. |
PS: Рекомендуется, чтобы указанные выше параметры были обязательными.notify_url
Параметры могут быть настроены как константы среды и адрес обратного вызова, который не будет вызываться в соответствии с различными конфигурациями среды.
Ниже приведен конкретный фактический SDKwxPay.refund
код вызова:
/**
* 作用:申请退款<br>
* 场景:当交易发生之后一段时间内,由于买家或者卖家的原因需要退款时,卖家可以通过退款接口将支付款退还给买家,
* 微信支付将在收到退款请求并且验证成功之后,按照退款规则将支付款按原路退到买家帐号上。
* 接口文档地址:https://pay.weixin.qq.com/wiki/doc/api/wxa/wxa_api.php?chapter=9_4
*
* @param notify_url 回调地址
* @param transaction_id 微信生成的订单号,在支付通知中有返回
* @param out_trade_no 商户系统内部订单号,要求32个字符内,只能是数字、大小写字母_-|*@ ,且在同一个商户号下唯一。
* @param out_refund_no 商户系统内部的退款单号,商户系统内部唯一,只能是数字、大小写字母_-|*@ ,同一退款单号多次请求只退一笔。
* @param total_fee 订单总金额,传入参数单位为:元
* @param refund_fee 退款总金额,订单总金额,传入参数单位为:元
* @param refund_desc 退款原因,若商户传入,会在下发给用户的退款消息中体现退款原因
* @return API返回数据
* @throws Exception e
*/
public Map<String, String> refund(String notify_url, String transaction_id, String out_trade_no, String out_refund_no,
String total_fee, String refund_fee, String refund_desc) throws Exception {
/** 构造请求参数数据 **/
Map<String, String> data = new HashMap<>();
// 变量名 字段名 必填 类型 示例值 描述
// 微信订单号 二选一 String(32) 1.21775E+27 微信生成的订单号,在支付通知中有返回
if (transaction_id != null) {
data.put("transaction_id", transaction_id);
}
// 商户订单号 String(32) 1.21775E+27 商户系统内部订单号,要求32个字符内,只能是数字、大小写字母_-|*@ ,且在同一个商户号下唯一。
data.put("out_trade_no", out_trade_no);
// 商户退款单号 是 String(64) 1.21775E+27 商户系统内部的退款单号,商户系统内部唯一,只能是数字、大小写字母_-|*@ ,同一退款单号多次请求只退一笔。
data.put("out_refund_no", out_refund_no);
// 订单金额 是 Int 100 订单总金额,单位为分,只能为整数,详见支付金额
data.put("total_fee", String.valueOf(new BigDecimal(total_fee).multiply(new BigDecimal(100)).setScale(2, BigDecimal.ROUND_HALF_UP).intValue()));
// 退款金额 是 Int 100 退款总金额,订单总金额,单位为分,只能为整数,详见支付金额
// 默认单位为分,系统是元,所以需要*100
data.put("refund_fee", String.valueOf(new BigDecimal(refund_fee).multiply(new BigDecimal(100)).setScale(2, BigDecimal.ROUND_HALF_UP).intValue()));
// 退款原因 否 String(80) 商品已售完 若商户传入,会在下发给用户的退款消息中体现退款原因
data.put("refund_desc", refund_desc);
// 货币种类 否 String(8) CNY 货币类型,符合ISO 4217标准的三位字母代码,默认人民币:CNY,其他值列表详见货币类型
data.put("refund_fee_type", WXPayConstants.FEE_TYPE_CNY);
// 退款结果通知url 否 String(256) https://weixin.qq.com/notify/ 异步接收微信支付退款结果通知的回调地址,通知URL必须为外网可访问的url,不允许带参数,如果参数中传了notify_url,则商户平台上配置的回调地址将不会生效。
data.put("notify_url", notify_url);
/** 以下参数为非必填参数 **/
// 退款资金来源 否 String(30) REFUND_SOURCE_RECHARGE_FUNDS 仅针对老资金流商户使用;REFUND_SOURCE_UNSETTLED_FUNDS---未结算资金退款(默认使用未结算资金退款);REFUND_SOURCE_RECHARGE_FUNDS---可用余额退款
// data.put("refund_account", null);
/** 以下五个参数,在 this.fillRequestData 方法中会自动赋值 **/
/*// 小程序ID appid 是 String(32) wxd678efh567hg6787 微信分配的小程序ID
data.put("appid", WXPayConstants.APP_ID);
// 商户号 mch_id 是 String(32) 1230000109 微信支付分配的商户号
data.put("mch_id", WXPayConstants.MCH_ID);
// 随机字符串 nonce_str 是 String(32) 5K8264ILTKCH16CQ2502SI8ZNMTM67VS 随机字符串,长度要求在32位以内。推荐随机数生成算法
data.put("nonce_str", nonce_str);
// 签名类型 sign_type 否 String(32) MD5 签名类型,默认为MD5,支持HMAC-SHA256和MD5。
data.put("sign_type", WXPayConstants.MD5);
// 签名 sign 是 String(32) C380BEC2BFD727A4B6845133519F3AD6 通过签名算法计算得出的签名值,详见签名生成算法
data.put("sign", sign);*/
// 微信退款接口
Map<String, String> resultMap = this.refund(data);
WXPayUtil.getLogger().info("wxPay.refund:" + resultMap);
return resultMap;
}
Значение конкретных полей, которые были подробно объяснены выше, студенты, которые не понимают, могут проверить официальные документы WeChat, а конкретный исходный код можно проверить на github автора.
Здесь есть момент, на который стоит обратить внимание.После того, как мы вызовем возврат, будут возвращены некоторые условия обработки исключений.Серия кодов ошибок включена в официальный документ, и мы можем разобраться с ними в системе, так что не буду' не вдаваться в подробности здесь. .
2. Интерфейс обратного вызова возврата
Ниже приведен официальный WeChat.退款结果通知
Документация:
https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=9_16&index=10
2.1. Сценарии применения
Когда возмещение, примененное продавцом, принесет результат, WeChat отправит соответствующий результат продавцу, и продавец должен получить и обработать его и вернуть ответ. При взаимодействии с уведомлениями в фоновом режиме, если WeChat получает ответ от продавца, который не был успешным или время ожидания истекло, WeChat считает, что уведомление не было выполнено, и WeChat будет периодически повторно отправлять уведомления с помощью определенных стратегий, чтобы повысить процент успешных уведомлений. насколько это возможно, но WeChat не гарантирует, что уведомление в конечном итоге будет успешным.
(Частота уведомлений составляет 15/15/30/180/1800/1800/1800/1800/3600, единица измерения: секунды)
Примечание. Одно и то же уведомление может быть отправлено в систему продавца несколько раз. Торговые системы должны иметь возможность правильно обрабатывать повторяющиеся уведомления. Рекомендуемая практика заключается в том, что при получении уведомления для обработки сначала проверьте состояние соответствующих бизнес-данных, чтобы определить, было ли уведомление обработано. Перед проверкой состояния и обработкой бизнес-данных следует использовать блокировки данных для управления параллелизмом, чтобы избежать путаницы данных, вызванной повторным входом в функцию.
Особое примечание: результат возврата шифрует важные данные, и продавцу необходимо расшифровать их с помощью ключа продавца, чтобы получить содержание уведомления о результате.
2.2 Ссылка на интерфейс
Загрузите параметр «notify_url» в интерфейс приложения возврата, чтобы включить эту функцию. Если ссылка недоступна, продавец не сможет получать уведомления WeChat. URL-адрес уведомления должен быть напрямую доступным URL-адресом и не может содержать параметры.
示例:notify_url:“https://pay.weixin.qq.com/wxpay/pay.action”
2.3 Метод расшифровки
解密步骤如下:
(1)对加密串A做base64解码,得到加密串B
(2)对商户key做md5,得到32位小写key* ( key设置路径:微信商户平台-->账户设置-->API安全-->密钥设置 )
(3)用key*对加密串B做AES-256-ECB解密(PKCS7Padding)
PS: обратите особое внимание, если вы хотите выполнить дешифрование WeChat AES, из-за ограничений контроля импорта GJ шифрование и дешифрование в пакете среды выполнения, выпущенном Java, имеют определенные ограничения. По умолчанию шифрование AES и дешифрование 256-битных ключей не разрешено.Решение состоит в изменении файла политики.Нам нужно загрузить файл политики неограниченного разрешения с официального сайта.Будьте осторожны, не загрузите неправильную версию JDK.
Адрес загрузки jce для jdk8:https://www.oracle.com/technetwork/java/javase/downloads/jce8-download-2133166.html
Замените два файла local_policy.jar и US_export_policy.jar исходными файлами в папках %JRE_HOME%\lib\security и %JDK_HOME%\jre\lib\security.Сначала обязательно сделайте резервную копию исходных файлов.
Если это jdk8, вы можете столкнуться с каталогом безопасности сpolicy
В случае с папками в качестве примера возьмем компьютер автора, путь jdk/opt/jdk1.8.0_152/jre/lib/security/policy
, в этом каталоге есть две подпапкиlimited
,limited
, нужно заменитьlimited
файлы в папкеlocal_policy.jar
,US_export_policy.jar
Этим двоим лучше сначала сделать резервную копию! ! ! После замены перезапустите проект.
2.4 Вызов интерфейса
Поскольку интерфейс обратного вызова для возврата средств предназначен для того, чтобы наша система пассивно получала сообщения WeChat, он аналогичен интерфейсу обратного вызова для оплаты и также использует метод потока. Формат — xml. Давайте посмотрим на код ниже:
/**
* 退款结果通知
* <p>
* 在申请退款接口中上传参数“notify_url”以开通该功能
* 如果链接无法访问,商户将无法接收到微信通知。
* 通知url必须为直接可访问的url,不能携带参数。示例:notify_url:“https://pay.weixin.qq.com/wxpay/pay.action”
* <p>
* 当商户申请的退款有结果后,微信会把相关结果发送给商户,商户需要接收处理,并返回应答。
* 对后台通知交互时,如果微信收到商户的应答不是成功或超时,微信认为通知失败,微信会通过一定的策略定期重新发起通知,尽可能提高通知的成功率,但微信不保证通知最终能成功。
* (通知频率为15/15/30/180/1800/1800/1800/1800/3600,单位:秒)
* 注意:同样的通知可能会多次发送给商户系统。商户系统必须能够正确处理重复的通知。
* 推荐的做法是,当收到通知进行处理时,首先检查对应业务数据的状态,判断该通知是否已经处理过,如果没有处理过再进行处理,如果处理过直接返回结果成功。在对业务数据进行状态检查和处理之前,要采用数据锁进行并发控制,以避免函数重入造成的数据混乱。
* 特别说明:退款结果对重要的数据进行了加密,商户需要用商户秘钥进行解密后才能获得结果通知的内容
* @param request req
* @param response resp
* @return res xml
*
* @author yclimb
* @date 2018/6/21
*/
@ApiOperation(value = "微信支付|微信退款回调接口", httpMethod = "POST", notes = "该链接是通过【微信退款API】中提交的参数notify_url设置,如果参数中传了notify_url,则商户平台上配置的回调地址将不会生效。")
@RequestMapping("/refund")
public void refund(HttpServletRequest request, HttpServletResponse response) {
String resXml = "";
InputStream inStream;
try {
inStream = request.getInputStream();
ByteArrayOutputStream outSteam = new ByteArrayOutputStream();
byte[] buffer = new byte[1024];
int len = 0;
while ((len = inStream.read(buffer)) != -1) {
outSteam.write(buffer, 0, len);
}
WXPayUtil.getLogger().info("refund:微信退款----start----");
// 获取微信调用我们notify_url的返回信息
String result = new String(outSteam.toByteArray(), "utf-8");
WXPayUtil.getLogger().info("refund:微信退款----result----=" + result);
// 关闭流
outSteam.close();
inStream.close();
// xml转换为map
Map<String, String> map = WXPayUtil.xmlToMap(result);
if (WXPayConstants.SUCCESS.equalsIgnoreCase(map.get(WXPayConstants.RETURN_CODE))) {
WXPayUtil.getLogger().info("refund:微信退款----返回成功");
/** 以下字段在return_code为SUCCESS的时候有返回: **/
// 加密信息:加密信息请用商户秘钥进行解密,详见解密方式
String req_info = map.get("req_info");
/**
* 解密方式
* 解密步骤如下:
* (1)对加密串A做base64解码,得到加密串B
* (2)对商户key做md5,得到32位小写key* ( key设置路径:微信商户平台(pay.weixin.qq.com)-->账户设置-->API安全-->密钥设置 )
* (3)用key*对加密串B做AES-256-ECB解密(PKCS7Padding)
*/
String resultStr = AESUtil.decryptData(req_info);
// WXPayUtil.getLogger().info("refund:解密后的字符串:" + resultStr);
Map<String, String> aesMap = WXPayUtil.xmlToMap(resultStr);
/** 以下为返回的加密字段: **/
// 商户退款单号 是 String(64) 1.21775E+27 商户退款单号
String out_refund_no = aesMap.get("out_refund_no");
// 退款状态 是 String(16) SUCCESS SUCCESS-退款成功、CHANGE-退款异常、REFUNDCLOSE—退款关闭
String refund_status = aesMap.get("refund_status");
// 商户订单号 是 String(32) 1.21775E+27 商户系统内部的订单号
String out_trade_no = aesMap.get("out_trade_no");
/*// 微信订单号 是 String(32) 1.21775E+27 微信订单号
String transaction_id = null;
// 微信退款单号 是 String(32) 1.21775E+27 微信退款单号
String refund_id = null;
// 订单金额 是 Int 100 订单总金额,单位为分,只能为整数,详见支付金额
String total_fee = null;
// 应结订单金额 否 Int 100 当该订单有使用非充值券时,返回此字段。应结订单金额=订单金额-非充值代金券金额,应结订单金额<=订单金额。
String settlement_total_fee = null;
// 申请退款金额 是 Int 100 退款总金额,单位为分
String refund_fee = null;
// 退款金额 是 Int 100 退款金额=申请退款金额-非充值代金券退款金额,退款金额<=申请退款金额
String settlement_refund_fee = null;*/
// 退款是否成功
if (!WXPayConstants.SUCCESS.equals(refund_status)) {
resXml = resFailXml;
} else {
// 通知微信.异步确认成功.必写.不然会一直通知后台.八次之后就认为交易失败了.
resXml = resSuccessXml;
isSuccess = true;
}
// 根据付款单号查询付款记录 out_refund_no
// 付款记录修改 & 记录付款日志
if (payment != null) {
WXPayUtil.getLogger().error("refund:微信支付回调:修改支付单");
} else {
WXPayUtil.getLogger().error("refund:微信支付回调:找不到对应的支付单");
}
} else {
WXPayUtil.getLogger().error("refund:支付失败,错误信息:" + map.get(WXPayConstants.RETURN_MSG));
resXml = resFailXml;
}
} catch (Exception e) {
WXPayUtil.getLogger().error("refund:微信退款回调发布异常:", e);
} finally {
try {
// 处理业务完毕
BufferedOutputStream out = new BufferedOutputStream(response.getOutputStream());
out.write(resXml.getBytes());
out.flush();
out.close();
} catch (IOException e) {
WXPayUtil.getLogger().error("refund:微信退款回调发布异常:out:", e);
}
}
}
Приведенный выше код подробно объясняет, как получать данные обратного вызова WeChat и декодировать данные.AESUtil.decryptData(req_info)
Пожалуйста, обратитесь к исходному коду автора, адрес есть в конце статьи, поэтому я не буду вдаваться в подробности.
Конкретные параметры получения возврата см. в официальной документации WeChat.商户退款单号
и微信退款单号
, эти два параметра являются необходимыми документами для изменения и регистрации возврата.
3. Запросить возврат
Ниже приведен официальный WeChat.查询退款
Документация:
https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=9_5
3.1 Сценарии применения
После отправки заявки на возврат запросите статус возврата, вызвав этот API. Возврат средств происходит с некоторой задержкой, средства, выплаченные сдачей, поступят на счет в течение 20 минут, а средства, выплаченные банковскими картами, будут перепроверены через 3 рабочих дня.
Примечание. Если количество частичных возвратов по одному платежному поручению превышает 20 раз, используйте для проверки номер заказа на возврат.
3.2 Ссылка на интерфейс
https://api.mch.weixin.qq.com/pay/refundquery
3.3 Требуется ли сертификат?
ненужный
3.4 Вызов интерфейса
Примечание. При наличии более 10 частичных возвратов по заказу, когда продавец использует номер заказа WeChat или номер заказа продавца, чтобы настроить API-интерфейс запроса на возврат, чтобы узнать о возмещении, первые 10 возмещений будут возвращены по умолчанию.total_refund_count
(Общее количество возвратов за заказ). Когда продавцу нужно узнать о более чем 10 заказах на возмещение по одному и тому же заказу, он может ввести номер заказа и смещение, чтобы узнать, и WeChat Pay вернет смещение, следующие 10 заказов и так далее. Когда смещение, переданное продавцом, превышаетtotal_refund_count
, система выдаст ошибкуPARAM_ERROR
.
Пример:
一笔订单下的退款单有36笔,当商户想查询第25笔时,可传入订单号及offset=24,微信支付平台会返回第25笔到第35笔的退款单信息,或商户可直接传入退款单号查询退款
Ниже приведен метод вызова:
private void doRefundQuery() {
// 四选一,微信订单号查询的优先级是: refund_id > out_refund_no > transaction_id > out_trade_no
HashMap<String, String> data = new HashMap<String, String>();
// 商户订单号
data.put("out_trade_no", out_trade_no);
// 微信订单号
data.put("transaction_id", out_trade_no);
// 商户退款单号
data.put("out_refund_no", out_trade_no);
// 微信退款单号
data.put("refund_id", out_trade_no);
try {
Map<String, String> r = wxpay.refundQuery(data);
System.out.println(r);
} catch (Exception e) {
e.printStackTrace();
}
}
PS: приоритет запроса номера заказа WeChat: return_id > out_refund_no > transaction_id > out_trade_no
Следует отметить, что при запросе на возврат необходимо обращать внимание на код ошибки, возвращаемый возвратом, при возникновении ошибки необходимо вовремя синхронизировать данные о возврате в системе мерчанта.
Эпилог
выше申请退款、退款回调接口、查询退款
Для соответствующего объяснения и исходного кода особое внимание следует уделить методу расшифровки и замены файлов безопасности при получении возвратов.Друзья должны обратить внимание.Конкретный исходный код можно найти на гитхабе автора, где есть подробные комментарии для каждого метода. .
Предварительный просмотр: Следующая статья下载对账单和资金账单
, быть в курсе! ! !
Если вы хотите увидеть исходный код заранее, вы можете взглянуть на мой github, адрес следующий:
https://github.com/YClimb/wxpay-sdk/blob/master/README.md
Добавьте личный WeChat автора, учетная запись WeChat автора выглядит следующим образомyclimb
, указывая微信支付
Вы можете вытащить его в группу обсуждения платежей WeChat для обсуждения с друзьями, обязательно укажите微信支付
О~
Эта статья окончена, обратите внимание на официальный аккаунт, чтобы увидеть больше! ! !