微信 支付异步回调 获取参数值
2016-07-05 08:49
369 查看
import java.io.StringReader; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Set; import java.util.SortedMap; import java.util.TreeMap; import javax.servlet.http.HttpServletRequest; import org.apache.commons.lang.StringUtils; import org.apache.log4j.Logger; import org.jdom2.Document; import org.jdom2.Element; import org.jdom2.input.SAXBuilder; import org.xml.sax.InputSource; import com.jfinal.aop.Before; import com.jfinal.ext.interceptor.POST; import com.jfinal.plugin.activerecord.NestedTransactionHelpException; import com.jfinal.plugin.activerecord.tx.Tx; import com.utils.MD5Util; import comwechat.config.WeChatConfig; public class WeChatPayController extends BaseController { private Logger logger = Logger.getLogger(getClass()); /** * 微信同步回调 * <p> * 返回结果.code=0:正常结束<br> * 返回结果.code=1:传参错误<br> * 返回结果.code=2:该账户已在其它设备上登录<br> * 返回结果.code=3:已被封号<br> * 返回结果.code=99:系统异常 * * @param deviceId * 设备ID * @param params * 加密过的参数({deviceId 设备ID, userId 用户ID, historyId 充值履历ID, state * 充值状态}) * @return 返回加密过的结果(null) */ @Before({ POST.class, Tx.class, DecryptParamsInterceptor.class }) public void synchronous_notify() { String userId = decryptParams.get("userId"); String deviceId = decryptParams.get("deviceId"); String transaction_id = decryptParams.get("transaction_id"); String state = decryptParams.get("state"); if (StringUtils.isEmpty(userId) || StringUtils.isEmpty(deviceId) || StringUtils.isEmpty(transaction_id) || StringUtils.isEmpty(state)) { throw new ServiceException(1, "传参错误"); } if (!PayState.SUCC.equals(state) && !PayState.FAIL.equals(state)) { throw new ServiceException(1, "传参错误"); } int int_userId = Integer.parseInt(userId); checkUser(int_userId, deviceId); Transaction transaction = common_Transaction(transaction_id, state); if (RechargeState.SUCC.equals(state)) { common_notify(transaction); } } /** * @Description: 微信异步回调 * @param @throws UnsupportedEncodingException * @return void * @throws * @author ChenFeng * @date 2016/06/30 */ @Before(Tx.class) public void asynchronousWeChat_notify() { try { Transaction transaction = weChat_notify(); common_notify(transaction); renderText("success"); } catch (ServiceException ex) { logger.error(ex.getMessage()); if (ex.getCode() == 33) { renderText("success"); } else { renderText("fail"); } throw new NestedTransactionHelpException(ex.getMessage()); } } private void common_notify(Transaction transaction) { RechargeHistory rh = RechargeHistory.dao.lockById(transaction.getLong("recharge_id")); if (rh == null) { throw new ServiceException(35, "没有发现对应充值履历(recharge_id=" + transaction.getInt("recharge_id") + ")"); } if (!RechargeType.WEIXIN.equals(rh.getStr("type"))) { throw new ServiceException(37, "非微信支付"); } rh.set("state", RechargeState.SUCC); rh.set("updater", "WeChatPay"); if (!rh.update()) { throw new ServiceException(36, "充值履历状态更新失败"); } RechargePackage rp = RechargePackage.dao.findById(rh.getInt("package_id")); if (rp == null) { throw new ServiceException(38, "充值套餐已不存在"); } User user = User.dao.lockById(rh.getInt("user_id")); if (user == null) { throw new ServiceException(38, "支付用户已不存在"); } int recharge_rmb = user.getInt("recharge_rmb") + rh.getInt("amount"); UserLevel nul = UserLevel.dao.getNext(user.getInt("level_id")); if (nul != null && recharge_rmb >= nul.getInt("min_rmb")) { UpLevel ul = new UpLevel(); ul.set("user_id", user.get("id")); ul.set("up_time", getNowTime()); ul.set("level_id", nul.get("id")); if (!ul.save()) { throw new ServiceException(39, "升级失败"); } user.set("level_id", nul.get("id")); } user.set("recharge_rmb", recharge_rmb); user.set("accum_diam", user.getInt("accum_diam") + rp.getInt("num")); user.set("resid_diam", user.getInt("resid_diam") + rp.getInt("num")); if (!user.update()) { throw new ServiceException(39, "充值失败"); } SysInfo si = SysInfo.dao.findById(SysInfoKey.INFORM_RECHARGE); if (si != null && StringUtils.isNotEmpty(si.getStr("value"))) { SysMsgService.getToken(); SysMsgService.publishTxtMsg(Integer.toString(user.getInt("id")), si.getStr("value")); } } @SuppressWarnings("rawtypes") private Transaction weChat_notify() { // 获取微信POST过来反馈信息 System.out.print("微信支付回调获取数据开始"); logger.debug("微信支付回调获取数据开始"); HttpServletRequest request = getRequest(); String inputLine; String notityXml = ""; try { while ((inputLine = request.getReader().readLine()) != null) { notityXml += inputLine; } request.getReader().close(); } catch (Exception e) { logger.debug("xml获取失败:" + e); throw new ServiceException(39, "xml获取失败!"); } System.out.println("接收到的报文:" + notityXml); logger.debug("收到微信异步回调:"); logger.debug(notityXml); if(StringUtils.isEmpty(notityXml)){ logger.debug("xml为空:"); throw new ServiceException(39, "xml为空!"); } Map m = parseXmlToList2(notityXml); String appid = m.get("appid").toString(); String bank_type = m.get("bank_type").toString(); String cash_fee = m.get("cash_fee").toString(); String fee_type = m.get("fee_type").toString(); String is_subscribe = m.get("is_subscribe").toString(); String mch_id = m.get("mch_id").toString(); String nonce_str = m.get("nonce_str").toString(); String openid = m.get("openid").toString(); String out_trade_no = m.get("out_trade_no").toString(); String result_code = m.get("result_code").toString(); String return_code = m.get("return_code").toString(); String sign = m.get("sign").toString(); String time_end = m.get("time_end").toString(); String total_fee = m.get("total_fee").toString(); String trade_type = m.get("trade_type").toString(); String transaction_id = m.get("transaction_id").toString(); SortedMap<Object, Object> parameters = new TreeMap<Object, Object>(); parameters.put("appid", appid); parameters.put("bank_type", bank_type); parameters.put("cash_fee", cash_fee); parameters.put("fee_type", fee_type); parameters.put("is_subscribe", is_subscribe); parameters.put("mch_id", mch_id); parameters.put("nonce_str", nonce_str); parameters.put("openid", openid); parameters.put("out_trade_no", out_trade_no); parameters.put("result_code", result_code); parameters.put("return_code", return_code); parameters.put("time_end", time_end); parameters.put("total_fee", total_fee); parameters.put("trade_type", trade_type); parameters.put("transaction_id", transaction_id); String characterEncoding = "UTF-8"; String mySign = createSign(characterEncoding, parameters); System.out.println("我 的签名是:" + mySign); logger.debug("我 的签名是:" + mySign); logger.debug("WeChat 的签名是:" + sign); if (sign.equals(mySign)) { System.out.println("签名一致"); logger.debug("签名一致"); } else { System.out.println("签名不一致"); logger.debug("签名不一致"); throw new ServiceException(39, "签名不一致!"); } if (!"SUCCESS".equals(result_code)) { throw new ServiceException(31, "微信返回的交易状态不正确(result_code=" + result_code + ")"); } return common_Transaction(out_trade_no, RechargeState.SUCC); } @SuppressWarnings({ "rawtypes", "unchecked" }) private static Map parseXmlToList2(String xml) { Map retMap = new HashMap(); try { StringReader read = new StringReader(xml); // 创建新的输入源SAX 解析器将使用 InputSource 对象来确定如何读取 XML 输入 InputSource source = new InputSource(read); // 创建一个新的SAXBuilder SAXBuilder sb = new SAXBuilder(); // 通过输入源构造一个Document Document doc = (Document) sb.build(source); Element root = doc.getRootElement();// 指向根节点 List<Element> es = root.getChildren(); if (es != null && es.size() != 0) { for (Element element : es) { retMap.put(element.getName(), element.getValue()); } } } catch (Exception e) { e.printStackTrace(); } return retMap; } private Transaction common_Transaction(String transaction_id, String state) { Transaction transaction = Transaction.dao.findById(transaction_id); if (transaction == null) { throw new ServiceException(32, "没有发现对应的交易流水账号(transaction_id=" + transaction_id + ")"); } if (RechargeState.SUCC.equals(transaction.getStr("state"))) { throw new ServiceException(33, "该交易流水状态已变更"); } transaction.set("state", state); transaction.set("updater", "WeChatPay"); if (!transaction.update()) { throw new ServiceException(34, "交易流水状态更新失败"); } return transaction; } /** * 微信支付签名算法sign * * @param characterEncoding * @param parameters * @return */ @SuppressWarnings("rawtypes") public static String createSign(String characterEncoding, SortedMap<Object, Object> parameters) { StringBuffer sb = new StringBuffer(); Set es = parameters.entrySet();// 所有参与传参的参数按照accsii排序(升序) Iterator it = es.iterator(); while (it.hasNext()) { Map.Entry entry = (Map.Entry) it.next(); String k = (String) entry.getKey(); Object v = entry.getValue(); if (null != v && !"".equals(v) && !"sign".equals(k) && !"key".equals(k)) { sb.append(k + "=" + v + "&"); } } String key = WeChatConfig.key; sb.append("key=" + key); String sign = MD5Util.MD5Encode(sb.toString(), characterEncoding).toUpperCase(); return sign; } }
相关文章推荐
- 微信签名生成算法
- PHP微信开发入门(一)
- 一个很赞的ecshop微信商城系统!
- 微信支付 h5
- 微信支付那些事
- 感觉今天一天没做什么事情啊QAQ,学习了一下java的基本语法,编写了几个小程序,还是总结一下吧
- 通过new Scanner(System.in)创建一个Scanner,命令行输出
- 二维数组静态初始化输出99乘法表
- 会员卡系统接入微信卡券那些事儿
- 某些磨人的小程序
- 利用servlet 实现JAVAWeb访问微信OAuth2.0认证,获取用户信息的实例
- 【微信开发】上传下载多媒体文件
- 关于微信网页调用js-sdk相关接口注意事项目(一级域名与二级域名互相干扰!!!)
- 实现微信透明弹窗
- 微信JS-SDK坐标位置如何转换为百度地图坐标
- 【腾讯bugly干货分享】微信Android热补丁实践演进之路
- xz记录 -微信部分
- java微信开发之--更换背景图片
- 【腾讯bugly干货分享】微信Android热补丁实践演进之路
- 微信硬件平台设备直连全讲解(6)设备端SDK导入和设备登陆