100字范文,内容丰富有趣,生活中的好帮手!
100字范文 > php 微信支付退款接口开发 微信支付退款功能开发

php 微信支付退款接口开发 微信支付退款功能开发

时间:2022-10-25 08:09:51

相关推荐

php 微信支付退款接口开发 微信支付退款功能开发

第一次做微信的退款处理,特此标记一下

准备

appId 微信分配的公众账号ID(企业号corpid即为此appId)

mch_id 微信支付分配的商户号

pay_secret 商户平台设置的秘钥:微信商户平台(pay.)-->账户设置-->API安全-->密钥设置

官方文档明确指出,退款还需使用到证书,至于证书怎么用后面说明

证书分为PHP版的和其他语言版的,这边以Java为例

下载证书放置服务器的文件目录,windows可直接导入

开发

请求实体对象

package com.macro.mall.portal.domain;

import lombok.Data;

@Data

public class WechatReturnRequestParam {

private String appId;//公众账号ID

private String mchId;//商户号

private String nonceStr;//随机字符串

private String sign;//签名

private String signType = "MD5";//签名类型

private String transactionId;//微信支付返回的订单号

private String outTradeNo;//商户订单号

private String outRefundNo;//退款单号

private Integer totalFee;//订单金额

private Integer refundFee;//退款金额

private String refundFeeType = "CNY";//货币类型

private String refundDesc;//退款原因

private String notifyUrl;//通知地址

private String mchSecret;

}

private static SortedMap buildParamter(WechatReturnRequestParam requstParam) {

SortedMap parameters = new TreeMap();

parameters.put("appid", requstParam.getAppId());

parameters.put("mch_id", requstParam.getMchId());

parameters.put("nonce_str", getNonceStr());

parameters.put("transaction_id", requstParam.getTransactionId());

parameters.put("out_refund_no", requstParam.getOutRefundNo());

parameters.put("total_fee", requstParam.getTotalFee() + "");

parameters.put("refund_fee", requstParam.getRefundFee() + "");

if (!StringUtils.isEmpty(requstParam.getRefundDesc())){

parameters.put("refund_desc", requstParam.getRefundDesc());

}

String sign = createSign("UTF-8", parameters, requstParam.getMchSecret());

parameters.put("sign", sign);

return parameters;

}

拼接参数并返回XML字符串

//1

String requestXML = WechatPayUtil.buildReturnXML(requstParam);

//2

public static String buildRequestXML(WechatPayRequestParam param) {

SortedMap parameters = buildParamter(param);

String requestXML = getRequestXml(parameters);

return requestXML;

}

//3

public static SortedMap buildParamter(WechatPayRequestParam param) {

if (param.getTotalFee() == null) {

param.setTotalFee(1);

}

SortedMap parameters = new TreeMap();

parameters.put("appid", param.getAppId());

parameters.put("mch_id", param.getMchId());

parameters.put("nonce_str", getNonceStr());

parameters.put("body", param.getBody());

parameters.put("out_trade_no", param.getOutTradeNo());

parameters.put("total_fee", param.getTotalFee() + "");

parameters.put("spbill_create_ip", param.getSpbillCreateIp());

parameters.put("notify_url", param.getNotifyUrl());

parameters.put("trade_type", param.getTradeType());

parameters.put("scene_info", param.getSceneInfo());

String sign = createSign("UTF-8", parameters, param.getMchSecret());

parameters.put("sign", sign);

return parameters;

}

//4.

public static String createSign(String characterEncoding, SortedMap parameters, String mchSecret) {

StringBuffer sb = new StringBuffer();

Set es = parameters.entrySet();

Iterator it = es.iterator();

while (it.hasNext()) {

Map.Entry entry = (Map.Entry) it.next();

String k = (String) entry.getKey();

Object v = entry.getValue();

if (null != v && !"".equals(v) && !"sign".equals(k) && !"key".equals(k)) {

sb.append(k + "=" + v + "&");

}

}

sb.append("key=" + mchSecret);

String sign = md5Encode(sb.toString(), characterEncoding).toUpperCase();

return sign;

}

//5

public static String getRequestXml(SortedMap parameters) {

StringBuffer sb = new StringBuffer();

sb.append("");

Set es = parameters.entrySet();

Iterator it = es.iterator();

while (true) {

while (it.hasNext()) {

Map.Entry entry = (Map.Entry) it.next();

String k = (String) entry.getKey();

String v = (String) entry.getValue();

if (!"attach".equalsIgnoreCase(k) && !"body".equalsIgnoreCase(k) && !"sign".equalsIgnoreCase(k)) {

sb.append("" + v + "" + k + ">");

} else {

sb.append("" + k + ">");

}

}

sb.append("");

return sb.toString();

}

}

创建请求

String responseString = WechatPayUtil.preReturnRequest(requestXML, config);

public static String preReturnRequest(String requestXML, WechatConfig config) throws Exception {

KeyStore keyStore = KeyStore.getInstance("PKCS12");

//config.getCertUrl() 是你存放证书的路径

FileInputStream instream = new FileInputStream(new File(config.getCertUrl()));

try {

//config.getMchId() 商户mch_id

keyStore.load(instream, config.getMchId().toCharArray());

} finally {

instream.close();

}

SSLContext sslcontext = SSLContexts.custom().loadKeyMaterial(keyStore, config.getMchId().toCharArray()).build();

SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(sslcontext, new String[]{"TLSv1"}, null, SSLConnectionSocketFactory.BROWSER_COMPATIBLE_HOSTNAME_VERIFIER);

String responseString = "";

CloseableHttpClient httpClient = HttpClients.custom().setSSLSocketFactory(sslsf).build();

CloseableHttpResponse httpResponse;

HttpPost httpPost = new HttpPost("https://api.mch./secapi/pay/refund");

httpPost.setEntity(new StringEntity(requestXML, "text/xml", "UTF-8"));

httpResponse = httpClient.execute(httpPost);

HttpEntity httpEntity = httpResponse.getEntity();

if (httpEntity != null) {

InputStream is = httpEntity.getContent();

BufferedReader br = new BufferedReader(new InputStreamReader(is, Consts.UTF_8));

for (String line; (line = br.readLine()) != null; responseString = responseString + line) ;

br.close();

is.close();

}

return responseString;

}

获取请求结果

WechatReturnRequestParam requstParam = getWechatReturnRequestParam(order, config);

String requestXML = WechatPayUtil.buildReturnXML(requstParam);

try {

log.info("发起微信退款的请求参数:{}", requestXML);

String responseString = WechatPayUtil.preReturnRequest(requestXML, config);

log.info("微信退款返回的参数:{}", responseString);

JSONObject result = WechatPayUtil.doXMLParse(responseString);

if (result == null) {

throw new RuntimeException("微信退款返回xml解析失败");

}

if (!"SUCCESS".equals(result.getString("return_code"))) {

throw new RuntimeException(result.getString("return_msg"));

}

if (!"SUCCESS".equals(result.getString("result_code"))) {

throw new RuntimeException(result.getString("err_code_des"));

}

log.info("订单{}已从微信退款,", order.getOrderSn());

} catch (Exception e) {

log.error("发起微信退款失败:错误异常:{}", e);

}

后记:我在请求参数的时候并没有传入notify_url通知地址这个参数,需要的童鞋请自行添加。

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。