JAVA移動支付微信和支付寶後臺代碼

前言:以前接APP支付,微信遇到了一點點坑,爲了方便之後copy,把以前寫的代碼粘貼出來。須要的同窗能夠參考一下,具體參數說明還請詳細查看官方文檔:php

支付寶回調參數說明:https://doc.open.alipay.com/docs/doc.htm?treeId=193&articleId=105301&docType=1java

微信支付回調參數:https://pay.weixin.qq.com/wiki/doc/api/app/app.php?chapter=9_7&index=3git

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 微信統一下單apache

/**
     * 統一下單
     *
     * @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代碼json

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代碼api

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代碼app

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包dom

<!--阿里支付-->
        <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) {

        }

    }

}

 

博客地址:https://my.oschina.net/wangnian

相關文章
相關標籤/搜索