1.第一步,通过令牌交易,使你的服务器与微信服务器之间能够交互。
1.1在工具类中随便定义自己服务器的令牌,如weixinCourse等
public class SignUtil {
// 与接口配置信息中的Token要一致
private static String token = "weixinCourse";
/**
* 验证签名
*
* @param signature
* @param timestamp
* @param nonce
* @return
*/
public static boolean checkSignature(String signature, String timestamp, String nonce) {
String[] arr = new String[]{token, timestamp, nonce};
// 将token、timestamp、nonce三个参数进行字典序排序
Arrays.sort(arr);
StringBuilder content = new StringBuilder();
for (int i = 0; i < arr.length; i++) {
content.append(arr[i]);
}
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;
// 将sha1加密后的字符串可与signature对比,标识该请求来源于微信
return tmpStr != null ? tmpStr.equals(signature.toUpperCase()) : false;
}
/**
* 将字节数组转换为十六进制字符串
*
* @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;
}
/**
* 将字节转换为十六进制字符串
*
* @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;
}
}
1.2服务器写程序接收微信服务器发来的验证
public class CheckServlet extends HttpServlet{
private static final long serialVersionUID = 1L;
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doPost(req, resp);
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
request.setCharacterEncoding("utf-8"); //设置编码
response.setCharacterEncoding("utf-8"); //设置编码
response.setHeader("Access-Control-Allow-Origin", "*");
// TODO 消息的接收、处理、响应
// 微信加密签名
String signature = request.getParameter("signature");
// 时间戳
String timestamp = request.getParameter("timestamp");
// 随机数
String nonce = request.getParameter("nonce");
// 随机字符串
String echostr = request.getParameter("echostr");
PrintWriter out = response.getWriter();
// 通过检验signature对请求进行校验,若校验成功则原样返回echostr,表示接入成功,否则接入失败
if (SignUtil.checkSignature(signature, timestamp, nonce)) {
out.print(echostr);
}else{
out.print("配置失败");
}
out.close();
out = null;
}
}
2.二者之间,确认过眼神后,达成交易,可以互相交互了,
kujusw.natappfree.cc自己的域名,/ showopenid,servlet的访问地址,appid = xxx(自己的appid)
拿到微信返回的代码,再向微信服务器发送请求,获取授权令牌
@WebServlet(urlPatterns = "/showopenid")
public class Showopenid extends HttpServlet{
private static final long serialVersionUID = 1L;
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("text/html");
request.setCharacterEncoding("UTF-8");
response.setCharacterEncoding("UTF-8");
String code = request.getParameter("code");//获取code
Map params = new HashMap();
params.put("secret", "01c89e807d6c30e175962e31bf761cba");
params.put("appid", "wx3b978975f1e9d57f");
params.put("grant_type", "authorization_code");
params.put("code", code);
String result = HttpGetUtil.httpRequestToString(
"https://api.weixin.qq.com/sns/oauth2/access_token", params);
JSONObject jsonObject = JSONObject.fromObject(result);
String openid = jsonObject.get("openid").toString();
System.out.println("得到的openid为:"+openid);
String a="df";
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
}
}
HTTPGET请求发送工具
public class HttpGetUtil {
public static String httpRequestToString(String url, Map<String,String> params) {
String result = null;
try {
InputStream is = httpRequestToStream(url, params);
BufferedReader in = new BufferedReader(new InputStreamReader(is,
"UTF-8"));
StringBuffer buffer = new StringBuffer();
String line = "";
while ((line = in.readLine()) != null) {
buffer.append(line);
}
result = buffer.toString();
} catch (Exception e) {
return null;
}
return result;
}
private static InputStream httpRequestToStream(String url,
Map<String, String> params) {
InputStream is = null;
try {
String parameters = "";
boolean hasParams = false;
for(String key : params.keySet()){
String value = URLEncoder.encode(params.get(key), "UTF-8");
parameters += key +"="+ value +"&";
hasParams = true;
}
if(hasParams){
parameters = parameters.substring(0, parameters.length()-1);
}
url += "?"+ parameters;
URL u = new URL(url);
HttpURLConnection conn = (HttpURLConnection) u.openConnection();
conn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
conn.setRequestProperty("Accept-Charset", "UTF-8");
conn.setRequestProperty("contentType", "utf-8");
conn.setConnectTimeout(50000);
conn.setReadTimeout(50000);
conn.setDoInput(true);
conn.setRequestMethod("GET");
is = conn.getInputStream();
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return is;
}
}
成功获得的OpenID,其中获得的授权访问令牌可以获取用户的基本信息接口为HTTPS://api.weixin.qq.com/sns/userinfo =的access_token XXX ,,,,微信端返回格式为JSON格式
最后再总结一遍吧:
- 第一次向微信服务器发请求,校对token,检验是否能与微信服务器对接
- 二次请求,得到code,
- 上次请求,得到openid
- 四次请求(统一下单请求,拿到预支付id,既prepay_id)
- 注:此步是将openid,商户id,订单号,价格,用户ip地址,拼成map,在经过md5加密生成签名(对象),而后将签名对象转成xml,发给微信服务器,这是四次请求,服务器返回prepay_id
- 本地通过appid,package,noncestr,signtype,timestamp参数生成签名
在通过appid,时间戳,随机数,prayid,经过md5本地生成签名paysign,通过paysign,appid,随机数,==》MD5调起js(h5页面)完成支付
需要参数:
开通服务号,平台配置,即可拿到四大参数
appid,appsecret,mch_id,paternerkey
2.1 11个参数:
appid,mch_id,nonce_str,body,out_trade_no,total_free,spbill_create
3.1后续再写微信支付,微信公众号,小程序的具体后台开发