打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
微信刷卡支付API详解

场景:

*对于一些必选参数,即使没什么用,也一定要传。

map.put('appid','你的公众号appid');map.put('mch_id', '微信支付商户号');map.put('sub_mch_id', '微信支付分配的子商户号,服务商必填');map.put('device_info', '终端设备号'));map.put('body', '商品名称');map.put('detail', '单品优惠功能字段');map.put('attach','附加数据');map.put('out_trade_no', '订单号,要求32个字符内');map.put('total_fee','支付金额'));map.put('fee_type','默认人民币:CNY');map.put('spbill_create_ip',InetAddress.getLocalHost().getHostAddress().toString());//获取调用支付接口的机器终端ipmap.put('goods_tag', '');map.put('limit_pay', '');map.put('time_start', '');map.put('auth_code','付款码' );map.put('scene_info','');map.put('nonce_str', '');sign = APIUtil.createSign(map, apikey, 'utf-8');logger.info('sign:'+sign);map.put('sign',sign);xml = APIUtil.buildXML(map);try { if(visitUrl!=''||visitUrl!=null) { reStr= APIUtil.post(visitUrl, xml); System.out.println('reStr:'+reStr); if (reStr != null ) { xmlMap = APIUtil.reqMsg2Map(reStr); String reSign = APIUtil.createSign(xmlMap, apikey, 'utf-8'); logger.info(xmlMap.toString()); if (reSign.toLowerCase().equals(xmlMap.get('sign').toString().toLowerCase())) { logger.info('reSign', true); } } } logger.info('接口返回数据=' + reStr);} catch (Exception e) { // TODO Auto-generated catch block logger.error(e.getMessage());}return xmlMap;

1.首先要明确微信支付是使用MD5进行签名的,这个是进行两次验签的,一次支付前进行验签,一次接收微信返回数据后进行验签,目的是确保这是一次交易。验签我们必须明确:

当然按ASCII排序直接一个TreeMap搞定(不熟悉TreeMap的孩纸们自行查阅资料)。

2. 我们要知道你发过去的数据是个XML,所以必须用把你的参数构造成XML形式。

3. 返回给你的数据也是XML,所以你得转两次。

4. 发送数据了,你发现返回给你签名错误,这时候从哪儿找问题呢?

(1)你的那些参数中有没有中文,有的话进行编码设置,可能你的数据已经乱码

(2)你的商户号和子商户号有没有写对(首先要明确一点,你是服务商还是特约客户,特约客户就是子商户,如果你是服务商,这两个参数你都应该有,如果没有请登陆商户平台进行查询)

(3) 你的密钥是否正确,加密的时候是拼接key的,所以确保你的key正确无误,如果不确定key,可以登陆商户平台(pay.weixin.qq.com)-->账户设置-->API安全-->密钥设置

(4)还有一种,这个就是我说的坑(话说微信的接口文档真叫一个烂),如果你确定你的密钥、商户号、子商户号、appid这些都正确的话,还报签名错误,那么你可以去他们官方的签名校验工具(https://pay.weixin.qq.com/wiki/doc/api/micropay_sl.php?chapter=20_1)检验下你的签名算法是否正确,如果计算出来的签名和你的签名算法算出来一样,那么恭喜你,踩坑了,重置你的密钥再试试(有可能会重置好几次哦,做好准备)。

(5) 如果很幸运,你成功调用了接口,这时候你高兴的递交了代码,静等测试给你反馈了,你觉得没问题,很完美。好了,梦醒了,继续测吧,bug很多:

① 你发现钱扣了,但是返回失败,为什么呢?

明确一个很重要的点,return_code是通信表示,他返回成功知识说明你接口调通了,不能说明业务成功,业务成功看result_code。

② 你的用户有可能开通了免密支付,如果免密支付,那你这个代码很成功,no bug。如果你的用户设置了非免密支付,那么bug来了。这时候result_code也是FAIL,但是钱扣了,怎么办?如果你用debug调试,你会发现 err_code是USERPAYING,这就表明用户在输入密码,所以你得调查询订单接口,去查询订单,不要立即去查,每隔10秒。

如果这个时候result_code和rade_state都返回成功,这才表示用户支付成功了。

下来就是你根据自己的业务进行的一些操作,就不表述了,下来咋们看微信退款,支付是不需要证书的,但是退款需要双向证书。你先要想一想你把证书放哪儿,两个建议,第一种放数据库(以二进制的形式存在BLOB类型),第二种放在resource里面单独建一个文件夹。

我是以第二种形式存放的。

但是记得在pom.xml中配置。

微信退款和支付传参、加密等一摸一样,就不多说了,我只说重点,怎么加载呢?明确一下,咋们是不需要解析证书的!而且证书默认密码是你的商户号。

加载:

KeyStore keyStore = KeyStore.getInstance('PKCS12');FileInputStream instream = new FileInputStream(new File('文件目录'));//P12文件目录try { keyStore.load(instream, '商户号'.toCharArray());//这里写密码..默认是你的MCHID} finally { instream.close();}SSLContext sslcontext = SSLContexts.custom() .loadKeyMaterial(keyStore, '商户号'.toCharArray())//这里也是写密码的 .build();// Allow TLSv1 protocol onlySSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory( sslcontext, new String[] { 'TLSv1' }, null, SSLConnectionSocketFactory.BROWSER_COMPATIBLE_HOSTNAME_VERIFIER);CloseableHttpClient httpclient = HttpClients.custom() .setSSLSocketFactory(sslsf) .build();

这样你发现,加载成功了,但是你还是没有调用成功,因为你没设置响应头信息,传过去是乱码!!!!相信我,你需要它,在你加载证书的工具类里把这些东西加上就完美了:

try { 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); try { HttpEntity entity = response.getEntity(); String jsonStr = EntityUtils.toString(response.getEntity(), 'UTF-8'); EntityUtils.consume(entity); return jsonStr; } finally { response.close(); }} finally { httpclient.close();}

这样微信支付就完了,建议不要用撤销接口,没必要。

本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
【热】打开小程序,算一算2024你的财运
微信支付v3——批量转账到零钱(提现)
android 虚拟机google map显示
Google Guava的介绍和使用(转)
天气预报-java代码
Java发送ios推送消息(APN)的代码示例
Java网络编程-用SSL构建安全的Socket - moonsee - JavaEye技...
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服