支付宝支付(JAVA)
开始
- 首先,我们需要支付宝的SDK,地址:开发平台文档中心
- app-id:商家id,可以在支付宝蚂蚁金服商家登录后,在开发平台的产品配置中获得
- merchant-private-key:商家私钥,刚才我们下载了Alipay的SDK,里面有商家私钥和公钥的生产,这里是商家私钥
- alipay-public-key:商家支付宝公钥,刚才我们生产的商家公钥还没使用,我们可以在支付宝产品配置
- notify-url:异步回调路径,客户支付成功后回调的页面,在我们下载的demo的其中页面。
- return-url:同步回调路径,客户支付成功后回调的页面,在我们下载的demo的其中页面。
- sign-type:签名方式,支持RSA和RSA2,我们采用的是RSA2。
- gatewayurl:请求网关
- 一些工具类
- AlipayConfig.class
public final class AlipayConfig {
// 应用ID,您的APPID,收款账号既是您的APPID对应支付宝账号
public static String app_id = "";
// 商户私钥,您的PKCS8格式RSA2私钥
public static String merchant_private_key = "";
// 支付宝公钥,查看地址:https://openhome.alipay.com/platform/keyManage.htm 对应APPID下的支付宝公钥。
public static String alipay_public_key = "";
// 服务器异步通知页面路径 需http://格式的完整路径,不能加?id=123这类自定义参数,必须外网可以正常访问
public static String notify_url = "/alipay/notify_url.jsp";
// 页面跳转同步通知页面路径 需http://格式的完整路径,不能加?id=123这类自定义参数,必须外网可以正常访问
public static String return_url = "/alipay/return_url.jsp";
// 签名方式
public static String sign_type = "RSA2";
// 签名
public static String sign = "";
// 字符编码格式
public static String charset = "utf-8";
// 支付宝网关
public static String gatewayurl = "https://openapi.alipay.com/gateway.do";
}
2. AlipayUtils.class
public final class AlipayUtils {
/**
* 默认支付宝订单支付
* @param productNum 产品号
* @param amount 金额
* @return
* @throws AlipayApiException
*/
public static AlipayTradePagePayRequest installAlipayTradePagePayRequestToFormExclude(String productNum, double amount) throws AlipayApiException {
return installAlipayTradePagePayRequestToForm(productNum, amount, "订单支付", "订单支付");
}
/**
* 带标题和内容支付宝支付
* @param productNum 产品号
* @param amount 金额
* @param subject 标题
* @param body 内容
* @return
* @throws AlipayApiException
*/
public static AlipayTradePagePayRequest installAlipayTradePagePayRequestToForm(String productNum, double amount, String subject, String body) throws AlipayApiException {
AlipayTradePagePayRequest alipayRequest = new AlipayTradePagePayRequest();//创建API对应的request
alipayRequest.setReturnUrl(AlipayConfig.return_url);
alipayRequest.setNotifyUrl(AlipayConfig.notify_url);//在公共参数中设置回跳和通知地址
JsonObject jsonObject = new JsonObject();
jsonObject.addProperty("out_trade_no", productNum);
jsonObject.addProperty("product_code", "FAST_INSTANT_TRADE_PAY");
jsonObject.addProperty("total_amount", amount);//amount
jsonObject.addProperty("subject", subject);
jsonObject.addProperty("body", body);
alipayRequest.setBizContent(jsonObject.toString());//填充业务参数
return alipayRequest; //调用SDK生成表单
}
}
-
调用
/* 支付宝 */ AlipayClient alipayClient = new DefaultAlipayClient(AlipayConfig.gatewayurl, AlipayConfig.app_id, AlipayConfig.merchant_private_key, "json", AlipayConfig.charset, AlipayConfig.alipay_public_key, AlipayConfig.sign_type); //获得初始化的AlipayClient AlipayTradePagePayRequest alipayRequest = AlipayUtils.installAlipayTradePagePayRequestToFormExclude(自己生成的商品号,金额); String form = alipayClient.pageExecute(alipayRequest).getBody();//请求响应的表单 /* 将表单写出到页面 */ httpResponse.setHeader("Content-type", "text/html;charset=UTF-8"); httpResponse.setCharacterEncoding("UTF-8"); httpResponse.getOutputStream().write(form.getBytes("utf-8")); httpResponse.getOutputStream().close();
-
alipay demo的jsp页面
-
notify_url.jsp(异步回调)
<% /* * * 功能:支付宝服务器异步通知页面 * 日期:2017-03-30 * 说明: * 以下代码只是为了方便商户测试而提供的样例代码,商户可以根据自己网站的需要,按照技术文档编写,并非一定要使用该代码。 * 该代码仅供学习和研究支付宝接口使用,只是提供一个参考。 *************************页面功能说明************************* * 创建该页面文件时,请留心该页面文件中无任何HTML代码及空格。 * 该页面不能在本机电脑测试,请到服务器上做测试。请确保外部可以访问该页面。 * 如果没有收到该页面返回的 success * 建议该页面只做支付成功的业务逻辑处理,退款的处理请以调用退款查询接口的结果为准。 */ //获取支付宝POST过来反馈信息 Map
params = new HashMap (); Map requestParams = request.getParameterMap(); for (Iterator iter = requestParams.keySet().iterator(); iter.hasNext(); ) { String name = (String) iter.next(); String[] values = (String[]) requestParams.get(name); String valueStr = ""; for (int i = 0; i < values.length; i++) { valueStr = (i == values.length - 1) ? valueStr + values[i] : valueStr + values[i] + ","; } //乱码解决,这段代码在出现乱码时使用 valueStr = new String(valueStr.getBytes("ISO-8859-1"), "utf-8"); params.put(name, valueStr); } boolean signVerified = AlipaySignature.rsaCheckV1(params, AlipayConfig.alipay_public_key, AlipayConfig.charset, AlipayConfig.sign_type); //调用SDK验证签名 //——请在这里编写您的程序(以下代码仅作参考)—— /* 实际验证过程建议商户务必添加以下校验: 1、需要验证该通知数据中的out_trade_no是否为商户系统中创建的订单号, 2、判断total_amount是否确实为该订单的实际金额(即商户订单创建时的金额), 3、校验通知中的seller_id(或者seller_email) 是否为out_trade_no这笔单据的对应的操作方(有的时候,一个商户可能有多个seller_id/seller_email) 4、验证app_id是否为该商户本身。 */ if (signVerified) {//验证成功 //商户订单号 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 total_amount = new String(request.getParameter("total_amount").getBytes("ISO-8859-1"), "UTF-8"); if (trade_status.equals("TRADE_FINISHED")) { //判断该笔订单是否在商户网站中已经做过处理 //如果没有做过处理,根据订单号(out_trade_no)在商户网站的订单系统中查到该笔订单的详细,并执行商户的业务程序 //如果有做过处理,不执行商户的业务程序 //注意: //退款日期超过可退款期限后(如三个月可退款),支付宝系统发送该交易状态通知 } else if (trade_status.equals("TRADE_SUCCESS")) { // 可以在此作回调业务处理,比如流水单补上银行流水单号,支付状态等 } response.getOutputStream().println("success"); } else {//验证失败 response.getOutputStream().println("fail"); //调试用,写文本函数记录程序运行情况是否正常 //String sWord = AlipaySignature.getSignCheckContentV1(params); //AlipayConfig.logResult(sWord); } %> -
return_url.jsp(同步回调)
<% /* * * 功能:支付宝服务器同步通知页面 * 日期:2017-03-30 * 说明: * 以下代码只是为了方便商户测试而提供的样例代码,商户可以根据自己网站的需要,按照技术文档编写,并非一定要使用该代码。 * 该代码仅供学习和研究支付宝接口使用,只是提供一个参考。 *************************页面功能说明************************* * 该页面仅做页面展示,业务逻辑处理请勿在该页面执行 */ //获取支付宝GET过来反馈信息 Map
params = new HashMap (); Map requestParams = request.getParameterMap(); for (Iterator iter = requestParams.keySet().iterator(); iter.hasNext(); ) { String name = (String) iter.next(); String[] values = (String[]) requestParams.get(name); String valueStr = ""; for (int i = 0; i < values.length; i++) { valueStr = (i == values.length - 1) ? valueStr + values[i] : valueStr + values[i] + ","; } //乱码解决,这段代码在出现乱码时使用 // valueStr = new String(valueStr.getBytes("ISO-8859-1"), "utf-8"); params.put(name, valueStr); } boolean signVerified = AlipaySignature.rsaCheckV1(params, AlipayConfig.alipay_public_key, AlipayConfig.charset, AlipayConfig.sign_type); //调用SDK验证签名 //——请在这里编写您的程序(以下代码仅作参考)—— if (signVerified) { //商户订单号 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 total_amount = new String(request.getParameter("total_amount").getBytes("ISO-8859-1"), "UTF-8"); // 可以在此作回调业务处理,比如流水单补上银行流水单号,支付状态等 } else { out.println("验签失败"); } %>
-