微信公众号支付 java支付的java版dome在哪

微信扫码支付原生Native支付 java版 php版-微信-手机开发-壹聚教程网微信扫码支付原生Native支付 java版 php版
微信支付是集成在微信客户端的支付功能,用户可以通过手机完成快速的支付流程。本文我们讲讲微信扫二维码支付
java版 php版 原生Native支付实例。
java版微信扫码支付账号配置参数生成等请参考官方文档:htt://pay./wiki/doc/api/native.php?chapter=6_1微信扫码支付。简单来说,就是你把微信支付需要的信息,生成到二维码图片中。通过微信扫一扫,发起支付。我们需要做的就是二件事:一是:按照微信扫码支付规则生成二维码信息.二是:微信没有提供生成二维码图片的接口。需要我们自己把二维码信息生成到二维码图片中。1.模式选择:微信扫码支付,有两种模式,文档中有介绍。第二种模式,微信接口会返回二维码信息给我们。而第一种模式则需要我们自己去生成二维码信息。会有些麻烦。尤其是参数大小写,还有签名的问题,容易出错。总的来说第二种模式比第一种模式简单。所有我采用的是第二种模式,比较通用。京东与携程亦用的是第二种模式。2.调用统一下单接口获取带有二维码信息的url:(模式二)模式二的微信扫码支付,需要先调用微信的统一下单接口,生成预交易单。(参数传递与接收都是XML 数据格式。)正确调用后,会返回含有交易标示ID,和二维码链接的URL。HashMap&String, String& paramMap = Maps.newHashMap(); paramMap.put(&trade_type&, &NATIVE&); //交易类型paramMap.put(&spbill_create_ip&,localIp()); //本机的IpparamMap.put(&product_id&, payOrderIdsStr); // 商户根据自己业务传递的参数 必填paramMap.put(&body&, orderSubject);&&&&&&&& //描述paramMap.put(&out_trade_no&, payOrderIdsStr); //商户 后台的贸易单号paramMap.put(&total_fee&, && + totalCount); //金额必须为整数& 单位为分paramMap.put(&notify_url&, &http://& + getAccessDomain() + &/wx_pay_notify&); //支付成功后,回调地址&&& &paramMap.put(&appid&, siteConfig.getWxPayAppId()); //appidparamMap.put(&mch_id&, siteConfig.getWxPayMchId()); //商户号&&&& &paramMap.put(&nonce_str&, CommonUtilPub.createNoncestr(32));& //随机数 &paramMap.put(&sign&,CommonUtilPub.getSign(paramMap,siteConfig.getWxPayPartnerKey()));//根据微信签名规则,生成签名 String xmlData = CommonUtilPub.mapToXml(paramMap);//把参数转换成XML数据格式/**&&&& * 获取本机Ip &&&& * &&&&& *& 通过 获取系统所有的networkInterface网络接口 然后遍历 每个网络下的InterfaceAddress组。&&&& *& 获得符合 &code&InetAddress instanceof Inet4Address&/code& 条件的一个IpV4地址&&&& * @return&&&& */&&& @SuppressWarnings(&rawtypes&)&&& private String localIp(){&&&&&&& String ip =&&&&&&& Enumeration allNetI&&&&&&& try {&&&&&&&&&&& allNetInterfaces = NetworkInterface.getNetworkInterfaces();&&&&&&&&&& &&&&&&&&&&&& while (allNetInterfaces.hasMoreElements()) {&&&&&&&&&&&&&&& NetworkInterface netInterface = (NetworkInterface) allNetInterfaces.nextElement();&&&&&&&&&&&&&&& List&InterfaceAddress& InterfaceAddress = netInterface.getInterfaceAddresses();&&&&&&&&&&&&&&& for (InterfaceAddress add : InterfaceAddress) {&&&&&&&&&&&&&&&&&&& InetAddress Ip = add.getAddress();&&&&&&&&&&&&&&&&&&& if (Ip != null && Ip instanceof Inet4Address) {&&&&&&&&&&&&&&&&&&&&&&& ip = Ip.getHostAddress();&&&&&&&&&&&&&&&&&&& }&&&&&&&&&&&&&&& }&&&&&&&&&&& }&&&&&&& }
(SocketException e) {&&&&&&&&&&& // TODO Auto-generated catch block&&&&&& &&&&&&&&&&&& logger.warn(&获取本机Ip失败:异常信息:&+e.getMessage());&&&&&&& }&&&&&&&&&& }&成功时返回的XML数据为:&xml&&return_code&&![CDATA[SUCCESS]]&&/return_code&&return_msg&&![CDATA[OK]]&&/return_msg&&appid&&![CDATA[wx49342bda0ef105dd]]&&/appid&&mch_id&&![CDATA[]]&&/mch_id&&nonce_str&&![CDATA[UneMQd4qWQd0hJ4L]]&&/nonce_str&&sign&&![CDATA[C621A9C586C1FB8003E0CBCE]]&&/sign&&result_code&&![CDATA[SUCCESS]]&&/result_code&&prepay_id&&![CDATA[wx1790742fea5e]]&&/prepay_id&&trade_type&&![CDATA[NATIVE]]&&/trade_type&&code_url&&![CDATA[weixin://wxpay/bizpayurl?pr=AOFEsxf]]&&/code_url&&/xml&解析XML 获取 code_url:String resXml = HtmlUtil.postData(&https://api.mch./pay/unifiedorder&, xmlData);Document dd =String code_url=try {&&& dd = DocumentHelper.parseText(resXml);& } catch (DocumentException e) {&&&&&& return &&; }if (dd != null) {&&& Element root = dd.getRootElement();&&& if (root == null) {&&& return &&;&&& }&&& Element codeUrl = root.element(&code_url&);&&& if (piEle == null) {&&& return &&;&&& } &&&& code_url = codeUrl.getText();& //解析 xml 获得 code_url}&3.动态生成二维码图片使用的是google ZXing库。 提供一个 jar 地址 直接引入到自己项目即可。http://download.csdn.net/detail/gonwy/7658135 &&页面代码:&img src=&qr_code.img?code_url= &#if code_url??&${code_url}&/#if&& style=&width:300height:300&/&java 代码:&& &/**&& * 生成二维码图片并直接以流的形式输出到页面&& * @param code_url&& * @param response&& */& @RequestMapping(&qr_code.img&)& @ResponseBody& public void getQRCode(String code_url,HttpServletResponse response){&&& GenerateQrCodeUtil.encodeQrcode(code_url, response);& }/**&&&& * 生成二维码图片 不存储 直接以流的形式输出到页面&&&& * @param content&&&& * @param response&&&& */&&& @SuppressWarnings({ &unchecked&, &rawtypes& })&&& public static void encodeQrcode(String content,HttpServletResponse response){&&&&&&& if(StringUtils.isBlank(content))&&&&&&&&&&&&&&&&&& MultiFormatWriter multiFormatWriter = new MultiFormatWriter();&&&&&&& Map hints = new HashMap();&&&&&&& hints.put(EncodeHintType.CHARACTER_SET, &UTF-8&); //设置字符集编码类型&&&&&&& BitMatrix bitMatrix =&&&&&&& try {&&&&&&&&&&& bitMatrix = multiFormatWriter.encode(content, BarcodeFormat.QR_CODE, 300, 300,hints);&&&&&&&&&&& BufferedImage image = toBufferedImage(bitMatrix);&&&&&&&&&&& //输出二维码图片流&&&&&&&&&&& try {&&&&&&&&&&&&&&& ImageIO.write(image, &png&, response.getOutputStream());&&&&&&&&&&& } catch (IOException e) {&&&&&&&&&&&&&&& // TODO Auto-generated catch block&&&&&&&&&&&&&&& e.printStackTrace();&&&&&&&&&&& }&&&&&&& } catch (WriterException e1) {&&&&&&&&&&& // TODO Auto-generated catch block&&&&&&&&&&& e1.printStackTrace();&&&&&&& }&&&&&&& &&&& }然后生成的图片,通过微信扫码就可以发起支付了。支付成功后,微信会调用,你之前设置的回调函数地址。并且会把你之前传给微信的商户自定义参数带给你,以帮助商户完成余下业务流程。php版微信扫码支付一、生成Native支付URLNative(原生)支付URL是一系列具有weixin://wxpay/bizpayurl?前缀的URL,同时后面紧跟着一系列辨别商户的键值对。Native(原生)支付URL的规则如下:weixin://wxpay/bizpayurl?sign=XXXXX&appid=XXXXXX&productid=XXXXXX&timestamp=XXXXXX&noncestr=XXXXXX&生成代码如下&?php_once(&WxPayHelper.php&);$wxPayHelper = new WxPayHelper();echo $wxPayHelper-&create_native_url(&&);?&其中productid是商品唯一id,开发人员需要定义并维护自己的商品id,这个id与一张订单等价,微信后台凭借该id通过POST商户后台获取交易信息。上述代码生成的URL如下:weixin://wxpay/bizpayurl?appid=wxb489e8caeabcdefg&noncestr=BBvdr5atZ9D7s08X&productid=&sign=e15db530e2f2f67ccb5&timestamp=&二、生成二维码生成二维码可以用第三方接口,也可以使用自己的代码或插件,这里介绍PHP QR Code。PHP QR Code是一个PHP二维码生成类库,利用它可以轻松生成二维码,官网提供了下载和多个演示demo,查看地址:http://phpqrcode.sourceforge.net/。其生成二维码的语法非常简单,直接填入URL当参数即可。范例如下include 'phpqrcode.php'; QRcode::png('/txw1958/');这样就生成了一个支付的二维码。&三、生成Package当用户扫描上述二维码的时候,会调用Native支付URL,URL需要调用订单信息Package返回给用户,而该Package由WxPayHelper类的create_native_package()实现,调用代码如下:&?phpinclude_once(&WxPayHelper.php&);$commonUtil = new CommonUtil();$wxPayHelper = new WxPayHelper();$wxPayHelper-&setParameter(&bank_type&, &WX&);$wxPayHelper-&setParameter(&body&, &方倍工作室微信支付开发教程&);$wxPayHelper-&setParameter(&partner&, &&);$wxPayHelper-&setParameter(&out_trade_no&, $commonUtil-&create_noncestr());$wxPayHelper-&setParameter(&total_fee&, &1&);$wxPayHelper-&setParameter(&fee_type&, &1&);$wxPayHelper-&setParameter(&notify_url&, &htttp://&);$wxPayHelper-&setParameter(&spbill_create_ip&, &127.0.0.1&);$wxPayHelper-&setParameter(&input_charset&, &GBK&);echo $wxPayHelper-&create_native_package();?&当用户扫描二维码后,将直接跳到商品页面,如下所示
上一页: &&&&&下一页:相关内容1.请求前的拼包
&英文全大写带下划线的,各位申请微信支付的时候都会给你的。
注意:微信demo里面RequestHandler 在设置商户key和appkey有点问题,ResponseHandler连postData都没获取到,下面把我修正后的贴出来做参考(注:其它java类没什么问题)
&RequestHandler:
ResponseHandler:
2.Jsapi调用
在第一步中已拼好包放入request中了,第二部js调用微信api,看代码:
[javascript]&&
点击支付按钮,调用callpay 即可。
3.微信支付后的通知接口
支付成功了,微信根据你提供的notify_url,来通知你支付成功与否,虽然js里知道了结果,但这里需要正式通知,并处理业务,下面是我的代码片段:
到这里OK了,支付接口完成了。
参考知识库
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:242次
排名:千里之外JAVA版微信支付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的最新馆藏}

我要回帖

更多关于 微信支付dome 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信