[分享] 微信支付中商户对个人用户付款案例

  随着微信支付的普及,越来越的APP要求支持微信支付。相信大多数开发者也碰到了这样的需求。百度了一下,大家用到最多的是微信支付中个人对商户的支付业务,而很少有人用到微信中商户对个人付款的业务。我最近就碰到了这样的需求,因为从来没有做过,所以只能查资料,可是百度到的资料很少,并且是过时的东西。又问了圈子里的高手,可是大家都没有做过。没办法只有硬着头皮自己拱吧!还好还好,功夫不负有心人啊!终于被我整明白了,现在得空,拿出来跟大家一起分享

  首先给大家吃颗定心丸,所有的东西在你没有用过之前,它都是神秘的,当你用过之后,就会发现,也就那么回事。呵呵,开始正题吧!

  这是企业付款的文档地址,大家需要先仔细看两遍。https://pay.weixin.qq.com/wiki/doc/api/tools/mch_pay.php?chapter=14_1 (就算有我的指导,也建议大家先看文档,看文档能便于加深大家的理解)

  总体思路: 1、准备数据;2、把所有的参数连接成一个字符串,然后进行MD5,把MD5得到的一个字符串做为最后一个参;3、把微信提供的安全证,封装到要提交的数据;(商户证书获取方法https://pay.weixin.qq.com/wiki/doc/api/tools/mch_pay.php?chapter=4_3 4、通过JAVA程序向微信提供的接口POST数据。微信接口返回处理结果。

  1、准备数据:所谓的数据就是请求参数,有9个参数是必须的,详细说明见文档(https://pay.weixin.qq.com/wiki/doc/api/tools/mch_pay.php?chapter=14_2)。下面我给大家提供我的示例代码

  

//配置接口参数,以下是9个必须的参数。

  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地址

  注意map.put()中的key是死的写法,不能改。

  2、把所有的参数拼接成一个字符串,然后进行MD5运算,把得到的运算结果,做为签名参数,一起POST给接口。详细做法参考文档(https://pay.weixin.qq.com/wiki/doc/api/tools/mch_pay.php?chapter=4_3)

  3、为了提高程序的可用性,我把一些受微信影响,会变动的参数写到了配置文件里。配置文件和JAVA文件放在同一目录里就可以了。

  安全证书这一步是关键,微信为了提高接口的安全性,所以增加了安全证书,以保证资金的安全。JAVA里用到的证书是pkcs12格式,大家按照文档里的提示,去下载相关证书,然后放到自己指定的目录里就可以了。下面是获取证书,并发起POST请求的代码示例。

 

 // 获取证书,发送POST请求;

  KeyStore keyStore = KeyStore.getInstance("PKCS12");

  FileInputStream instream = new FileInputStream(new File(config.elementTextTrim("cert_path"))); // 从配置文件里读取证书的路径信息

  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);

  CloseableHttpClient httpclient = HttpClients.custom().setSSLSocketFactory(sslsf).build();

  HttpPost httpost = new HttpPost(url); //发起POST请求

  4、向接口POST数据 ,获得返回结果。下面是我的示例代码

  

CloseableHttpResponse response = httpclient.execute(httpost);

  httpentity entity = response.getEntity();

  String jsonStr = EntityUtils.toString(response.getEntity(),"UTF-8");

  EntityUtils.consume(entity);

  // 把返回的字符串解释成DOM节点

  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;

  }

  以上4步,就完成了微信企业付款的业务。

  需要用到的jar包和我的程序示例代码。喜欢拿来就用的伙伴只需要写写配置文件,下载了安全证书,我的程序就可以直接拿来用了。源码地址:http://pan.baidu.com/s/1gfqbVJt

  有问题可以跟帖咨询。

  欢迎大家共同学习,共同进步。

相关文章

HTML5和CSS3实现3D展示商品信息的代码
利用HTML5中的Canvas绘制笑脸的代码
Html5剪切板功能的实现
如何通过HTML5触摸事件实现移动端简易进度条
Html5移动端获奖无缝滚动动画实现
关于HTML5和CSS3实现机器猫的代码