java服务端接入微信支付

App里做微信支付的前提是有在微信开放平台注册账号,然后在微信商户平台成为商家,并且在开放平台里绑定商户id

一:设置密钥

在账户中心-API安全-API密钥 里设置下API密钥。

二:写配置文件

配置文件WeixinPayConfig .java

public class WeixinPayConfig {
		
	/**
	 * 微信开放平台分配的应用ID
	 * 
	 */
	public static String APP_ID = "应用ID";
	/**
	 * API密钥
	 */
	public static String KEY="9022C9F9347F970A9CE87BB2A3B7543A";
	/**
	 * 回调地址
	 */
	public static String CALLBACK_URL = "外网可以访问的不需要参数的接口地址";
	/**
	 * 商户id
	 */
	public static String MERCHANT_ID= "商户id";
}

三:微信支付

/**
	 * 
	 * 生成微信支付接口所需的签名
	 * @param paramMap
	 * @return
	 */
	private static String buildWXPaySign(String paramStr) {
		Object params[]=paramStr.split("&");
		Arrays.sort(params);
		int length=params.length;
		String signStr="";
		if (params != null &&length>0) {
			StringBuilder sb=new StringBuilder(length);
			for (int i = 0; i < length; i++) {
				sb.append(params[i]+"&");
			}
			sb.append("key="+WeixinPayConfig.KEY);
			signStr=MD5Helper.encrypt(sb.toString());
		}
		return signStr;
	}
	//生成随机字符串
	private static String createNonceStr() {
	    return UUID.randomUUID().toString().replace("-", "");
	}
 /**
     * 元转换成分
     * @param amount
     * @return
     */
    public static String getMoney(String amount) {
        if(amount==null){
            return "";
        }
        // 金额转化为分为单位
        // 处理包含, ¥ 或者$的金额
        String currency =  amount.replaceAll("\\$|\\¥|\\,", "");
        int index = currency.indexOf(".");
        int length = currency.length();
        Long amLong = 0l;
        if(index == -1){
            amLong = Long.valueOf(currency+"00");
        }else if(length - index >= 3){
            amLong = Long.valueOf((currency.substring(0, index+3)).replace(".", ""));
        }else if(length - index == 2){
            amLong = Long.valueOf((currency.substring(0, index+2)).replace(".", "")+0);
        }else{
            amLong = Long.valueOf((currency.substring(0, index+1)).replace(".", "")+"00");
        }
        return amLong.toString();
}
/**
	 * 微信支付
	 * @param token
	 * @param amount
	 * @param request
	 * @param response
	 * @throws UnsupportedEncodingException 
	 */
	@RequestMapping(value = "/recharge.json")
	@AuthorizationApi
	public void recharge(@CurrentToken Token token,String amount,HttpServletRequest request,HttpServletResponse response) throws Exception{
		if(StringUtil.isBlank(amount)) {
			apiData(request, response, ReqJson.error(BusinessError.AMOUNT_IS_NULL));
			return;
		}
		if(!ToolUtils.isNumeric(amount)) {
			apiData(request, response, ReqJson.error(BusinessError.AMOUNT_IS_ILLEGAL));
			return;
		}else {
			double number=Double.parseDouble(amount);
			if(number<0.01||number>10000) {
				apiData(request, response, ReqJson.error(BusinessError.EXCEEDING_THE_QUOTA));
				return;
			}
		}
		String accessToken=token.getAccessToken();
		String body= "测试钱包充值";
		String subject="钱包充值";
		String tradeNo=generateOrderNo(token.getUserId());
		String goodsType="0";
		String tradeStaue="1";
		String userId=token.getUserId();
		String ip="123.12.12.123";
		String params="access_token="+accessToken;
		tradeBiz.save(new TradeLog(Double.parseDouble(amount), body, subject, tradeNo, goodsType,tradeStaue,userId,"recharge"));
		String requestUrl = "https://api.mch.weixin.qq.com/pay/unifiedorder"; 
		String paramStr="attach="+URLEncoder.encode(params,"utf-8")+"&sign_type=MD5&body="+body+"&appid="+WeixinPayConfig.APP_ID+"&mch_id="+WeixinPayConfig.MERCHANT_ID+"&nonce_str="+createNonceStr()+
				"&out_trade_no="+tradeNo+"&total_fee="+getMoney(amount)+"&spbill_create_ip="+ip+"¬ify_url="+basePath+WeixinPayConfig.CALLBACK_URL+"&trade_type="+"APP";
		String sign=buildWXPaySign(paramStr);
		paramStr=paramStr+"&sign="+sign;
		String result = HttpUtil.sendPost(requestUrl,XMLUtil.stringToxml(paramStr));
		apiData(request, response, ReqJson.ok(result));
		return;
	}
	/**
	 * 生成订单id
	 * @param userId
	 * @return
	 */
	private String generateOrderNo(String userId) {
		String orderNo="";
		String date=DateUtil.formatDate(new Date(), "yyMMddHHmmss");
		int hashCode=userId.hashCode();
		orderNo=(date+hashCode).replace("-", "");
		return orderNo;
	}

四:微信支付回调

	/**
	 * 校验签名
	 * @param map
	 * @param sign
	 * @return
	 */
	private static boolean checkSign(Map map,String sign){
		boolean flag=false;
		if(map==null||map.size()==0) {
			return flag;
		}
		Object params[]=new Object[map.size()];
		int i=0;
		for(String key:map.keySet()) {
			params[i]=key+"="+map.get(key);
			i++;
		}
		Arrays.sort(params);
		int length=params.length;
		String signStr="";
		if (params != null &&length>0) {
			StringBuilder sb=new StringBuilder(length);
			for (int j = 0; j < length; j++) {
				sb.append(params[j]+"&");
			}
			sb.append("key="+WeixinPayConfig.KEY);
			signStr=MD5Helper.encrypt(sb.toString());
		}
		if(sign.equals(signStr)) {
			flag=true;
		}
		return flag;
	}
	private static Map getParamMap(String params){
		if(StringUtil.isBlank(params)) {
			return null;
		}
		Map paramMap=new HashMap<>();
		String param[]=null;
		if(params.contains("&")) {
			String paramArray[]=params.split("&");
			for (int i = 0; i < paramArray.length; i++) {
				param=paramArray[i].split("=");
				paramMap.put(param[0], param[1]);
			}
		}else {
			param=params.split("=");
			paramMap.put(param[0], param[1]);
		}		
		System.out.println(paramMap.toString());
		return paramMap;
	}
	/**
	 * 微信支付回调
	 * @param request
	 * @param response
	 * @throws IOException 
	 */
		@RequestMapping(value = "/getWeixinPayNotify.json")
	public void getWeixinPayNotify(HttpServletRequest request,HttpServletResponse response) throws Exception {
		logger.info("********进入回调*******"+request.getMethod());
		TradeLog temp=null;
		Map map = XMLUtil.xml2Map(request);
		String sign=map.get("sign").toString();
		map.remove("sign");
		boolean flag = checkSign(map, sign);
		if (flag) {
			String resultCode=map.get("result_code");
			String outTradeNo = map.get("out_trade_no");
			String params=URLDecoder.decode(map.get("attach"), "utf-8");
			Map attachMap=getParamMap(params);
			if(attachMap==null||attachMap.size()==0) {
				apiData(request, response, ReqJson.error(CommonError.PARAMS_IMPERFECT));
				return;
			}
			String access_token=(String) attachMap.get("access_token");
			if (StringUtil.isBlank(access_token)) {
				apiData(request, response, ReqJson.error(CommonError.PARAMS_IMPERFECT));
				return;
			}
			// 校验token
			Token token = tokenBiz.checkToken(access_token, response);
			// 参数access_token不合法
			if (token == null) {
				ReqDataUtil.apiData(request, response, ReqJson.error(SysReqJsonStatus.PARAMETERS_ACCESS_TOKEN_INVALID));
				return;
			}
			String userId = token.getUserId();
			temp = tradeBiz.get(new TradeLog(null, outTradeNo));
			if (temp == null) {
				apiData(request, response, ReqJson.error(CommonError.PARAMS_IMPERFECT));
				return;
			}
			if (temp != null && !temp.getUserId().equals(userId)) {
				apiData(request, response, ReqJson.error(CommonError.PARAMS_IMPERFECT));
				return;
			}
			if (resultCode.equals("SUCCESS")&&temp.getTradeState().equals("1")) { // 交易支付成功的执行相关业务逻辑
				if (temp != null) {
						
				}
			} else if (resultCode.equals("FAIL")) { // 未付款交易超时关闭,或支付完成后全额退款,执行相关业务逻辑
			
			}
		}else {
			logger.info("********签名不正确*******");
		}
		String str = "return_code=SUCCESS&return_msg=OK";
		response.getWriter().write(XMLUtil.stringToxml(str));
		return;
	}

工具类XMLUtil.java

	/**
	 * 将请求的xml转成map
	 * @param request
	 * @return
	 * @throws IOException
	 */
 public static Map xml2Map(HttpServletRequest request) throws IOException {
        Map map = new HashMap();
        SAXReader reader = new SAXReader();
        InputStream is = null;
        Document doc = null;
        try {
            is = request.getInputStream();
            doc = reader.read(is);
            Element root = doc.getRootElement();
            List list = root.elements();
            for (Element e : list) {
                map.put(e.getName(), e.getText());
            }
        } catch (IOException e) {
            e.printStackTrace();
        } catch (DocumentException e) {
            e.printStackTrace();
        } finally {
            is.close();
        }
        return map;
    }
	/**
	 * 将字符串转成xml
	 * @param params
	 * @return
	 */
	public static String stringToxml(String params) {
		try {
			String paramArray[] = params.split("&");
			String param[] = null;
			String xml = "";
			for (int i = 0; i < paramArray.length; i++) {
				param = paramArray[i].split("=");
				xml += "<" + param[0] + ">";
				xml += param[1];
				xml += "";
			}
			xml += "";
			return xml;
		} catch (Exception e) {
			e.printStackTrace();
		}
		return null;
	}

 

你可能感兴趣的:(java)