转载地址:https://blog.csdn.net/maple980326/article/details/51828554
-
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;
-
}