Java开发SSM框架微信企业付款

 

微信企业转账相比支付和退款,相关的文章少很多。下面笔者把转账的开发流程写下来,大家不要心急耐心的看下去照着做参考一定可以实现。

做之前希望大家花一点时间看看微信的官方文档,如果看过了请略过。  微信企业付款官方文档,企业付款需要你的商户号去开通这个功能,相比支付和退款企业付款是需要一点前提条件的。

下面展开代码讲解:

首先做企业付款我们要先get到用户的openID这个id是每个用户独有的。

String openid = request.getParameter("openid"); // 用户的openid重要参数
			if (!openid.equals("") && openid != null) {
               
}

我在方法的开始就做了判断是否get到openId,拿到openId之后我们开始给其他付款需要的参数进行赋值。

String url = "https://api.mch.weixin.qq.com/mmpaymkttransfers/promotion/transfers";
				InetAddress ia = InetAddress.getLocalHost();
				String ip = ia.getHostAddress(); // 获取本机IP地址
				String uuid = UUID.randomUUID().toString().toUpperCase().replaceAll("-", "");// 随机获取UUID
				String appid = Configure.getAppID();// 微信分配的公众账号ID(企业号corpid即为此appId)
				String mchid = Configure.getMch_id();// 微信支付分配的商户号
				String partner_trade_no = RandCharsUtils.getOutTradeNo();
				int amount = 100; // 微信转账金额(最少1元)
				String desc = "测试"; // 付款操作说明信息

URL是微信官方提供的付款接口,amount则是转账的金额1表示1分钱,转账最少需要一元也就是100。

				SortedMap<Object, Object> signParams = new TreeMap<Object, Object>();
				signParams.put("mch_appid", appid); // 微信分配的公众账号ID(企业号corpid即为此appId)
				signParams.put("mchid", mchid);// 微信支付分配的商户号
				signParams.put("nonce_str", uuid); // 随机字符串,不长于32位
				signParams.put("partner_trade_no", partner_trade_no); // 商户订单号,需保持唯一性
				signParams.put("openid", openid); // 商户appid下,某用户的openid
				signParams.put("check_name", "NO_CHECK"); // NO_CHECK:不校验真实姓名
															// FORCE_CHECK:强校验真实姓名(未实名认证的用户会校验失败,无法转账)
															// OPTION_CHECK:针对已实名认证的用户才校验真实姓名(未实名认证用户不校验,可以转账成功)
				signParams.put("amount", amount); // 企业付款金额,单位为分
				signParams.put("desc", desc); // 企业付款操作说明信息。必填。
				signParams.put("spbill_create_ip", ip); // 调用接口的机器Ip地址

然后把赋值的参数保存在SortedMap里面等下签名加密会用到。

String sign = WXSignUtils.createSign("UTF-8", signParams);
				// sign = createSign("UTF-8", signParams);
				// System.out.println(sign);
				String data = "<xml><mch_appid>";
				data += appid + "</mch_appid><mchid>"; // APPID
				data += mchid + "</mchid><nonce_str>"; // 商户ID
				data += uuid + "</nonce_str><partner_trade_no>"; // 随机字符串
				data += partner_trade_no + "</partner_trade_no><openid>"; // 订单号
				data += openid + "</openid><check_name>NO_CHECK</check_name><amount>"; // 是否强制实名验证
				data += amount + "</amount><desc>"; // 企业付款金额,单位为分
				data += desc + "</desc><spbill_create_ip>"; // 企业付款操作说明信息。必填。
				data += ip + "</spbill_create_ip><sign>";// 调用接口的机器Ip地址
				data += sign + "</sign></xml>";// 签名

这是签名的部分,签名之后的数据和之前上面赋值的数据一定要按照这个xml的格式保存起来不然你发送给官方api是不认的,之前我做的时候一直付款失败就是因为签名的方法出了问题。

    public static String createSign(String characterEncoding, Map<Object, Object> parameters){
    	StringBuffer sb = new StringBuffer();
		Set<Entry<Object, Object>> es = parameters.entrySet();
		Iterator<Entry<Object, Object>> it = es.iterator();
		while (it.hasNext()) {
			Entry<Object, Object> entry = it.next();
			String k = (String) entry.getKey();
			Object v = entry.getValue();
			if (null != v && !"".equals(v) && !"sign".equals(k) && !"key".equals(k)) {
				sb.append(k + "=" + v + "&");
			}
		}
		sb.append("key=" + Configure.getKey());
		String sign = MD5Util.MD5Encode(sb.toString(), characterEncoding).toUpperCase();
		return sign;
    }

这个是我签名的方法,大家可以直接复制拿去用就好。

<xml>

<mch_appid>wxe062425f740c30d8</mch_appid>

<mchid>10000098</mchid>

<nonce_str>3PG2J4ILTKCH16CQ2502SI8ZNMTM67VS</nonce_str>

<partner_trade_no>100000982014120919616</partner_trade_no>

<openid>ohO4Gt7wVPxIT1A9GjFaMYMiZY1s</openid>

<check_name>FORCE_CHECK</check_name>

<re_user_name>张三</re_user_name>

<amount>100</amount>

<desc>节日快乐!</desc>

<spbill_create_ip>10.2.3.10</spbill_create_ip>

<sign>C97BDBACF37622775366F38B629F45E3</sign>

</xml>

 这是生成的签名,可以对比一下自己生成的签名有没有少东西或者格式不正确。

KeyStore keyStore = KeyStore.getInstance("PKCS12");
				FileInputStream instream = new FileInputStream(new File(Configure.getUrl())); // 从配置文件里读取证书的路径信息
				keyStore.load(instream, mchid.toCharArray());// 证书密码是商户ID
				instream.close();
				SSLContext sslcontext = SSLContexts.custom().loadKeyMaterial(keyStore, mchid.toCharArray()).build();
				SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(sslcontext, new String[] { "TLSv1" },
						null, SSLConnectionSocketFactory.BROWSER_COMPATIBLE_HOSTNAME_VERIFIER);

企业付款需要有登陆商户号下载的安全证书,这个证书的有效期是半年,我们下载下来之后把证书起来用的时候直接引用证书URL即可。

CloseableHttpClient httpclient = HttpClients.custom().setSSLSocketFactory(sslsf).build();
				HttpPost httpost = new HttpPost(url); //
				httpost.addHeader("Connection", "keep-alive");
				httpost.addHeader("Accept", "*/*");
				httpost.addHeader("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8");
				httpost.addHeader("Host", "api.mch.weixin.qq.com");
				httpost.addHeader("X-Requested-With", "XMLHttpRequest");
				httpost.addHeader("Cache-Control", "max-age=0");
				httpost.addHeader("User-Agent", "Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.0) ");
				httpost.setEntity(new StringEntity(data, "UTF-8"));
				CloseableHttpResponse response = httpclient.execute(httpost);
				HttpEntity entity = response.getEntity();

				String jsonStr = EntityUtils.toString(response.getEntity(), "UTF-8");
				System.out.println("请求返回的数据为:" + jsonStr);
				EntityUtils.consume(entity);

这一段是把数据发送给官方api的代码赋值即用。

Document dom = DocumentHelper.parseText(jsonStr);
				Element root = dom.getRootElement();
				String returnCode = root.element("result_code").getText(); // 获取返回代码
				if (StringUtils.equals(returnCode, "SUCCESS")) { // 判断返回码为成功还是失败
					String payment_no = root.element("payment_no").getText(); // 获取支付流水号
					String payment_time = root.element("payment_time").getText(); // 获取支付时间
					map.put("state", returnCode);
					map.put("payment_no", payment_no);
					map.put("payment_time", payment_time);
					return map;
				} else {
					String err_code = root.element("err_code").getText(); // 获取错误代码
					String err_code_des = root.element("err_code_des").getText();// 获取错误描述
					map.put("state", returnCode);// state
					map.put("err_code", err_code);// err_code
					map.put("err_code_des", err_code_des);// err_code_des
					return map;
				}

然后通过Document 把返回的字符串解析成DOM节点,通过返回数据的return_code来判断api是否执行成功。

<xml>

<return_code><![CDATA[SUCCESS]]></return_code>

<return_msg><![CDATA[]]></return_msg>

<mch_appid><![CDATA[wxec38b8ff840bd989]]></mch_appid>

<mchid><![CDATA[10013274]]></mchid>

<device_info><![CDATA[]]></device_info>

<nonce_str><![CDATA[lxuDzMnRjpcXzxLx0q]]></nonce_str>

<result_code><![CDATA[SUCCESS]]></result_code>

<partner_trade_no><![CDATA[10013574201505191526582441]]></partner_trade_no>

<payment_no><![CDATA[1000018301201505190181489473]]></payment_no>

<payment_time><![CDATA[2015-05-19 15:26:59]]></payment_time>

</xml>

这个是调用成功返回的xml。

企业付款的流程就是这样,如果有不懂的可以下载源码:微信企业付款源码

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值