java开发微信分享到朋友圈功能

微信分享功能开发

用了一天时间,把微信发送给朋友和分享到朋友圈功能开发出来,在这里给大家分享一下,避免大家走弯路。

一、服务器端程序

package com.wiimedia.controller;

import java.io.IOException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Arrays;
import java.util.Date;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;

import com.google.gson.Gson;
import com.wiimedia.model.Ticket;
import com.wiimedia.service.ArticleSolrService;
import com.wiimedia.service.TicketRepository;
import com.wiimedia.service.TicketRepositorySolr;
import com.wiimedia.utils.GetRandomStr;
import com.wiimedia.utils.SignatureBean;
import com.wiimedia.utils.weixin.WeixinUtil;
/**
 *
 *
 *<p>Project:mryl_phone_v2</p>
 *
 *<p>Package:com.wiimedia.controller</p>
 *
 *<p>Description:微信分享Controller</p>
 *
 *<p>Company:Wiimedia</p>
 *
 *@Athor:SongJia
 *
 *@Date:2016-7-15 上午09:34:10
 *
 */

@Controller
@RequestMapping("/WeixinshareController/Api/Inteface")
public class WeixinshareController {
 @Autowired
 private TicketRepositorySolr ticketRepositorySolr;

 @RequestMapping("/getSignature")
 public String getSignature( HttpServletRequest request,
  HttpServletResponse response) throws IOException, ParseException{
 //获取签名页面链接
 String url = request.getParameter("url");
 SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
 //从数据库中获取标签,并检查标签是否过期
 Ticket oldticket = ticketRepositorySolr.getTicketById("20160114wiimediamrylsong1152");
 if(oldticket==null){//第一次访问,标签不存在。
  executeTicket(response,"1",url,format);
  return null;
 }else{//标签存在,判断标签是否超时
  String oldAcquiretime = oldticket.getAcquiretime();
  long difference=format.parse(format.format(new Date())).getTime()-format.parse(oldAcquiretime).getTime();
  if(difference>7100000){//标签超时,重新到微信服务器请求标签超时时间为7200秒(7200000毫秒)
  executeTicket(response,"2",url,format);
  return null;
  }else{//标签未超时
  /**
   * 注意事项
   * 1.签名用的noncestr和timestamp必须与wx.config中的nonceStr和timestamp相同。
   * 2.签名用的url必须是调用JS接口页面的完整URL。
   * 3.出于安全考虑,开发者必须在服务器端实现签名的逻辑。
   *
   ****根据第1点要求  signature 配置的时候很容易出错,需要把生成 Ticket的 noncestr和 timestamp传给客户端***
   */
  String signature = signature(oldticket.getTicket(),oldticket.getTimestamp(),oldticket.getNoncestr(),url);
  SignatureBean signatureBean = new SignatureBean();
  signatureBean.setNoncestr(oldticket.getNoncestr());
  signatureBean.setSignature(signature);
  signatureBean.setTimestamp(oldticket.getTimestamp());
  signatureBean.setUrl(url);
  response.setContentType("text/html;charset=UTF-8");
  response.getWriter().print(new Gson().toJson(signatureBean));
  return null;
  }
 }

 }
 /**
 *
 *<p>Project:mryl_phone_v2</p>
 *
 *<p>:mryl_phone_v2</p>
 *
 *<p>Description:更新和获取ticket的方法,因为用的solr所以更新和新增是一样的ID无则添加,有责更新</p>
 *
 *<p>Company:Wiimedia</p>
 *
 *@Athor:SongJia
 *
 *@Date:2016-7-15 上午09:45:00
 *
 */
 public void executeTicket(HttpServletResponse response,String flag,String url,SimpleDateFormat format) throws IOException{

 //获取签名随即字符串
 GetRandomStr randomStr = new GetRandomStr();
 String noncestr = randomStr.getRandomString(15);
 //获取签名时间戳
 String timestamp = Long.toString(System.currentTimeMillis());
 //请求accessToken
 String accessTokenUrl ="https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=您的APPID&secret=您的密匙";
 String tokenJson = WeixinUtil.httpRequest(accessTokenUrl, "GET", null);
 Gson gson = new Gson();
 ShareAccess_Token token = gson.fromJson(tokenJson, ShareAccess_Token.class);
 String to= token.getAccess_token();
 //获取标签
 String urlTicket ="https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token="+to+"&type=jsapi";
 String ticketJson = WeixinUtil.httpRequest(urlTicket, "GET", null);
 Ticket ticket = gson.fromJson(ticketJson, Ticket.class);
 String t = ticket.getTicket();
 //String uuid = UUID.randomUUID().toString().trim().replaceAll("-", "");
 //我的Ticket ID是写死的
 String acquiretime = format.format(new Date());
 ticket.setTid("20160114wiimediamrylsong1152");
 ticket.setAcquiretime(acquiretime);
 ticket.setTimestamp(timestamp);
 ticket.setNoncestr(noncestr);
 //因为用的SOLR所以更新和添加的方法是一样的,可以根据自己具体需求进行修改,本文不再贴出代码.
 if(flag.equals("2")){
  ticketRepositorySolr.addTicketToSolr(ticket);
 }else{
  ticketRepositorySolr.addTicketToSolr(ticket);
 }
 /**
  * 注意事项
  * 1.签名用的noncestr和timestamp必须与wx.config中的nonceStr和timestamp相同。
  * 2.签名用的url必须是调用JS接口页面的完整URL。
  * 3.出于安全考虑,开发者必须在服务器端实现签名的逻辑。
  *
  *根据第1点要求  signature 配置的时候很容易出错,需要把生成 Ticket的 noncestr和 timestamp传给客户端*
  */
 String signature = signature(t,timestamp,noncestr,url);
 SignatureBean signatureBean = new SignatureBean();
 signatureBean.setNoncestr(noncestr);
 signatureBean.setSignature(signature);
 signatureBean.setTimestamp(timestamp);
 signatureBean.setUrl(url);
 response.setContentType("text/html;charset=UTF-8");
 response.getWriter().print(new Gson().toJson(signatureBean));
 }

 /**
 *
 *<p>Project:mryl_phone_v2</p>
 *
 *<p>:mryl_phone_v2</p>
 *
 *<p>Description:根据标签,时间戳,密匙,URL进行签名</p>
 *
 *<p>Company:Wiimedia</p>
 *
 *@Athor:SongJia
 *
 *@Date:2016-7-15 上午09:37:13
 *
 */
 private String signature(String jsapi_ticket, String timestamp, String noncestr, String url) {
 jsapi_ticket = "jsapi_ticket=" + jsapi_ticket;
 timestamp = "timestamp=" + timestamp;
 noncestr = "noncestr=" + noncestr;
 url = "url=" + url;
 String[] arr = new String[] { jsapi_ticket, timestamp, noncestr, url };
 // 将token、timestamp、nonce,url参数进行字典序排序
 Arrays.sort(arr);
 StringBuilder content = new StringBuilder();
 for (int i = 0; i < arr.length; i++) {
  content.append(arr[i]);
  if (i != arr.length - 1) {
  content.append("&");
  }
 }
 MessageDigest md = null;
 String tmpStr = null;

 try {
  md = MessageDigest.getInstance("SHA-1");
  // 将三个参数字符串拼接成一个字符串进行sha1加密
  byte[] digest = md.digest(content.toString().getBytes());
  tmpStr = byteToStr(digest);
 } catch (NoSuchAlgorithmException e) {
  e.printStackTrace();
 }

 content = null;
 return tmpStr;
 }
 /**
 * 将字节转换为十六进制字符串
 *
 * @param mByte
 * @return
 */
 private static String byteToHexStr(byte mByte) {

 char[] Digit = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };
 char[] tempArr = new char[2];
 tempArr[0] = Digit[(mByte >>> 4) & 0X0F];
 tempArr[1] = Digit[mByte & 0X0F];

 String s = new String(tempArr);
 return s;
 }
 /**
 * 将字节数组转换为十六进制字符串
 *
 * @param byteArray
 * @return
 */
 private static String byteToStr(byte[] byteArray) {
 String strDigest = "";
 for (int i = 0; i < byteArray.length; i++) {
  strDigest += byteToHexStr(byteArray[i]);
 }
 return strDigest;
 }

 class ShareAccess_Token{
 private String access_token;
 private String expires_in;
 public String getAccess_token() {
  return access_token;
 }
 public void setAccess_token(String accessToken) {
  access_token = accessToken;
 }
 public String getExpires_in() {
  return expires_in;
 }
 public void setExpires_in(String expiresIn) {
  expires_in = expiresIn;
 }

 }
}

二、客户端代码.

<script type="text/javascript">
  var url = window.location.href;
  var articleId = "";
  var shareTitle="明日医疗资讯";
  var shareImgUrl="";
  var userinfo = localStorage.getItem("_userinfo");
  var timestamp;
  var noncestr;
  var signature;
  //获取签名
  $.ajax({
   type: "GET",
   url: "WeixinshareController/Api/Inteface/getSignature",
   //data:{timestamp:timestamp,noncestr:noncestr,url:url},
   data:{url:url},
   success: function(data){
    var objData=JSON.parse(data);
    timestamp=objData.timestamp;
    noncestr=objData.noncestr;
    signature=objData.signature;
     console.log(objData);
     wxShare();
   }
   });
  function wxShare(){
  wx.config({
  debug: false, // 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印。
  appId: '您的appid', // 和获取Ticke的必须一样------必填,公众号的唯一标识
  timestamp:timestamp, // 必填,生成签名的时间戳
  nonceStr: noncestr, // 必填,生成签名的随机串
  signature: signature,// 必填,签名,见附录1
  jsApiList: [
  'onMenuShareAppMessage'
  ] // 必填,需要使用的JS接口列表,所有JS接口列表见附录2
  });
  }
  wx.ready(function(){
   //config信息验证后会执行ready方法,所有接口调用都必须在config接口获得结果之后,
   //config是一个客户端的异步操作,所以如果需要在页面加载时就调用相关接口,则须把相关
   //接口放在ready函数中调用来确保正确执行。对于用户触发时才调用的接口,则可以直接调用,不需要放在ready函数中。

  //----------“分享给朋友”
  wx.onMenuShareAppMessage({
   title: "明日医疗资讯", // 分享标题
   desc: shareTitle, // 分享描述
   link: url, // 分享链接
   imgUrl: shareImgUrl, // 分享图标
   type: '', // 分享类型,music、video或link,不填默认为link
   dataUrl: '', // 如果type是music或video,则要提供数据链接,默认为空
   success: function () {
   // 用户确认分享后执行的回调函数、
   },
   cancel: function () {
   // 用户取消分享后执行的回调函数
   }
  });
  //------------"分享到朋友圈"
  wx.onMenuShareTimeline({
   title: '明日医疗资讯', // 分享标题
   link: '', // 分享链接
   imgUrl: shareImgUrl, // 分享图标
   success: function () {
   // 用户确认分享后执行的回调函数
   },
   cancel: function () {
   // 用户取消分享后执行的回调函数
   }
  });
  //-------------分享到QQ
  wx.onMenuShareQQ({
   title: '明日医疗资讯', // 分享标题
   desc: shareTitle, // 分享描述
   link: '', // 分享链接
   imgUrl: shareImgUrl, // 分享图标
   success: function () {
   // 用户确认分享后执行的回调函数
   },
   cancel: function () {
   // 用户取消分享后执行的回调函数
   }
  });
  //-------------分享到QQ空间
  wx.onMenuShareQZone({
   title: '明日医疗资讯', // 分享标题
   desc: shareTitle, // 分享描述
   link: '', // 分享链接
   imgUrl: shareImgUrl, // 分享图标
   success: function () {
   // 用户确认分享后执行的回调函数
   },
   cancel: function () {
   // 用户取消分享后执行的回调函数
   }
  });

  });

三、服务器需要的工具类和Model

① Ticket

package com.wiimedia.model;

public class Ticket{
 private String tid;
 private String ticket;
 private String errcode;
 private String errmsg;
 private String expires_in;
 private String acquiretime;
 private String noncestr;
 private String timestamp;

 public Ticket(String tid, String ticket, String errcode, String errmsg,
  String expiresIn, String acquiretime, String noncestr,
  String timestamp) {
 super();
 this.tid = tid;
 this.ticket = ticket;
 this.errcode = errcode;
 this.errmsg = errmsg;
 expires_in = expiresIn;
 this.acquiretime = acquiretime;
 this.noncestr = noncestr;
 this.timestamp = timestamp;
 }
 public String getTid() {
 return tid;
 }
 public void setTid(String tid) {
 this.tid = tid;
 }
 public String getTicket() {
 return ticket;
 }
 public void setTicket(String ticket) {
 this.ticket = ticket;
 }
 public String getErrcode() {
 return errcode;
 }
 public void setErrcode(String errcode) {
 this.errcode = errcode;
 }
 public String getErrmsg() {
 return errmsg;
 }
 public void setErrmsg(String errmsg) {
 this.errmsg = errmsg;
 }
 public String getExpires_in() {
 return expires_in;
 }
 public void setExpires_in(String expiresIn) {
 expires_in = expiresIn;
 }
 public String getAcquiretime() {
 return acquiretime;
 }
 public void setAcquiretime(String acquiretime) {
 this.acquiretime = acquiretime;
 }
 public String getNoncestr() {
 return noncestr;
 }
 public void setNoncestr(String noncestr) {
 this.noncestr = noncestr;
 }
 public String getTimestamp() {
 return timestamp;
 }
 public void setTimestamp(String timestamp) {
 this.timestamp = timestamp;
 }

}

② 添加到数据库的业务根据自己需要进行实现.
③ GetRandomStr

package com.wiimedia.utils;

import java.util.Random;

public class GetRandomStr {
 /**
 *
 *<p>Project:mryl_phone_v2</p>
 *
 *<p>:mryl_phone_v2</p>
 *
 *<p>Description:生成随即字符串 </p>
 *
 *<p>Company:Wiimedia</p>
 *
 *@Athor:SongJia
 *
 *@Date:2016-7-14 上午11:14:46
 *
 */
 public String getRandomString(int length) {
 String base = "abcdefghijklmnopqrstuvwxyz0123456789";
 Random random = new Random();
 StringBuffer sb = new StringBuffer();
 for (int i = 0; i < length; i++) {
  int number = random.nextInt(base.length());
  sb.append(base.charAt(number));
 }
 return sb.toString();
 }
}

 ④ SignatureBean

package com.wiimedia.utils;

public class SignatureBean {
 private String noncestr;
 private String url;
 private String timestamp;
 private String signature;
 public String getNoncestr() {
 return noncestr;
 }
 public void setNoncestr(String noncestr) {
 this.noncestr = noncestr;
 }
 public String getUrl() {
 return url;
 }
 public void setUrl(String url) {
 this.url = url;
 }
 public String getTimestamp() {
 return timestamp;
 }
 public void setTimestamp(String timestamp) {
 this.timestamp = timestamp;
 }
 public String getSignature() {
 return signature;
 }
 public void setSignature(String signature) {
 this.signature = signature;
 }

}

⑤ WeixinUtil

package com.wiimedia.utils.weixin;
import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.ConnectException;
import java.net.URL;

import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManager;

/**
 *
 *<p>Project:mryl_phone_v2</p>
 *
 *<p>:mryl_phone_v2</p>
 *
 *<p>Description:公众平台接口工具类</p>
 *
 *<p>Company:Wiimedia</p>
 *
 *@Athor:SongJia
 *
 *@Date:2016-7-15 上午09:37:13
 *
 */
public class WeixinUtil {

 /**
 * 发起https请求并获取结果
 *
 * @param requestUrl 请求地址
 * @param requestMethod 请求方式(GET、POST)
 * @param outputStr 提交的数据
 * @return JSONObject(通过JSONObject.get(key)的方式获取json对象的属性值)
 */
 public static String httpRequest(String requestUrl, String requestMethod, String outputStr) { 

 StringBuffer buffer = new StringBuffer();
 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 httpUrlConn = (HttpsURLConnection) url.openConnection();
  httpUrlConn.setSSLSocketFactory(ssf); 

  httpUrlConn.setDoOutput(true);
  httpUrlConn.setDoInput(true);
  httpUrlConn.setUseCaches(false);
  // 设置请求方式(GET/POST)
  httpUrlConn.setRequestMethod(requestMethod); 

  if ("GET".equalsIgnoreCase(requestMethod))
  httpUrlConn.connect(); 

  // 当有数据需要提交时
  if (null != outputStr) {
  OutputStream outputStream = httpUrlConn.getOutputStream();
  // 注意编码格式,防止中文乱码
  outputStream.write(outputStr.getBytes("UTF-8"));
  outputStream.close();
  } 

  // 将返回的输入流转换成字符串
  InputStream inputStream = httpUrlConn.getInputStream();
  InputStreamReader inputStreamReader = new InputStreamReader(inputStream, "utf-8");
  BufferedReader bufferedReader = new BufferedReader(inputStreamReader); 

  String str = null;
  while ((str = bufferedReader.readLine()) != null) {
  buffer.append(str);
  }
  bufferedReader.close();
  inputStreamReader.close();
  // 释放资源
  inputStream.close();
  inputStream = null;
  httpUrlConn.disconnect();
  return buffer.toString();
 } catch (ConnectException ce) {
  ce.printStackTrace();
 } catch (Exception e) {
  e.printStackTrace();
 }
 return "";
 }
}

 四、至此,分享功能已经开发完成,但是,在生成signature的时候会遇到很多问题,这里提供一些wx.config失败的排错方法。

① 确认自己的生成的signature是否正确
在微信提供的http://mp.weixin.qq.com/debug/cgi-bin/sandbox?t=jsapisign进行校验

② wx.config中使用的noncestr, timestamp与用以签名中的对应noncestr, timestamp是否一致一致…如上面(一.服务器代码)
(有可能因为JS页面加载顺序问题,服务器生成的signature,noncestr,timestamp在wx.config中没有获取到)。

③ 确认url是页面完整的url,包括GET参数部分
需要去掉#后面的部分

④ config 中的 appid 与用来获取 jsapi_ticket 的 appid 是否一致

⑤ 报错{errmsg:config:ok}是debug的正常返回把调试模式关掉就OK
wx.config debug: false,

本文已被整理到了《Android微信开发教程汇总》,《java微信开发教程汇总》欢迎大家学习阅读。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • java微信公众号开发案例

    微信公众号开发一般是针对企业和组织的,个人一般只能申请订阅号,并且调用的接口有限,下面我们就来简单的描述下接入公众号的步骤: 1.首先你需要一个邮箱在微信公众号平台进行注册:      注册的方式有订阅号.公众号.小程序和企业号,个人我们这里只能选择订阅号 2.注册完后,我们登录到公众号平台--->开发--->基本配置,这里需要填写URL和token,URL就是我们使用服务器的接口: 3.Java Web服务器程序编译好且在服务器上部署可以运行的话,可在微信公众号进行在线接口调试: 1).选择

  • Java实现仿微信红包分配规则

    最近过年发红包拜年成为一种新的潮流,作为程序猿对算法的好奇远远要大于对红包的好奇,这里介绍一种自己想到的一种随机红包分配策略,还请大家多多指教. 算法介绍 一.红包金额限制 对于微信红包,我们知道没人随机的最小红包是1分,最大金额是200元,这里我们同样来设置红包的范围,下面代码我们统一金钱的单位为分. //最小红包额度 private static final int MINMONEY = 1; //最大红包额度 private static final int MAXMONEY = 200

  • java实现微信支付(服务端)

    废话不多说,直接看代码. RequestHandler requestHandler = new RequestHandler(super.getRequest(),super.getResponse()); //获取token //两小时内有效,两小时后重新获取 Token = requestHandler.GetToken(); //更新token 到应用中 requestHandler.getTokenReal(); System.out.println("微信支付获取token=====

  • java微信公众号开发(搭建本地测试环境)

    俗话说,工欲善其事,必先利其器.要做微信公众号开发,两样东西不可少,那就是要有一个用来测试的公众号,还有一个用来调式代码的开发环境. 测试公众号 微信公众号有订阅号.服务号.企业号,在注册的时候看到这样的信息,只有订阅号可以个人申请,服务号和企业号要有企业资质才可以.这里所说的微信公众号开发指的是订阅号和服务号. 另外,未认证的个人订阅号有一些接口是没有权限的,并且目前个人订阅号已不支持微信认证,也就是说个人订阅号无法调用一些高级的权限接口,下图就是一个未认证的个人订阅号所具备权限列表,像生成二

  • Java开发微信公众号接收和被动回复普通消息

    上篇说完了如何接入微信公众号,本文说一下微信公众号的最基本功能:普通消息的接收和回复.说到普通消息,那么什么是微信公众号所定义的普通消息呢,微信开发者文档中提到的接收的普通消息包括如下几类: 1.文本消息 2.图片消息 3.语音消息 4.视频消息 5.小视频消息 6.地理位置消息 7.链接消息(被动回复的消息) 被动回复的普通消息包括: 1.回复文本消息 2.回复图片消息 3.回复语音消息 4.回复视频消息 5.回复音乐消息 6.回复图文消息 其实接收消息和被动回复消息这两个动作是不分家的,这本

  • 微信java开发之实现微信主动推送消息

    1.拉取access_token2.拉取用户信息3.主动推送消息4.接口貌似要申请权限5.依赖httpclient4.2.3 和jackson 2.2.1 复制代码 代码如下: public class WeixinAPIHelper { /**  * 获取token接口  */ private String getTokenUrl = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=

  • Java编程调用微信分享功能示例

    本文实例讲述了Java编程调用微信分享功能.分享给大家供大家参考,具体如下: 这篇文章介绍如何使用java开发微信分享功能,因为工作,已经开发完成,可使用. 如果想要自定义微信的分享功能,首先在自己的页面内首先使用AJAX.下面我具体举例. 首先是在页面内写入请求后台的AJAX /** * 调用微信分享接口 * */ public void WXConfig(){ String url = getPara("href"); WXConfigController scan = new W

  • 第三方网站微信登录java代码实现

    前两个星期在公司中的项目加上了微信登录.绑定的功能,在这里做个记录! 一.开发前知识 1.微信开放平台与微信公众平台的区别 1.1 微信公众平台: ① 地址:https://mp.weixin.qq.com/cgi-bin/loginpage?t=wxm2-login&lang=zh_CN ② 微信公众平台面向的是普通的用户,比如自媒体和媒体,企业官方微信公众账号运营人员使用,当然你所在的团队或者公司有实力去开发一些内容,也可以调用公众平台里面的接口,比如自定义菜单,自动回复,查询功能. 1.2

  • 微信支付H5调用支付详解(java版)

    最近项目需要微信支付,然后看了下微信公众号支付,,虽然不难,但是细节还是需要注意的,用了大半天时间写了个demo,并且完整的测试了一下支付流程,下面分享一下微信公众号支付的经验. 一.配置公众号微信支付  需要我们配置微信公众号支付地址和测试白名单. 比如:支付JS页面的地址为 http://www.xxx.com/shop/pay/ 那此处配置www.xxx.com/shop/pay/ 二.开发流程 借用微信公众号支付api(地址 http://pay.weixin.qq.com/wiki/d

  • Java通过JsApi方式实现微信支付

    要使用JsApi进行微信支付,首先要从微信获得一个prepay_id,然后通过调用微信的jsapi完成支付,JS API的返回结果get_brand_wcpay_request:ok仅在用户成功完成支付时返回.由于前端交互复杂,get_brand_wcpay_request:cancel或者get_brand_wcpay_request:fail可以统一处理为用户遇到错误或者主动放弃,不必细化区分. 示例代码如下: function onBridgeReady(){ WeixinJSBridge

  • java开发微信公众号支付

    最近做了微信公众号支付的开发,由于是第一次做也摸索了几天的时间,也只是达到了实现功能的水平,并没有太多考虑到性能问题,所以这篇文章比较适合初学者. 微信公众号支付的总体其实很简单,大致就分为三步.第一步需要获取用户授权:第二步调用统一下单接口获取预支付id:第三步H5调起微信支付的内置的js.下面介绍具体每一步的开发流程. 一    首先要明确微信公众号支付属于网页版支付,所以相较于app的直接调取微信支付要多一步微信授权.也就是需要获取用户的openid.微信公众号使用的交易类型是JSAPI,

  • java实现微信公众平台自定义菜单的创建示例

    复制代码 代码如下: import java.io.IOException;import java.io.InputStream;import java.io.OutputStream;import java.net.HttpURLConnection;import java.net.MalformedURLException;import java.net.URL; import org.json.JSONObject; public class MenuUtil { /**  * 获得ACC

随机推荐