应用场景:
商户出售商品,用户购买支付,商户接入第三方支付平台支付宝
对接要求:
1、先创建网页&移动应用点击打开链接,提交并且通过审核后才能进行对接
2、开发者调用接口前需要先生成RSA2密钥,RSA密钥包含应用私钥(APP_PRIVATE_KEY)、应用公钥(APP_PUBLIC_KEY)。生成密钥后在开放平台管理中心进行密钥配置,配置完成后可以获取支付宝公钥(ALIPAY_PUBLIC_KEY)
3、搭建和配置开发环境
下载服务端SDK:
<!-- https://mvnrepository.com/artifact/com.alipay.sdk/alipay-sdk-java --> <dependency> <groupId>com.alipay.sdk</groupId> <artifactId>alipay-sdk-java</artifactId> <version>3.0.0</version> </dependency>
对接流程:
1、封装参数,申请接入支付宝支付,会有APPID,公钥私钥等参数。
2、支付流程
-
- 发起一个支付请求(携带订单号,价格等参数)到支付宝统一下单接口,生成预支付路径,响应给客户端浏览器。
- 用户进行扫码或者在页面登录支付宝支付。
- 服务端异步接收支付结果。
①:发起支付请求
@RequestMapping("gotoPay") public void gotoPay(HttpServletRequest httpRequest,HttpServletResponse httpResponse) throws ServletException, IOException { AlipayClient alipayClient = new DefaultAlipayClient("https://openapi.alipay.com/gateway.do", APP_ID, APP_PRIVATE_KEY, FORMAT, CHARSET, ALIPAY_PUBLIC_KEY, SIGN_TYPE); //获得初始化的AlipayClient AlipayTradePagePayRequest alipayRequest = new AlipayTradePagePayRequest();//创建API对应的request alipayRequest.setReturnUrl("http://domain.com/CallBack/returnURL.html");//回跳地址 alipayRequest.setNotifyUrl("http://domain.com/CallBack/notifyURL.html");//通知地址 alipayRequest.setBizContent("{" + " \"out_trade_no\":\"20150320010101001\"," + //订单号(支付宝要求商户订单号必须唯一) " \"product_code\":\"FAST_INSTANT_TRADE_PAY\"," + //销售产品码,与支付宝签约的产品码名称,目前仅支持FAST_INSTANT_TRADE_PAY。 " \"total_amount\":88.88," + //价格 " \"subject\":\"Iphone6 16G\"," + //订单标题 " \"body\":\"Iphone6 16G\"," + //订单描述 " \"passback_params\":\"merchantBizType%3d3C%26merchantBizNo%3d2016010101111\"," + //公用回传参数,如果请求时传递了该参数,则返回给商户时会回传该参数。支付宝只会在异步通知时将该参数原样返回。本参数必须进行UrlEncode之后才可以发送给支付宝 " \"extend_params\":{" + //业务扩展参数 " \"sys_service_provider_id\":\"2088511833207846\"" + //系统商编号,该参数作为系统商返佣数据提取的依据,请填写系统商签约协议的PID " }"+ " }");//填充业务参数 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(); }
②、用户确认支付后,支付宝get请求returnUrl(将网页重定向到何处)
@RequestMapping(value = "returnURL", method = RequestMethod.GET) public String returnURL(Device device) { System.out.println("支付宝处理完毕后返回商户网站"); if (device.isNormal()) { return "shop/alipay/payResult"; } else { return "mobile/alipay/payResult"; } }
③、交易成功后,支付宝post请求notifyUrl
@RequestMapping(value = "notifyURL", method = RequestMethod.POST) public void notifyURL(HttpServletRequest httpRequest){ //将异步通知中收到的所有参数都存放到map中 ↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓ Map<String, String> paramsMap = MapUtil.map(); Map<String, String[]> requestParams = request.getParameterMap(); for (Object element : requestParams.keySet()) { String name = (String) element; String[] values = requestParams.get(name); StringBuilder valueStr = new StringBuilder(); for (int i = 0; i < values.length; i++) { valueStr.append((i == values.length - 1) ? values[i] : values[i] + ","); } params.put(name, valueStr.toString()); } //将异步通知中收到的所有参数都存放到map中 ↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑ boolean signVerified = AlipaySignature.rsaCheckV1(paramsMap, ALIPAY_PUBLIC_KEY, CHARSET, SIGN_TYPE) //调用SDK验证签名 if(signVerfied){ // TODO 验签成功后,按照支付结果异步通知中的描述,对支付结果中的业务内容进行二次校验,校验成功后在response中返回success并继续商户自身业务处理,校验失败返回failure }else{ // TODO 验签失败则记录异常日志,并在response中返回failure. } }
④、若由于网络等问题异步通知没有到达,商户可自行调用alipay.trade.query接口进行查询,根据查询接口获取交易以及支付信息(商户也可以直接调用查询接口,不需要依赖异步通知)。
public void query(){ AlipayClient alipayClient = new DefaultAlipayClient("https://openapi.alipay.com/gateway.do","app_id","your private_key","json","GBK","alipay_public_key","RSA2"); AlipayTradeQueryRequest request = new AlipayTradeQueryRequest(); request.setBizContent("{" + "\"out_trade_no\":\"20150320010101001\"," + //订单支付时传入的商户订单号,和支付宝交易号不能同时为空。 "\"trade_no\":\"2014112611001004680 073956707\"" + //支付宝交易号,和商户订单号不能同时为空 " }"); AlipayTradeQueryResponse response = alipayClient.execute(request); if(response.isSuccess()){ //获取支付信息 System.out.println("调用成功"); } else { System.out.println("调用失败"); } }
⑤、交易发生后一段时间内,如果用户想退款,买家可以通过退款接口将支付款退给买家。
public void refund() throws AlipayApiException { AlipayClient alipayClient = new DefaultAlipayClient("https://openapi.alipay.com/gateway.do","app_id","your private_key","json","GBK","alipay_public_key","RSA2"); AlipayTradeRefundRequest request = new AlipayTradeRefundRequest(); request.setBizContent("{" + "\"out_trade_no\":\"20150320010101001\"," + "\"trade_no\":\"2014112611001004680073956707\"," + "\"refund_amount\":200.12," + "\"refund_currency\":\"USD\"," + "\"refund_reason\":\"正常退款\"," + "\"out_request_no\":\"HZ01RF001\"," + "\"operator_id\":\"OP001\"," + "\"store_id\":\"NJ_S_001\"," + "\"terminal_id\":\"NJ_T_001\"," + " \"goods_detail\":[{" + " \"goods_id\":\"apple-01\"," + "\"alipay_goods_id\":\"20010001\"," + "\"goods_name\":\"ipad\"," + "\"quantity\":1," + "\"price\":2000," + "\"goods_category\":\"34543238\"," + "\"body\":\"特价手机\"," + "\"show_url\":\"http://www.alipay.com/xxx.jpg\"" + " }]" + " }"); AlipayTradeRefundResponse response = alipayClient.execute(request); if(response.isSuccess()){ System.out.println("调用成功"); } else { System.out.println("调用失败"); } }
⑥、统一收单交易退款查询
public void queryRefund(){ AlipayClient alipayClient = new DefaultAlipayClient("https://openapi.alipay.com/gateway.do","app_id","your private_key","json","GBK","alipay_public_key","RSA2"); AlipayTradeFastpayRefundQueryRequest request = new AlipayTradeFastpayRefundQueryRequest(); request.setBizContent("{" + "\"trade_no\":\"20150320010101001\"," + "\"out_trade_no\":\"2014112611001004680073956707\"," + "\"out_request_no\":\"2014112611001004680073956707\"" + " }"); AlipayTradeFastpayRefundQueryResponse response = alipayClient.execute(request); if(response.isSuccess()){ System.out.println("调用成功"); } else { System.out.println("调用失败"); } }
⑦、统一收单交易关闭接口(用于交易创建后,用户在一定时间内未进行支付,可调用该接口直接将未付款的交易进行关闭。)
public void tradeClose(){ AlipayClient alipayClient = new DefaultAlipayClient("https://openapi.alipay.com/gateway.do","app_id","your private_key","json","GBK","alipay_public_key","RSA2"); AlipayTradeRefundRequest request = new AlipayTradeRefundRequest(); request.setBizContent("{" + "\"out_trade_no\":\"20150320010101001\"," + "\"trade_no\":\"2014112611001004680073956707\"," + "\"refund_amount\":200.12," + "\"refund_currency\":\"USD\"," + "\"refund_reason\":\"正常退款\"," + "\"out_request_no\":\"HZ01RF001\"," + "\"operator_id\":\"OP001\"," + "\"store_id\":\"NJ_S_001\"," + "\"terminal_id\":\"NJ_T_001\"," + " \"goods_detail\":[{" + " \"goods_id\":\"apple-01\"," + "\"alipay_goods_id\":\"20010001\"," + "\"goods_name\":\"ipad\"," + "\"quantity\":1," + "\"price\":2000," + "\"goods_category\":\"34543238\"," + "\"body\":\"特价手机\"," + "\"show_url\":\"http://www.alipay.com/xxx.jpg\"" + " }]" + " }"); AlipayTradeRefundResponse response = alipayClient.execute(request); if(response.isSuccess()){ System.out.println("调用成功"); } else { System.out.println("调用失败"); } }真心话,支付宝对接的API比微信写的强太多了 支付宝官方API