alipay 移动端网页支付

最近做的项目,用到了支付,使用alipay 移动端支付,一开始一头雾水,总结一下,其实官方文档已经很详细了 ,本次总结全部基于沙箱测试。

环境

本文假设你已经有账户可以登陆


  1. 登陆完成后,进入开放平台-开发者中心-沙箱环境 这个一个测试环境,里面有一个默认app ,在沙箱账号菜单还有测试用的买家账号和余额。
    1. 配置公钥私钥,在沙箱环境中配置好应用公钥。
    2. 在项目中引入依赖
      1
      2
      3
      4
      5
      <dependency>
      <groupId>com.alipay.sdk</groupId>enter description here
      <artifactId>alipay-sdk-java</artifactId>
      <version>3.0.0</version>
      </dependency>

到这环境就ok了

开发

本篇以alipay移动端网页支付为例 官方文档中很详细 可以仔细阅读,下面简短说明


支付流程说明:

  1. 用户在页面下单。
  2. 后端接收页面请求调用alipay生成一个订单。
  3. alipay处理后返回给后端一个html,里面有formsubmit 按钮。
  4. 后端返回给页面,页面执行submit后,页面会调用支付宝支付页面,会打开本地支付宝(沙箱测试版)或网页登陆后支付。(沙箱版支付宝可在支付宝沙箱测试平台中进行下载),买家账号也可以在沙箱测试平台找到。
  5. 支付完成后,支付宝会回调你的后台,并且重定向你的前台。告诉你支付的结果。这两个地址是在请求支付宝的时候传的参数。
  6. 后台接收到回调将订单状态进行修改,如果你是在本地测试,注意你给支付宝的回调地址,支付宝处理完毕后,会根据这个地址调用你的服务,也就是说必须让回调地址可以外网访问,可使用ngrok 之类实现,推荐使用Sunny-Ngrok(目前有免费的通道)。
  7. 前端自动重定向到你给支付宝传的通知地址。

开发(官方实例)

开发主要由两个方法 调用支付宝生成订单和 接收支付宝回传的支付结果
本文实例可能并不适用于你项目的架构,在执行成功调通请求和回调后,可查看开源项目synergic-developing 示例。

调用支付宝生成订单

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
public void doPost(HttpServletRequest httpRequest,
HttpServletResponse httpResponse) throws ServletException, IOException {
AlipayClient alipayClient = new DefaultAlipayClient("https://openapi.alipay.com/gateway.do", APP_ID, APP_PRIVATE_KEY, "json", CHARSET, ALIPAY_PUBLIC_KEY, "RSA2"); //获得初始化的AlipayClient, 支付宝地址(改为沙箱测试地址),应用id(改为沙箱appid),应用私钥,数据格式,编码格式,阿里公钥(非应用公钥,设置为沙箱支付宝公钥),加密方式。
AlipayTradeWapPayRequest alipayRequest = new AlipayTradeWapPayRequest();//创建API对应的request
alipayRequest.setReturnUrl("http://domain.com/CallBack/return_url.jsp");//回跳地址页面302
alipayRequest.setNotifyUrl("http://domain.com/CallBack/notify_url.jsp");//通知地址服务端接收
alipayRequest.setBizContent("{" +
" \"out_trade_no\":\"20150320010101002\"," +
" \"total_amount\":\"88.88\"," +
" \"subject\":\"Iphone6 16G\"," +
" \"product_code\":\"QUICK_WAP_PAY\"" +
" }");//填充业务参数
String form="";
try {
form = alipayClient.pageExecute(alipayRequest).getBody(); //调用SDK生成表单
} catch (AlipayApiException e) {
e.printStackTrace();
}
httpResponse.setContentType("text/html;charset=" + CHARSET);
httpResponse.getWriter().write(form);//直接将完整的表单html输出到页面
httpResponse.getWriter().flush();
httpResponse.getWriter().close();
}

接收支付宝回传的支付结果

1
2
3
4
5
6
7
Map<String, String> paramsMap = ... //将异步通知中收到的所有参数都存放到map中
boolean signVerified = AlipaySignature.rsaCheckV1(paramsMap, ALIPAY_PUBLIC_KEY, CHARSET, SIGN_TYPE) //调用SDK验证签名
if(signVerified){
// TODO 验签成功后,按照支付结果异步通知中的描述,对支付结果中的业务内容进行二次校验,校验成功后在response中返回success并继续商户自身业务处理,校验失败返回failure
}else{
// TODO 验签失败则记录异常日志,并在response中返回failure.
}

遇到的问题

在开发中遇到一个问题,回调接口,提示验签失败,后排查发现是在调用alipay生成订单的时候alipayClient中设置支付宝公钥设置错了,设置成了应用公钥了,这里必须设置支付宝公钥,在沙箱测试平台中可以找到支付宝公钥。