java paysign_JAVA实现微信支付功能

②准备好11个参数JSAPI支付方式

1 配置微信平台

①配置微信公众平台

登录微信公众平台=》公众号设置=》功能设置=》网页授权域名

b87d259bf7c25a2cb0d99954efdc88f9.png

e19aadfc0d050b739e7619786d52c41b.png

②配置微信商家平台

5e59a1411338ffeddb1ecfe2475ab056.png①先去官方下载SDK,并导进项目中

5579bee72f521af380365e39032eb4a7.png

2 后台代码的实现

JSAPI官方文档:https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=9_1

①先去官方下载SDK,并导进项目中

地址:https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=11_1

d01d99d8b951d054cd664948f1942254.png

②准备好11个参数appid:商家平台ID。在微信的平台上有

body:商品描述。

mch_id:商户ID。在微信的平台上有

nonce_str:随机字符串,UUID就好了。

openid:用户标识。因为这边是用户已经登录成功了。所以在session中就能拿到。

out_trade_no:商户订单号

spbill_create_ip:终端IP。这个可以从请求头中拿到

total_fee:支付金额。单位是分。

trade_type:交易类型。这里我填JSAPI

notify_url:通知地址。就是用户支付成功之后,微信访问你的哪个接口,跟你传递支付成功的相关信息。

sign:签名。这个签名它是由上面的10个参数计算得出的。

③源码

sendPay类:

import java.io.IOException;import java.io.InputStream;import java.math.BigDecimal;import java.net.URLEncoder;import java.util.HashMap;import java.util.Map;import java.util.UUID;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import org.apache.http.auth.AUTH;import org.hamcrest.core.Is;import org.springframework.stereotype.Controller;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.bind.annotation.RequestMethod;import org.springframework.web.bind.annotation.ResponseBody;import com.jc.util.wxPay.WXPayUtil;import com.sun.xml.internal.fastinfoset.Encoder;import controller.AuthUtil;import net.sf.json.JSONObject;

@Controller

@RequestMapping("/pay")public class sendPay { /** * @Description 微信浏览器内微信支付/公众号支付(JSAPI)

* @param request

* @param code

* @return Map     */@RequestMapping(value = "orders")public @ResponseBody Map orders(HttpServletRequest request, HttpServletResponse response) {try {

String openId = "用户的openid";// 拼接统一下单地址参数Map paraMap = new HashMap();// 获取请求ip地址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();

}

paraMap.put("appid", AuthUtil.APPID); // 商家平台IDparaMap.put("body", "纯情小店铺-薯条"); // 商家名称-销售商品类目、String(128)paraMap.put("mch_id", AuthUtil.MCHID); // 商户IDparaMap.put("nonce_str", WXPayUtil.generateNonceStr()); // UUIDparaMap.put("openid", openId);

paraMap.put("out_trade_no", UUID.randomUUID().toString().replaceAll("-", ""));// 订单号,每次都不同paraMap.put("spbill_create_ip", ip);

paraMap.put("total_fee", "1"); // 支付金额,单位分paraMap.put("trade_type", "JSAPI"); // 支付类型paraMap.put("notify_url", "用户支付完成后,你想微信调你的哪个接口");// 此路径是微信服务器调用支付结果通知路径随意写String sign = WXPayUtil.generateSignature(paraMap, AuthUtil.PATERNERKEY);

paraMap.put("sign", sign);

String xml = WXPayUtil.mapToXml(paraMap);// 将所有参数(map)转xml格式// 统一下单 https://api.mch.weixin.qq.com/pay/unifiedorderString unifiedorder_url = "https://api.mch.weixin.qq.com/pay/unifiedorder";

System.out.println("xml为:" + xml);// String xmlStr = HttpRequest.sendPost(unifiedorder_url,// xml);//发送post请求"统一下单接口"返回预支付id:prepay_idString xmlStr = HttpRequest.httpsRequest(unifiedorder_url, "POST", xml);

System.out.println("xmlStr为:" + xmlStr);// 以下内容是返回前端页面的json数据String prepay_id = "";// 预支付idif (xmlStr.indexOf("SUCCESS") != -1) {

Map map = WXPayUtil.xmlToMap(xmlStr);

prepay_id = (String) map.get("prepay_id");

}

Map payMap = new HashMap();

payMap.put("appId", AuthUtil.APPID);

payMap.put("timeStamp", WXPayUtil.getCurrentTimestamp() + "");

payMap.put("nonceStr", WXPayUtil.generateNonceStr());

payMap.put("signType", "MD5");

payMap.put("package", "prepay_id=" + prepay_id);

String paySign = WXPayUtil.generateSignature(payMap, AuthUtil.PATERNERKEY);

payMap.put("paySign", paySign);//将这个6个参数传给前端return payMap;

} catch (Exception e) {

e.printStackTrace();

}return null;

}/** * @Title: callBack

* @Description: 支付完成的回调函数

* @param:

* @return:     */@RequestMapping("/notify")public String callBack(HttpServletRequest request, HttpServletResponse response) {// System.out.println("微信支付成功,微信发送的callback信息,请注意修改订单信息");InputStream is = null;try {

is = request.getInputStream();// 获取请求的流信息(这里是微信发的xml格式所有只能使用流来读)String xml = WXPayUtil.InputStream2String(is);

Map notifyMap = WXPayUtil.xmlToMap(xml);// 将微信发的xml转map

System.out.println("微信返回给回调函数的信息为:"+xml);            if (notifyMap.get("result_code").equals("SUCCESS")) {

String ordersSn = notifyMap.get("out_trade_no");// 商户订单号String amountpaid = notifyMap.get("total_fee");// 实际支付的订单金额:单位 分BigDecimal amountPay = (new BigDecimal(amountpaid).divide(new BigDecimal("100"))).setScale(2);// 将分转换成元-实际支付金额:元/* * 以下是自己的业务处理------仅做参考 更新order对应字段/已支付金额/状态码                 */System.out.println("===notify===回调方法已经被调!!!");

}            // 告诉微信服务器收到信息了,不要在调用回调action了========这里很重要回复微信服务器信息用流发送一个xml即可response.getWriter().write("");

} catch (Exception e) {

e.printStackTrace();

} finally {if (is != null) {try {

is.close();

} catch (IOException e) {

e.printStackTrace();

}

}

}        return null;

}

}

HttpRequest类:

import java.io.BufferedReader;import java.io.IOException;import java.io.InputStream;import java.io.InputStreamReader;import java.io.OutputStream;import java.io.PrintWriter;import java.net.URL;import java.net.URLConnection;import java.util.List;import java.util.Map;import javax.net.ssl.HttpsURLConnection;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;

System.out.println(urlNameString);

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> 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(), "UTF-8"));

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;

}/** * post请求并得到返回结果

*

* @param requestUrl

* @param requestMethod

* @param output

* @return */public static String httpsRequest(String requestUrl, String requestMethod, String output) {try {

URL url = new URL(requestUrl);

HttpsURLConnection connection = (HttpsURLConnection) url.openConnection();

connection.setDoOutput(true);

connection.setDoInput(true);

connection.setUseCaches(false);

connection.setRequestMethod(requestMethod);if (null != output) {

OutputStream outputStream = connection.getOutputStream();

outputStream.write(output.getBytes("UTF-8"));

outputStream.close();

}// 从输入流读取返回内容InputStream inputStream = connection.getInputStream();

InputStreamReader inputStreamReader = new InputStreamReader(inputStream, "utf-8");

BufferedReader bufferedReader = new BufferedReader(inputStreamReader);

String str = null;

StringBuffer buffer = new StringBuffer();while ((str = bufferedReader.readLine()) != null) {

buffer.append(str);

}

bufferedReader.close();

inputStreamReader.close();

inputStream.close();

inputStream = null;

connection.disconnect();return buffer.toString();

} catch (Exception ex) {

ex.printStackTrace();

}return "";

}

}

AuthUtil类import java.io.IOException;import org.apache.http.HttpEntity;import org.apache.http.HttpResponse;import org.apache.http.client.ClientProtocolException;import org.apache.http.client.methods.HttpGet;import org.apache.http.impl.client.DefaultHttpClient;import org.apache.http.util.EntityUtils;import net.sf.json.JSONObject;public class AuthUtil {public static final String APPID = "平台ID";public static final String APPSECRET = "平台密钥";public static final String MCHID = "商家ID";public static final String PATERNERKEY = "商家密钥";

public static JSONObject doGetJson(String url) throws ClientProtocolException, IOException {

JSONObject jsonObject = null;// 首先初始化HttpClient对象DefaultHttpClient client = new DefaultHttpClient();// 通过get方式进行提交HttpGet httpGet = new HttpGet(url);// 通过HTTPclient的execute方法进行发送请求HttpResponse response = client.execute(httpGet);// 从response里面拿自己想要的结果HttpEntity entity = response.getEntity();if (entity != null) {

String result = EntityUtils.toString(entity, "UTF-8");

jsonObject = jsonObject.fromObject(result);

}// 把链接释放掉        httpGet.releaseConnection();return jsonObject;

}

}

2.3 前端的实现

这是只用一个jsp页面来做测试

html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">

微信支付JSP

$(function(){var appId,timeStamp,nonceStr,package,signType,paySign;

$("#payId").click(function(){

pay();

});            //去后台拿六个参数function pay(){   var url = "http://localhost:8082/WeChat/pay/orders";

$.get(url,function(result) {

appId = result.appId;

timeStamp = result.timeStamp;

nonceStr = result.nonceStr;

package = result.package;

signType = result.signType;

paySign = result.paySign;                        if (typeof WeixinJSBridge == "undefined") {if (document.addEventListener) {

document.addEventListener('WeixinJSBridgeReady',onBridgeReady, false);

} else if (document.attachEvent) {

document.attachEvent('WeixinJSBridgeReady',onBridgeReady);

document.attachEvent('onWeixinJSBridgeReady',onBridgeReady);

}

alert("请在微信上进行支付操作!");

onBridgeReady();

} else {

onBridgeReady();

}

});

}//去微信那边发起支付请求function onBridgeReady(){

alert("appId:"+appId+" "+"timeStamp:"+timeStamp+" "+"nonceStr:"+nonceStr+" "+"package:"+package+" "+"signType:"+signType+" "+"paySign:"+paySign+" ");

WeixinJSBridge.invoke( 'getBrandWCPayRequest', {                      "appId":appId,     //公众号名称,由商户传入       "timeStamp":timeStamp,         //时间戳,自1970年以来的秒数       "nonceStr":nonceStr, //随机串       "package":package,

"signType":signType,         //微信签名方式:       "paySign":paySign //微信签名  },

function(res){

if(res.err_msg == "get_brand_wcpay_request:ok" ) {                             //alert('支付成功'); console.log("支付成功");                             //支付成功后跳转的页面 }else if(res.err_msg == "get_brand_wcpay_request:cancel"){

alert('支付取消');

}else if(res.err_msg == "get_brand_wcpay_request:fail"){

alert('支付失败');

alert(JSON.stringify(res));

WeixinJSBridge.call('closeWindow');

} //使用以上方式判断前端返回,微信团队郑重提示:res.err_msg将在用户支付成功后返回ok,但并不保证它绝对可靠。               });

}

})

三,总结

虽然第一次看官方文档很乱,信息量很多,但仔细总结一下,其实就下面这点流程而已。

再记录点,以防有用:

url urlencodepublic static String inputStream2String(InputStream inStream, String encoding){

String result = null;

ByteArrayOutputStream outStream = null;try {         if(inStream != null){

outStream = new ByteArrayOutputStream();          byte[] tempBytes = new byte[1024];          int count = 0;          while((count = inStream.read(tempBytes)) != -1){

outStream.write(tempBytes, 0, count);

}

tempBytes = null;

outStream.flush();

result = new String(outStream.toByteArray(), encoding);

outStream.close();

}

} catch (Exception e) {

result = null;

} return result;

}

转载:

https://blog.csdn.net/daotiao0199/article/details/85284038

https://blog.csdn.net/javaYouCome/article/details/79473743

5400ca10e3150180b37862fdaa76a7a1.png


版权声明:本文为weixin_34157892原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。