https://blog.csdn.net/u012552275/article/details/78320051
网上找了一个可以起吊支付宝的appdemo ,它集成了服务器端,我先将其分离为app和服务器端,保证app在接收参数后可以启调支付宝
(保证app这边是正确的 不然出错都不知道是服务器出错还是app出错),在
找网上资料修改服务器端,做好app请求接口,和支付宝的服务器回调接口
@RequestMapping("pay2.do")@ResponseBodypublic Object pay2(String money){try{AlipayClient alipayClient = new DefaultAlipayClient("https://openapi.alipaydev.com/gateway.do",PropertiesAlipayUtil.getProperty("appid"),PropertiesAlipayUtil.getProperty("private_key"),"json","UTF-8",PropertiesAlipayUtil.getProperty("public_key"),"RSA2");AlipayTradeAppPayRequest request = new AlipayTradeAppPayRequest();AlipayTradeAppPayModel model = new AlipayTradeAppPayModel();model.setOutTradeNo(getOutTradeNo() + "");// 订单号。model.setTimeoutExpress("30m");// 设置未付款支付宝交易的超时时间,一旦超时,该笔交易就会自动被关闭。当用户进入支付宝收银台页面(不包括登录页面),会触发即刻创建支付宝交易,此时开始计时。取值范围:1m~15d。m-分钟,h-小时,d-天,1c-当天(1c-当天的情况下,无论交易何时创建,都在0点关闭)。// 该参数数值不接受小数点, 如 1.5h,可转换为 90m。model.setTotalAmount("0.01");// 订单总金额,单位为元,精确到小数点后两位,取值范围[0.01,100000000]这里调试每次支付1分钱,在项目上线前应将此处改为订单的总金额model.setProductCode("QUICK_MSECURITY_PAY");// 销售产品码,商家和支付宝签约的产品码,为固定值QUICK_MSECURITY_PAYrequest.setBizModel(model);request.setNotifyUrl(PropertiesUtil.getProperty("alipay.callback.url.app")); // 设置后台异步通知的地址,在手机端支付成功后支付宝会通知后台,手机端的真实支付结果依赖于此地址// 根据不同的产品model.setBody("body");// 对一笔交易的具体描述信息。如果是多种商品,请将商品描述字符串累加传给body。model.setSubject("111商品的标题/交易标题/订单标题/订单关键字等");//break;// 这里和普通的接口调用不同,使用的是sdkExecuteAlipayTradeAppPayResponse response = alipayClient.sdkExecute(request);// 可以直接给客户端请求,无需再做处理。
// orders.setAliPayOrderString(response.getBody());
// baseResult.setData(orders);Map map = new HashMap();
// map.put("code",201);
// map.put("message","支付宝下单失败");map.put("orderString",response.getBody());return map;}catch (Exception e){e.printStackTrace();
// baseResult.setState(-999);
// baseResult.setMsg("程序异常!");
// baseResult.setSuccess(false);
// logger.error(e.getMessage());System.out.println("程序异常!");}return null;}@RequestMapping("alipay_callback.do")@ResponseBodypublic Object alipayCallback(HttpServletRequest request){System.out.println("alipay_callback 回调了"+request);//返回object 因为可能不止是字符串 这个要返回 alipay 按要求的格式返回//支付宝的回调会放到request中供 我们自己取 只要一个参数就好了//自己从新组装mapMap<String, String> params = Maps.newHashMap();//支付宝将回调放request中是数组Map<String, String[]> parameterParams = request.getParameterMap();for(Iterator iterator = parameterParams.keySet().iterator(); iterator.hasNext();){String key = (String) iterator.next();String[] values = parameterParams.get(key);//支付宝将回调放request中是数组String valueStr = "";for(int i = 0; i < values.length ; i++){//遍历数组 拼接之后 1,2,3,4valueStr = (i == values.length -1)? valueStr + values[i]: valueStr + values[i]+",";}自己从新组装mapparams.put(key,valueStr);}logger.info("支付宝回调,sign:{},trade_status:{},参数:{}",params.get("sign"),params.get("trade_status"),params.toString());//验证是不是我们的订单号 总价是不是对的 数量是不是对的 等等//非常重要,验证回调的正确性,是不是支付宝发的,并且能还要避免重复通知,这个说了好多次了ppt里面//我们使用rsa2 256位的进行验证 ctrl+shift+t 查class ctrl+o 查方法params.remove("sign_type");try {
// boolean alipoayRSACheckedV2 = AlipaySignature.rsaCheckV2(params, Configs.getAlipayPublicKey(),"utf-8",Configs.getSignType());boolean alipoayRSACheckedV2 = AlipaySignature.rsaCheckV1(params,PropertiesAlipayUtil.getProperty("public_key"),"utf-8", "RSA2");if(!alipoayRSACheckedV2){return ServerResponse.createByErrorMessage("验证不通过,非法请求,在恶意请求我就报网警了");}} catch (AlipayApiException e) {logger.error("支付宝验证回调异常",e);}//todo 验证各种数据 如果正确 减少库存 增加订单 修改状态 在service层做 你们下去自己做吧ServerResponse serverResponse = iOrderService.aliCallback(params);if(serverResponse.isSuccess()){return Const.AlipayCallback.RESPONSE_SUCCESS;}return Const.AlipayCallback.RESPONSE_FAILED;}/*** 要求外部订单号必须唯一。* @return*/public static String getOutTradeNo() {SimpleDateFormat format = new SimpleDateFormat("MMddHHmmss", Locale.getDefault());Date date = new Date();String key = format.format(date);Random r = new Random();key = key + r.nextInt();key = key.substring(0, 15);return key;}