微信支付笔记-移动应用和网页支付Java后端实现

微信申请创建应用,获取APPID、应用私钥、商户ID、商户私钥等。

具体可以参考官方文档资料:https://pay.weixin.qq.com/wiki/doc/api/index.html

支付参数配置

import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Configuration;

@Configuration
public class WechatpayConfiguration {
	
	@Value("${wechatpay.app_id}")
    private String appId = null;
    
    @Value("${wechatpay.app_secret}")
    private String appSecret = null;
	
    @Value("${wechatpay.mch_id}")
    private String mchId = null;
    
    @Value("${wechatpay.mch_secret}")
    private String mchSecret = null;
    
    @Value("${wechatpay.trade_type_app}")
    private String tradeTypeApp = null;
    
    @Value("${wechatpay.trade_type_native}")
    private String tradeTypeNative = null;
    
    @Value("${wechatpay.package}")
    private String packageWechat = null;
    
    @Value("${wechatpay.notify_url}")
    private String notifyUrl = null;

	public String getAppId() {
		return appId;
	}

	public String getAppSecret() {
		return appSecret;
	}

	public String getMchId() {
		return mchId;
	}

	public String getMchSecret() {
		return mchSecret;
	}

	public String getTradeTypeApp() {
		return tradeTypeApp;
	}

	public String getTradeTypeNative() {
		return tradeTypeNative;
	}

	public String getPackageWechat() {
		return packageWechat;
	}

	public String getNotifyUrl() {
		return notifyUrl;
	}

}
public class WechatpayUtils {
	
	private static Random random = new Random();
	
	private static SimpleDateFormat SDF_1 = new SimpleDateFormat("yyyyMMdd");
	
	private static SimpleDateFormat SDF_2 = new SimpleDateFormat("yyyyMMddHHmmss");
	
	private static String CHARS = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
	
	/** 创建订单号 */
	public static String genOutTradeNo() throws BusinessException {
		return SDF_1.format(new Date()) + MD5Utils.hash(UUID.randomUUID().toString());
	}
	
	/** 创建订单号 */
	public static String genNativeOutTradeNo() throws BusinessException {
		return SDF_2.format(new Date()) + MD5Utils.hash(UUID.randomUUID().toString()).substring(8, 24);
	}
	
	/** 微信签名 */
	public static String genSignature(SortedMap<String, Object> params, String mchSecretKey) {
		StringBuilder sb = new StringBuilder(100);
		for (Map.Entry<String, Object> entry : params.entrySet()) {
			sb.append(entry.getKey() + "=" + entry.getValue()+ "&");
		}
		sb.append("key=").append(mchSecretKey);
		return MD5Utils.hash(sb.toString()).toUpperCase();
	}
	
	/** 生成微信请求参数 */
	public static String genRequestParams(SortedMap<String, Object> params) {
		StringBuilder sb = new StringBuilder(100);
        sb.append("<xml>");
        for (Map.Entry<String, Object> entry : params.entrySet()) {
            String paramKey = (String) entry.getKey();
            Object paramValue = entry.getValue();
            if ("attach".equalsIgnoreCase(paramKey) || "body".equalsIgnoreCase(paramKey)) {
                sb.append("<" + paramKey + ">" + "<![CDATA[" + paramValue + "]]></" + paramKey + ">");
            } else {
                sb.append("<" + paramKey + ">" + paramValue + "</" + paramKey + ">");
            }
        }
        sb.append("</xml>");
        return sb.toString();
	}
	
	/** 生成微信响应 */
	public static String genResponse(String returnCode, String returnMsg) {
        return "<xml><return_code><![CDATA[" + returnCode + "]]></return_code>"
        	+ "<return_msg><![CDATA[" + returnMsg + "]]></return_msg></xml>";
    }
	
	/** 生成微信参数nonce-str */
	public static String genParamNonceStr() {
        StringBuilder sb = new StringBuilder(26);
        for (int i = 0; i < 16; i++) {
        	sb.append(CHARS.charAt(random.nextInt(CHARS.length())));
        }
        return sb.toString();
    }
	
	/** 生成微信参数time-start */
	public static String genParamTimeV1() {
		return SDF_2.format(new Date());
	}
	
	/** 生成微信参数timestamp */
	public static String genParamTimeV2() {
		return String.valueOf(System.currentTimeMillis() / 1000);
	}

}

移动应用支付

可以参考官方文档:https://pay.weixin.qq.com/wiki/doc/api/app/app_sl.php?chapter=8_1

@ApiV1RestController
public class WechatpayController {
	
	private Logger LOG = LoggerFactory.getLogger(WechatpayController.class);
	
	@Resource(name = "wechatpayTerminalService")
	private IWechatpayService wechatpayTerminalService = null;
	
	@RequestMapping(value = "/recharge/wechatpay/terminal", method = RequestMethod.POST)
	public WebResult rechargeWechatpayTerminal(Long rechargeItemId) {
		WebResult webResult = new WebResult();
		try {
			webResult.setCode(ResultCode.SUCCESS.getCode());
			webResult.setData(wechatpayTerminalService.mreadPaymentRequest(rechargeItemId));
		} catch (BusinessException be) {
			webResult.setCode(ResultCode.FAILURE.getCode());
			webResult.setFailure(be.getDefaultMessage());
		} catch (Exception e) {
			webResult.setCode(ResultCode.SYSTEM_IS_BUSY.getCode());
			webResult.setFailure(ResultCode.SYSTEM_IS_BUSY.getDesc());
		}
		return webResult;
	}
	
	/** 验证微信支付充值结果 */
	@RequestMapping(value = "/recharge/wechatpay/terminal/notify", method = RequestMethod.POST)
	public void verifyWxPaymentTerminalNotify(HttpServletRequest request, HttpServletResponse response) {
		InputStream in = null;
		ByteArrayOutputStream out = null;
		try {
			in = request.getInputStream();
			int bufferSize = 1024;
            if (null != in) {
                out = new ByteArrayOutputStream();
                byte[] buff = new byte[bufferSize];
                int count = -1;
                while ((count = in.read(buff, 0, bufferSize)) != -1) {
                    out.write(buff, 0, count);
                }
                buff = null;
                out.flush();
                response.getWriter().write(wechatpayTerminalService
                	.verifyPaymentNotifyCallback(new String(out.toByteArray(), "UTF-8")));
            }
		} catch (Exception e) {
			LOG.error(e.getMessage(), e);
		} finally {
			try {
				if (null != in ) in.close();
				if (null != out) out.close();
			} catch (IOException e) {
				LOG.error(e.getMessage(), e);
			}
		}
	}

}
@Service("wechatpayTerminalService")
public class WechatpayTerminalServiceImpl implements IWechatpayService {
	
	private Logger LOG = LoggerFactory.getLogger(WechatpayTerminalServiceImpl.class);

	private static final String ORDER_URL = "https://api.mch.weixin.qq.com/pay/unifiedorder";
	
	private static final String ORDER_QUERY_URL = "https://api.mch.weixin.qq.com/pay/orderquery";
	
	@Autowired
	private WechatpayConfiguration wechatpayConfiguration = null;
	
	@Resource(name = "rechargeItemService")
	private IRechargeItemService rechargeItemService = null;

	@Resource(name = "rechargeRecordService")
	private IRechargeRecordService rechargeRecordService = null;
	
	@Override
	public Object mreadPaymentRequest(Long rechargeItemId) throws BusinessException {
		RechargeItem rechargeItem = rechargeItemService.readRechargeItemById(rechargeItemId);
		TreeMap<String, Object> params = new TreeMap<String, Object>();
		params.put("appid", wechatpayConfiguration.getAppId());
		params.put("mch_id", wechatpayConfiguration.getMchId());
		params.put("body", "");
		params.put("trade_type", wechatpayConfiguration.getTradeTypeApp());
		params.put("notify_url", wechatpayConfiguration.getNotifyUrl());
		params.put("nonce_str", WechatpayUtils.genParamNonceStr());
		params.put("out_trade_no", WechatpayUtils.genOutTradeNo());
		params.put("total_fee", (int) Math.ceil(rechargeItem.getPresentPrice() * 100));
		params.put("spbill_create_ip", IPUtils.getIPAddress(((ServletRequestAttributes) 
			RequestContextHolder.getRequestAttributes()).getRequest()));
		params.put("time_start", WechatpayUtils.genParamTimeV1());
		params.put("sign", WechatpayUtils.genSignature(params, wechatpayConfiguration.getMchSecret()));
		String respTxt = HttpClientUtils.sendPost(ORDER_URL, WechatpayUtils
			.genRequestParams(params), 5000, ContentType.APPLICATION_XML, "UTF-8", null);
		Map<String, String> resultMap = null;
		try {
			resultMap = XMLUtils.parseXML(respTxt);
		} catch (Exception e) {
			LOG.error(e.getMessage(), e);
			throw new BusinessException(ResultCode.SYSTEM_IS_BUSY);
		}
		if (!"SUCCESS".equals(resultMap.get("return_code")) || 
				!"SUCCESS".equals(resultMap.get("result_code"))) {
			throw new BusinessException("获取prepayid失败!" + resultMap.get("return_msg"));
		}
		TreeMap<String, Object> sparams = new TreeMap<String, Object>();
		sparams.put("appid", wechatpayConfiguration.getAppId());
		sparams.put("partnerid", wechatpayConfiguration.getMchId());
		sparams.put("prepayid", resultMap.get("prepay_id"));
		sparams.put("package", wechatpayConfiguration.getPackageWechat());
		sparams.put("noncestr", resultMap.get("nonce_str"));
		sparams.put("timestamp", WechatpayUtils.genParamTimeV2());
		String secondSign = WechatpayUtils.genSignature(sparams, wechatpayConfiguration.getMchSecret());
		sparams.put("sign", secondSign);
		insertRechargeRecord(rechargeItem, (String) params.get("out_trade_no"), sparams);
		return sparams;
	}

	@Override
	public String verifyPaymentNotifyCallback(Object callbackParams) throws BusinessException {
		Map<String, String> notifyParams = null;
		try {
			notifyParams = XMLUtils.parseXML((String) callbackParams);
		} catch (Exception e) {
			LOG.error(e.getMessage(), e);
			throw new BusinessException(ResultCode.SYSTEM_IS_BUSY);
		}
		String sign = notifyParams.remove("sign");
		TreeMap<String, Object> vparams = new TreeMap<String, Object>();
		vparams.putAll(notifyParams);
		String vsign = WechatpayUtils.genSignature(vparams, wechatpayConfiguration.getMchSecret());
		if (!sign.equals(vsign)) {
			LOG.error("签名错误! {}", notifyParams.get("return_msg"));
			return WechatpayUtils.genResponse("FAIL", "签名错误!");
		}
		if (!"SUCCESS".equals(notifyParams.get("return_code"))) {
			LOG.error("通信标识失败! {}", notifyParams.get("return_msg"));
			return WechatpayUtils.genResponse("FAIL", "通信标识失败!");
		}
		if (!wechatpayConfiguration.getMchId().equals(notifyParams.get("mch_id"))) {
			LOG.error("商户ID不正确! {}", notifyParams.get("return_msg"));
			return WechatpayUtils.genResponse("FAIL", "商户ID不正确!");
		}
		int cashFee = Integer.parseInt(notifyParams.get("cash_fee"));
		int totalFee = Integer.parseInt(notifyParams.get("total_fee"));
		if (cashFee != totalFee) {
			LOG.error("支付金额与订单金额不一致! {}", notifyParams.get("return_msg"));
			return WechatpayUtils.genResponse("FAIL", "支付金额与订单金额不一致!");
		}
		String outTradeNo = notifyParams.get("out_trade_no");
		RechargeRecord rechargeRecord = rechargeRecordService.readRechargeRecordByOutTradeNo(outTradeNo);
		if (null == rechargeRecord) {
			LOG.error("商户生成的订单号未找到记录! {}", notifyParams.get("return_msg"));
			return WechatpayUtils.genResponse("FAIL", "商户生成的订单号未找到记录!");
		}
		double actualCashFee = Double.parseDouble(String.valueOf(cashFee)) / 100;
		if (!rechargeRecord.getTotalMoney().equals(actualCashFee)) {
			LOG.error("支付金额与订单金额不一致! {}", notifyParams.get("return_msg"));
			LOG.error("{} , {}", rechargeRecord.getTotalMoney(), actualCashFee);
			return WechatpayUtils.genResponse("FAIL", "支付金额与订单金额不一致!");
		}
		if (!"SUCCESS".equals(notifyParams.get("result_code"))) {
			LOG.error("业务标识失败! {}", notifyParams.get("return_msg"));
			updateRechargeRecordFailure(rechargeRecord, notifyParams);
			return WechatpayUtils.genResponse("FAIL", "业务标识失败!");
		}
		updateRechargeRecordSuccess(rechargeRecord, notifyParams);
		return WechatpayUtils.genResponse("SUCCESS", "OK");
	}

	@Override
	public void updateOrderByOrderNo(String orderNo, boolean isMch) throws BusinessException {
		TreeMap<String, Object> params = new TreeMap<String, Object>();
		params.put("appid", wechatpayConfiguration.getAppId());
		params.put("mch_id", wechatpayConfiguration.getMchId());
		params.put(isMch ? "out_trade_no" : "transaction_id", orderNo);
		params.put("nonce_str", WechatpayUtils.genParamNonceStr());
		params.put("sign", WechatpayUtils.genSignature(params, wechatpayConfiguration.getMchSecret()));
		String respTxt = HttpClientUtils.sendPost(ORDER_QUERY_URL, WechatpayUtils
			.genRequestParams(params), 5000, ContentType.APPLICATION_XML, "UTF-8", null);
		Map<String, String> resultMap = null;
		try {
			resultMap = XMLUtils.parseXML(respTxt);
		} catch (Exception e) {
			LOG.error(e.getMessage(), e);
			throw new BusinessException(ResultCode.SYSTEM_IS_BUSY);
		}
		if (!"SUCCESS".equals(resultMap.get("return_code"))) return;
		String outTradeNo = resultMap.get("out_trade_no");
		if (!"SUCCESS".equals(resultMap.get("result_code"))) {
			RechargeRecord rechargeRecord = new RechargeRecord();
			rechargeRecord.setOutTradeNo(outTradeNo);
			rechargeRecord.setResultNote(GsonUtils.fromMapExtToJson(resultMap));
			rechargeRecord.setTradeStatus(TradeStatus.FAILURE.value());
			rechargeRecordService.update(rechargeRecord);
		} else {
			RechargeRecord chargingRecord = rechargeRecordService.readRechargeRecordByOutTradeNo(outTradeNo);
			updateRechargeRecordSuccess(chargingRecord, resultMap);
		}
	}
	
	/** 保存充值记录 */
	private void insertRechargeRecord(RechargeItem rechargeItem, String outTradeNo, Map<String, Object> params) {
		RechargeRecord rechargeRecord = new RechargeRecord();
		rechargeRecord.setUserId(WebUtils.getCurrentUserId()); 
		rechargeRecord.setTotalMoney(rechargeItem.getPresentPrice());
		rechargeRecord.setRechargeItem(GsonUtils.builder().toJson(rechargeItem));
		rechargeRecord.setChannel("wechatpay");
		rechargeRecord.setOutTradeNo(outTradeNo);
		rechargeRecord.setSign((String) params.get("sign"));
		rechargeRecord.setRechargeNote(GsonUtils.fromMapToJson(params));
		rechargeRecord.setTradeStatus(TradeStatus.INITIAL.value());
		rechargeRecord.setInsertTime(new Date());
		rechargeRecordService.insert(rechargeRecord);
	}
	
	/** 充值失败处理 */
	private void updateRechargeRecordFailure(RechargeRecord rechargeRecord, Map<String, String> notifyParams) {
		RechargeRecord uRechargeRecord = new RechargeRecord();
		uRechargeRecord.setUserId(rechargeRecord.getUserId());
		uRechargeRecord.setOutTradeNo(rechargeRecord.getOutTradeNo());
		uRechargeRecord.setResultNote(GsonUtils.fromMapExtToJson(notifyParams));
		uRechargeRecord.setTradeNo(notifyParams.get("transaction_id"));
		uRechargeRecord.setTradeStatus(TradeStatus.FAILURE.value());
		rechargeRecordService.update(uRechargeRecord);
	}
	
	/** 充值成功处理 */
	private void updateRechargeRecordSuccess(RechargeRecord rechargeRecord, Map<String, String> notifyParams) {
		String dbTradeStatus = rechargeRecord.getTradeStatus();
		if (TradeStatus.judgeIn(dbTradeStatus, TradeStatus.SUCCESS, TradeStatus.FINISHED)) return;
		RechargeRecord updateRechargeRecord = new RechargeRecord();
		updateRechargeRecord.setUserId(rechargeRecord.getUserId());
		updateRechargeRecord.setOutTradeNo(rechargeRecord.getOutTradeNo());
		updateRechargeRecord.setTradeNo(notifyParams.get("transaction_id"));
		updateRechargeRecord.setResultNote(GsonUtils.fromMapExtToJson(notifyParams));
		updateRechargeRecord.setTradeStatus(TradeStatus.SUCCESS.value());
		rechargeRecordService.update(updateRechargeRecord);
	}
	
}

Native支付

可以参考官方文档:https://pay.weixin.qq.com/wiki/doc/api/native.php?chapter=6_1

@ApiV1RestController
public class WechatpayController {
	
	private Logger LOG = LoggerFactory.getLogger(WechatpayController.class);
	
	@Resource(name = "wechatpayWebPageService")
	private IWechatpayService wechatpayWebPageService = null;
	
	@RequestMapping(value = "/recharge/wechatpay/webpage", method = RequestMethod.GET)
	public void rechargeWechatpayWebPage(Long rechargeItemId, HttpServletResponse response) {
		try {
			ZXingImageUtils.writeToStream(300, 300, "png", String.valueOf(
				wechatpayWebPageService.mreadPaymentRequest(rechargeItemId)), response.getOutputStream());
		} catch (Exception e) {
			e.printStackTrace();
			LOG.error("generate verification code error {}", e.getMessage());
		}
	}
	
	@RequestMapping(value = "/recharge/wechatpay/webpage/notify", method = RequestMethod.POST)
	public void verifyWxPaymentWebPageNotify(HttpServletRequest request, HttpServletResponse response) {
		InputStream in = null;
		ByteArrayOutputStream out = null;
		try {
			in = request.getInputStream();
			int bufferSize = 1024;
            if (null != in) {
                out = new ByteArrayOutputStream();
                byte[] buff = new byte[bufferSize];
                int count = -1;
                while ((count = in.read(buff, 0, bufferSize)) != -1) {
                    out.write(buff, 0, count);
                }
                buff = null;
                out.flush();
                response.getWriter().write(wechatpayWebPageService
                	.verifyPaymentNotifyCallback(new String(out.toByteArray(), "UTF-8")));
            }
		} catch (Exception e) {
			LOG.error(e.getMessage(), e);
		} finally {
			try {
				if (null != in ) in.close();
				if (null != out) out.close();
			} catch (IOException e) {
				LOG.error(e.getMessage(), e);
			}
		}
	}

}
@Service("wechatpayWebPageService")
public class WechatpayWebPageServiceImpl implements IWechatpayService {
	
	private Logger LOG = LoggerFactory.getLogger(WechatpayWebPageServiceImpl.class);

	private static final String ORDER_URL = "https://api.mch.weixin.qq.com/pay/unifiedorder";
	
	private static final String ORDER_QUERY_URL = "https://api.mch.weixin.qq.com/pay/orderquery";
	
	@Autowired
	private WechatpayConfiguration wechatpayConfiguration = null;
	
	@Resource(name = "rechargeItemService")
	private IRechargeItemService rechargeItemService = null;

	@Resource(name = "rechargeRecordService")
	private IRechargeRecordService rechargeRecordService = null;
	
	@Override
	public Object mreadPaymentRequest(Long rechargeItemId) throws BusinessException {
		RechargeItem rechargeItem = rechargeItemService.readRechargeItemById(rechargeItemId);
		TreeMap<String, Object> params = new TreeMap<String, Object>();
		params.put("appid", wechatpayConfiguration.getAppId());
		params.put("mch_id", wechatpayConfiguration.getMchId());
		params.put("body", rechargeItem.getDesc());
		params.put("trade_type", wechatpayConfiguration.getTradeTypeNative());
		params.put("notify_url", wechatpayConfiguration.getNotifyUrl());
		params.put("nonce_str", WechatpayUtils.genParamNonceStr());
		params.put("out_trade_no", WechatpayUtils.genNativeOutTradeNo());
		params.put("total_fee", (int) Math.ceil(rechargeItem.getPresentPrice() * 100));
		params.put("spbill_create_ip", IPUtils.getIPAddress(WebContext.get().getRequest()));
		params.put("time_start", WechatpayUtils.genParamTimeV1());
		params.put("sign", WechatpayUtils.genSignature(params, wechatpayConfiguration.getMchSecret()));
		String respTxt = HttpClientUtils.sendPost(ORDER_URL, WechatpayUtils
			.genRequestParams(params), 5000, ContentType.APPLICATION_XML, "UTF-8", null);
		Map<String, String> resultMap = null;
		try {
			resultMap = XMLUtils.parseXML(respTxt);
		} catch (Exception e) {
			LOG.error(e.getMessage(), e);
			throw new BusinessException(ResultCode.SYSTEM_IS_BUSY);
		}
		if (!"SUCCESS".equals(resultMap.get("return_code")) || 
				!"SUCCESS".equals(resultMap.get("result_code"))) {
			throw new BusinessException("获取prepayid失败!" + resultMap.get("return_msg"));
		}
		TreeMap<String, Object> sparams = new TreeMap<String, Object>();
		sparams.put("appid", wechatpayConfiguration.getAppId());
		sparams.put("partnerid", wechatpayConfiguration.getMchId());
		sparams.put("prepayid", resultMap.get("prepay_id"));
		sparams.put("package", wechatpayConfiguration.getPackageWechat());
		sparams.put("noncestr", resultMap.get("nonce_str"));
		sparams.put("timestamp", WechatpayUtils.genParamTimeV2());
		String secondSign = WechatpayUtils.genSignature(sparams, wechatpayConfiguration.getMchSecret());
		sparams.put("sign", secondSign);
		insertRechargeRecord(rechargeItem, (String) params.get("out_trade_no"), sparams);
		return resultMap.get("code_url");
	}

	@Override
	public String verifyPaymentNotifyCallback(Object callbackParams) throws BusinessException {
		Map<String, String> notifyParams = null;
		try {
			notifyParams = XMLUtils.parseXML((String) callbackParams);
		} catch (Exception e) {
			LOG.error(e.getMessage(), e);
			throw new BusinessException(ResultCode.SYSTEM_IS_BUSY);
		}
		String sign = notifyParams.remove("sign");
		TreeMap<String, Object> vparams = new TreeMap<String, Object>();
		vparams.putAll(notifyParams);
		String vsign = WechatpayUtils.genSignature(vparams, wechatpayConfiguration.getMchSecret());
		if (!sign.equals(vsign)) {
			LOG.error("签名错误! {}", notifyParams.get("return_msg"));
			return WechatpayUtils.genResponse("FAIL", "签名错误!");
		}
		if (!"SUCCESS".equals(notifyParams.get("return_code"))) {
			LOG.error("通信标识失败! {}", notifyParams.get("return_msg"));
			return WechatpayUtils.genResponse("FAIL", "通信标识失败!");
		}
		if (!wechatpayConfiguration.getMchId().equals(notifyParams.get("mch_id"))) {
			LOG.error("商户ID不正确! {}", notifyParams.get("return_msg"));
			return WechatpayUtils.genResponse("FAIL", "商户ID不正确!");
		}
		int cashFee = Integer.parseInt(notifyParams.get("cash_fee"));
		int totalFee = Integer.parseInt(notifyParams.get("total_fee"));
		if (cashFee != totalFee) {
			LOG.error("支付金额与订单金额不一致! {}", notifyParams.get("return_msg"));
			return WechatpayUtils.genResponse("FAIL", "支付金额与订单金额不一致!");
		}
		String outTradeNo = notifyParams.get("out_trade_no");
		RechargeRecord rechargeRecord = rechargeRecordService.readRechargeRecordByOutTradeNo(outTradeNo);
		if (null == rechargeRecord) {
			LOG.error("商户生成的订单号未找到记录! {}", notifyParams.get("return_msg"));
			return WechatpayUtils.genResponse("FAIL", "商户生成的订单号未找到记录!");
		}
		double actualCashFee = Double.parseDouble(String.valueOf(cashFee)) / 100;
		if (!rechargeRecord.getTotalMoney().equals(actualCashFee)) {
			LOG.error("支付金额与订单金额不一致! {}", notifyParams.get("return_msg"));
			LOG.error("{} , {}", rechargeRecord.getTotalMoney(), actualCashFee);
			return WechatpayUtils.genResponse("FAIL", "支付金额与订单金额不一致!");
		}
		if (!"SUCCESS".equals(notifyParams.get("result_code"))) {
			LOG.error("业务标识失败! {}", notifyParams.get("return_msg"));
			updateRechargeRecordFailure(rechargeRecord, notifyParams);
			return WechatpayUtils.genResponse("FAIL", "业务标识失败!");
		}
		updateRechargeRecordSuccess(rechargeRecord, notifyParams);
		return WechatpayUtils.genResponse("SUCCESS", "OK");
	}

	@Override
	public void updateOrderByOrderNo(String orderNo, boolean isMch) throws BusinessException {
		TreeMap<String, Object> params = new TreeMap<String, Object>();
		params.put("appid", wechatpayConfiguration.getAppId());
		params.put("mch_id", wechatpayConfiguration.getMchId());
		params.put(isMch ? "out_trade_no" : "transaction_id", orderNo);
		params.put("nonce_str", WechatpayUtils.genParamNonceStr());
		params.put("sign", WechatpayUtils.genSignature(params, wechatpayConfiguration.getMchSecret()));
		String respTxt = HttpClientUtils.sendPost(ORDER_QUERY_URL, WechatpayUtils
			.genRequestParams(params), 5000, ContentType.APPLICATION_XML, "UTF-8", null);
		Map<String, String> resultMap = null;
		try {
			resultMap = XMLUtils.parseXML(respTxt);
		} catch (Exception e) {
			LOG.error(e.getMessage(), e);
			throw new BusinessException(ResultCode.SYSTEM_IS_BUSY);
		}
		if (!"SUCCESS".equals(resultMap.get("return_code"))) return;
		String outTradeNo = resultMap.get("out_trade_no");
		if (!"SUCCESS".equals(resultMap.get("result_code"))) {
			RechargeRecord rechargeRecord = new RechargeRecord();
			rechargeRecord.setOutTradeNo(outTradeNo);
			rechargeRecord.setResultNote(GsonUtils.fromMapExtToJson(resultMap));
			rechargeRecord.setTradeStatus(TradeStatus.FAILURE.value());
			rechargeRecordService.update(rechargeRecord);
		} else {
			RechargeRecord chargingRecord = rechargeRecordService.readRechargeRecordByOutTradeNo(outTradeNo);
			updateRechargeRecordSuccess(chargingRecord, resultMap);
		}
	}
	
	/** 保存充值记录 */
	private void insertRechargeRecord(RechargeItem rechargeItem, String outTradeNo, Map<String, Object> params) {
		RechargeRecord rechargeRecord = new RechargeRecord();
		rechargeRecord.setUserId(WebUtils.getCurrentUserId());
		rechargeRecord.setTotalMoney(rechargeItem.getPresentPrice());
		rechargeRecord.setRechargeItem(GsonUtils.builder().toJson(rechargeItem));
		rechargeRecord.setChannel("wechatpay");
		rechargeRecord.setOutTradeNo(outTradeNo);
		rechargeRecord.setSign((String) params.get("sign"));
		rechargeRecord.setRechargeNote(GsonUtils.fromMapToJson(params));
		rechargeRecord.setTradeStatus(TradeStatus.INITIAL.value());
		rechargeRecord.setInsertTime(new Date());
		rechargeRecordService.insert(rechargeRecord);
	}
	
	/** 充值失败处理 */
	private void updateRechargeRecordFailure(RechargeRecord rechargeRecord, Map<String, String> notifyParams) {
		RechargeRecord uRechargeRecord = new RechargeRecord();
		uRechargeRecord.setUserId(rechargeRecord.getUserId());
		uRechargeRecord.setOutTradeNo(rechargeRecord.getOutTradeNo());
		uRechargeRecord.setResultNote(GsonUtils.fromMapExtToJson(notifyParams));
		uRechargeRecord.setTradeNo(notifyParams.get("transaction_id"));
		uRechargeRecord.setTradeStatus(TradeStatus.FAILURE.value());
		rechargeRecordService.update(uRechargeRecord);
	}
	
	/** 充值成功处理 */
	private void updateRechargeRecordSuccess(RechargeRecord rechargeRecord, Map<String, String> notifyParams) {
		String dbTradeStatus = rechargeRecord.getTradeStatus();
		if (TradeStatus.judgeIn(dbTradeStatus, TradeStatus.SUCCESS, TradeStatus.FINISHED)) return;
		RechargeRecord uRechargeRecord = new RechargeRecord();
		uRechargeRecord.setUserId(rechargeRecord.getUserId());
		uRechargeRecord.setOutTradeNo(rechargeRecord.getOutTradeNo());
		uRechargeRecord.setTradeNo(notifyParams.get("transaction_id"));
		uRechargeRecord.setResultNote(GsonUtils.fromMapExtToJson(notifyParams));
		uRechargeRecord.setTradeStatus(TradeStatus.SUCCESS.value());
		rechargeRecordService.update(uRechargeRecord);
	}
	
}
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.io.OutputStream;
import java.util.HashMap;
import java.util.Map;

import javax.imageio.ImageIO;

import com.google.zxing.BarcodeFormat;
import com.google.zxing.EncodeHintType;
import com.google.zxing.MultiFormatWriter;
import com.google.zxing.common.BitMatrix;
import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;

public class ZXingImageUtils {
	
	private static final int BLACK = 0xFF000000;

	private static final int WHITE = 0xFFFFFFFF;
	
	private static Map<EncodeHintType, Object> hints = new HashMap<EncodeHintType, Object>();

	private ZXingImageUtils() {
	}
	
	static {
		hints.put(EncodeHintType.CHARACTER_SET, "utf-8");    //指定字符编码utf-8
        hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.M);  //指定二维码的纠错等级为中级
        hints.put(EncodeHintType.MARGIN, 2);    //设置图片的边距
	}

	public static BufferedImage toBufferedImage(BitMatrix bitMatrix) {
		int width = bitMatrix.getWidth();
		int height = bitMatrix.getHeight();
		BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
		for (int x = 0; x < width; x++) {
			for (int y = 0; y < height; y++) {
				image.setRGB(x, y, bitMatrix.get(x, y) ? BLACK : WHITE);
			}
		}
		return image;
	}
	
	public static void writeToFile(int width, int height, String format, String content, String filePath) throws Exception {
        BitMatrix bitMatrix = new MultiFormatWriter().encode(content, BarcodeFormat.QR_CODE, width, height, hints);
        writeToFile(bitMatrix, format, filePath);
	}
	
	public static void writeToFile(BitMatrix bitMatrix, String format, String filePath) throws IOException {
		writeToFile(bitMatrix, format, new File(filePath));
	}

	public static void writeToFile(BitMatrix bitMatrix, String format, File file) throws IOException {
		BufferedImage image = toBufferedImage(bitMatrix);
		if (!ImageIO.write(image, format, file)) {
			throw new IOException("could not write an image of format " + format + " to " + file);
		}
	}
	
	public static void writeToStream(int width, int height, String format, String content, OutputStream outputStream) throws Exception {
        BitMatrix bitMatrix = new MultiFormatWriter().encode(content, BarcodeFormat.QR_CODE, width, height, hints);
        writeToStream(bitMatrix, format, outputStream);
	}

	public static void writeToStream(BitMatrix bitMatrix, String format, OutputStream outputStream) throws IOException {
		BufferedImage image = toBufferedImage(bitMatrix);
		if (!ImageIO.write(image, format, outputStream)) {
			throw new IOException("could not write an image of format " + format);
		}
	}
	
}
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import org.jdom2.Document;
import org.jdom2.Element;
import org.jdom2.JDOMException;
import org.jdom2.input.SAXBuilder;

public class XMLUtils {
	
	/**
     * @param xmltext
     * @return
     * @throws JDOMException
     * @throws IOException
     */
    public static Map<String, String> parseXML(String xmltext) throws JDOMException, IOException {
        xmltext = xmltext.replaceFirst("encoding=\".*\"", "encoding=\"UTF-8\"");
        if(null == xmltext || "".equals(xmltext))  return null;
        Map<String, String> result = new HashMap<String, String>();
        InputStream in = new ByteArrayInputStream(xmltext.getBytes("UTF-8"));
        Document document = new SAXBuilder().build(in);
        Element root = document.getRootElement();
        Iterator<Element> iterator = root.getChildren().iterator();
        while(iterator.hasNext()) {
            Element element = iterator.next();
            String k = element.getName();
            String v = "";
            List<Element> children = element.getChildren();
            if(children.isEmpty()) {
                v = element.getTextNormalize();
            } else {
                v = getChildrenText(children);
            }
            result.put(k, v);
        }
        in.close();
        return result;
    }
     
    /**
     * 获取子结点的xml
     * @param children
     * @return String
     */
    public static String getChildrenText(List<Element> children) {
        StringBuilder sb = new StringBuilder();
        if(!children.isEmpty()) {
            Iterator<Element> iterator = children.iterator();
            while(iterator.hasNext()) {
                Element element = iterator.next();
                String name = element.getName();
                String value = element.getTextNormalize();
                List<Element> list = element.getChildren();
                sb.append("<" + name + ">");
                if(!list.isEmpty()) {
                    sb.append(getChildrenText(list));
                }
                sb.append(value);
                sb.append("</" + name + ">");
            }
        }
        return sb.toString();
    }
     
}

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值