一,简要说明: 支付宝支付大概分为2种方式:1.app支付 2.手机网站支付。所用的参数:appid,private_key,open_public_key也基本相同,感觉没有微信那么乱。但是使用的时候要确保是完整的一套,基本上报以上3个中参数错误,大概就是没有使用一套参数,另外sign_type签名方式也要注意,新旧版本不同,新的是RSA2(阿里推荐),旧的是RSA。
二.准备工作,申请账号>签约>配置,具体的有支付宝得到文档接口说:https://openhome.alipay.com/developmentDocument.htm“>这里写链接内容, 选择自己需要的按照文档来。
三.开发: 1.app支付代码 后台接口中的代码:
Map<String, String> params = OrderInfoUtil2_0.buildOrderParamMap(APP_ID, outTradeNo, subject,body, totalamount, UtilDate.getDateFormatter()); String orderParam = OrderInfoUtil2_0.buildOrderParam(params); String sign = OrderInfoUtil2_0.getSign(params, AlipayConfig.private_key); final String orderInfo = orderParam + "&" + sign;回调解析业务处理:
//异步通知ID String notify_id=request.getParameter("notify_id"); //sign String sign=request.getParameter("sign"); if(notify_id!=""&¬ify_id!=null){判断接受的post通知中有无notify_id,如果有则是异步通知。 if(AlipayNotify.verifyResponse(notify_id).equals("true"))//判断成功之后使用getResponse方法判断是否是支付宝发来的异步通知。 { if(AlipayNotify.getSignVeryfy(params, sign))//使用支付宝公钥验签 { //——请根据您的业务逻辑来编写程序(以下代码仅作参考)—— if(trade_status.equals("TRADE_FINISHED")){ //判断该笔订单是否在商户网站中已经做过处理 //如果没有做过处理,根据订单号(out_trade_no)在商户网站的订单系统中查到该笔订单的详细,并执行商户的业务程序 //如果有做过处理,不执行商户的业务程序 //注意: //退款日期超过可退款期限后(如三个月可退款),支付宝系统发送该交易状态通知 //请务必判断请求时的total_fee、seller_id与通知时获取的total_fee、seller_id为一致的 } else if (trade_status.equals("TRADE_SUCCESS")){ 《@@》 //自己的业务逻辑出来 }工具方法:
/** * 构造支付订单参数列表 * * @param pid * @param app_id * @param target_id * @return */ public static Map<String, String> buildOrderParamMap(String app_id,String outTradeNo,String subject,String body,String total_amount,String timestamp) { Map<String, String> keyValues = new HashMap<String, String>(); keyValues.put("app_id", app_id); keyValues .put("biz_content", "{\"timeout_express\":\"30m\",\"product_code\":\"QUICK_MSECURITY_PAY\",\"total_amount\":\""+total_amount+"\",\"subject\":\""+subject+"\",\"body\":\""+body+"\",\"out_trade_no\":\"" + outTradeNo + "\"}"); keyValues.put("charset", "utf-8"); keyValues.put("method", "alipay.trade.app.pay"); keyValues.put("sign_type", "RSA2"); keyValues.put("timestamp", timestamp); keyValues.put("notify_url", "回调地址"); keyValues.put("version", "1.0"); return keyValues; } /** * 构造支付订单参数信息 * * @param map * 支付订单参数 * @return */ public static String buildOrderParam(Map<String, String> map) { List<String> keys = new ArrayList<String>(map.keySet()); StringBuilder sb = new StringBuilder(); for (int i = 0; i < keys.size() - 1; i++) { String key = keys.get(i); String value = map.get(key); sb.append(buildKeyValue(key, value, true)); sb.append("&"); } String tailKey = keys.get(keys.size() - 1); String tailValue = map.get(tailKey); sb.append(buildKeyValue(tailKey, tailValue, true)); return sb.toString(); } /** * 拼接键值对 * * @param key * @param value * @param isEncode * @return */ private static String buildKeyValue(String key, String value, boolean isEncode) { StringBuilder sb = new StringBuilder(); sb.append(key); sb.append("="); if (isEncode) { try { sb.append(URLEncoder.encode(value, "UTF-8")); } catch (UnsupportedEncodingException e) { sb.append(value); } } else { sb.append(value); } return sb.toString(); } /** * 对支付参数信息进行签名 * * @param map 待签名授权信息 * @return */ public static String getSign(Map<String, String> map, String rsaKey) { List<String> keys = new ArrayList<String>(map.keySet()); // key排序 Collections.sort(keys); StringBuilder authInfo = new StringBuilder(); for (int i = 0; i < keys.size() - 1; i++) { String key = keys.get(i); String value = map.get(key); authInfo.append(buildKeyValue(key, value, false)); authInfo.append("&"); } String tailKey = keys.get(keys.size() - 1); String tailValue = map.get(tailKey); authInfo.append(buildKeyValue(tailKey, tailValue, false)); String oriSign = SignUtils.sign(authInfo.toString(), rsaKey); String encodedSign = ""; try { encodedSign = URLEncoder.encode(oriSign, "UTF-8"); } catch (UnsupportedEncodingException e) { e.printStackTrace(); } return "sign=" + encodedSign; } /** * 根据反馈回来的信息,生成签名结果 * @param Params 通知返回来的参数数组 * @param sign 比对的签名结果 * @return 生成的签名结果 */ public static boolean getSignVeryfy(Map<String, String> Params, String sign) { //过滤空值、sign与sign_type参数 Map<String, String> sParaNew = AlipayCore.paraFilter(Params); //获取待签名字符串 String preSignStr = AlipayCore.createLinkString(sParaNew); //获得签名验证结果 boolean isSign = false; if(AlipayConfig.sign_type.equals("RSA")){ isSign = RSA.verify(preSignStr, sign, open_public_key, charset); } return isSign; }2.网页支付:
首先 集成Alipay-sdk,本人用的是maven,具体可参考:这里写链接内容
public void doPost(HttpServletRequest httpRequest, HttpServletResponse httpResponse,String json, ModelMap modelMap)throws ServletException, IOException { AlipayClient alipayClient = new DefaultAlipayClient("https://openapi.alipay.com/gateway.do", APP_ID, private_key, "json", CHARSET, public_key, AlipayConfig.sign_type); //获得初始化的AlipayClient AlipayTradeWapPayRequest alipayRequest = new AlipayTradeWapPayRequest();//创建API对应的request alipayRequest.setReturnUrl("http://domain.com/CallBack/return_url.jsp"); alipayRequest.setNotifyUrl( "回调地址");//在公共参数中设置回跳和通知地址 Result result = new Result(); result.setStatus(ResultEnum.fail_blank.getCode()); //获取对应的参数值 try { String type =""; String subject = ""; String body = ""; String userid = ""; String money = "";//圆 alipayRequest.setBizContent("{" + " \"out_trade_no\":\""+outTradeNo+"\"," + " \"total_amount\":\""+money+"\"," + " \"subject\":\""+subject+"\"," + " \"body\":\""+subject+"\"," + " \"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(); } catch (Exception e) { e.printStackTrace(); result.setMsg(e.getMessage()); } }待续。