仔细看一遍微信官方文档,配置好支付的回调地址(支付只能在线上,手机端测试,web开发者工具也帮不了你)
所需要的参数:AppSecret:、微信支付商户号、公众号APPID、API密钥
思路大概就是:
1,先向微信发出请求拿到微信返回来的code,这里需要先去微信配置好回调地址,微信配置的回调地址不用具体到某一个方法。
2、通过code,在后台发送get或post请求拿到openid
3,通过openid,再一次在后台发送post或者get请求拿到 prepay_id(预支付id)
4,将参数发到前台,调起微信支付
下面就是CV操作了(这个项目的框架有点老,不过不影响逻辑,什么框架都是这样弄,cv就完事了)
1.第一步:
//我这边的逻辑是先提交订单,当订单提交成功后,向微信发出请求(ajax补全就好了)
success: function (data) {
if (data.href != null) {
setTimeout("window.location.href='" + data.href + "';", 2000);
}
if (data.status == 1) {
var redirect_uri = "http://fx.zwolftech.com/user/money?id=" + data.id;//回调的地址,这里要具体到哪个action,把订单id给它带上
var href = "https://open.weixin.qq.com/connect/oauth2/authorize?redirect_uri=" + encodeURIComponent(redirect_uri);
href += "&appid=123456795&response_type=code&scope=snsapi_base";
window.location.href = href;//这一串就是请求微信,返回code
} else {
alertDefaultStyle("mini", "生成订单失败,请联系管理员");
}
}
第二步
本人这边有个支付的页面,里面提示多少金额,,在money的方法接收了微信返回来的code,再发到前台,再发回来后台。所以;啰嗦了一点,那一步就不带上给了
//获取所有调支付的参数,发送到前端
public void money2() {
JSONObject jsons = new JSONObject();
String nonce_str = PayUtil.getRandomStringByLength(16);//生成随机数,可直接用系统提供的方法
String trade_type = "JSAPI";
String openid = "";
String prepay_id = "";
String appid = "65453151321654654";
String secret = "6846513516546654654";
String code = "";
code = this.request.getParameter("code");、、微信的返回来的凑得,有效五分钟
// System.out.println("momey2======"+code);
String id = this.request.getParameter("id");
//System.out.println("orderid======"+id);
try {
HttpRequest http = new HttpRequest();
if (id != null) {
Orders byId = this.ordersService.findById(Orders.class, Integer.parseInt(id));
if (byId != null) {
// String ip = this.request.getHeader("x-forwarded-for");47.104.171.145
String ip = "57.105.94.105";
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
ip = this.request.getHeader("Proxy-Client-IP");
}
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
ip = this.request.getHeader("WL-Proxy-Client-IP");
}
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
ip = this.request.getRemoteAddr();
}
// if(ip.indexOf(",")!=-1) {
String[] ips = ip.split(",");
ip = ips[0].trim();
//静默登录获取openid
String openIdInfo = http.sendGet("https://api.weixin.qq.com/sns/oauth2/access_token",
"appid=" + appid + "&secret=" + secret + "&code=" + code + "&grant_type=authorization_code");
//openIdInfo json字符串
JSONObject json = JSONObject.parseObject(openIdInfo);
openid = json.getString("openid");
System.out.println("========openid=" + openid);
HashMap<String, String> map = new HashMap();
map.put("appid", appid);
map.put("mch_id", "52255254851");//商户号
map.put("device_info", "WEB");
map.put("nonce_str", nonce_str);
//map.put("body", byId.getProductName());//订单标题
map.put("body", "shopping");
map.put("out_trade_no", byId.getNo());//订单编号,随机生成的
System.out.println("订单编号=============out_trade_no=" + byId.getNo());
Double aa = (byId.getMoney() * 100);
int b = aa.intValue();//订单金额
map.put("total_fee", b + "");//订单需要支付的金额
map.put("spbill_create_ip", ip);
map.put("trade_type", trade_type);
//map.put("notify_url", "http://fx.zwolftech.com/user/moneysuccess?id="+byId.getId());//notify_url 支付成功之后 微信会进行异步回调的地址
map.put("notify_url", "http://fx.zwolftech.com/moneysuccess");//notify_url 支付成功之后 微信会进行异步回调的地址,这个方法不能带参数,不能设置拦截,权限控制
map.put("openid", openid);
String sign = WXPayUtil.generateSignature(map, "wusushijieshijidadao1196hao1002z");//参数加密 该方法key的需要根据你当前公众号的key进行修改
map.put("sign", sign);
//String content = XMLParser.getXMLFromMap(map);
String xml = WXPayUtil.mapToXml(map);
http = new HttpRequest();
String PostResult = http.sendPost("https://api.mch.weixin.qq.com/pay/unifiedorder", xml);//再次发送请求微信获取prepay_id
Map<String, Object> cbMap = XMLParser.getMapFromXML(PostResult);
if (cbMap.get("return_code").equals("SUCCESS") && cbMap.get("result_code").equals("SUCCESS")) {
prepay_id = cbMap.get("prepay_id") + "";//这就是预支付id
// System.out.println("======preay_id="+prepay_id);
//String timeStamp = String.valueOf(DateUtil.getNow().getTime() / 1000);
map = new HashMap<String, String>();
map.put("appId", appid);
map.put("nonceStr", nonce_str);
map.put("package", "prepay_id=" + prepay_id);
map.put("signType", "MD5");
map.put("timeStamp", new Date().getTime() + "");
sign = WXPayUtil.generateSignature(map, "wusushijieshijidadao1196hao1002z");//参数加密,这里使用的是微信官网提供的,在官网可以下载
map.put("sign", sign);
// this.request.setAttribute("map", map);//发回去给前台
List<String> list = new ArrayList<String>();
for (String s : map.keySet()) {
// System.out.println("key : "+s+" value : "+map.get(s));
list.add(map.get(s));
}
//发回去给前台
jsons.put("list", list);
}
// }else{
// System.out.println("获取不到用户ip");
// }
} else {
System.out.println("订单获取不了");
}
} else {
System.out.println("=====================");
}
} catch (Exception e) {
e.printStackTrace();
System.out.println(e.getMessage());
}
PrintWriter out = null;
try {
out = this.response.getWriter();
} catch (IOException e1) {
e1.printStackTrace();
}
out.print(jsons);
out.flush();
out.close();
}
前台处理一下
<script type="text/javascript">
var appId,timeStamp,nonceStr,package,signType,paySig;
function pay() {
var code=$("#code").val();
var id=$("#orderid").val();
//alert(code);
$.ajax({
url: "${pageContext.request.contextPath}/user/money2",
type: "post",
async: false,
dataType: "json",
data:{
code:code,
id:id
},
success: function(data) {
//alert(data);
var map=data.list;
//console.log(map[2]+"=="+map[1]+"--paysig="+map[3]);
//alert(map[2]);
//alert(map[1]);
appId=map[2],
timeStamp=map[0], //时间戳,自1970年以来的秒数
nonceStr=map[5], //随机串
package=map[1],
signType="MD5", //微信签名方式:
paySig=map[3]
if (typeof WeixinJSBridge == "undefined"){
if( document.addEventListener ){
document.addEventListener('WeixinJSBridgeReady', onBridgeReady, false);
}else if (document.attachEvent){
document.attachEvent('WeixinJSBridgeReady', onBridgeReady);
document.attachEvent('onWeixinJSBridgeReady', onBridgeReady);
}
}else{
onBridgeReady();
}
}
});
}
function onBridgeReady(){
WeixinJSBridge.invoke(
'getBrandWCPayRequest', {
"appId":appId, //公众号名称,由商户传入
"timeStamp":timeStamp, //时间戳,自1970年以来的秒数
"nonceStr":nonceStr, //随机串
"package":package,
"signType":"MD5", //微信签名方式:
"paySign":paySig //微信签名
},
function(res){
if(res.err_msg == "get_brand_wcpay_request:ok" ){
// 使用以上方式判断前端返回,微信团队郑重提示:
//res.err_msg将在用户支付成功后返回ok,但并不保证它绝对可靠。
window.location.href='';//支付成功后你要去到的方法
}
});
}
</script>
//处理支付成功后的逻辑
/支付回调接口(微信异步会通知)notify_url 配置的值
public void moneysuccess() {
System.out.println("==============成功!!");
InputStream is = null;
try {
is = this.request.getInputStream();
String retStr = new String(Util.readInput(is), "utf-8");
//Map<String,String> map =WXPayUtil.xmlToMap(retStr);
Map<String, Object> map = XMLParser.getMapFromXML(retStr);
//返回的数据
if (map.get("return_code").equals("SUCCESS")) {
System.out.println("微信支付返回成功!!");
if (map.get("result_code").equals("SUCCESS")) {
String ordersSn = (String) map.get("out_trade_no");//商户订单号
String amountpaid = (String) map.get("total_fee");//实际支付的订单金额:单位 分
BigDecimal amountPay = (new BigDecimal(amountpaid).divide(new BigDecimal("100"))).setScale(2);//将分转换成元-实际支付金额:元
String openId = (String) map.get("openid");//获取openid。如果是公众号的话,可以通过这个发送推送消息
}
//高数微信,支付返回成功,这一步是必须要做的!@!!
this.response.setContentType("text/xml");
String xml = "<xml>"
+ "<return_code><![CDATA[SUCCESS]]></return_code>"
+ "<return_msg><![CDATA[OK]]></return_msg>"
+ "</xml>";
this.response.getWriter().print(xml);
this.response.getWriter().flush();
this.response.getWriter().close();
} catch (Exception e) {
e.printStackTrace();
}
}
发送HttpRequest,pot,get请求的方法,这个网上大把
public class HttpRequest {
/**
* 向指定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;
}
}