第一步:蚂蚁金服开放平台注册账号
该步骤的详细流程请参考蚂蚁金服官方说明,本示例主要关注Java后台代码的实现
第二步:下载SDK,安装到本地或远程Maven仓库
1. 进入下载的SDK的如下目录
alipay.trade.page.pay-JAVA-UTF-8\WebContent\WEB-INF\lib
2. 安装alipay-sdk-javaXXX.jar
mvn install:install-file -Dfile=D:\alipay.trade.page.pay-JAVA-UTF-8\WebContent\WEB-INF\lib alipay-sdk-java20170324180803.jar -DgroupId=com.bounter -DartifactId=bounter-alipay -Dversion=1.0.RELEASE -Dpackaging=jar
第三步:创建第三方支付Maven项目
1. 添加Maven依赖(这里支付宝的依赖包为上一步安装在本地的Jar)
<!-- alipay --> <dependency> <groupId>com.bounter</groupId> <artifactId>bounter-alipay</artifactId> <version>1.0.RELEASE</version> </dependency>
2. 创建支付宝支付的控制器、JSP页面
2.1 实现支付接口(简单的跳转到支付页面)
/** * 支付接口 * @param order * @return * @throws Exception */ @PostMapping("/alipay/pay") public String pay(AlipayOrder order) throws Exception { //跳转到支付页面 return "alipay.payPage"; }
2.2 创建支付页面(这里我直接拿的官方Demo里的页面修改而来,核心代码如下;该支付页面请求支付成功后会生成一个支付的二维码)
//获得初始化的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); //商户订单号,商户网站订单系统中唯一订单号,必填 String out_trade_no = new String(request.getParameter("out_trade_no")); //付款金额,必填 String total_amount = new String(request.getParameter("total_amount")); //订单名称,必填 String subject = new String(request.getParameter("subject")); //商品描述,可空 String body = new String(request.getParameter("body")); alipayRequest.setBizContent("{\"out_trade_no\":\""+ out_trade_no +"\"," + "\"total_amount\":\""+ total_amount +"\"," + "\"subject\":\""+ subject +"\"," + "\"body\":\""+ body +"\"," + "\"product_code\":\"FAST_INSTANT_TRADE_PAY\"}"); //请求 String result = alipayClient.pageExecute(alipayRequest).getBody(); //输出 out.println(result);
2.3 创建扫码支付成功后的回调接口和页面( 回调的URL必须公网可以访问,测试时可以使用花生壳等工具映射一个公网地址;成功页面可根据自己公司业务创建)
/** * 付款成功后同步跳转到商家页面 * @return */ @RequestMapping("/return_url") public String returnPage() { return "alipay.paySuccess"; }
2.4 创建支付成功异步回调的接口( 回调的URL必须公网可以访问,测试时可以使用花生壳等工具映射一个公网地址;支付是否成功以此回调为准,可以在这里实现支付成功后的业务处理,该结果不需要反馈给用户)
/** * 支付结果异步通知,POST方式,支付结果以异步通知内容为准 * @return * @throws Exception */ @PostMapping("/notify_url") public void notifyUrl(HttpServletRequest request, HttpServletResponse response) throws Exception { //获取支付宝POST过来反馈信息 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] + ","; } 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")); //交易状态 String trade_status = new String(request.getParameter("trade_status")); //验证该通知数据中的out_trade_no是否为商户系统中创建的订单号 AlipayOrder order = alipayService.getOrder(out_trade_no); if(order != null) { //TODO:更新订单 if(trade_status.equals("TRADE_FINISHED")){ //判断该笔订单是否在商户网站中已经做过处理 //如果没有做过处理,根据订单号(out_trade_no)在商户网站的订单系统中查到该笔订单的详细,并执行商户的业务程序 //如果有做过处理,不执行商户的业务程序 //注意: //退款日期超过可退款期限后(如三个月可退款),支付宝系统发送该交易状态通知 }else if (trade_status.equals("TRADE_SUCCESS")){ //判断该笔订单是否在商户网站中已经做过处理 //如果没有做过处理,根据订单号(out_trade_no)在商户网站的订单系统中查到该笔订单的详细,并执行商户的业务程序 //如果有做过处理,不执行商户的业务程序 //注意: //付款完成后,支付宝系统发送该交易状态通知 } System.out.println("success"); //通知支付宝交易成功,否则支付宝会一直尝试异步通知 response.getWriter().println("success"); } } else { System.out.println("fail"); response.getWriter().println("fail"); } }
2.5 实现交易退款接口
/** * 统一收单交易退款接口 * @param order * @return * @throws Exception */ @PostMapping("/alipay/refund") public void refund(AlipayOrder order, HttpServletResponse response) throws Exception { //创建退款请求,设置请求参数 AlipayTradeRefundRequest alipayRequest = new AlipayTradeRefundRequest(); alipayRequest.setBizContent("{\"out_trade_no\":\""+ order.getOut_trade_no() +"\"," + "\"trade_no\":\""+ order.getTrade_no() +"\"," + "\"refund_amount\":\""+ order.getRefund_amount() +"\"," + "\"refund_reason\":\""+ order.getRefund_reason() +"\"," + "\"out_request_no\":\""+ order.getOut_request_no() +"\"}"); //调用SDK发起请求 String result = alipayClient.execute(alipayRequest).getBody(); //TODO:解析返回对象,更新系统订单状态 //输出 response.getWriter().println(result); }
至此,一个包含支付和退款功能的后台接口就做完了,下面就进行简单的测试
第四步:测试支付和退款
1. 运行项目
mvn jetty:run
2. 浏览器输入:
http://localhost:8080 打开测试首页(直接拿的官方Demo页面)
3. 测试支付
4. 测试退款
说明:当前项目仅实现了简单的支付和退款功能,代码大部分搬自官方示例,并不包括完整的支付流程,有什么不明白的地方,欢迎留言