SpringMvc 集成支付宝沙盒测试
环境配置:
沙盒环境入口
网址:https://open.alipay.com/platform/developerIndex.htm
使用支付宝账号扫码登录,进入沙盒环境配置相关参数
配置沙盒环境参数
RSA2 秘钥官方配置文档:https://docs.open.alipay.com/291/105971
下载支付宝沙箱 app,用于沙箱扫码支付使用
下载支付宝沙盒demo地址
下载地址:http://p.tb.cn/rmsportal_6680_alipay.trade.page.pay-JAVA-UTF-8.zip
官方 demo 截图:
集成 Spring Mvc
项目结构
支付接口调用时序图
AlipayConfig配置文件
// 应用ID,您的APPID,收款账号既是您的APPID对应支付宝账号
public static String app_id = "2016101800716335";
// 商户私钥,您的PKCS8格式RSA2私钥
public static String merchant_private_key = "自己的商户私钥";
// 支付宝公钥,查看地址:https://openhome.alipay.com/platform/keyManage.htm 对应APPID下的支付宝公钥。
public static String alipay_public_key = "自己的支付宝公钥,如果签名方式是RSA2则选择RSA2对应 的支付宝公钥";
// 服务器异步通知页面路径 需http://格式的完整路径,不能加?id=123这类自定义参数,必须外网可以正常访问
public static String notify_url = "http://vyq8dp.natappfree.cc/aliPay_demo/syncNotice";
// 页面跳转同步通知页面路径 需http://格式的完整路径,不能加?id=123这类自定义参数,必须外网可以正常访问
public static String return_url = "http://vyq8dp.natappfree.cc/aliPay_demo/returnUrl";
// 签名方式
public static String sign_type = "RSA2";
// 字符编码格式
public static String charset = "utf-8";
// 支付宝网关
public static String gatewayUrl = "https://openapi.alipaydev.com/gateway.do";
支付Controller
@PostMapping(value = "aliPayQuickPay", produces = "text/plain;charset=utf-8")
public void aliPayQuickPay(QuickPayModel model, HttpServletResponse response) throws Exception {
//获得初始化的AlipayClient
AlipayClient alipayClient = new DefaultAlipayClient(AlipayConfig.gatewayUrl, AlipayConfig.app_id, AlipayConfig.merchant_private_key, "json", AlipayConfig.charset, AlipayConfig.alipay_public_key, AlipayConfig.sign_type);
//设置请求参数
AlipayTradePagePayRequest alipayRequest = new AlipayTradePagePayRequest();
alipayRequest.setReturnUrl(AlipayConfig.return_url);
alipayRequest.setNotifyUrl(AlipayConfig.notify_url);
alipayRequest.setBizContent("{\"out_trade_no\":\""+ model.getOrderNo() +"\","
+ "\"total_amount\":\""+ model.getOrderAmt() +"\","
+ "\"subject\":\""+ model.getOrderSubject() +"\","
+ "\"body\":\""+ model.getBusinessDesc() +"\","
+ "\"product_code\":\"FAST_INSTANT_TRADE_PAY\"}");
//请求
String result = alipayClient.pageExecute(alipayRequest).getBody();
//记录日志
AlipayConfig.logResult(result);
System.out.println(result);
response.setContentType("text/html;charset=" + "UTF-8");
response.getWriter().write(result);// 直接将完整的表单html输出到页面
response.getWriter().flush();
response.getWriter().close();
}
支付结果回调Controller
@RequestMapping("returnUrl")
public void returnUrl(HttpServletRequest request, HttpServletResponse response) throws Exception {
//获取支付宝GET过来反馈信息
Map<String,String> params = new HashMap<String,String>();
Map<String,String[]> requestParams = request.getParameterMap();
for (Iterator<String> 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);
}
System.out.println(params.toString());
boolean signVerified = AlipaySignature.rsaCheckV2(params, AlipayConfig.alipay_public_key, AlipayConfig.charset, AlipayConfig.sign_type); //调用SDK验证签名
PrintWriter out = response.getWriter();
//——请在这里编写您的程序(以下代码仅作参考)——
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");
out.println("trade_no:"+trade_no+"<br/>out_trade_no:"+out_trade_no+"<br/>total_amount:"+total_amount);
}else {
out.println("signVerified fail");
}
}
支付结果同步返回结果在本地就可以;
异步支付返回结果必须使用外网(可以使用内网穿透)
内网穿透可以参考https://blog.csdn.net/ejinxian/article/details/76061059
支付结果验签失败踩过的坑:
支付 jsp 页面
<form name=alipayment action="${root}/aliPayQuickPay" method=post
target="_blank">
<div id="body1" class="show" name="divcontent">
<dl class="content">
<dt>商户订单号 :</dt>
<dd>
<input id="orderNo" name="orderNo" />
</dd>
<hr class="one_line">
<dt>订单名称 :</dt>
<dd>
<input id="orderSubject" name="orderSubject" />
</dd>
<hr class="one_line">
<dt>付款金额 :</dt>
<dd>
<input id="orderAmt" name="orderAmt" />
</dd>
<hr class="one_line">
<dt>商品描述:</dt>
<dd>
<input id="businessDesc " name="businessDesc " />
</dd>
<hr class="one_line">
<dt></dt>
<dd id="btn-dd">
<span class="new-btn-login-sp">
<button class="new-btn-login" type="submit"
style="text-align: center;">付 款</button>
</span> <span class="note-help">如果您点击“付款”按钮,即表示您同意该次的执行操作。</span>
</dd>
</dl>
</div>
</form>
最后附上 demo 地址:https://github.com/Break0504/demo/tree/master/aliPay-demo