最近在接入支付宝和微信的app支付 , 之前因为大部分做的都是网页版的支付,没接触过app,这次把遇到的坑都记录下来。


首先 支付宝支付 https://openhome.alipay.com/platform/home.htm 先去这里 注册商户   然后就是填写一系列的资料 申请啊 什么的。  最后通过了。



登陆后  点击这个 

java支付宝账号绑定 java支付宝支付和微信支付_java支付宝账号绑定


  然后  

java支付宝账号绑定 java支付宝支付和微信支付_支付宝_02

 这样 就创建了 一个app支付的应用



——————


java支付宝账号绑定 java支付宝支付和微信支付_支付宝_03

 这个是你创建好的app  里面有我们需要的信息 



这地方 我们需要修改 

1. 应用网关 :修改为你服务器的ip或者域名  

2. 授权回调地址  修改为 : 你自己写好的 处理支付宝支付成功后的 业务逻辑 (@RequestMapping) 地址 

3. RSA 密钥  :你自己生成的 应用公钥  上传后 会得到  支付宝公钥  (回调时候需要 支付宝公钥 才可以获得支付宝传回来的参数)   (支付宝密钥生成 https://doc.open.alipay.com/docs/doc.htm?spm=a219a.7629140.0.0.Rju6nj&treeId=291&articleId=105971&docType=1)


4. 通过 密钥生成工具 得到  商户私钥  一定要保存好 后面签名的时候需要  而且要和 你自己生成的  公钥(不是支付宝的公钥 是你自己拿工具生成的)  对应 


5. appid : 上面图片里面的 你创建的应用的 id 

 

注意 !!!  授权回调 地址 默认为 80端口  不可以为其他端口  也就是说你本地是 不会回调的 或者 其他 比如  xx.12.34.9:8080/xx/notifyMobile  这是不行的 必须部署为 80端口  




java支付宝账号绑定 java支付宝支付和微信支付_java支付宝账号绑定_04


这就是 支付宝整个 签名过程 然后你把他 返回的 东西 给  ios 或者 android 就行了  就可以唤醒 手机端app 


以下是回调的代码 包括 微信和支付宝的回调 



//支付宝回调
	@RequestMapping(value = "/mobilePayNotify")
	public void alipayNotify(HttpServletRequest request, HttpServletResponse response) throws Exception {
		logger.info("$$$$alipayNotify进入!");
		try {
			// 获取支付宝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 = 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);
			}
			// 买家付款账号
			String buyer_logon_id = params.get("buyer_logon_id");
			BigDecimal total_amount = new BigDecimal(params.get("total_amount"));
			// 商户订单号
			String out_trade_no = params.get("out_trade_no");
			// 支付宝交易号
			String trade_no = params.get("trade_no");
			// 交易状态
			String trade_status = params.get("trade_status");
			String extraParam = "";
			int offset = out_trade_no.indexOf("_");
			if(offset>-1){
				extraParam = out_trade_no.substring(offset+1);
				out_trade_no = out_trade_no.substring(0,offset);
			}

			// 获得支付信息
			String payKey = PayPropertySupport.getProperty("pay.ali.publicKey");

			if (AlipayNotify.verifyMobileNotify(params, payKey)) {// 验证成功
				if (trade_status.equals("TRADE_FINISHED") || trade_status.equals("TRADE_SUCCESS")) {
					// 支付成功后执行相关业务
					
					logger.info("订单编号:"+out_trade_no+";支付金额:"+total_amount);
					
					afterPay(out_trade_no, trade_no,ConstantUtil.alipay);
					
				}
			} else {
				logger.info("$$$$alipayNotify验证失败——商户订单号:" + out_trade_no + ";支付宝交易号:" + trade_no + ",交易状态:" + trade_status);
			}
			ResponseUtils.renderText(response, "success");
		} catch (Exception e) {
			logger.info("$$$$alipayNotify业务逻辑异常:" + e.getMessage(), e);
			ResponseUtils.renderText(response, "fail");
		}
	}
	
	
	@RequestMapping("/wxMobileNotify")
	public void wxNotify(HttpServletRequest request, HttpServletResponse response) throws Exception {
		logger.info("@@@@收到微信支付信息,进入notify流程@@@@");
		try {
			InputStream in = request.getInputStream();
			String s = null;
			BufferedReader br = new BufferedReader(new InputStreamReader(in, "utf-8"));
			StringBuffer sb = new StringBuffer();
			while ((s = br.readLine()) != null) {
				sb.append(s);
			}
			br.close();
			in.close();
			Map<String, String> params = XMLUtil.doXMLParse(sb.toString());

			SortedMap<String, String> newParams = new TreeMap<String, String>(params);
			
			newParams.put("key", ConstantUtil.APP_KEY);

			String out_trade_no = (String) params.get("out_trade_no");

			String trade_no = (String) params.get("transaction_id");
			// 总金额,分
			String total = (String) params.get("total_fee");

			String respCode = (String) params.get("result_code");

			String openId = (String) params.get("openid");
			// 自定义参数
			String extraParam = (String) params.get("attach");
			if (WxPrepay.isValiSign(newParams)) {
				logger.info("@@@@验证成功@@@@");
				if (respCode != null && respCode.equals("SUCCESS")) {
					
					//支付成功后 业务逻辑 
					afterPay(out_trade_no, trade_no,ConstantUtil.wxpay);
					
				} else {
					logger.info("@@@@支付交易状态未知——订单号:" + out_trade_no + ";交易状态:" + respCode + ";微信支付订单号:" + trade_no);
				}
			} else {
				logger.info("@@@@验证失败@@@@");
			}
		} catch (Exception e) {
			logger.info("@@@@支付后业务逻辑异常" + e.getMessage() + "@@@@");
		}

	}
	
	public void afterPay(String out_trade_no,String trade_no,String payMethod){
		
		OrderPayExample example = new OrderPayExample();
		example.createCriteria().andOrderNoEqualTo(out_trade_no);
		List<OrderPay> list = orderPayService.selectByExample(example);
		
		//设置 单个订单状态
		for (OrderPay orderPay : list) {
			Order order = orderService.selectByPrimaryKey(orderPay.getOrderId());
			order.setStatus(1);
			order.setRemark(trade_no);
			order.setPayMethod(payMethod);
			orderService.updateByPrimaryKeySelective(order);
		}
		
		//设置 购物车订单状态
		for (OrderPay orderPay : list) {
			orderPay.setStates(1);
			orderPayService.updateByPrimaryKeySelective(orderPay);
		}	
	}
}



可以根据自己要求 的修改  切记 支付宝的回调 如果要获取 支付相关信息 必须用 支付宝的公钥  (不是自己生成的)


——————


微信  去这 https://open.weixin.qq.com/cgi-bin/index?t=home/index&lang=zh_CN 申请 并且签约 app支付  (支付宝也是要签约的 )



public static Map wxAppPrepareId(BigDecimal price, String orderId, String info, String ip)
  {
  SortedMap<String, String> params =new TreeMap();
    params.put("body", info); 
    params.put("nonce_str", WXUtil.getNonceStr());
    params.put("out_trade_no", orderId);
    params.put("total_fee", String.valueOf(price.multiply(new BigDecimal(100)).intValue()));
    params.put("spbill_create_ip", "8.8.8.8");
    params.put("notify_url", ConstantUtil.BACK_URL);
    params.put("trade_type", "APP");
    params.put("mch_id", ConstantUtil.PARTNER);
    params.put("appid", ConstantUtil.APP_ID);
    params.put("key", ConstantUtil.APP_KEY);
    params.put("sign", createSign(params));
    SortedMap<String,String> map =  new TreeMap();
    
    Map mapStr = getPrepayApp(params);
    
    map.put("key", ConstantUtil.APP_KEY);
    map.put("timestamp",  WXUtil.getTimeStamp());
    map.put("package","Sign=WXPay");
    map.put("noncestr", (String)mapStr.get("nonce_str"));
    map.put("partnerid", ConstantUtil.PARTNER);
    map.put("appid", ConstantUtil.APP_ID);
    map.put("prepayid",(String)mapStr.get("prepay_id"));
    map.put("sign",createSign(map));
    return map;
  }



微信需要  

java支付宝账号绑定 java支付宝支付和微信支付_微信_05

 其实还有 api_key  那 个需要在 商户平台去设置  是在签名的时候使用的  


大致 到这里 就都ok了  


其实主要还是 拼接字符串 签名的时候会出现问题 一旦你拼错一点点  就会出现各种问题  不唤醒app 等 。 代码大概贴出来了  更多资料 去 格子的 官网查看 api    


Mark 一下 防止自己忘记   =。=