网站对接支付宝即时到账接口步骤

时间:2022-08-06 03:23:27

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加密未提供,这个简单应该都会,如果有不会的我再贴:>