应用场景:

支付完成后,微信会把相关支付结果和用户信息发送给商户,商户需要接收处理,并返回应答。

对后台通知交互时,如果微信收到商户的应答不是成功或超时,微信认为通知失败,微信会通过一定的策略定期重新发起通知,尽可能提高通知的成功率,但微信不保证通知最终能成功。 (通知频率为15/15/30/180/1800/1800/1800/1800/3600,单位:秒)

注意:同样的通知可能会多次发送给商户系统。商户系统必须能够正确处理重复的通知。

推荐的做法是,当收到通知进行处理时,首先检查对应业务数据的状态,判断该通知是否已经处理过,如果没有处理过再进行处理,如果处理过直接返回结果成功。在对业务数据进行状态检查和处理之前,要采用数据锁进行并发控制,以避免函数重入造成的数据混乱。

特别提醒:商户系统对于支付结果通知的内容一定要做签名验证,防止数据泄漏导致出现“假通知”,造成资金损失。

//支付结果通知接口

@RequestMapping(“/qlydweixinotify.do”)

public void weixinotify(HttpServletRequest request,

HttpServletResponse response) {

PrintWriter out = null;

StringBuffer xmlStr = new StringBuffer();

try {

BufferedReader reader = request.getReader();

String line = null;

while ((line = reader.readLine()) != null) {

xmlStr.append(line);

}

Logger.getLogger(getClass()).debug(“支付回调通知:”+xmlStr.toString());

//检查xml是否有效

boolean flag=Signature.checkIsSignValidFromResponseString(xmlStr.toString());

WeixinNotifyResult result=null;

if(flag){

NotifyResData wxData=(NotifyResData) Util.getObjectFromXML(xmlStr.toString(),NotifyResData.class);

if(wxData !=null){

if(“SUCCESS”.equals(wxData.getReturn_code())){

OrderPayInfo orderPayInfo = new OrderPayInfo();

orderPayInfo.setOrderNum(wxData.getOut_trade_no());

orderPayInfo.setPayNum(wxData.getTransaction_id());

orderPayInfo.setPayPrice((double)wxData.getTotal_fee()/100+”“);

orderPayInfo.setPaySource(wxData.getOpenid());

orderPayInfo.setPayTime(wxData.getTime_end());

orderPayInfo.setPayType(“2”);//1支付宝,2微信支付

OrderMessage returnMessage = orderProductServer

.completeProductOrder(orderPayInfo);

if (OrderStatus.FAIL.equals(returnMessage

.getOrderStatus())) {

Logger.getLogger(getClass()).error(“远程接口完成订单失败”);

result=new WeixinNotifyResult(“FAIL”);

result.setReturn_msg(“远程接口完成订单失败”);

} else {

result=new WeixinNotifyResult(“SUCCESS”);

result.setReturn_msg(“成功”);

}

}else{

result=new WeixinNotifyResult(“FAIL”);

result.setReturn_msg(“失败”);

}

}else{

result=new WeixinNotifyResult(“FAIL”);

result.setReturn_msg(“解析参数格式失败”);

}

}else{

result=new WeixinNotifyResult(“FAIL”);

result.setReturn_msg(“签名失败”);

}

response.getWriter().write(result.toString());

} catch (Exception e) {

Logger.getLogger(getClass()).error(“qlydweixinotify.do”, e);

ResponeDeal.getInstance().sendResponseStr(response, “404”, “连接超时”);

} finally {

if (out != null) {

out.close();

}

}

}

模拟http请求工具类:

HttpsRequestUtil.java

package com.qlwb.weixin.util;

import java.io.IOException;

import org.apache.commons.httpclient.HttpClient;

import org.apache.commons.httpclient.HttpException;

import org.apache.commons.httpclient.methods.PostMethod;

import org.apache.commons.httpclient.methods.RequestEntity;

import org.apache.commons.httpclient.methods.StringRequestEntity;

import org.apache.log4j.Logger;

import com.qlwb.weixin.common.Configure;

import com.qlwb.weixin.common.Util;

import com.qlwb.weixin.protocol.pay_protocol.WxPayReqData;

import com.qlwb.weixin.protocol.payquery_protocol.PayQueryReqData;

public class HttpsRequestUtil {

/**
*
* @方法名称:sendWxPayRequest
* @内容摘要: <发送统一下单请求>
* @param body
* @param outTradeNo
* @param totalFee
* @param spBillCreateIP
* @return
* String
* @exception
* @author:鹿伟伟
* @创建日期:2016年2月19日-下午2:24:05
*/
public String sendWxPayRequest(String body,String detail,String outTradeNo,int totalFee,String spBillCreateIP
) {
// 构造HTTP请求
HttpClient httpclient = new HttpClient(); PostMethod postMethod = new PostMethod(Configure.PAY_API); WxPayReqData wxdata = new WxPayReqData(body,detail,outTradeNo,totalFee,spBillCreateIP); String requestStr="";
requestStr=Util.ConvertObj2Xml(wxdata);
// 发送请求
String strResponse = null;
try {
RequestEntity entity = new StringRequestEntity(
requestStr.toString(), "text/xml", "UTF-8");
postMethod.setRequestEntity(entity);
httpclient.executeMethod(postMethod);
strResponse = new String(postMethod.getResponseBody(), "utf-8");
Logger.getLogger(getClass()).debug(strResponse);
} catch (HttpException e) {
Logger.getLogger(getClass()).error("sendWxPayRequest", e);
} catch (IOException e) {
Logger.getLogger(getClass()).error("sendWxPayRequest", e);
} finally {
postMethod.releaseConnection();
}
return strResponse;
}
/**
*
* @方法名称:orderQueryRequest
* @内容摘要: <查询订单信息>
* @param transaction_id 微信的订单号,优先使用
* @return
* String
* @exception
* @author:鹿伟伟
* @创建日期:2016年2月19日-下午2:44:11
*/
public String orderQueryRequest(String transactionID, String outTradeNo
) {
// 构造HTTP请求
HttpClient httpclient = new HttpClient(); PostMethod postMethod = new PostMethod(Configure.PAY_QUERY_API); PayQueryReqData wxdata = new PayQueryReqData(transactionID,outTradeNo); String requestStr="";
requestStr=Util.ConvertObj2Xml(wxdata);
// 发送请求
String strResponse = null;
try {
RequestEntity entity = new StringRequestEntity(
requestStr.toString(), "text/xml", "UTF-8");
postMethod.setRequestEntity(entity);
httpclient.executeMethod(postMethod);
strResponse = new String(postMethod.getResponseBody(), "utf-8"); } catch (HttpException e) {
Logger.getLogger(getClass()).error("orderQueryRequest", e);
} catch (IOException e) {
Logger.getLogger(getClass()).error("orderQueryRequest", e);
} finally {
postMethod.releaseConnection();
}
return strResponse;
}

}

微信支付(java版本)_支付结果通知的更多相关文章

  1. 微信支付(java版本)_统一下单

    最近工作接触到微信支付,刚开始解决微信支付很神秘,接触之后发现并没有那么神秘,就是有很多坑,在开发的时候需要注意,整理出来: 1.准备工作 首先需要登录微信支付公众平台阅读接口文档,地址:https: ...

  2. 崔用志-微信开发-java版本

    崔用志-微信开发-java版本 今天看到一些关于微信开发的知识蛮好的博客,分享给大家,希望对大家有帮助. 微信开发准备(一)--Maven仓库管理新建WEB项目 微信开发准备(二)--springmv ...

  3. 手把手教你完成App支付JAVA后台-支付宝支付JAVA

    接着上一篇博客,我们暂时完成了手机端的部分支付代码,接下来,我们继续写后台的代码. 后台基本需要到以下几个参数,我都将他们写在了properties文件中: 支付宝参数 AliPay.payURL = ...

  4. 微信公众号支付java版本

    回调函数 @RequestMapping("/toPay") public String toPay(HttpServletRequest request, HttpServlet ...

  5. app微信支付-java服务端接口 支付-查询-退款

    个人不怎么看得懂微信的文档,看了很多前辈的写法,终于调通了,在这里做一下记录. 首先来定义各种处理类(微信支付不需要特殊jar包,很多处理需要自己封装,当然也可以自己写完打个jar包) 参数要用jdo ...

  6. [支付]微信NATIVE扫码支付JAVA实现

    步骤: 1.预订单 2.接受微信返回的url 3.将url转为二维码显示到页面上 4.扫码支付 5.接收微信的异步通知,在这步修改订单的状态 6.收到异步通知的同时给微信返回指定数据,告知对方已成功处 ...

  7. 微信支付java版V3验证数据合法性

    [TOC] 1. 微信支付java版V3验证数据合法性 概要:使用微信支付接口时,微信会返回或回调给商户XML数据,开发者需要验证微信返回的数据是否合法. 特别提醒:商户系统对于支付结果通知的内容一定 ...

  8. 微信原生支付 Native扫码支付( V3.3.7 版本)

    原文:微信原生支付 Native扫码支付( V3.3.7 版本) [尊重别人的劳动成果,转载请注明出处:一缕晨光工作室,www.wispdawn.com] 前言 辛苦研究三天,遇到各种困难,最终还是克 ...

  9. Java微信公众平台开发之公众号支付(微信内H5调起支付)

    官方文档点击查看准备工作:已通过微信认证的公众号,必须通过ICP备案域名(否则会报支付失败)借鉴了很多大神的文章,在此先谢过了 整个支付流程,看懂就很好写了 一.设置支付目录 在微信公众平台设置您的公 ...

随机推荐

  1. 集训Day8

    旧试题Day2... bzoj3436 有若干个集合和一些信息 信息有3种: I.集合A比集合B至少多C个元素 II.集合A比集合B至多多C个元素 III.集合A和集合B元素一样多 求这些信息是否有矛 ...

  2. poj1821 Fence(单调队列优化dp)

    地址 一排N个木板,M个工匠站在不同位置$S_i$,每个人可以粉刷覆盖他位置的.最长长度为$L_i$木板段,每刷一个有$P_i$报酬.同一木板只刷一次.求最大报酬. 根据每个人的位置dp,设$f[i] ...

  3. 「LuoguP4995」「洛谷11月月赛」 跳跳!(贪心

    题目描述 你是一只小跳蛙,你特别擅长在各种地方跳来跳去. 这一天,你和朋友小 F 一起出去玩耍的时候,遇到了一堆高矮不同的石头,其中第 ii 块的石头高度为 h_ihi​,地面的高度是 h_0 = 0 ...

  4. 「BZOJ2721」「LuoguP1445」 [Violet]樱花(数论

    题目背景 我很愤怒 题目描述 求方程 $\frac{1}{x}+\frac{1}{y}=\frac{1}{N!}$ 的正整数解的组数,其中$N≤10^6$. 解的组数,应模$1e9+7$. 输入输出格 ...

  5. 【Lintcode】028.Search a 2D Matrix

    题目: Write an efficient algorithm that searches for a value in an m x n matrix. This matrix has the f ...

  6. 洛谷 P4238 [模板] 多项式求逆

    题目:https://www.luogu.org/problemnew/show/P4238 看博客:https://www.cnblogs.com/xiefengze1/p/9107752.html ...

  7. poj3666序列对应——DP

    题目:http://poj.org/problem?id=3666 很普通的DP,离散化(sort)一下即可: mn的求法很不错(比我原来开了mn[]……简洁). 代码如下: #include< ...

  8. CentOS7 安装 odoo10

    一.安装Postgresql数据库 #添加RPM     yum install https://download.postgresql.org/pub/repos/yum/9.5/redhat/rh ...

  9. 3-C++程序的结构1.5

    多文件结构和编译预处理命令 1.c++程序的一般组织结构 通常一个项目至少划分为三个文件:类定义文件(*.h文件).类实现文件(*.cpp文件)和类的使用文件(*.cpp,主函数文件).如下: 这三个 ...

  10. selenium+Python搭建

    安装环境:windows 7 64位   1.安装python,版本为python2.7 1)下载安装包. 在python官方网站选择下载python2版本的windows安装包:python-2.7 ...