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<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;
}
}
4、微信支付前端页面调用
$('#btn').click(function() {
var param = { //传入参数
.....
};
$.ajax({
type: "post",
url: 'http://XXXX.com/项目名/wechat-createInsurance',
contentType: 'application/json;charset=UTF-8',
dataType: 'json',
data: JSON.stringify(param),
success: function(result) {
if(result.code==SUCCESS){
function onBridgeReady() {
WeixinJSBridge.invoke(
'getBrandWCPayRequest', {
"appId": result.result.appId, // 公众账号ID
"timeStamp": result.result.timeStamp, //时间戳,自1970年以来的秒
"nonceStr": result.result.nonceStr, //随机串
"package": result.result.package,
"signType": result.result.signType, //微信签名方式:
"paySign": result.result.paySign //微信签名
},
function(res) {
if (res.err_msg == "get_brand_wcpay_request:ok") {
// 使用以上方式判断前端返回,微信团队郑重提示:
//res.err_msg将在用户支付成功后返回ok,但并不保证它绝对可靠。
window.location.href = 'sucess.html' ; //成功支付后跳转到下个页面
}else{
alert("微信支付失败");
}
}
);
}
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();
}
}else{
alert(result.msg);
}
},
error: function(err) {
alert("登陆失败");
console.log(err);
}
});
});
点击按钮,访问接口成功后,微信端h5页面自动弹出微信自带的支付页面,支付完成后,点击确定,微信会自动回调用户写微信支付回调接口。(微信支付回调接口具体实现看第五章)
5、微信支付回调接口
应用场景:
支付完成后,微信会把相关支付结果及用户信息通过数据流的形式发送给商户,商户需要接收处理,并按文档规范返回应答。
微信的通知参数格式:(具体查看微信支付结果通知)
1
微信支付回调接口的实现:
@POST
@Path(value = "wechat-notification")
public Response WeChatNotification(@Context HttpServletRequest request, @Context HttpServletResponse response)
throws IOException, DocumentException {
try {
//微信发的xml格式的数据转为Map格式
Map<String, String> paramMap = new HashMap<String, String>();
InputStream inputStream = request.getInputStream();
SAXReader reader = new SAXReader();
Document document = reader.read(inputStream);
Element root = document.getRootElement();
List<Element> elementList = root.elements();
for (Element e : elementList) {
paramMap.put(e.getName(), e.getText());
}
inputStream.close();
inputStream = null;
if("FAIL".equals(paramMap.get("return_code"))){
throw new RuntimeException("return_code为fail, " + paramMap.get("return_msg"));
}
if("FAIL".equals(paramMap.get("result_code"))){
throw new RuntimeException("result_code为fail, " + paramMap.get("err_code_des"));
}
//...... 业务流程 ......
//响应给微信的一定是以流的方式
//告诉微信服务器收到信息了,不要在调用回调action了(回复微信服务器信息用流发送一个xml即可)
return Response.ok(" "
+ " ").build();
} catch (Exception e) {
e.printStackTrace();
return Response.ok(" "
+"+e.getMessage() +"]]> ").build();
}
}
注意:
(1)该链接是通过【[统一下单】中提交的参数设置,如果链接无法访问,商户将无法接收到微信通知。
(2)通知url必须为直接可访问的url,不能携带参数。
(3)商户系统对于支付结果通知的内容一定要做签名验证,并校验返回的订单金额是否与商户侧的订单金额一致,防止数据泄漏导致出现“假通知”,造成资金损失。
(4)技术人员可登进微信商户后台扫描加入接口报警群,获取接口告警信息。
(5)同样的通知可能会多次发送给商户系统。商户系统必须能够正确处理重复的通知。
(6)后台通知交互时,如果微信收到商户的应答不符合规范或超时微信订单系统,微信会判定本次通知失败,重新发送通知,直到成功为止,但微信不保证通知最终一定能成功。
(7)在订单状态不明或者没有收到微信支付结果通知的情况下,建议商户主动调用微信支付【查询订单】确认订单状态。(可查看第六章,注意可以通过轮询查询支付订单来监控是否已支付)
6、查询订单接口
应用场景:
该接口提供所有微信支付订单的查询微信订单系统,商户可以通过查询订单接口主动查询订单状态,完成下一步的业务逻辑。
需要调用查询接口的情况:
(1)当商户后台、网络、服务器等出现异常,商户系统最终未接收到支付通知;
(2)调用支付接口后,返回系统错误或未知交易状态情况;
(3)调用付款码支付API,返回的状态;
(4)调用关单或撤销接口API之前,需确认支付状态;
查询订单接口实现:
@GET
@Path(value = "wechat-orderquery")
@Produces(MediaType.APPLICATION_JSON)
public Response WechatOrderquery(@QueryParam("outTradeNo") String outTradeNo){
Map<String, Object> result = new HashMap<String, Object>();
try {
HashMap<String, String> data = new HashMap<String, String>();
data.put("out_trade_no", outTradeNo);// 商户订单号
data.put("mch_id", mchid);// 商户号
data.put("nonce_str", WXPayUtil.generateNonceStr());// 随机字符串
data.put("appid", appid);// 公众账号ID
String sign = WXPayUtil.generateSignature(data, paternerKey);
data.put("sign", sign);// 签名
WXPay wxpay = new WXPay(MyConfig.getInstance()); //导入微信的下载的包
Map<String, String> resp = wxpay.orderQuery(data);
if("FAIL".equals(resp.get("return_code"))){
throw new RuntimeException("return_code为fail, " + resp.get("return_msg"));
}
if("FAIL".equals(resp.get("result_code"))){
throw new RuntimeException("result_code为fail, " + resp.get("err_code_des"));
}
if(!"SUCCESS".equals(resp.get("trade_state"))){
throw new RuntimeException("trade_state为" + resp.get("trade_state"));
}
//.......业务流程......
result.put("paperno", paperno);
result.put("code", SUCCESS);
}catch(Exception e){
e.printStackTrace();
result.put("code", ERROR);
result.put("msg", "订单查询异常");
}
return Response.ok(result).build();
}
微信公众号
免责声明:部分文章信息来源于网络以及网友投稿,本站只负责对文章进行整理、排版、编辑,出于传递更多信息之目的,并不意味着赞同其观点或证实其内容的真实性,如本站文章和转稿涉及版权等问题,请作者在及时联系本站,我们会尽快为您处理。