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



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;
	}

}


  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 答1: Delphi是一种流行的编程语言,可以用于开发Windows平台上的应用程序。在Delphi中,我们可以使用微信支付宝的支付接口来实现在线支付功能。 首先,我们需要在微信支付宝的开放平台注册开发者账号,并获取相应的appid和支付密钥。 对于微信支付,我们可以使用微信支付SDK提供的接口来完成支付流程。在Delphi中,我们可以通过导入微信支付SDK的Delphi单元来使用相关功能。我们需要按照微信支付的文档指引完成支付请求的组装和签名等操作,并将请求发送给微信服务器。微信服务器会返一个预支付交易会话标识,我们需要使用该标识生成二维码或跳转支付链接供用户支付支付完成后,微信服务器会向我们指定的URL发送支付结果通知,我们需要处理该通知并更新订单状态。 对于支付支付,我们可以使用支付宝提供的接口来完成支付流程。在Delphi中,我们可以通过导入支付宝SDK的Delphi单元来使用相关功能。我们需要按照支付支付的文档指引,生成待签名字符串,并使用支付宝提供的RSA算法对该字符串进行签名。之后,我们将带有签名的字符串作为参数发送给支付宝服务器。支付宝服务器会返一个支付链接或二维码供用户支付支付完成后,支付宝服务器也会向我们指定的URL发送支付结果通知,我们同样需要处理该通知并更新订单状态。 以上是Delphi中使用微信支付支付接口实现在线支付的简要说明。具体的实现步骤和细节可以参考微信支付支付支付的开发文档。 ### 答2: Delphi是一种用于软件开发的集成开发环境(IDE),支持使用多种编程语言进行应用程序开发。微信支付支付支付是两种流行的移动支付方式,用户可以通过微信支付宝应用程序直接进行支付和转账。 在Delphi中实现微信支付支付支付,需要借助第三方SDK(软件开发工具包)来进行集成。这些SDK通常由微信支付宝提供,开发者可以根据自己的需求选择合适的SDK进行集成。 使用Delphi进行微信支付支付支付的步骤如下: 1. 下载并导入相应的SDK:开发者需要在微信支付宝开放平台下载相应的SDK,并将其导入到Delphi项目中。 2. 配置支付参数:根据实际情况,开发者需要配置支付参数,如商户号、AppID、密钥等。 3. 发起支付请求:在用户选择支付方式后,开发者需要用相应的API接口,传递支付相关信息(如订单号、支付金额等),并等待支付结果返。 4. 处理支付结果:支付结果通常以异步通知的方式返给开发者的服务器,开发者需要编写相应的代码来处理支付结果,例如更新订单状态、发送支付成功通知等。 需要注意的是,微信支付支付支付的具体实现步骤可能会有所不同,具体细节可参考官方文档或相关开发者社区的讨论。 总之,通过在Delphi中集成微信支付支付支付的SDK,开发者可以方便地实现移动支付功能,提供更便捷的支付体验给用户。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值