微信刷卡支付ios开发微信支付demodemo 可以用吗

微信刷卡支付 或许是空欢喜一场--百度百家
微信刷卡支付 或许是空欢喜一场
分享到微信朋友圈
所以,微信目前想通过刷卡功能来进入线下市场,更像是在扫码市场进入多元化竞争后的一种着急应对的表现,虽然微信支付在用户时间占有上有足够的优势,但是相 对而言,不论是在商户资源,商户管理体系还是流量转化和周边服务而言,微信支付恐怕都没有做好准备。
微信刷卡支付 进入线下没那么容易
日前,最新版本的 iOS 和 Android
微信应用的钱包功能中都加入了刷卡功能,该功能意味着微信部分合作方的线下条码支付功能已经上线。对于微信而言,此前在3月份曾经推出了二维码支付的应
用,但是那个时候的扫码支付是主读模式(也就是用户主动扫描商户的二维码),在安全流程上并未能获得央行对支付安全的流程认可,因此也和支付宝的二维码支
付一样被严厉叫停。
那么,微信此次推出的全新的二维码和条形码扫描模式,是否可以从安全认证上通过监管的认证呢?相对而言,微信推出的刷卡支付采用的是被读模式(也就是用户展示二维码被商家扫描),并且条形码和二维码每分钟会自动更新,在安全性能上有所提高,随着国内银行、银联以及支付宝
等多家机构在二维码支付方式上投入,相信后期二维码支付有望进入一个标准化的安全阶段。
既然在安全上基本过了关,是否意味着微信二维码支付迎来了最好的春天?其实未必,相反,微信虽然在支付技术上过了关,但是在市场开拓和线上商户资源的拓展方面却未必能过五关斩六将,获得较高的市场份额。
首先,从市场准入来看,微信刷卡支付所能产生的便捷支付功能,只要是以小额的临时性支付需求为客户市场,但是从3月份被叫停至今,市场上开发二维码支付的公
司已经绝非微信和支付宝两家了,传统的商业银行和银联等收单机构也已经开始介入。并且,从第二次扫码支付的功能推出时间来看,微信此次并不占优天时和地利的优势。道理很简单,节奏相对而言慢了一拍,且在线下的商户资源占有上没有优势。
为什么这里要提到商户呢?对于微信支付所处于的O2O支付产业链而言,要从线上的流量引入,刷卡支付再到线下的扫码支付,或者是从线下的购买场景应用到线上的刷卡支付,对于微信而言,最重要的,同时也是最大的一块软肋是线下的合作商户。微信因为没有自主开展过O2O业务,因此也就没有自己的商户管理和资源体系,虽然微信在前段时间入股了58同城和大众点评,以及通过微信电商的模式来获取了部分线下商户的认可,但是总体而言,微信的商户体系还是不完善的。从社交基因到O2O的电商基因需要一个时间转换和客户认知的培养过程,而商户体系上的缺陷将成为微信刷卡应用的一大软肋。
其次,微信支付以及其全新的刷卡功能,所处在的已经不是一个未开发的处女地市场,而是诸多巨头开始进入,从互联网企业到传统支付机构再到商业银行等多方混战的一个市场。
银行有支付的优惠和安全的保障,同时还有大量的线下POS收单商户,建行、招行、交行等多家银行也已经悄悄在手机银行APP里嵌入了二维码功能,有的二维
码可以在部分领域使用,比如缴话费、系统内转账等,某家银行甚至开始通过手机银行二维码支付卖起了理财产品;银联就不用说了,线下有200万商户,且分布更广泛,行业更全面,随着银联钱包的推出,功能匹配将更为完善;而支付宝在线下商户拓展的力度和合作的强度也更为广阔,加上电商平台的资源较为丰富,和商户开展合作的效率也相对更高,早在几个月之前,支付宝在线下的二维码支付就已经悄然开始。
最后,微信刷卡支付能否顺利进入线下的支付交易环节,还有一个很重要的问题,那就是流量的转化问题。对于微信而言,其最大的优势是线上用户的流量,现在基本上微信APP已经成为了移动互联网用户花费时间最多的社交软件,这对用户的粘性保持和流量的转化是一个天然的优势。但是,流量的转化需要一个前置条件,就是高频率的优惠活动和大量的线下商户的主动推动,这个就需要一支布局全面的线下业务推广团队,并对商家提供一整套的刷卡支付服务解决方案。对用户让利,提供优惠,对商户提供支付的全流程服务,这样才
能快速启动流量的转化,并培育出扫码支付的客户群体。
但是,微信虽然目前首批接入了DQ冰雪皇后、国大药房、天虹、壹加壹、卜蜂莲花(华南)、好邻居、爱婴室、民生百货、国大365等9家商户,在全国其他地方的商户也在逐步接入中,但是微信扫码支付的全流程服务并没有完善起来。此外,微信和上述商家的合作还处在初步阶段,在试运营过程中难免会出现其他问题,在商户接入的费率上也没有一致的标准。
所以,微信目前想通过刷卡功能来进入线下市场,更像是在扫码市场进入多元化竞争后的一种着急应对的表现,虽然微信支付在用户时间占有上有足够的优势,但是相
对而言,不论是在商户资源,商户管理体系还是流量转化和周边服务而言,微信支付恐怕都没有做好准备。因为O2O业务不同于传统的电商和社交业务,需要在线下建立一个长效的服务和流程管理机制,这个时间是长期的,也会消耗大量的线下服务成本,而微信在线下资源的整合方面恐怕不会占有优势。
最后插一句,微信支付说依托的是社交基因,但是能否顺利进入线下,成为O2O中的支付基因,还存在一个很大的未知,一份针对移动支付用户的使用终端情况调查显示,70%以上的用户目前习惯使用的支付工具是支付宝钱包,而微信支付只有30%不到,这充分说明了微信在跨界社交进入支付领域的某种内在基因限制。
一言蔽之,微信虽然有了刷卡支付,但是具体到线下效果如何,还未可知。&
阅读:9330
分享到微信朋友圈
在手机阅读、分享本文
还可以输入250个字
推荐文章RECOMMEND
阅读:3183
阅读:15万
热门文章HOT NEWS
剩者为王?
百度新闻客户端
百度新闻客户端
百度新闻客户端
扫描二维码下载
订阅 "百家" 频道
观看更多百家精彩新闻微信刷卡怎么用 微信刷卡支付使用教程
时间: 19:37:51来源:作者:cx(0)
微信5.4后又推出了一项新功能微信刷卡,微信刷卡是什么?微信刷卡怎么用?下面为大家详细介绍一下。微信刷卡是什么?用户可在支持刷卡的商家购物/付款时,商家使用带有扫码功能的POS机只需扫描微信用户的(刷卡页面)二维码/条形码,便可完成支付的功能,为了资金安全,微信刷卡条形码页面会每分钟自行变换一次,这也大大的提高了安全支付保障,同时微信刷卡可自行选择使用”微信零钱包或储蓄卡“支付,暂不支持信用卡。微信刷卡怎么用?下载最新版微信:
名称:v6.3.18最新版大小:34.7M下载:
打开微信→我→我的钱包选择“刷卡”购物时向收银员出示此二维码即可,这里比支付宝多了一次刷卡支付密码,虽说麻烦一点但是更安全~129679人阅读
java web(18)
Java(22)
最近准备上网页的微信支付,大家可以参考后续教程:
因微信支付已经升级到V3版本,请大家参考官网的帮助文档。
之前一篇提到微信支付的开发过程,写得有点乱,现在重新整理一下。
好了,说说到底该怎样一步一步分享处理。
解压从官网下载下来的开发说明文档(下载地址:):
先把服务端demo的代码整理到我们的服务端中(注意,此代码的编码格式是GBK,直接复制过去注释都会变乱码。可用文本文件打开后再复制过去)。处理完成后启动;且访问:http://localhost:8080/WeiXinpay/
会得到以下视图:
-------------------------------------------------------------------------------------------------------------
页面跳转调用:
后台调用:
点击链接:
0OK&wxd930ea5d5a258f4f&454ceccd624cd8a8c9ddf1&Sign=WXPay&&1c0c02c882&eb139e44b8df8ce01b386f7c016defe5b04896
-------------------------------------------------------------------------------------------------------------
返回控制台可以得到以下视图:
好了,到这里,算是成功了一小步了(哈哈哈哈哈哈 yy一下)。
你也许会问,这些参数到底是作什么用的?更可悲的是,居然没有服务端的接口文档。
唯有先看手头上有的资料了。打开《【微信APP支付】接口文档V1.2_For_Android.pdf》
里面有提到微信支付的调用步骤:
1、获取& access_token
2、生成预支付订单
3、调起微信支付
下面说说这几个步骤:
1、access_token的获取
因为access_token的获取有请求频的限制,只能固化到数据库中了。这个不是难题。
2、生成预支付订单
在微信支付android的接口文档开头有提到:
注意:appsecret、appkey、partnerkey 不应硬编码到客户端程序中,建议需要用到这三个字段的过程都在服务器端完成
故此过程所有的信息全部在服务端生成。那么问题来了?挖掘机.... kao, 应该是,如何生成?
在翻看服务端的demo中,有jsp文件夹。打开一看,都几乎可以直接搬运使用了。
实现该过程的文件:payRequest.jsp
如何在JAVA中实现上面jsp的请求?项目中用到了Spring MVC,代码如下:
@Controller
@RequestMapping(&/weixin/&)
public class WeiXinPayController extends ResponsePage
private Logger log = Logger.getLogger(WeiXinPayController.class);
@RequestMapping(&weixin.do&)
public String doWeinXinRequest(HttpServletRequest request,HttpServletResponse response) throws Exception {
Map&Object,Object& resInfo = new HashMap&Object, Object&();
//接收财付通通知的URL
String notify_url = &http://127.0.0.1:8180/tenpay_api_b2c/payNotifyUrl.jsp&;
//---------------生成订单号 开始------------------------
//当前时间 yyyyMMddHHmmss
String currTime = TenpayUtil.getCurrTime();
String strTime = currTime.substring(8, currTime.length());
//四位随机数
String strRandom = TenpayUtil.buildRandom(4) + &&;
//10位序列号,可以自行调整。
String strReq = strTime + strR
//订单号,此处用时间加随机数生成,商户根据自己情况调整,只要保持全局唯一就行
String out_trade_no = strR
//---------------生成订单号 结束------------------------
PackageRequestHandler packageReqHandler = new PackageRequestHandler(request, response);//生成package的请求类
PrepayIdRequestHandler prepayReqHandler = new PrepayIdRequestHandler(request, response);//获取prepayid的请求类
ClientRequestHandler clientHandler = new ClientRequestHandler(request, response);//返回客户端支付参数的请求类
packageReqHandler.setKey(ConstantUtil.PARTNER_KEY);
String retmsg = &&;
String xml_body = &&;
//获取token值
String token = AccessTokenRequestHandler.getAccessToken();
(&获取token------值 & + token);
if (!&&.equals(token)) {
//设置package订单参数
packageReqHandler.setParameter(&bank_type&, &WX&);//银行渠道
packageReqHandler.setParameter(&body&, &测试&); //商品描述
packageReqHandler.setParameter(&notify_url&, notify_url); //接收财付通通知的URL
packageReqHandler.setParameter(&partner&, ConstantUtil.PARTNER); //商户号
packageReqHandler.setParameter(&out_trade_no&, out_trade_no); //商家订单号
packageReqHandler.setParameter(&total_fee&, &1&); //商品金额,以分为单位
packageReqHandler.setParameter(&spbill_create_ip&,request.getRemoteAddr()); //订单生成的机器IP,指用户浏览器端IP
packageReqHandler.setParameter(&fee_type&, &1&); //币种,1人民币
packageReqHandler.setParameter(&input_charset&, &GBK&); //字符编码
//获取package包
String packageValue = packageReqHandler.getRequestURL();
resInfo.put(&package&, packageValue);
(&获取package------值 & + packageValue);
String noncestr = WXUtil.getNonceStr();
String timestamp = WXUtil.getTimeStamp();
String traceid = &&;
////设置获取prepayid支付参数
prepayReqHandler.setParameter(&appid&, ConstantUtil.APP_ID);
prepayReqHandler.setParameter(&appkey&, ConstantUtil.APP_KEY);
prepayReqHandler.setParameter(&noncestr&, noncestr);
prepayReqHandler.setParameter(&package&, packageValue);
prepayReqHandler.setParameter(&timestamp&, timestamp);
prepayReqHandler.setParameter(&traceid&, traceid);
//生成获取预支付签名
String sign = prepayReqHandler.createSHA1Sign();
//增加非参与签名的额外参数
prepayReqHandler.setParameter(&app_signature&, sign);
prepayReqHandler.setParameter(&sign_method&,
ConstantUtil.SIGN_METHOD);
String gateUrl = ConstantUtil.GATEURL +
prepayReqHandler.setGateUrl(gateUrl);
//获取prepayId
String prepayid = prepayReqHandler.sendPrepay();
(&获取prepayid------值 & + prepayid);
//吐回给客户端的参数
if (null != prepayid && !&&.equals(prepayid)) {
//输出参数列表
clientHandler.setParameter(&appid&, ConstantUtil.APP_ID);
clientHandler.setParameter(&appkey&, ConstantUtil.APP_KEY);
clientHandler.setParameter(&noncestr&, noncestr);
//clientHandler.setParameter(&package&, &Sign=& + packageValue);
clientHandler.setParameter(&package&, &Sign=WXPay&);
clientHandler.setParameter(&partnerid&, ConstantUtil.PARTNER);
clientHandler.setParameter(&prepayid&, prepayid);
clientHandler.setParameter(&timestamp&, timestamp);
//生成签名
sign = clientHandler.createSHA1Sign();
clientHandler.setParameter(&sign&, sign);
xml_body = clientHandler.getXmlBody();
resInfo.put(&entity&, xml_body);
retcode = 0;
retmsg = &OK&;
retcode = -2;
retmsg = &错误:获取prepayId失败&;
retcode = -1;
retmsg = &错误:获取不到Token&;
resInfo.put(&retcode&, retcode);
resInfo.put(&retmsg&, retmsg);
String strJson = JSON.toJSONString(resInfo);
return responseAjax(request, strJson);
好了此时,客户端需要的参数都已经可以通过请求:http://localhost:8080/WeiXinpay/weixin/weixin.do 来获取
3、调起微信支付
这步就不需要我们服务端处理了。客户端的兄弟,来接力。
示例的完整代码可以在此链接下载:
最后,微信回调:可以参考jsp文件夹中的payNotifyUrl.jsp来处理,处理过程和上面第二步差不多。
参考知识库
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:336808次
积分:2273
积分:2273
排名:第13431名
原创:65篇
评论:162条
(1)(3)(2)(6)(1)(1)(2)(5)(6)(6)(7)(4)(5)(1)(1)(2)(1)(1)(2)(1)(1)(1)(3)(2)(1)(1)(2)(2)(2)发送私信成功
DevStore用户登录
还没有DevStore帐号?
快捷登录:
您目前的活力值不够下载该资源哦~~
怎么样快速获得活力值?
下载此资源将扣除活力值-20
(只在首次下载扣除活力值,之后可以免费下载)
为了尽快解决大伙儿的问题,请务必要找相对应的客服哦~
> 源码详情
微信支付demo
17:09 && 浏览量(19441) &&
功能分类:工具
支持平台:Android
运行环境:Eclipse
开发语言:Java
开发工具:Eclipse
源码大小:717.24KB
3172 人下载
微信支付demo(官方demo)
DevStore所有源码来自用户上传分享,版权问题及牵扯到商业纠纷均与DevStore无关。
PayReq req = new PayReq();
req.appId = Constants.APP_ID;
req.partnerId = Constants.PARTNER_ID;
req.prepayId = result.prepayId;
req.nonceStr = nonceS
req.timeStamp = String.valueOf(timeStamp);
req.packageValue = "Sign=Wxpay";//"Sign=" + packageV
List signParams = new LinkedList();
signParams.add(new BasicNameValuePair("appid", req.appId));
signParams.add(new BasicNameValuePair("appkey", APP_KEY));
signParams.add(new BasicNameValuePair("noncestr", req.nonceStr));
signParams.add(new BasicNameValuePair("package", req.packageValue));
signParams.add(new BasicNameValuePair("partnerid", req.partnerId));
signParams.add(new BasicNameValuePair("prepayid", req.prepayId));
signParams.add(new BasicNameValuePair("timestamp", req.timeStamp));
req.sign = genSign(signParams);
Log.d("d", "调起支付的package串:"+req.packageValue);
// 在支付之前,如果应用没有注册到微信,应该先调用IWXMsg.registerApp将应用注册到微信
api.sendReq(req);
下载(3172)
回复@cjcj125125:http://blog.csdn.net/u/article/details/ 已转CSDN
获取活力值
源码上传作者
资料下载排行
开发者交流群:
DevStore技术交流群2:
运营交流群:
产品交流群:
深圳尺子科技有限公司
深圳市南山区蛇口网谷万海大厦C栋504
Copyright (C) 2015 DevStore. All Rights ReservedJAVA版微信支付V3-完全版
我的图书馆
JAVA版微信支付V3-完全版
本人用的开发框架是:struts2(用了struts2的0配置,对于struts的0配置不熟悉的可以看看这个博客了解下)
本人做的是微信V3版本的微信支付,也是目前最新的微信支付接口。官方文档下载地址
微信支付成功后&&你的邮件会有以下信息:
1、 信息包括:商户ID(mch_id)、申请编号、登录帐号、登录密码、商户API密码(key)
2.、证书包括:商户API证书、证书密钥、CA证书
开发前,我们先登录自己的服务号,点击微信支付-----&开发配置。
如果这里的授权路径和下面参数的notify_url不对&&调用付款接口时会弹出access_denied。
比如,我的授权目录是http://183.33.212.175/wxweb/config/,那么我对应的notify_url的回调方法必须是String notify_url = "http://183.33.212.175:8016/wxweb/config/pay!paySuccess.action";这样的
下图是微信支付JSAPI支付方法的流程图。
登陆Oauth2授权的问题,我会另外写篇博客。在此略过。需要注意一点的是,微信支付是微信5.0以上版本才能支持,所以,可能有些用户的微信版本是低版本无法进行微信支付而用户又不知道为什么就是不能支付,我们需要进行一个版本判断,如果用户的微信版本低于5.0就告知用户一些提示信息。那么,如何判断用户的微信版本是多少呢?我们可以通过这个方法可以获取一些信息然后进行判断:request.getHeader("user-agent")获取信息。
以 iPhone 版本为例,可以通过 user agent 可获取如下微信版本示例信息:
"Mozilla/5.0(CPU iphone OS 5_1_1 like Mac OS X) AppleWebKit/534.46(KHTML,like Geocko) Mobile/9B206 MicroMessenger/5.0"
其中 5.0 为用户安装的微信版本号,商户可以判定版本号是否高于或者等于 5.0。具体判断代码请留意后面代码。
流程图中,我们看到需要先调用一次统一接口,然后微信会返回一个prepayId给我们。那么我们先来调用统一接口。调用接口的URL地址:https://api.mch./pay/unifiedorder,调用统一接口需要以下参数。
看到这些参数,不难理解需要传入什么。那么参数中的sign需要以下规则进行生成。
下面是我生成sign的方法。注意,参数是必填项的必须加进去。sign的生成规则是,除了上除列表中sign字段为所有的参数都可以参与sign的生成且参与生成sign的参数值不为空.
&& & * @author 李欣桦
&& & * @date 下午2:29:34
&& & * @Description:sign签名
&& & * @param characterEncoding 编码格式
&& & * @param parameters 请求参数
&& & * @return
&& &public static String createSign(String characterEncoding,SortedMap&Object,Object& parameters){
&& &&& &StringBuffer sb = new StringBuffer();
&& &&& &Set es = parameters.entrySet();
&& &&& &Iterator it = es.iterator();
&& &&& &while(it.hasNext()) {
&& &&& &&& &Map.Entry entry = (Map.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=" + ConfigUtil.API_KEY);
&& &&& &String sign = MD5Util.MD5Encode(sb.toString(), characterEncoding).toUpperCase();
MD5Util工具类中相关的方法
public class MD5Util {
&& &private static String byteArrayToHexString(byte b[]) {
&& &&& &StringBuffer resultSb = new StringBuffer();
&& &&& &for (int i = 0; i & b. i++)
&& &&& &&& &resultSb.append(byteToHexString(b[i]));
&& &&& &return resultSb.toString();
&& &private static String byteToHexString(byte b) {
&& &&& &int n =
&& &&& &if (n & 0)
&& &&& &&& &n += 256;
&& &&& &int d1 = n / 16;
&& &&& &int d2 = n % 16;
&& &&& &return hexDigits[d1] + hexDigits[d2];
&& &public static String MD5Encode(String origin, String charsetname) {
&& &&& &String resultString =
&& &&& &try {
&& &&& &&& &resultString = new String(origin);
&& &&& &&& &MessageDigest md = MessageDigest.getInstance("MD5");
&& &&& &&& &if (charsetname == null || "".equals(charsetname))
&& &&& &&& &&& &resultString = byteArrayToHexString(md.digest(resultString
&& &&& &&& &&& &&& &&& &.getBytes()));
&& &&& &&& &else
&& &&& &&& &&& &resultString = byteArrayToHexString(md.digest(resultString
&& &&& &&& &&& &&& &&& &.getBytes(charsetname)));
&& &&& &} catch (Exception exception) {
&& &&& &return resultS
&& &private static final String hexDigits[] = { "0", "1", "2", "3", "4", "5",
&& &&& &"6", "7", "8", "9", "a", "b", "c", "d", "e", "f" };
各位需要记住,我们发送给微信服务器的参数是xml格式的string,微信返回来的信息也是xml格式的string。
我们提交的正确数据应该是这样的。
&appid&wx0ec43b&/appid&
&attach&&![CDATA[att1]]&&/attach&
&body&&![CDATA[JSAPI 支付测试]]&&/body&
&device_info&1000&/device_info&
&mch_id&&/mch_id&
&nonce_str&bd1d9ed8b2&/nonce_str&
&notify_url&http://wxpay./pub_v2/pay/notify.php&;/notify_url&
&out_trade_no&&/out_trade_no&
&spbill_create_ip&127.0.0.1&/spbill_create_ip&
&total_fee&1&/total_fee&
&trade_type&JSAPI&/trade_type&
&sign&&![CDATA[3CA89BCCF4]]&&/sign&
那么。我们来生成这样的post data
SortedMap&Object,Object& parameters = new TreeMap&Object,Object&();
parameters.put("appid", ConfigUtil.APPID);
parameters.put("mch_id", ConfigUtil.MCH_ID);
parameters.put("nonce_str", PayCommonUtil.CreateNoncestr());
parameters.put("body", "LEO测试");
parameters.put("out_trade_no", "");
parameters.put("total_fee", "1");
parameters.put("spbill_create_ip",IpAddressUtil.getIpAddr(request));
parameters.put("notify_url", ConfigUtil.NOTIFY_URL);
parameters.put("trade_type", "JSAPI");
parameters.put("openid", "o7W6yt9DUOBpjEYogs4by1hD_OQE");
String sign = PayCommonUtil.createSign("UTF-8", parameters);
parameters.put("sign", sign);
String requestXML = PayCommonUtil.getRequestXml(parameters);
PayCommonUtil.getRequestXml(parameters)方法如下:
&& & * @author 李欣桦
&& & * @date 下午2:32:05
&& & * @Description:将请求参数转换为xml格式的string
&& & * @param parameters& 请求参数
&& & * @return
&& &public static String getRequestXml(SortedMap&Object,Object& parameters){
&& &&& &StringBuffer sb = new StringBuffer();
&& &&& &sb.append("&xml&");
&& &&& &Set es = parameters.entrySet();
&& &&& &Iterator it = es.iterator();
&& &&& &while(it.hasNext()) {
&& &&& &&& &Map.Entry entry = (Map.Entry)it.next();
&& &&& &&& &String k = (String)entry.getKey();
&& &&& &&& &String v = (String)entry.getValue();
&& &&& &&& &if ("attach".equalsIgnoreCase(k)||"body".equalsIgnoreCase(k)||"sign".equalsIgnoreCase(k)) {
&& &&& &&& &&& &sb.append("&"+k+"&"+"&![CDATA["+v+"]]&&/"+k+"&");
&& &&& &&& &}else {
&& &&& &&& &&& &sb.append("&"+k+"&"+v+"&/"+k+"&");
&& &&& &&& &}
&& &&& &sb.append("&/xml&");
&& &&& &return sb.toString();
最后我们要将这些参数以POST方式调用微信统一支付接口:代码如下
String result =CommonUtil.httpsRequest(ConfigUtil.UNIFIED_ORDER_URL, "POST", requestXML);
CommonUtil.httpsRequest(ConfigUtil.UNIFIED_ORDER_URL, "POST", requestXML);方法如下:
&& & * 发送https请求
&& & * @param requestUrl 请求地址
&& & * @param requestMethod 请求方式(GET、POST)
&& & * @param outputStr 提交的数据
&& & * @return 返回微信服务器响应的信息
&& &public static String httpsRequest(String requestUrl, String requestMethod, String outputStr) {
&& &&& &try {
&& &&& &&& &// 创建SSLContext对象,并使用我们指定的信任管理器初始化
&& &&& &&& &TrustManager[] tm = { new MyX509TrustManager() };
&& &&& &&& &SSLContext sslContext = SSLContext.getInstance("SSL", "SunJSSE");
&& &&& &&& &sslContext.init(null, tm, new java.security.SecureRandom());
&& &&& &&& &// 从上述SSLContext对象中得到SSLSocketFactory对象
&& &&& &&& &SSLSocketFactory ssf = sslContext.getSocketFactory();
&& &&& &&& &URL url = new URL(requestUrl);
&& &&& &&& &HttpsURLConnection conn = (HttpsURLConnection) url.openConnection();
&& &&& &&& &conn.setSSLSocketFactory(ssf);
&& &&& &&& &conn.setDoOutput(true);
&& &&& &&& &conn.setDoInput(true);
&& &&& &&& &conn.setUseCaches(false);
&& &&& &&& &// 设置请求方式(GET/POST)
&& &&& &&& &conn.setRequestMethod(requestMethod);
&& &&& &&& &conn.setRequestProperty("content-type", "application/x-www-form-urlencoded");
&& &&& &&& &// 当outputStr不为null时向输出流写数据
&& &&& &&& &if (null != outputStr) {
&& &&& &&& &&& &OutputStream outputStream = conn.getOutputStream();
&& &&& &&& &&& &// 注意编码格式
&& &&& &&& &&& &outputStream.write(outputStr.getBytes("UTF-8"));
&& &&& &&& &&& &outputStream.close();
&& &&& &&& &}
&& &&& &&& &// 从输入流读取返回内容
&& &&& &&& &InputStream inputStream = conn.getInputStream();
&& &&& &&& &InputStreamReader inputStreamReader = new InputStreamReader(inputStream, "utf-8");
&& &&& &&& &BufferedReader bufferedReader = new BufferedReader(inputStreamReader);
&& &&& &&& &String str =
&& &&& &&& &StringBuffer buffer = new StringBuffer();
&& &&& &&& &while ((str = bufferedReader.readLine()) != null) {
&& &&& &&& &&& &buffer.append(str);
&& &&& &&& &}
&& &&& &&& &// 释放资源
&& &&& &&& &bufferedReader.close();
&& &&& &&& &inputStreamReader.close();
&& &&& &&& &inputStream.close();
&& &&& &&& &inputStream =
&& &&& &&& &conn.disconnect();
&& &&& &&& &return buffer.toString();
&& &&& &} catch (ConnectException ce) {
&& &&& &&& &log.error("连接超时:{}", ce);
&& &&& &} catch (Exception e) {
&& &&& &&& &log.error("https请求异常:{}", e);
接着,我们来解析微信返回给我们的信息。返回信息是xml格式的String
XMLUtil.工具类如下:
public class XMLUtil {
&& & * 解析xml,返回第一级元素键值对。如果第一级元素有子节点,则此节点的值是子节点的xml数据。
&& & * @param strxml
&& & * @return
&& & * @throws JDOMException
&& & * @throws IOException
&& &public static Map doXMLParse(String strxml) throws JDOMException, IOException {
&& &&& &strxml = strxml.replaceFirst("encoding=\".*\"", "encoding=\"UTF-8\"");
&& &&& &if(null == strxml || "".equals(strxml)) {
&& &&& &&& &
&& &&& &Map m = new HashMap();
&& &&& &InputStream in = new ByteArrayInputStream(strxml.getBytes("UTF-8"));
&& &&& &SAXBuilder builder = new SAXBuilder();
&& &&& &Document doc = builder.build(in);
&& &&& &Element root = doc.getRootElement();
&& &&& &List list = root.getChildren();
&& &&& &Iterator it = list.iterator();
&& &&& &while(it.hasNext()) {
&& &&& &&& &Element e = (Element) it.next();
&& &&& &&& &String k = e.getName();
&& &&& &&& &String v = "";
&& &&& &&& &List children = e.getChildren();
&& &&& &&& &if(children.isEmpty()) {
&& &&& &&& &&& &v = e.getTextNormalize();
&& &&& &&& &} else {
&& &&& &&& &&& &v = XMLUtil.getChildrenText(children);
&& &&& &&& &}
&& &&& &&& &
&& &&& &&& &m.put(k, v);
&& &&& &//关闭流
&& &&& &in.close();
&& & * 获取子结点的xml
&& & * @param children
&& & * @return String
&& &public static String getChildrenText(List children) {
&& &&& &StringBuffer sb = new StringBuffer();
&& &&& &if(!children.isEmpty()) {
&& &&& &&& &Iterator it = children.iterator();
&& &&& &&& &while(it.hasNext()) {
&& &&& &&& &&& &Element e = (Element) it.next();
&& &&& &&& &&& &String name = e.getName();
&& &&& &&& &&& &String value = e.getTextNormalize();
&& &&& &&& &&& &List list = e.getChildren();
&& &&& &&& &&& &sb.append("&" + name + "&");
&& &&& &&& &&& &if(!list.isEmpty()) {
&& &&& &&& &&& &&& &sb.append(XMLUtil.getChildrenText(list));
&& &&& &&& &&& &}
&& &&& &&& &&& &sb.append(value);
&& &&& &&& &&& &sb.append("&/" + name + "&");
&& &&& &&& &}
&& &&& &return sb.toString();
Map&String, String& map = XMLUtil.doXMLParse(result);//解析微信返回的信息,以Map形式存储便于取值
现在我们可以拿到想要拿的值,那么可以调用微信H5网页端调用支付接口。在微信浏览器里面打开 H5 网页中执行 JS 调起支付。接口输入输出数据格式为 JSON。
注意:WeixinJSBridge 内置对象在其他浏览器中无效;列表中参数名区分大小。
现在我们将返回的值传入到支付jsp页面,在支付jsp页面调用支付接口。
SortedMap&Object,Object& params = new TreeMap&Object,Object&();
&& &&& &params.put("appId", "wx0953bae287adfeee");
&& &&& &params.put("timeStamp", Long.toString(new Date().getTime()));
&& &&& &params.put("nonceStr", PayCommonUtil.CreateNoncestr());
&& &&& &params.put("package", "prepay_id="+map.get("prepay_id"));
&& &&& &params.put("signType", ConfigUtil.SIGN_TYPE);
&& &&& &String paySign =& PayCommonUtil.createSign("UTF-8", params);
&& &&& &params.put("packageValue", "prepay_id="+map.get("prepay_id"));&&& //这里用packageValue是预防package是关键字在js获取值出错
&& &&& &params.put("paySign", paySign);&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& //paySign的生成规则和Sign的生成规则一致
&& &&& &params.put("sendUrl", ConfigUtil.SUCCESS_URL);&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& //付款成功后跳转的页面
&& &&& &String userAgent = request.getHeader("user-agent");
&& &&& &char agent = userAgent.charAt(userAgent.indexOf("MicroMessenger")+15);
&& &&& &params.put("agent", new String(new char[]{agent}));//微信版本号,用于前面提到的判断用户手机微信的版本是否是5.0以上版本。
&& &&& &String json = JSONObject.fromObject(params).toString();
下面是一个简洁的支付页面。代码如下:
[html] &body&&&&&&&&form&action=""&method="post"&&&&&&&&&&&&&input&type="button"&value="确认支付"&name="ajaxLoadId"&id="test"/&&&&&&&&/form&&&&&&&&script&type="text/javascript"&&&&&&&var&basePath&=&"&%=basePath%&";&&&&&&$("#test").one("click",function(){&&&&&&&&&&$.ajax({&&&&&&&&&&&&&&url:basePath+"config/pay!execute.action"&&&&&&&&&&&&//&span&style="font-family:微软雅黑;"&ajax调用微信统一接口获取prepayId&/span&&&&&&&&&&&}).done(function(data){&&&&&&&&&&&&&&var&obj&=&eval('('&+&data&+&')');&&&&&&&&&&&&&&if(parseInt(obj.agent)&5){&&&&&&&&&&&&&&&&&&alert("您的微信版本低于5.0无法使用微信支付");&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&}&&&&&&&&&&&&&&WeixinJSBridge.invoke('getBrandWCPayRequest',{&&&&&&&&&&&&&&&&&&"appId"&:&obj.appId,&&&&&&&&&&&&&&&&&&//公众号名称,由商户传入&&&&&&&&&&&&&&&&&&"timeStamp":obj.timeStamp,&&&&&&&&&&//时间戳,自&1970&年以来的秒数&&&&&&&&&&&&&&&&&&"nonceStr"&:&obj.nonceStr,&&&&&&&&&//随机串&&&&&&&&&&&&&&&&&&"package"&:&obj.packageValue,&&&&&&//&span&style="font-family:微软雅黑;"&商品包信息&/span&&&&&&&&&&&&&&&&&&&"signType"&:&obj.signType,&&&&&&&&//微信签名方式:&&&&&&&&&&&&&&&&&&"paySign"&:&obj.paySign&&&&&&&&&&&//微信签名&&&&&&&&&&&&&&&&&&},function(res){&&&&&&&&&&&&&&&&&&&&&&&&&&alert(res.err_msg);&&&&&&&&&&&&&&&&&&if(res.err_msg&==&"get_brand_wcpay_request:ok"&)&{&&&&&&&&&&&&&&&&&&&&&&window.location.href=obj.sendU&&&&&&&&&&&&&&&&&&}else{&&&&&&&&&&&&&&&&&&&&&&alert("fail");&&&&&&&&&&&&&&&&&&&&&&window.location.href="http://183.45.18.197:8016/wxweb/config/oauth!execute.action";&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&//&span&style="font-family:微软雅黑;"&当失败后,继续跳转该支付页面让用户可以继续付款,贴别注意不能直接调转jsp,&/span&&span&style="font-size:10.5pt"&不然会报&/span&&span&style="font-size:12.0pt"&&system:access_denied。&/span&&&&&&&&&&&&&&&&&&&}&&&&&&&&&&&&&&});&&&&&&&&&&&&&&&&&&&&&&&&});&&&&&&});&&&&&&&/script&&&&&&/body&&&支付成功后,微信就会调用你填写的notify_url的方法,本人微信支付的开发配置中说明了我的notify_url为http://183.33.212.175:8016/wxweb/config/pay!paySuccess.action
对后台通知交互时,如果微信收到商户的应答不是成功或超时,微信认为通知失败,微信会通过一定的策略(如
30 分钟共 8 次)定期重新发起通知,尽可能提高通知的成功率,
但微信不保证通知最终能成功。由于存在重新収送后台通知的情况,因此同样的通知可能会多次収送给商户系统。 商户系统必须能够正确处理重复的通知。
推荐的做法是,当收到通知进行处理时,首先检查对应业务数据的状态,判断该通知是否已经处理过,如果没有处理过再进行处理,如果处理过直接返回结果成功。在对业务数据
进行状态检查和处理之前,要采用数据锁进行幵収控制,以避免凼数重入造成的数据混乱。
判断完成后,我们需要通知微信,我们收到信息了,不然微信就会通过一定的策略定期重新发起通知。
怎么通知微信呢。方法如下。
void paySuccess() throws Exception{
&& &&& &HttpServletRequest request = ServletActionContext.getRequest();
&& &&& &HttpServletResponse response = ServletActionContext.getResponse();
&& &&& &InputStream inStream = request.getInputStream();
&& &&& &ByteArrayOutputStream outSteam = new ByteArrayOutputStream();
&& &&& &byte[] buffer = new byte[1024];
&& &&& &int len = 0;
&& &&& &while ((len = inStream.read(buffer)) != -1) {
&& &&& &&& &outSteam.write(buffer, 0, len);
&& &&& &System.out.println("~~~~~~~~~~~~~~~~付款成功~~~~~~~~~");
&& &&& &outSteam.close();
&& &&& &inStream.close();
&& &&& &String result& = new String(outSteam.toByteArray(),"utf-8");//获取微信调用我们notify_url的返回信息
&& &&& &Map&Object, Object& map = XMLUtil.doXMLParse(result);
&& &&& &for(Object keyValue : map.keySet()){
&& &&& &&& &System.out.println(keyValue+"="+map.get(keyValue));
&& &&& &if (map.get("result_code").toString().equalsIgnoreCase("SUCCESS")) {
&& &&& &&& &//TODO 对数据库的操作
&& &&& &&& &response.getWriter().write(PayCommonUtil.setXML("SUCCESS", ""));&& //告诉微信服务器,我收到信息了,不要在调用回调action了
&& &&& &&& &System.out.println("-------------"+PayCommonUtil.setXML("SUCCESS", ""));
PayCommonUtil.setXML("SUCCESS",
""))方法如下:
static String setXML(String return_code, String return_msg) {
& && &&&return "&xml&&return_code&&![CDATA[" + return_code
& && && && && & + "]]&&/return_code&&return_msg&&![CDATA[" + return_msg
& && && && && & + "]]&&/return_msg&&/xml&";
上面代码中工具类打包下载地址:http://download.csdn.net/detail/u54883
官方文档有少许常见错误解决方法,观众们可自行下载查阅,仍有不懂的可留言。
第一次写这么长的博客,不足之处请留言告之便于本人成长,再次感谢你的阅读。
发表评论:
TA的最新馆藏

我要回帖

更多关于 微信刷卡支付开发 的文章

 

随机推荐