https://www.cnblogs.com/gopark/p/9394951.html,这篇文章写的已经很详细了。

下面写一下自己的思路:

1.首先下载demo,地址:https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=11_1

2.demo中很多方法对于公众号支付用不到,不需要全都看

3.主要是获取11个参数,放到Map中,用demo里提供WXPayUtil.mapToXml方法转为XML格式,通过post方法请求微信端的统一下单接口,后台收到微信传过来的XML字符串,通过WXPayUtil.xmlToMap方法转为Map,根据key值,获取prepay_id(预支付ID),再把需要的6个参数放到Map中,发送给前台,前台根据prepay_id,唤起微信支付,完成付款。

4.11个参数跟6个参数在controller里面都有写,重点的是:openid

5.查看订单,取消订单等其他功能,后续接触到再进行更新

下面放上自己写的controller

 package com.github.wxpay.controller;

 import com.github.wxpay.sdk.WXPayConstants;
import com.github.wxpay.sdk.WXPayUtil;
import com.github.wxpay.util.Constant;
import com.github.wxpay.util.HttpRequestUtil;
import com.github.wxpay.util.OrderUtil;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody; import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import java.util.HashMap;
import java.util.Map;
import org.springframework.web.bind.annotation.RequestMapping;
import com.github.wxpay.sdk.WXPayConstants.SignType; public class WxPayController { /**
*
* @Description 微信浏览器内微信支付/公众号支付(JSAPI)
*/
@RequestMapping(value = "/orders",method = RequestMethod.GET)
@ResponseBody
public Map orders(HttpServletRequest request){
try {
Map<String, String> paramMap = new HashMap<String, String>();
HttpSession session = request.getSession();
String wxopenid = session.getAttribute("openid") == null ? null : session.getAttribute("openid").toString();
//在商户平台的账户中心下:需要用户自行下载证书及安装
String key = Constant.signCustomerKey;
String ip = request.getHeader("x-forwarded-for"); if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
ip = request.getHeader("Proxy-Client-IP");
}
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
ip = request.getHeader("WL-Proxy-Client-IP");
}
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
ip = request.getRemoteAddr();
}
if (ip.indexOf(",") != -1) {
String[] ips = ip.split(",");
ip = ips[0].trim();
}
paramMap.put("appid", Constant.APPIDS[0]);
paramMap.put("mch_id", "");
paramMap.put("nonce_str", WXPayUtil.generateNonceStr());
paramMap.put("body", "测试订单XX矿泉水");
paramMap.put("openid", wxopenid);
paramMap.put("out_trade_no", OrderUtil.orderNumber());
paramMap.put("spbill_create_ip", ip);
paramMap.put("total_fee", "0.01");
paramMap.put("notify_url", "http://127.0.0.1:8080/alipay.trade.page.pay-JAVA-UTF-8/notify_url.jsp");// 此路径是微信服务器调用支付结果通知路径
paramMap.put("trade_type", "JSAPI");
String sign = WXPayUtil.generateSignature(paramMap,key,SignType.MD5);
paramMap.put("sign", sign); // 将所有参数(map)转xml格式
String mapToXml = WXPayUtil.mapToXml(paramMap);
System.out.println(mapToXml);
// 统一下单 https://api.mch.weixin.qq.com/pay/unifiedorder
String unifiedorder_url = "https://api.mch.weixin.qq.com/pay/unifiedorder";
// 发送post请求"统一下单接口"返回预支付id:prepay_id
String xmlStr = HttpRequestUtil.sendPost(unifiedorder_url,mapToXml); Map<String,String> XmlToMap = WXPayUtil.xmlToMap(xmlStr);
// 以下内容是返回前端页面的json数据
String prepay_id = ""; // 预支付ID
if (xmlStr.indexOf("SUCCESS") != -1) {
Map<String, String> map = WXPayUtil.xmlToMap(xmlStr);
prepay_id = map.get("prepay_id");
}
Map<String, String> payMap = new HashMap<String, String>();
XmlToMap.put("appId", Constant.APPIDS[0]);
XmlToMap.put("timeStamp", WXPayUtil.getCurrentTimestamp()+"");
XmlToMap.put("nonceStr", WXPayUtil.generateNonceStr());
XmlToMap.put("signType", "MD5");
XmlToMap.put("package", "prepay_id=" + prepay_id);
String paySign = WXPayUtil.generateSignature(payMap, key);
payMap.put("paySign", paySign);
return XmlToMap;
}catch (Exception e){
e.printStackTrace();
}
return null;
}
}

httpRequest工具:

 package com.github.wxpay.util;

 import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.URLConnection;
import java.util.List;
import java.net.URL;
import java.util.Map; public class HttpRequestUtil {
/**
* 向指定URL发送GET方法的请求
*
* @param url
* 发送请求的URL
* @param param
* 请求参数,请求参数应该是 name1=value1&name2=value2 的形式。
* @return URL 所代表远程资源的响应结果
*/
public static String sendGet(String url, String param) {
String result = "";
BufferedReader in = null;
try {
String urlNameString = url + "?" + param;
URL realUrl = new URL(urlNameString);
// 打开和URL之间的连接
URLConnection connection = realUrl.openConnection();
// 设置通用的请求属性
connection.setRequestProperty("accept", "*/*");
connection.setRequestProperty("connection", "Keep-Alive");
connection.setRequestProperty("user-agent",
"Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)");
// 建立实际的连接
connection.connect();
// 获取所有响应头字段
Map<String, List<String>> map = connection.getHeaderFields();
// 遍历所有的响应头字段
for (String key : map.keySet()) {
System.out.println(key + "--->" + map.get(key));
}
// 定义 BufferedReader输入流来读取URL的响应
in = new BufferedReader(new InputStreamReader(
connection.getInputStream()));
String line;
while ((line = in.readLine()) != null) {
result += line;
}
} catch (Exception e) {
System.out.println("发送GET请求出现异常!" + e);
e.printStackTrace();
}
// 使用finally块来关闭输入流
finally {
try {
if (in != null) {
in.close();
}
} catch (Exception e2) {
e2.printStackTrace();
}
}
return result;
} /**
* 向指定 URL 发送POST方法的请求
*
* @param url
* 发送请求的 URL
* @param param
* 请求参数,请求参数应该是 name1=value1&name2=value2 的形式。
* @return 所代表远程资源的响应结果
*/
public static String sendPost(String url, String param) {
PrintWriter out = null;
BufferedReader in = null;
String result = "";
try {
URL realUrl = new URL(url);
// 打开和URL之间的连接
URLConnection conn = realUrl.openConnection();
// 设置通用的请求属性
conn.setRequestProperty("accept", "*/*");
conn.setRequestProperty("connection", "Keep-Alive");
conn.setRequestProperty("user-agent",
"Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)");
// 发送POST请求必须设置如下两行
conn.setDoOutput(true);
conn.setDoInput(true);
// 获取URLConnection对象对应的输出流
out = new PrintWriter(conn.getOutputStream());
// 发送请求参数
out.print(param);
// flush输出流的缓冲
out.flush();
// 定义BufferedReader输入流来读取URL的响应
in = new BufferedReader(
new InputStreamReader(conn.getInputStream()));
String line;
while ((line = in.readLine()) != null) {
result += line;
}
} catch (Exception e) {
System.out.println("发送 POST 请求出现异常!"+e);
e.printStackTrace();
}
//使用finally块来关闭输出流、输入流
finally{
try{
if(out!=null){
out.close();
}
if(in!=null){
in.close();
}
}
catch(IOException ex){
ex.printStackTrace();
}
}
return result;
}
}

随机数工具:

package com.github.wxpay.util;

import com.github.wxpay.sdk.WXPayUtil;

public class OrderUtil {

    public static String orderNumber(){
int r1 = (int)(Math.random()*10);
int r2 = (int)(Math.random()*10);
long now = WXPayUtil.getCurrentTimestampMs();
String paymentID = String.valueOf(r1)+String.valueOf(r2)+String.valueOf(now);
return paymentID;
}
}

java开发微信公众号支付(JSAPI)的更多相关文章

  1. Java开发微信公众号(五)---微信开发中如何获取access_token以及缓存access_token

    获取access_token是微信api最重要的一个部分,因为调用其他api很多都需要用到access_token.比如自定义菜单接口.客服接口.获取用户信息接口.用户分组接口.群发接口等在请求的时候 ...

  2. Java开发微信公众号(四)---微信服务器post消息体的接收及消息的处理

    在前几节文章中我们讲述了微信公众号环境的搭建.如何接入微信公众平台.以及微信服务器请求消息,响应消息,事件消息以及工具处理类的封装:接下来我们重点说一下-微信服务器post消息体的接收及消息的处理,这 ...

  3. Java开发微信公众号(三)---微信服务器请求消息,响应消息,事件消息以及工具处理类的封装

    在前面几篇文章我们讲了微信公众号环境的配置 和微信公众号服务的接入,接下来我们来说一下微信服务器请求消息,响应消息以及事件消息的相关内容,首先我们来分析一下消息类型和返回xml格式及实体类的封装. ( ...

  4. Java开发微信公众号(二)---开启开发者模式,接入微信公众平台开发

    接入微信公众平台开发,开发者需要按照如下步骤完成: 1.填写服务器配置 2.验证服务器地址的有效性 3.依据接口文档实现业务逻辑 资料准备: 1.一个可以访问的外网,即80的访问端口,因为微信公众号接 ...

  5. Java开发微信公众号(一)---初识微信公众号以及环境搭建

    ps:1.开发语言使用Java springMvc+Mybaits+spring maven实现 2.使用微信接口测试账号进行本地测试 https://mp.weixin.qq.com/debug/c ...

  6. java版微信公众号支付(H5调微信内置API)

    最近需要做微信公众号支付,网上找了大堆的代码,大多都只说了个原理,自己踩了太多坑,所有的坑,都会再下面的文章中标注,代码我也贴上最全的(叫我雷锋)!!! 第一步:配置支付授权目录 你需要有将你公司的微 ...

  7. 微信公众号支付JSAPI网页,total_fee错误不正确,header重定向参数丢失,无法获取订单号和金额解决

    微信公众号支付官方demo错误, 公众号支付只能用在微信里,也就是微信内部浏览器. 1.到WxPayHubHelper.php文件 JsApi_pub()类下createOauthUrlForCode ...

  8. 用java开发微信公众号:测试公众号与本地测试环境搭建(一)

    本文为原创,原始地址为:http://www.cnblogs.com/fengzheng/p/5023678.html 俗话说,工欲善其事,必先利其器.要做微信公众号开发,两样东西不可少,那就是要有一 ...

  9. Java 关于微信公众号支付总结附代码

    很多朋友第一次做微信支付的时候都有蒙,但当你完整的做一次就会发现其实并没有那么难 业务流程和应用场景官网有详细的说明:https://pay.weixin.qq.com/wiki/doc/api/js ...

随机推荐

  1. 还是bib问题

    虽然昨天把添加bib的基本问题解决了,但是bib的参考文献没有了中括号.查了一下华东师大,只是给出了如何去掉中括号的方法. http://math.ecnu.edu.cn/~latex/doc.htm ...

  2. 乌班图 之 apt命令 及 VMware共享文件夹

    apt是Advanced Packaging Tool ,是Ubuntu下的一个安装包管理工具 大部分软件的安装.更新.卸载 都是利用apt命令来实现 直接在终端输入apt即可查阅命令的帮助信息 常用 ...

  3. 虚拟机CentOS6.8下安装JDK

    CentOS6.8下 首先下载JDK,执行命令如下: wget http://download.oracle.com/otn-pub/java/jdk/8u172-b11/a58eab1ec24242 ...

  4. hdu 2037 - 典型贪心*

    题目链接 给一堆电视节目的起止时间,问最多能完整收看几个节目 --------------------------------------------------------------------- ...

  5. js邮箱,汉字,数字 表单验证

    //电子邮箱验证 function isEmail(str) { var myreg = /^([a-zA-Z0-9]+[_|\_|\.]?)*[a-zA-Z0-9]+@([a-zA-Z0-9]+[_ ...

  6. 小型ceph集群的搭建

    了解ceph DFS(distributed file system)分布式存储系统,指文件系统管理的物理存储资源,不一定直接连接在本地节点上,而是通过计算机网络与节点相连,众多类别中,ceph是当下 ...

  7. 【BZOJ4448】【SCOI2015】情报传递

    这题面错别字真tm多 题意: Description 奈特公司是一个巨大的情报公司,它有着庞大的情报网络.情报网络中共有n名情报员.每名情报员口J-能有若T名(可能没有)下线,除1名大头日外其余n-1 ...

  8. (2016北京集训十四)【xsy1557】task

    题解: 限制可以看成图状结构,每个任务的对物品数量的影响可以看成权值,只不过这个权值用一个五元组来表示. 那么题意要求的就是最大权闭合子图,网络流经典应用. 代码: #include<algor ...

  9. vue-cli#2.0项目结构分析

    项目结构 build 构建工具相关的目录 config 配置目录 dist 通过工具打包生成的最终需要上线的目录 node_modules 存放本地开发所有的依赖包的目录 src 源码目录 stati ...

  10. NYIST 531 太空飞行计划

    太空飞行计划 时间限制:1000 ms  |  内存限制:65535 KB 难度:4   描述        W 教授正在为国家航天中心计划一系列的太空飞行.每次太空飞行可进行一系列商业性实验而获取利 ...