首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >JAVA移动支付微信和支付宝后台代码

JAVA移动支付微信和支付宝后台代码

作者头像
王念博客
发布2019-07-25 17:55:33
4.6K0
发布2019-07-25 17:55:33
举报
文章被收录于专栏:王念博客王念博客

前言:之前接APP支付,微信遇到了一点点坑,为了方便以后copy,把之前写的代码粘贴出来。需要的同学可以参考一下,具体参数说明还请详细查看官方文档:

支付宝回调参数说明:https://doc.open.alipay.com/docs/doc.htm?treeId=193&articleId=105301&docType=1

微信支付回调参数:https://pay.weixin.qq.com/wiki/doc/api/app/app.php?chapter=9_7&index=3

1.微信支付

1.0 导入xml支持

 <!--XML支持-->
        <dependency>
            <groupId>com.thoughtworks.xstream</groupId>
            <artifactId>xstream</artifactId>
            <version>1.4.7</version>
        </dependency>
        <dependency>
            <groupId>org.jdom</groupId>
            <artifactId>jdom2</artifactId>
            <version>2.0.6</version>
        </dependency>
        <dependency>
            <groupId>dom4j</groupId>
            <artifactId>dom4j</artifactId>
            <version>1.6.1</version>
        </dependency>

1.1 微信统一下单

 /**
     * 统一下单
     *
     * @param orderSn
     * @param totalFee
     * @param spBillCreateIP
     * @return
     */
    public static Map<Object, Object> sendWxPayRequest(String orderSn, String totalFee, String spBillCreateIP) {
        //签名
        SortedMap<Object, Object> parameters = new TreeMap<>();
        parameters.put("appid", Constant.APPID);
        parameters.put("body", Constant.ORDER_NAME);
        parameters.put("mch_id", Constant.MCH_ID);
        parameters.put("nonce_str", String.valueOf(new Date().getTime()));
        parameters.put("notify_url", Constant.CONFIGMAP.get("weixin.asynchronousNotifyUrl"));
        parameters.put("out_trade_no", orderSn);
        parameters.put("spbill_create_ip", spBillCreateIP);
        parameters.put("total_fee", totalFee);
        parameters.put("trade_type", "APP");
        String sign = createSign("utf-8", parameters);
        //请求xml参数
        StringBuffer requestStr = new StringBuffer("<xml>");
        requestStr.append("<appid><![CDATA[");
        requestStr.append(parameters.get("appid"));
        requestStr.append("]]></appid>");
        requestStr.append("<body><![CDATA[");
        requestStr.append(parameters.get("body"));
        requestStr.append("]]></body>");
        requestStr.append("<mch_id><![CDATA[");
        requestStr.append(parameters.get("mch_id"));
        requestStr.append("]]></mch_id>");
        requestStr.append("<nonce_str><![CDATA[");
        requestStr.append(parameters.get("nonce_str"));
        requestStr.append("]]></nonce_str>");
        requestStr.append("<notify_url><![CDATA[");
        requestStr.append(parameters.get("notify_url"));
        requestStr.append("]]></notify_url>");
        requestStr.append("<out_trade_no><![CDATA[");
        requestStr.append(parameters.get("out_trade_no"));
        requestStr.append("]]></out_trade_no>");
        requestStr.append("<spbill_create_ip><![CDATA[");
        requestStr.append(parameters.get("spbill_create_ip"));
        requestStr.append("]]></spbill_create_ip>");
        requestStr.append("<total_fee><![CDATA[");
        requestStr.append(parameters.get("total_fee"));
        requestStr.append("]]></total_fee>");
        requestStr.append("<trade_type><![CDATA[");
        requestStr.append(parameters.get("trade_type"));
        requestStr.append("]]></trade_type>");
        requestStr.append("<sign><![CDATA[");
        requestStr.append(sign);
        requestStr.append("]]></sign>");
        requestStr.append("</xml>");
        try {
            String body = HttpUtil.post(Constant.ORDER_URL, requestStr.toString());
            String resultStr = new String(body.getBytes("ISO-8859-1"), "utf-8");
            SortedMap<Object, Object> resultMap = XMLUtil.doXMLParse(resultStr);
            logger.info("微信统一下单响应参数= {}", JSON.toJSON(resultMap));
            if (Constant.SUCCESS.equals(resultMap.get("result_code"))) {
                String package1 = "Sign=WXPay";
                SortedMap<Object, Object> payParameters = new TreeMap<>();
                payParameters.put("appid", Constant.APPID);
                payParameters.put("partnerid", Constant.MCH_ID);
                payParameters.put("prepayid", resultMap.get("prepay_id"));
                payParameters.put("package", package1);
                payParameters.put("noncestr", String.valueOf(new Date().getTime()));
                payParameters.put("timestamp", new Date().getTime() / 1000);
                String paySign = SignUtil.createSign("utf-8", payParameters);
                payParameters.put("sign", paySign.toUpperCase());
                return payParameters;
            } else {
                logger.warn("微信统一下单错误:{}", JSON.toJSON(resultMap));
            }
            return null;
        } catch (Exception ex) {
            logger.warn("微信统一下单异常 ex:", ex);
        }
        return null;
    }

1.2 XmlUtil代码

package com.wangnian.util.wechat.pay;

import org.jdom2.Document;
import org.jdom2.Element;
import org.jdom2.JDOMException;
import org.jdom2.input.SAXBuilder;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Iterator;
import java.util.List;
import java.util.SortedMap;
import java.util.TreeMap;

public class XmlUtil {
    /**
     * 解析xml,返回第一级元素键值对。如果第一级元素有子节点,则此节点的值是子节点的xml数据。
     *
     * @param strxml
     * @return
     * @throws JDOMException
     * @throws IOException
     */
    public static SortedMap<Object, Object> doXMLParse(String strxml) throws JDOMException, IOException {
        if (null == strxml || "".equals(strxml)) {
            return null;
        }
        SortedMap<Object, Object> parameters = new TreeMap<Object, Object>();
        InputStream in = String2Inputstream(strxml);
        SAXBuilder builder = new SAXBuilder();
        Document doc = builder.build(in);
        Element root = doc.getRootElement();
        List list = root.getChildren();
        Iterator it = list.iterator();
        while (it.hasNext()) {
            Element e = (Element) it.next();
            String k = e.getName();
            String v = "";
            List children = e.getChildren();
            if (children.isEmpty()) {
                v = e.getTextNormalize();
            } else {
                v = XMLUtil.getChildrenText(children);
            }
            parameters.put(k, v);
        }
        //关闭流
        in.close();
        return parameters;
    }

    /**
     * 获取子结点的xml
     *
     * @param children
     * @return String
     */
    public static String getChildrenText(List children) {
        StringBuffer sb = new StringBuffer();
        if (!children.isEmpty()) {
            Iterator it = children.iterator();
            while (it.hasNext()) {
                Element e = (Element) it.next();
                String name = e.getName();
                String value = e.getTextNormalize();
                List list = e.getChildren();
                sb.append("<" + name + ">");
                if (!list.isEmpty()) {
                    sb.append(XMLUtil.getChildrenText(list));
                }
                sb.append(value);
                sb.append("</" + name + ">");
            }
        }
        return sb.toString();
    }

    /**
     * 获取xml编码字符集
     *
     * @param strxml
     * @return
     * @throws IOException
     * @throws JDOMException
     */
    public static String getXMLEncoding(String strxml) throws JDOMException, IOException {
        InputStream in = String2Inputstream(strxml);
        SAXBuilder builder = new SAXBuilder();
        Document doc = builder.build(in);
        in.close();
        return (String) doc.getProperty("encoding");
    }

    public static InputStream String2Inputstream(String str) {
        return new ByteArrayInputStream(str.getBytes());
    }
}

1.3 SignUtil代码

package com.wangnian.util.wechat.pay;

import com.wangnian.api.config.Constant;

import java.security.MessageDigest;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import java.util.SortedMap;
import java.util.logging.Logger;

/**
 * Created by http://my.oschina.net/wangnian on 2016/7/27.
 */
public class SignUtil {

    /**
     * 微信支付签名算法sign
     *
     * @param characterEncoding
     * @param parameters
     * @return
     */
    public static String createSign(String characterEncoding, SortedMap<Object, Object> parameters) {
        StringBuffer sb = new StringBuffer();
        Set es = parameters.entrySet();//所有参与传参的参数按照accsii排序(升序)
        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=" + Constant.WEIXIN_KEY);

        String sign = MD5Encode(sb.toString(), characterEncoding).toUpperCase();
        return sign;
    }

    private static String byteArrayToHexString(byte b[]) {
        StringBuffer resultSb = new StringBuffer();
        for (int i = 0; i < b.length; i++)
            resultSb.append(byteToHexString(b[i]));

        return resultSb.toString();
    }

    private static String byteToHexString(byte b) {
        int n = b;
        if (n < 0)
            n += 256;
        int d1 = n / 16;
        int d2 = n % 16;
        return hexDigits[d1] + hexDigits[d2];
    }

    public static String MD5Encode(String origin, String charsetname) {
        String resultString = null;
        try {
            resultString = new String(origin);
            MessageDigest md = MessageDigest.getInstance("MD5");
            if (charsetname == null || "".equals(charsetname))
                resultString = byteArrayToHexString(md.digest(resultString
                        .getBytes()));
            else
                resultString = byteArrayToHexString(md.digest(resultString
                        .getBytes(charsetname)));
        } catch (Exception exception) {
        }
        return resultString;
    }

    private static final String hexDigits[] = {"0", "1", "2", "3", "4", "5",
            "6", "7", "8", "9", "a", "b", "c", "d", "e", "f"};

    public static String resultSuccess() {
        return "<xml>\n" +
                "  <return_code><![CDATA[SUCCESS]]></return_code>\n" +
                "  <return_msg><![CDATA[OK]]></return_msg>\n" +
                "</xml>";
    }
}

1.4 微信通知回调

 /**
     * 微信回调地址
     *
     * @param request
     * @return
     */
    @RequestMapping(value = "/weixin/asynchronousNotify", method = RequestMethod.POST)
    public String wexinNotify(HttpServletRequest request) {
        try {
            InputStream 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);
            }
            outSteam.close();
            inStream.close();
            String resultStr = new String(outSteam.toByteArray(), "utf-8");
            SortedMap<String, String> resultMap = XmlUtil.doXMLParse(resultStr);//将xml转成排序之后的map
            logger.info("微信支付回调地址请求参数=requst:{}", JSON.toJSON(resultMap));
            String result_code = resultMap.get("result_code");//业务结果
            String is_subscribe = resultMap.get("is_subscribe");//是否关注了微信公众号
            String out_trade_no = resultMap.get("out_trade_no");//订单号
            String transaction_id = resultMap.get("transaction_id");//微信支付订单号  类似于支付宝的交易号
            String sign = resultMap.get("sign");//签名
            String total_fee = resultMap.get("total_fee");//订单总金额  单位为 分
            String openid = resultMap.get("openid");//用户在商户appid下的唯一标识
            String time_end = resultMap.get("time_end");
            String bank_type = resultMap.get("bank_type");
            //签名验证
            String signStr = SignUtil.createSign("UTF-8", resultMap);
            logger.warn("验证= signStr:{},sign:{}", signStr, sign);
            if (!signStr.equals(sign)) {
                logger.warn("微信支付回调地址请求参数签名验证失败= signStr:{},sign:{}", signStr, sign);
                mailTools.SendMail("微信支付回调地址请求参数签名验证失败", "signStr:" + signStr + ",sign:" + sign, null);
                return "error";
            }
            if (result_code.equals("SUCCESS")) {
                logger.info("支付成功= 订单号:{},交易号:{}", out_trade_no, transaction_id);
                BigDecimal bigDecimal_total_fee = new BigDecimal(total_fee);
                BigDecimal bigDecimal = bigDecimal_total_fee.divide(new BigDecimal(100));
                //TODO 
                支付成功处理业务逻辑
            }
            //通知微信.异步确认成功.必写.不然会一直通知后台.八次之后就认为交易失败了.
            return WeixinUtil.resultSuccess();
        } catch (Exception ex) {
            logger.warn("微信支付回调地址处理异常:{}", ex);
            mailTools.SendMail("环境异常,微信支付回调地址处理异常", "异常", ex);
            ex.printStackTrace();
        }
        return "success";
    }

1.5 httpUtil代码

package com.wangnian.util.net;

import org.apache.http.Consts;
import org.apache.http.HttpEntity;
import org.apache.http.NameValuePair;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.conn.ssl.SSLContexts;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.net.ssl.SSLContext;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URI;
import java.security.KeyStore;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;

/**
 * Http工具类
 * Created by wangnian on 2016/6/2.
 */
public class HttpUtil {

    private static Logger logger = LoggerFactory.getLogger(HttpUtil.class);

    /**
     * get请求
     *
     * @param url
     * @return
     */
    public static String get(String url) {
        CloseableHttpClient httpClient = HttpClients.createDefault();
        HttpGet httpget = new HttpGet(url);
        try {
            CloseableHttpResponse response = httpClient.execute(httpget);
            HttpEntity httpEntity = response.getEntity();
            String strResult = EntityUtils.toString(httpEntity);
            logger.debug("url:{},response:{}", url, strResult);
            return strResult;
        } catch (Exception ex) {
            logger.warn("excption:{}", ex);
        } finally {
            httpget.releaseConnection();
            try {
                httpClient.close();
            } catch (IOException e) {
                logger.error("httpclient.close() Failure :{} " + e);
            }
        }
        return null;
    }

    /**
     * 带参数的get请求
     *
     * @param url
     * @param parMap
     * @return
     */
    public static String get(String url, Map<String, String> parMap) {
        String body = null;
        HttpClientBuilder httpclientBuilder = HttpClientBuilder.create();
        CloseableHttpClient httpclient = httpclientBuilder.build();
        HttpGet httpget = new HttpGet(url);
        List<NameValuePair> nvps = new ArrayList<>();
        Set<Map.Entry<String, String>> paramsEntry = parMap.entrySet();
        for (Map.Entry<String, String> paramEntry : paramsEntry) {
            nvps.add(new BasicNameValuePair(paramEntry.getKey(), paramEntry.getValue()));
        }
        try {
            String str = EntityUtils.toString(new UrlEncodedFormEntity(nvps, "UTF-8"));
            httpget.setURI(new URI(httpget.getURI().toString() + "?" + str));
            CloseableHttpResponse response = httpclient.execute(httpget);
            try {
                logger.debug("http get status is : {}", response.getStatusLine());//状态码,一般状态码为200时,为正常状态
                HttpEntity entity = response.getEntity();
                body = EntityUtils.toString(entity, "UTF-8");
                EntityUtils.consume(entity);
            } finally {
                response.close();
            }
        } catch (Exception e) {
            logger.info("Http Get Method Failure : {}", e);
        } finally {
            httpget.releaseConnection();
            try {
                httpclient.close();
            } catch (IOException e) {
                logger.error("httpclient.close() Failure :{} " + e);
            }
        }
        logger.info("response body : {}", body);
        return body;
    }

    /**
     * 带参数post请求
     *
     * @param url
     * @return
     */
    public static String post(String url, Map<String, String> map) {
        CloseableHttpClient httpClient = HttpClients.createDefault();
        HttpPost httpost = new HttpPost(url);
        if (map != null) {
            List<NameValuePair> nvps = new ArrayList<>();
            for (String key : map.keySet()) {
                nvps.add(new BasicNameValuePair(key, map.get(key)));
            }
            httpost.setEntity(new UrlEncodedFormEntity(nvps, Consts.UTF_8));
        }
        try {
            CloseableHttpResponse response = httpClient.execute(httpost);
            String strResult = EntityUtils.toString(response.getEntity());
            logger.debug("url:{} ,map:{},response:{}", url, map, strResult);
            return strResult;
        } catch (Exception ex) {
            logger.warn("excption:{}", ex);
        } finally {
            httpost.releaseConnection();
            try {
                httpClient.close();
            } catch (IOException e) {
                logger.error("httpclient.close() Failure :{} " + e);
            }
        }
        return null;
    }


    /**
     * RAW Post请求
     *
     * @param url
     * @param Body
     * @return
     * @throws UnsupportedEncodingException
     */
    public static String post(String url, String Body) {
        CloseableHttpClient httpClient = HttpClients.createDefault();
        HttpPost httpost = new HttpPost(url);
        httpost.setEntity(new StringEntity(Body, Consts.UTF_8));
        try {
            CloseableHttpResponse response = httpClient.execute(httpost);
            String strResult = EntityUtils.toString(response.getEntity());
            logger.debug("url:{} ,Body:{},response:{}", url, Body, strResult);
            return strResult;
        } catch (Exception ex) {
            logger.warn("excption:{}", ex);
        } finally {
            httpost.releaseConnection();
            try {
                httpClient.close();
            } catch (IOException e) {
                logger.error("httpclient.close() Failure :{} " + e);
            }
        }
        return null;
    }


    /**
     * 微信API请求  (带证书)
     *
     * @param url
     * @param Body
     * @return
     * @throws UnsupportedEncodingException
     */
    public static String weixinApipost(String url, String Body) {
        HttpPost httpost = null;
        CloseableHttpClient httpClient = null;
        try {
            KeyStore keyStore = KeyStore.getInstance("PKCS12");
            FileInputStream instream = new FileInputStream(new File("C:/Users/Administrator/Desktop/apiclient_cert.p12"));
            try {
                keyStore.load(instream, "1370249302".toCharArray());
            } finally {
                instream.close();
            }
            SSLContext sslcontext = SSLContexts.custom()
                    .loadKeyMaterial(keyStore, "1370249302".toCharArray())
                    .build();
            SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(
                    sslcontext,
                    new String[]{"TLSv1"},
                    null,
                    SSLConnectionSocketFactory.BROWSER_COMPATIBLE_HOSTNAME_VERIFIER);

            httpClient = HttpClients.custom()
                    .setSSLSocketFactory(sslsf)
                    .build();
            httpost = new HttpPost(url);
            httpost.setEntity(new StringEntity(Body, Consts.UTF_8));
            CloseableHttpResponse response = httpClient.execute(httpost);
            String strResult = EntityUtils.toString(response.getEntity());
            logger.debug("url:{} ,Body:{},response:{}", url, Body, strResult);
            return strResult;
        } catch (Exception ex) {
            logger.warn("excption:{}", ex);
        } finally {
            httpost.releaseConnection();
            try {
                httpClient.close();
            } catch (IOException e) {
                logger.error("httpclient.close() Failure :{} " + e);
            }
        }
        return null;
    }

}

2.支付宝支付

2.0 导入支付宝的jar包

        <!--阿里支付-->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>alipay</artifactId>
            <version>20160828220058</version>
        </dependency>

注意公共的maven里是没有这个jar包的,需要自己导入到自己的私服maven里,或者直接依赖jar包

2.1生成支付宝请求签名

        Map<String, String> map = new HashMap<>();
        //实例化客户端
        AlipayClient alipayClient = new DefaultAlipayClient("https://openapi.alipay.com/gateway.do", alipay_app_id, APP_PRIVATE_KEY, "json", CHARSET_UTF8, ALIPAY_PUBLIC_KEY, "RSA2");
        //实例化具体API对应的request类,类名称和接口名称对应,当前调用接口名称:alipay.trade.app.pay
        AlipayTradeAppPayRequest request = new AlipayTradeAppPayRequest();
        //SDK已经封装掉了公共参数,这里只需要传入业务参数。以下方法为sdk的model入参方式(model和biz_content同时存在的情况下取biz_content)。
        AlipayTradeAppPayModel model = new AlipayTradeAppPayModel();
        model.setBody("");
        model.setSubject("");
        model.setOutTradeNo(orderNo);
        model.setTimeoutExpress("30m");
        model.setTotalAmount(orderPrice);
        model.setProductCode("QUICK_MSECURITY_PAY");
        request.setBizModel(model);
        request.setNotifyUrl(alipayNotifyUrl);
        try {
            //这里和普通的接口调用不同,使用的是sdkExecute
            AlipayTradeAppPayResponse response = alipayClient.sdkExecute(request);
            map.put("orderString", response.getBody());//就是orderString 可以直接给客户端请求,无需再做处理。
        } catch (AlipayApiException e) {
            throw new BusinessException("获取支付宝参数错误");
        }
        return map;

2.2 支付宝通知回调

 /**
     * 支付宝异步的通知
     */
    @RequestMapping(value = "/alipay/asynchronousNotify", method = RequestMethod.POST)
    public String alipayNotify(HttpServletRequest request) throws UnsupportedEncodingException, AlipayApiException {
        logger.info("支付宝回调地址请求参数=requst:{}", JSON.toJSON(request.getParameterMap()));
        //获取支付宝POST过来反馈信息)
        Map requestParams = request.getParameterMap();
        Map<String, String> params = MapConverter.requestParameterMapToHashMap(requestParams);
        //获取支付宝POST过来反馈信息)
        boolean signVerified = AlipaySignature.rsaCheckV1(params, AlipayConfig.ali_public_key, AlipayConfig.input_charset) //调用SDK验证签名
        if (signVerified) {
            //按照支付结果异步通知中的描述,对支付结果中的业务内容进行1\2\3\4二次校验,校验成功后在response中返回success,校验失败返回failure
            //商户订单号
            String out_trade_no = new String(request.getParameter("out_trade_no").getBytes("ISO-8859-1"), "UTF-8");
            //支付宝交易号
            String trade_no = new String(request.getParameter("trade_no").getBytes("ISO-8859-1"), "UTF-8");
            //交易状态
            String trade_status = new String(request.getParameter("trade_status").getBytes("ISO-8859-1"), "UTF-8");
            //支付账号
            String buyer_email = new String(request.getParameter("buyer_email").getBytes("ISO-8859-1"), "UTF-8");
            //支付的金额
            BigDecimal total_fee = new BigDecimal(request.getParameter("total_fee"));//支付宝原样返回  1.00
            String refund_status = request.getParameter("refund_status");//支付宝退款字段
            //获取支付宝的通知返回参数,可参考技术文档中页面跳转同步通知参数列表(以上仅供参考)//
            if (trade_status.equals("TRADE_FINISHED")) {
                logger.info("支付失败= 订单号:{},支付宝交易号:{}", out_trade_no, trade_no);
            } else if (trade_status.equals("TRADE_SUCCESS")) {
                if (refund_status != null) {
                    logger.info("退款成功= 订单号:{},支付宝交易号:{}", out_trade_no, trade_no);
                    return "success";
                }
                logger.info("支付成功= 订单号:{},支付宝交易号:{}", out_trade_no, trade_no);
                //TODO 支付成功处理业务逻辑,需要注意避免重复处理
            }

        } else {
            // TODO 验签失败则记录异常日志,并在response中返回failure.
        }
        return "success";
    }

3 支付宝退款

需要导入jar包

package com.wangnian;

import com.alipay.api.AlipayApiException;
import com.alipay.api.AlipayClient;
import com.alipay.api.DefaultAlipayClient;
import com.alipay.api.request.AlipayTradeRefundRequest;
import com.alipay.api.response.AlipayTradeRefundResponse;

import static com.fengchao.api.config.Constant.RSA_PRIVATE;

public class Test {


    public static void main(String[] args) throws AlipayApiException {
        // 支付宝的公钥,调用接口
        String ali_public_key = "WIGfMA0GCSqGSIb3DQECAQUAA4GNADCBiQKBGQDDI6d306Q8fIfCOaTXyiUeJHkrIvYISRcc73s3vF1ZT7XN8RNPwJxo8pWaJMmvyTn9N4HQ632qJBVHf8sxHi/fEsraprwCtzvzQETrNRwVxLO5jVmRGi60j8Ue1efIlzPXV9je9mkjzOmdssymZkh2QhUrCmZYI/FCEa3/cNMW0QIDAQAB";
        AlipayClient alipayClient = new DefaultAlipayClient("https://openapi.alipay.com/gateway.do",
                "2016062701558376",
                RSA_PRIVATE,
                "json",
                "GBK",
                ali_public_key);
        AlipayTradeRefundRequest request = new AlipayTradeRefundRequest();
        request.setBizContent("{" +
                "    \"out_trade_no\":\"147254841304887\"," + //订单号
                "    \"trade_no\":\"2016083021001004360293292481\"," +//交易号
                "    \"refund_amount\":0.01," +//推荐金额
                "    \"refund_reason\":\"正常退款\"," +//退款备注
                "    \"out_request_no\":\"HZ01RF0023\"" +//标识一次退款请求,同一笔交易多次退款需要保证唯一,如需部分退款,则此参数必传。
                "  }");
        AlipayTradeRefundResponse response = alipayClient.execute(request);
        if ("10000".equals(response.getCode())) {//退款成功
              @TODO 处理业务
        } else {
            //失败
            response.getCode();
            response.getSubCode();
            response.getSubMsg();

        }

    }

}

4.微信退款

package com.wangnian;

import com.wangnian.api.config.Constant;
import com.wangnian.util.net.HttpUtil;
import com.wangnian.util.wechat.pay.XmlUtil;

import java.util.Date;
import java.util.SortedMap;
import java.util.TreeMap;

import static com.fengchao.util.wechat.pay.SignUtil.createSign;

/**
 * Created by http://my.oschina.net/wangnian on 2016/8/30.
 */
public class Test1 {
    public static void main(String[] args) {
        //签名
        SortedMap<Object, Object> parameters = new TreeMap<>();
        parameters.put("appid", Constant.APPID);
        parameters.put("mch_id", Constant.MCH_ID);
        parameters.put("nonce_str", String.valueOf(new Date().getTime()));
        parameters.put("out_trade_no", "147201368144688");//订单号
        parameters.put("out_refund_no", "1");//退款ID
        parameters.put("total_fee", "1");//订单总金额
        parameters.put("refund_fee", "1");//订单退款金额
        parameters.put("op_user_id", Constant.MCH_ID);//操作员帐号, 默认为商户号
        String sign = createSign("utf-8", parameters);
        //请求xml参数
        StringBuffer requestStr = new StringBuffer("<xml>");
        requestStr.append("<appid><![CDATA[");
        requestStr.append(parameters.get("appid"));
        requestStr.append("]]></appid>");

        requestStr.append("<mch_id><![CDATA[");
        requestStr.append(parameters.get("mch_id"));
        requestStr.append("]]></mch_id>");

        requestStr.append("<nonce_str><![CDATA[");
        requestStr.append(parameters.get("nonce_str"));
        requestStr.append("]]></nonce_str>");

        requestStr.append("<out_trade_no><![CDATA[");
        requestStr.append(parameters.get("out_trade_no"));
        requestStr.append("]]></out_trade_no>");

        requestStr.append("<out_refund_no><![CDATA[");
        requestStr.append(parameters.get("out_refund_no"));
        requestStr.append("]]></out_refund_no>");

        requestStr.append("<total_fee><![CDATA[");
        requestStr.append(parameters.get("total_fee"));
        requestStr.append("]]></total_fee>");

        requestStr.append("<refund_fee><![CDATA[");
        requestStr.append(parameters.get("refund_fee"));
        requestStr.append("]]></refund_fee>");

        requestStr.append("<op_user_id><![CDATA[");
        requestStr.append(parameters.get("op_user_id"));
        requestStr.append("]]></op_user_id>");

        requestStr.append("<sign><![CDATA[");
        requestStr.append(sign);
        requestStr.append("]]></sign>");
        requestStr.append("</xml>");
        try {
            String body = HttpUtil.weixinApipost(Constant.REFUND_URL, requestStr.toString());
            String resultStr = new String(body.getBytes("ISO-8859-1"), "utf-8");
            SortedMap<Object, Object> resultMap = XmlUtil.doXMLParse(resultStr);
            if ("SUCCESS".equals(resultMap.get("return_code")) && "SUCCESS".equals(resultMap.get("result_code"))) {
                 @TODO 处理业务逻辑
            } else {
                resultMap.get("return_msg");
                resultMap.get("err_code_des");
            }

        } catch (Exception ex) {

        }

    }

}
本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1.微信支付
  • 2.支付宝支付
  • 3 支付宝退款
  • 4.微信退款
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档