java微信 支付异步回调 获取参数值

转载地址:https://blog.csdn.net/maple980326/article/details/51828554

  1. import java.io.StringReader;

  2. import java.util.HashMap;

  3. import java.util.Iterator;

  4. import java.util.List;

  5. import java.util.Map;

  6. import java.util.Set;

  7. import java.util.SortedMap;

  8. import java.util.TreeMap;

  9.  
  10. import javax.servlet.http.HttpServletRequest;

  11.  
  12. import org.apache.commons.lang.StringUtils;

  13. import org.apache.log4j.Logger;

  14. import org.jdom2.Document;

  15. import org.jdom2.Element;

  16. import org.jdom2.input.SAXBuilder;

  17. import org.xml.sax.InputSource;

  18.  
  19.  
  20.  
  21. import com.jfinal.aop.Before;

  22. import com.jfinal.ext.interceptor.POST;

  23. import com.jfinal.plugin.activerecord.NestedTransactionHelpException;

  24. import com.jfinal.plugin.activerecord.tx.Tx;

  25. import com.utils.MD5Util;

  26.  
  27. import comwechat.config.WeChatConfig;

  28.  
  29. public class WeChatPayController extends BaseController {

  30.  
  31. private Logger logger = Logger.getLogger(getClass());

  32.  
  33. /**

  34. * 微信同步回调

  35. * <p>

  36. * 返回结果.code=0:正常结束<br>

  37. * 返回结果.code=1:传参错误<br>

  38. * 返回结果.code=2:该账户已在其它设备上登录<br>

  39. * 返回结果.code=3:已被封号<br>

  40. * 返回结果.code=99:系统异常

  41. *

  42. * @param deviceId

  43. * 设备ID

  44. * @param params

  45. * 加密过的参数({deviceId 设备ID, userId 用户ID, historyId 充值履历ID, state

  46. * 充值状态})

  47. * @return 返回加密过的结果(null)

  48. */

  49. @Before({ POST.class, Tx.class, DecryptParamsInterceptor.class })

  50. public void synchronous_notify() {

  51. String userId = decryptParams.get("userId");

  52. String deviceId = decryptParams.get("deviceId");

  53. String transaction_id = decryptParams.get("transaction_id");

  54. String state = decryptParams.get("state");

  55.  
  56. if (StringUtils.isEmpty(userId) || StringUtils.isEmpty(deviceId) || StringUtils.isEmpty(transaction_id) || StringUtils.isEmpty(state)) {

  57. throw new ServiceException(1, "传参错误");

  58. }

  59. if (!PayState.SUCC.equals(state) && !PayState.FAIL.equals(state)) {

  60. throw new ServiceException(1, "传参错误");

  61. }

  62.  
  63. int int_userId = Integer.parseInt(userId);

  64.  
  65. checkUser(int_userId, deviceId);

  66.  
  67. Transaction transaction = common_Transaction(transaction_id, state);

  68. if (RechargeState.SUCC.equals(state)) {

  69. common_notify(transaction);

  70. }

  71. }

  72.  
  73. /**

  74. * @Description: 微信异步回调

  75. * @param @throws UnsupportedEncodingException

  76. * @return void

  77. * @throws

  78. * @author ChenFeng

  79. * @date 2016/06/30

  80. */

  81. @Before(Tx.class)

  82. public void asynchronousWeChat_notify() {

  83. try {

  84. Transaction transaction = weChat_notify();

  85. common_notify(transaction);

  86. renderText("success");

  87. } catch (ServiceException ex) {

  88. logger.error(ex.getMessage());

  89. if (ex.getCode() == 33) {

  90. renderText("success");

  91. } else {

  92. renderText("fail");

  93. }

  94. throw new NestedTransactionHelpException(ex.getMessage());

  95. }

  96. }

  97.  
  98. private void common_notify(Transaction transaction) {

  99. RechargeHistory rh = RechargeHistory.dao.lockById(transaction.getLong("recharge_id"));

  100. if (rh == null) {

  101. throw new ServiceException(35, "没有发现对应充值履历(recharge_id=" + transaction.getInt("recharge_id") + ")");

  102. }

  103. if (!RechargeType.WEIXIN.equals(rh.getStr("type"))) {

  104. throw new ServiceException(37, "非微信支付");

  105. }

  106. rh.set("state", RechargeState.SUCC);

  107. rh.set("updater", "WeChatPay");

  108. if (!rh.update()) {

  109. throw new ServiceException(36, "充值履历状态更新失败");

  110. }

  111.  
  112. RechargePackage rp = RechargePackage.dao.findById(rh.getInt("package_id"));

  113. if (rp == null) {

  114. throw new ServiceException(38, "充值套餐已不存在");

  115. }

  116.  
  117. User user = User.dao.lockById(rh.getInt("user_id"));

  118. if (user == null) {

  119. throw new ServiceException(38, "支付用户已不存在");

  120. }

  121. int recharge_rmb = user.getInt("recharge_rmb") + rh.getInt("amount");

  122. UserLevel nul = UserLevel.dao.getNext(user.getInt("level_id"));

  123. if (nul != null && recharge_rmb >= nul.getInt("min_rmb")) {

  124. UpLevel ul = new UpLevel();

  125. ul.set("user_id", user.get("id"));

  126. ul.set("up_time", getNowTime());

  127. ul.set("level_id", nul.get("id"));

  128. if (!ul.save()) {

  129. throw new ServiceException(39, "升级失败");

  130. }

  131.  
  132. user.set("level_id", nul.get("id"));

  133. }

  134. user.set("recharge_rmb", recharge_rmb);

  135. user.set("accum_diam", user.getInt("accum_diam") + rp.getInt("num"));

  136. user.set("resid_diam", user.getInt("resid_diam") + rp.getInt("num"));

  137. if (!user.update()) {

  138. throw new ServiceException(39, "充值失败");

  139. }

  140.  
  141. SysInfo si = SysInfo.dao.findById(SysInfoKey.INFORM_RECHARGE);

  142. if (si != null && StringUtils.isNotEmpty(si.getStr("value"))) {

  143. SysMsgService.getToken();

  144. SysMsgService.publishTxtMsg(Integer.toString(user.getInt("id")), si.getStr("value"));

  145. }

  146. }

  147.  
  148. @SuppressWarnings("rawtypes")

  149. private Transaction weChat_notify() {

  150. // 获取微信POST过来反馈信息

  151. System.out.print("微信支付回调获取数据开始");

  152. logger.debug("微信支付回调获取数据开始");

  153. HttpServletRequest request = getRequest();

  154. String inputLine;

  155. String notityXml = "";

  156. try {

  157.  
  158. while ((inputLine = request.getReader().readLine()) != null) {

  159. notityXml += inputLine;

  160. }

  161. request.getReader().close();

  162. } catch (Exception e) {

  163. logger.debug("xml获取失败:" + e);

  164. throw new ServiceException(39, "xml获取失败!");

  165.  
  166. }

  167. System.out.println("接收到的报文:" + notityXml);

  168. logger.debug("收到微信异步回调:");

  169. logger.debug(notityXml);

  170. if(StringUtils.isEmpty(notityXml)){

  171. logger.debug("xml为空:");

  172. throw new ServiceException(39, "xml为空!");

  173.  
  174. }

  175. Map m = parseXmlToList2(notityXml);

  176.  
  177. String appid = m.get("appid").toString();

  178. String bank_type = m.get("bank_type").toString();

  179. String cash_fee = m.get("cash_fee").toString();

  180. String fee_type = m.get("fee_type").toString();

  181. String is_subscribe = m.get("is_subscribe").toString();

  182. String mch_id = m.get("mch_id").toString();

  183. String nonce_str = m.get("nonce_str").toString();

  184. String openid = m.get("openid").toString();

  185. String out_trade_no = m.get("out_trade_no").toString();

  186. String result_code = m.get("result_code").toString();

  187. String return_code = m.get("return_code").toString();

  188. String sign = m.get("sign").toString();

  189. String time_end = m.get("time_end").toString();

  190. String total_fee = m.get("total_fee").toString();

  191. String trade_type = m.get("trade_type").toString();

  192. String transaction_id = m.get("transaction_id").toString();

  193.  
  194. SortedMap<Object, Object> parameters = new TreeMap<Object, Object>();

  195.  
  196. parameters.put("appid", appid);

  197. parameters.put("bank_type", bank_type);

  198. parameters.put("cash_fee", cash_fee);

  199. parameters.put("fee_type", fee_type);

  200. parameters.put("is_subscribe", is_subscribe);

  201. parameters.put("mch_id", mch_id);

  202. parameters.put("nonce_str", nonce_str);

  203. parameters.put("openid", openid);

  204. parameters.put("out_trade_no", out_trade_no);

  205. parameters.put("result_code", result_code);

  206. parameters.put("return_code", return_code);

  207. parameters.put("time_end", time_end);

  208. parameters.put("total_fee", total_fee);

  209. parameters.put("trade_type", trade_type);

  210. parameters.put("transaction_id", transaction_id);

  211. String characterEncoding = "UTF-8";

  212. String mySign = createSign(characterEncoding, parameters);

  213. System.out.println("我 的签名是:" + mySign);

  214. logger.debug("我 的签名是:" + mySign);

  215. logger.debug("WeChat 的签名是:" + sign);

  216. if (sign.equals(mySign)) {

  217. System.out.println("签名一致");

  218. logger.debug("签名一致");

  219.  
  220. } else {

  221. System.out.println("签名不一致");

  222. logger.debug("签名不一致");

  223. throw new ServiceException(39, "签名不一致!");

  224. }

  225. if (!"SUCCESS".equals(result_code)) {

  226. throw new ServiceException(31, "微信返回的交易状态不正确(result_code=" + result_code + ")");

  227. }

  228. return common_Transaction(out_trade_no, RechargeState.SUCC);

  229. }

  230.  
  231. @SuppressWarnings({ "rawtypes", "unchecked" })

  232. private static Map parseXmlToList2(String xml) {

  233. Map retMap = new HashMap();

  234. try {

  235. StringReader read = new StringReader(xml);

  236. // 创建新的输入源SAX 解析器将使用 InputSource 对象来确定如何读取 XML 输入

  237. InputSource source = new InputSource(read);

  238. // 创建一个新的SAXBuilder

  239. SAXBuilder sb = new SAXBuilder();

  240. // 通过输入源构造一个Document

  241. Document doc = (Document) sb.build(source);

  242. Element root = doc.getRootElement();// 指向根节点

  243. List<Element> es = root.getChildren();

  244. if (es != null && es.size() != 0) {

  245. for (Element element : es) {

  246. retMap.put(element.getName(), element.getValue());

  247. }

  248. }

  249. } catch (Exception e) {

  250. e.printStackTrace();

  251. }

  252. return retMap;

  253. }

  254.  
  255. private Transaction common_Transaction(String transaction_id, String state) {

  256. Transaction transaction = Transaction.dao.findById(transaction_id);

  257. if (transaction == null) {

  258. throw new ServiceException(32, "没有发现对应的交易流水账号(transaction_id=" + transaction_id + ")");

  259. }

  260. if (RechargeState.SUCC.equals(transaction.getStr("state"))) {

  261. throw new ServiceException(33, "该交易流水状态已变更");

  262. }

  263. transaction.set("state", state);

  264. transaction.set("updater", "WeChatPay");

  265. if (!transaction.update()) {

  266. throw new ServiceException(34, "交易流水状态更新失败");

  267. }

  268. return transaction;

  269. }

  270.  
  271. /**

  272. * 微信支付签名算法sign

  273. *

  274. * @param characterEncoding

  275. * @param parameters

  276. * @return

  277. */

  278. @SuppressWarnings("rawtypes")

  279. public static String createSign(String characterEncoding, SortedMap<Object, Object> parameters) {

  280. StringBuffer sb = new StringBuffer();

  281. Set es = parameters.entrySet();// 所有参与传参的参数按照accsii排序(升序)

  282. Iterator it = es.iterator();

  283. while (it.hasNext()) {

  284. Map.Entry entry = (Map.Entry) it.next();

  285. String k = (String) entry.getKey();

  286. Object v = entry.getValue();

  287. if (null != v && !"".equals(v) && !"sign".equals(k) && !"key".equals(k)) {

  288. sb.append(k + "=" + v + "&");

  289. }

  290. }

  291. String key = WeChatConfig.key;

  292. sb.append("key=" + key);

  293. String sign = MD5Util.MD5Encode(sb.toString(), characterEncoding).toUpperCase();

  294. return sign;

  295. }

  296.  
  297.  

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值