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. spark集群体系结构

  2. springMVC接受对象实体并且对象实体里面又有对象集合方式

    springMVC接受对象实体并且对象实体里面又有对象集合方式: Ajax: function add(){ var orders = [ { orderNo : "H222255" ...

  3. C++之指针与引用,函数和数组

    ]={,,}; //ptr是指针,该指针类型是int[3] ]=&arr; cout << **ptr << endl;//第一次解指针时得到数组地址,第二次解指针取数 ...

  4. EL与JSTL学习(一)EL技术

    1.EL 表达式概述 EL(Express Lanuage)表达式可以嵌入在jsp页面内部,减少jsp脚本的编写,EL出现的目的是要替代jsp页面中脚本的编写. 2.EL从域中取出数据(EL最重要的作 ...

  5. eclipse的maven工程视图切换

    上面图切换成下面图: 点击eclipse右上角,如下图红圈,然后在选择javaEE这样就切换成javaEE视图了

  6. 【python爬虫和正则表达式】爬取表格中的的二级链接

    开始进公司实习的一个任务是整理一个网页页面上二级链接的内容整理到EXCEL中,这项工作把我头都搞大了,整理了好几天,实习生就是端茶送水的.前段时间学了爬虫,于是我想能不能用python写一个爬虫一个个 ...

  7. nginx 多级7层代理安装配置

    编译安装 yum install zlib-devel -y wget https://nginx.org/download/nginx-1.15.12.tar.gz tar -zxf nginx-1 ...

  8. 双系统 windows引导项添加

    [root@MiWiFi-R2D-srv ~]# vi /etc/grub.d/40_custom #!/bin/sh exec tail -n +3 $0# This file provides a ...

  9. vijos - P1732能量採集 (状态转移)

    P1732能量採集 Accepted 标签:NOI2010[显示标签] 背景 描写叙述 栋栋有一块长方形的地.他在地上种了一种能量植物,这样的植物能够採集太阳光的能量. 在这些植物採集能量后,栋栋再使 ...

  10. [NOI2002] Savage 解题报告(扩展欧几里得)

    题目链接:https://www.lydsy.com/JudgeOnline/problem.php?id=1407 Description 克里特岛以野人群居而著称.岛上有排列成环行的M个山洞.这些 ...