java之微信退款

最近在做微信支付,其中有个申请退款环节;

关于申请退款,这里其实个人觉得比较简单,

Map<String, String> params = new HashMap<String, String>();
params.put("appid", wechatInfo.getAppId());  
params.put("mch_id",wechatInfo.getStr("mchId"));
//商户订单号和微信订单号二选一
if(null != order.getOrderId()){
    //商户订单号
    params.put("out_trade_no", order.getOrderId() + ""); 
}else if (null != order.getTransactionId()){
    //微信订单号
    params.put("transaction_id", order.getTransactionId()); 
}else{
    throw new BaseRuntimeException("商户订单号和微信订单号都不存在");
}
//商户退款单号
params.put("out_refund_no", System.currentTimeMillis()+""); 
//总金额
params.put("total_fee", order.getTotalFee() + ""); 
//退款金额
params.put("refund_fee", order.getCashFee() + ""); 
//操作员帐号, 默认为商户号 
params.put("op_user_id", wechatInfo.getStr("mchId"));
//退款结果回调地址
params.put("notify_url", "https://weixin.qq.com/notify/refundNotify"); 
//随机字符串
params.put("nonce_str", System.currentTimeMillis() + "");
//这里根据当前的params和商户密钥key去生成一个签名,百度一下,有很多,这里就不细说了
//生成sign
String sign = "(这里是生成的签名)";
params.put("sign", sign);
// 申请退款文档地址:https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=9_4
//微信申请退款接口
String wx_refund_url = "https://api.mch.weixin.qq.com/secapi/pay/refund";

//然后把params拼接成xml,调用退款接口;
//返回一个xml字符串,转成Map<String,String>
//返回一个refundCallParams;

Map<String,String> refundCallParams ;
if("SUCCESS".equalsIgnoreCase((String) refundCallParams.get("return_code"))){
log.info("------申请退款成功,正在退款中----orderId:" + orderId);
    //申请微信退款接口返回success,但是退款到账还需要时间;
    //把订单状态改为退款中
    order.setTradeState("REFUNDING");
    order.update();
    renderJsonSuccess();
}else{
    log.error("------退款失败----orderId:" + orderId);
    order.setTradeState("REFUND_ERROR");
    order.update();
    renderJsonError("退款失败:" + refundCallParams.get("return_msg"));
}

这里要注意了,申请退款返回成功,并不退款成功,只是申请退款成功而已;

这个时候我们申请退款的时候传的

notify_url //结果回调地址

这个就很重要的,微信会有退款产生结果的时候通知我们,

首先退款结果通知返回的是这样的XML:

<xml>
   <return_code>SUCCESS</return_code>
   <appid><![CDATA[wx2421b1c4370ec43b]]></appid>
   <mch_id><![CDATA[10000100]]></mch_id>
   <nonce_str><![CDATA[TeqClE3i0mvn3DrK]]></nonce_str>
   <req_info><![CDATA[T87GAHG17TGAHG1TGHAHAHA1Y1CIOA9UGJH1GAHV871HAGAGQYQQPOOJMXNBCXBVNMNMAJAA]]></req_info>
</xml>

这里的req_info是加密过的,下面是微信官方给出的解密方式:

解密步骤如下:

(1)对加密串A做base64解码,得到加密串B

(2)对商户key做md5,得到32位小写key* ( key设置路径:微信商户平台(pay.weixin.qq.com)-->账户设置-->API安全-->密钥设置 )

(3)用key*对加密串B做AES-256-ECB解密(PKCS7Padding)

-----------------------------------------------

我只想说,还好有百度,不然这解密方式,靠自己,不知道什么时候能解开密文信息;

下面贴上这个解密的类文件:

ps:其实解密这里大部分都是摘录人家的,小小的搬运一下,见谅呀;

package com.abc.utils;
import java.security.Security;
import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
import org.apache.commons.codec.binary.Base64;
import org.bouncycastle.jce.provider.BouncyCastleProvider;

/**
 * 解密微信退款中返回相关信息的字符串
 * @author wxy
 * @since 2018/04/25
 */
public class AESDecodeUtil {

     public static final String ALGORITHM = "AES/ECB/PKCS7Padding"; 
     
     /**
      * @author wxy
      * @param reqInfo 退款结果里的密文
      * @param paternerKey 商户微信支付key
      * @return
      * @throws Exception
      */
     public static String decode(String reqInfo, String paternerKey) throws Exception{
        try {
            byte[] decodeBase64 = Base64.decodeBase64(reqInfo);
            String md5Key = MD5Util.GetMD5Code(paternerKey);
            Security.addProvider(new BouncyCastleProvider());
            Cipher cipher = Cipher.getInstance(ALGORITHM);  
            SecretKey keySpec = new SecretKeySpec(md5Key.getBytes(), "AES"); //生成加密解密需要的Key  
            cipher.init(Cipher.DECRYPT_MODE, keySpec);  
            byte[] decoded = cipher.doFinal(decodeBase64);  
            String  result = new String(decoded, "UTF-8");  
            return result;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
     }
}

这段解密的代码,我觉得最重要的是要引入对的包;

至于详细的解密方式 ,我没有去细究;

这里返回的是一个xml字符串,直接转成Map就可以直接取其中的参数了,

参考官方微信退款结果通知文档:

https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=9_16&index=10

喜欢的话,点个赞吧!


猜你喜欢

转载自blog.csdn.net/weixin_40337982/article/details/80095083