網站對接支付寶即時到賬接口步驟


1:必須由公司去支付寶申請簽約(申請地址:https://b.alipay.com/order/productDetail.htm?productId=2015110218012942);

2:申請好后就可以獲取到PID(以2088開頭的16位純數字),下載RSA密鑰,解密后結果就是后面代碼里的KEY;

3:在代碼里拼裝好接口需要的參數,發送一個post請求到支付寶網關(https://mapi.alipay.com/gateway.do)就OK

4:支付寶響應包含同步和異步方式(按時間段最多6次,稱為最大補償策略),同步方式可以在你本地調試,而異步回調要求你的環境在外網,僅支持https,而且不要用.do?methodname 這種方式的url,建議用restful風格的url,要不接收不到的(當時這個我算是入坑了)

下面我貼上比較核心代碼分享:

 

1)支付寶操作工具類

package com.vstecs.system.core.pay.alipay;

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.security.MessageDigest;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

/**
 * 支付寶工具類 <br>
 *
 * @function Service Api.
 * @author zhangyi
 * @date 2017年2月6日 下午5:01:31
 * @version 1.0.0
 * @since JDK 1.8
 */
public class AlipayCore {

    private static Log log = LogFactory.getLog(AlipayCore.class);

    // 支付寶提供給商戶的服務接入網關URL(新)
    public static final String GATEWAY = "https://mapi.alipay.com/gateway.do";

    // 商戶的私鑰
    public static final String KEY = "不給看";

    // 合作身份者ID,以2088開頭由16位純數字組成的字符串
    public static final String PARTNER = "2088不給看";

    // 字符編碼格式 目前支持 gbk 或 utf-8
    public static final String INPUT_CHARSET = "utf-8";

    // 收款支付寶賬號,一般情況下收款賬號就是簽約賬號
    public static final String SELLER_EMAIL = "不給看";

    // 簽名方式 不需修改
    public static final String SIGN_TYPE = "MD5";

    // 簽名時需要忽略的參數集合
    private static List<String> ignore;

    // 初始化
    static {
        ignore = new ArrayList<String>();
        ignore.add("sign");
        ignore.add("sign_type");
    }

    /**
     * 
     * 簽名
     * 
     * @param map
     * @return
     * 
     */
    public static String sign(Map<String, String> map) {

        log.debug("簽名參數(map):" + map);

        // 過濾空參
        if (map == null || map.isEmpty()) {
            return null;
        }

        // 排序參數
        List<String> keys = new ArrayList<String>(map.keySet());
        Collections.sort(keys);

        // 過濾空參,組裝參數鍵值
        StringBuffer sb = new StringBuffer();
        for (int i = 0; i < keys.size(); i++) {

            String key = keys.get(i);
            String value = map.get(key);

            if (isEmpty(key, value) || ignore.contains(key)) {
                continue;
            }

            sb.append(sb.length() > 0 ? "&" : "");
            sb.append(key).append("=").append(value);

        }
        sb.append(KEY);

        log.debug("待簽名字符串:" + sb.toString());

        // 獲取MD5簽名
        try {
            return MD5Encode(sb.toString(), "UTF-8");
        } catch (Exception e) {
            log.error("簽名發生異常:", e);
            return null;
        }

    }

    /**
     * 
     * 空值校驗
     * 
     * @param input
     * @return
     * 
     */
    private static boolean isEmpty(String... input) {

        if (input == null || input.length == 0) {
            return true;
        }

        for (String s : input) {
            if (s == null || s.length() == 0) {
                return true;
            }
        }

        return false;

    }

    /**
     * 
     * 校驗
     * 
     * @param map
     * @return
     * 
     */
    public static boolean verify(Map<String, String> map) {

        log.debug("校驗參數(map):" + map);

        // 過濾空參
        if (map == null || map.isEmpty()) {
            return false;
        }

        String sign = map.get("sign");
        String signType = map.get("sign_type");
        String notifyId = map.get("notify_id");

        // 過濾不匹配參數
        if (isEmpty(sign, notifyId) || !SIGN_TYPE.equals(signType)) {
            log.debug("參數不匹配!");
            return false;
        }

        // 校驗簽名
        if (!sign.equals(sign(map))) {
            log.debug("簽名不匹配!");
            return false;
        }

        // 校驗 notify_id
        String result = "false";
        try {
            URL url = new URL(GATEWAY + "?service=notify_verify&partner=" + PARTNER + "&notify_id=" + notifyId);
            HttpURLConnection conn = (HttpURLConnection) url.openConnection();
            BufferedReader br = new BufferedReader(new InputStreamReader(conn.getInputStream()));
            result = br.readLine();
            br.close();
            conn.disconnect();
        } catch (Exception e) {
            log.error("校驗(notify_id)發生異常:" + e);
            return false;
        }

        log.debug("校驗(notify_id)結果:" + result);

        return "true".equals(result);

    }

    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 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];
    }

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

2)業務操作

        alipay(params, request, response);
        
    // 支付寶支付
    private void alipay(Map<String, String> params, HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        Map<String, String> map = new HashMap<String, String>();
        map.put("_input_charset", AlipayCore.INPUT_CHARSET); // 編碼
        map.put("service", "create_direct_pay_by_user");

        map.put("partner", AlipayCore.PARTNER); // 合作身份者ID
        map.put("seller_email", AlipayCore.SELLER_EMAIL); // 收款支付寶賬號

        map.put("subject", "訂單號:" + params.get("orderNo")); // 訂單名稱
        map.put("body", "訂單號:" + params.get("orderNo")); // 訂單描述

        map.put("out_trade_no", params.get("orderNo")); // 商戶訂單號
        map.put("total_fee", params.get("totalPrice")); // 付款金額
        map.put("payment_type", "1"); // 支付類型,必填,不能修改

        map.put("show_url", getBasePath(request) + "/pay/book"); // 這個是你支付成功后需要展示的頁面
        map.put("notify_url", getBasePath(request) + "/pay/Notify"); // 服務器異步通知
        map.put("return_url", getBasePath(request) + "/pay/Return"); // 頁面跳轉同步通知

        // 注意:以下參數需在簽名生成后加入
        map.put("sign", AlipayCore.sign(map));
        map.put("sign_type", AlipayCore.SIGN_TYPE); // 簽名方式 不需修改
        map.put("gateway", AlipayCore.GATEWAY); // 支付寶提供給商戶的服務接入網關URL(新)

        /* ----- 跳轉 ----- */
        request.setAttribute("alipay", map);
        request.getRequestDispatcher("/WEB-INF/pay/alipay/alipay.jsp").forward(request, response);
    }

3)頁面

<c:if test="${empty alipay}"><c:redirect url="${basePath}/pay/book" /></c:if>

<c:if test="${not empty alipay}">

    <c:redirect url="${alipay['gateway']}">

        <c:param name="_input_charset" value="${alipay['_input_charset']}" />
        <c:param name="service" value="${alipay['service']}" />

        <c:param name="partner" value="${alipay['partner']}" />
        <c:param name="seller_email" value="${alipay['seller_email']}" />

        <c:param name="subject" value="${alipay['subject']}" />
        <c:param name="body" value="${alipay['body']}" />

        <c:param name="out_trade_no" value="${alipay['out_trade_no']}" />
        <c:param name="total_fee" value="${alipay['total_fee']}" />
        <c:param name="payment_type" value="${alipay['payment_type']}" />

        <c:param name="show_url" value="${alipay['show_url']}" />
        <c:param name="notify_url" value="${alipay['notify_url']}" />
        <c:param name="return_url" value="${alipay['return_url']}" />

        <c:param name="sign" value="${alipay['sign']}" />
        <c:param name="sign_type" value="${alipay['sign_type']}" />

    </c:redirect>

</c:if>

4)頁面的包結構,其中notify.jsp和return.jsp都是空文件

 

到這一步,應該就差不多了,里面的MD5加密未提供,這個簡單應該都會,如果有不會的我再貼:>

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM