微信PC扫码支付(二)-发起支付

一、介绍

本文介绍了微信发起支付的步骤和代码实例,如有不足的请提出,我会做出改正。

二、官方文档

统一下单:https://pay.weixin.qq.com/wiki/doc/api/native.php?chapter=9_1

三、微信SDK安装方法

微信PC扫码支付(一)-maven本地仓库安装:微信支付sdk

四、发起支付

  • 下文PayException为自定义异常类
  • 下文WeixinConfig为微信需要固定参数类

第一步:调用微信支付

public Object pay(Map<String, Object> map) throws PayException{
	Map<String,Object> resultMap=new HashMap<>();
	//设备号
	String deviceInfo="WEB";
	//随机字符串
	String nonceStr=Long.toString(System.currentTimeMillis() / 1000);
	logger.info("微信扫码支付-nonceStr:"+nonceStr);
	//商品描述
	String body=(String)map.get("body");
	logger.info("微信扫码支付-body:"+body);
	//订单编号号(多个订单号用逗号分割)
	String orderId=(String)map.get("orderIds");
	logger.info("微信扫码支付-订单号:"+orderId);
	//订单价格
	String prices=(String)map.get("prices");
	logger.info("微信扫码支付-订单价格:"+prices);
	//总金额
	String amountPaid=(String)map.get("amountPaid");订单总金额,单位为元
	logger.info("微信扫码支付-订单总金额:"+amountPaid);
	//商户订单号(多个订单标志)
	String outTradeNo=(String)map.get("outTradeNo");
	logger.info("微信扫码支付-商户订单号:"+outTradeNo);
	//ip
	String ip = "XXXXXXXXX";
	logger.info("微信扫码支付-ip:"+ip);
	//交易类型
	String tradeType="NATIVE";
	//验证参数
	if(StringUtils.isBlank(body)){
		throw new PayException("商品描述不能为空");
	}
	if(StringUtils.isBlank(orderId)){
		throw new PayException("订单编号不能为空");
	}
	if(StringUtils.isBlank(prices)){
		throw new PayException("订单价格不能为空");
	}
	if(StringUtils.isBlank(amountPaid)){
		throw new PayException("订单总金额不能为空");
	}
	if(StringUtils.isBlank(outTradeNo)){
		throw new PayException("商户订单号不能为空");
	}
	if (StringUtils.isBlank(ip)) {
		ip = "127.0.0.1";
	}
	//组装参数
	Map<String, String> packageParams = new HashMap<String, String>();
	WeixinConfig weixinConfig=new WeixinConfig();
	String appid=weixinConfig.getAppID();
	logger.info("微信扫码支付-appid:"+appid);
	String mchId=weixinConfig.getMchID();
	logger.info("微信扫码支付-mchId:"+mchId);
	String notifyUrl=weixinConfig.getNotifyUrl();
	logger.info("微信扫码支付-notifyUrl:"+notifyUrl);
	int price=(int)(Float.valueOf(amountPaid)*100);//订单总金额,单位为分
	packageParams.put("appid", appid);
	packageParams.put("mch_id", mchId);
	packageParams.put("device_info", deviceInfo);
	packageParams.put("nonce_str", nonceStr);
	packageParams.put("body", body);
	packageParams.put("attach",orderId+";"+prices);
	packageParams.put("out_trade_no",outTradeNo);
	packageParams.put("total_fee", Integer.toString(price));
	packageParams.put("spbill_create_ip", ip);
	packageParams.put("notify_url", notifyUrl);
	packageParams.put("trade_type", tradeType);
	//签名
	String sign="";
	Map<String, String> result=new HashMap<>();
	try {
		sign = WXPayUtil.generateSignature(packageParams, weixinConfig.getKey());
		packageParams.put("sign",sign);
		logger.info("微信扫码支付-sign:"+sign);
		WXPay wxpay=new WXPay(weixinConfig,WXPayConstants.SignType.MD5,false);
		//统一下单
		result = wxpay.unifiedOrder(packageParams);
	} catch (Exception e) {
		logger.info("请求微信支付错误:",e);
		throw new PayException("请求微信支付错误");
	}
	String returnCode = result.get("return_code");
	logger.info("微信扫码支付-returnCode:"+returnCode);
	String returnMsg = result.get("return_msg");
	logger.info("微信扫码支付-returnMsg:"+returnMsg);
	//code 标记成功失败,默认0:成功,1:失败、用于alert,2:失败、用于confirm
	if (StringUtils.isBlank(returnCode) || !"SUCCESS".equals(returnCode)) {
		throw new PayException(returnMsg);
	}
	String resultCode = result.get("result_code");
	if (StringUtils.isBlank(resultCode) || !"SUCCESS".equals(resultCode)) {
		throw new PayException(result.get("err_code_des"));
	}
	// 以下字段在return_code 和result_code都为SUCCESS的时候有返回
	String codeUrl = result.get("code_url");
	logger.info("微信扫码支付-codeUrl:"+codeUrl);
	resultMap.put("returnCode", "SUCCESS");
	resultMap.put("codeUrl", codeUrl);
	return resultMap;
}

第二步:从调用返回的map中取出codeUrl,发到客户端(自己写的页面)

<div class="sui-container payOrder">
	<p class="title">微信支付</p>
	<div class="payOrderImg">
		<div class="code">
			<div class="codeImgDiv">
				<img alt="" src="/front/trade/pay/weixin/codeImg.htm?codeUrl=${codeUrl}">
			</div>
			<div class="codeFoot">
				<p>请使用微信扫一扫</p>
				<p>扫描二维码支付</p>
			</div>
		</div>
	</div>
</div>

第三步:客户端(页面)发起二次请求把图片加载出来

/**
 * 微信二维码图片
 * @param codeUrl	微信支付返回的code_url
 * @return
 */
@ResponseBody
@RequestMapping(value = "/pay/weixin/codeImg")
public void codeImg(HttpServletResponse response, String codeUrl){
	ServletOutputStream stream = null;
	try {
		stream = response.getOutputStream();
		QRCodeWriter writer = new QRCodeWriter();
		BitMatrix m = writer.encode(codeUrl, BarcodeFormat.QR_CODE, 300,300);
		MatrixToImageWriter.writeToStream(m, "png", stream);
	} catch (Exception e) {
		logger.info("生成二维码图片错误:",e);
	}finally {
        if (stream != null) {
            try {
				stream.flush();
				stream.close();
			} catch (IOException e) {
				logger.info("生成二维码图片错误:",e);
			}
        }
    }
}

(重要) 第四步:由于二维码页面是自己写的,需要在页面写一个查询微信订单的定时器,发现订单成功了就去订单列表页面

订单查询:https://blog.csdn.net/cl11992/article/details/86712544

$(function(){
	/**
	 * 查询订单,付款成功后跳转到订单列表页
	 * */
	var repeat = 200; // 限制执行次数为200次  
	var timer = setInterval(function(){
		if (repeat == 0){
			clearInterval(timer);
		} else{
			/**
			 * 发起ajax请求(请求微信查询订单)
			 */
		}
		repeat--;
	}, 3000);//3秒执行一次 总共200次 10分钟  
	
});

如需查看支付回调通知请看点击下面,查看文章:

https://blog.csdn.net/cl11992/article/details/86712519

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值