微信支付 - 生成支付二维码

/**
 * @Description: 微信扫码支付页面
 */
//	@GetMapping(value="/getWXPayQRCode")
@PostMapping(value="/getWXPayQRCode")
public JSONResult getWXPayQRCode(String merchantOrderId, String merchantUserId) throws Exception{

//		System.out.println(wxPayResource.toString());

	// 根据订单ID和用户ID查询订单详情
	Orders waitPayOrder = paymentOrderService.queryOrderByStatus(merchantUserId, merchantOrderId, PaymentStatus.WAIT_PAY.type);

	// 商品描述
	String body = "天天吃货-付款用户[" + merchantUserId + "]";
	// 商户订单号
	String out_trade_no = merchantOrderId;
	// 从redis中去获得这笔订单的微信支付二维码,如果订单状态没有支付没有就放入,这样的做法防止用户频繁刷新而调用微信接口
	if (waitPayOrder != null) {
		String qrCodeUrl = redis.get(wxPayResource.getQrcodeKey() + ":" + merchantOrderId);

		if (StringUtils.isEmpty(qrCodeUrl)) {
			// 订单总金额,单位为分
			String total_fee = String.valueOf(waitPayOrder.getAmount());
//				String total_fee = "1";	// 测试用 1分钱

			// 统一下单
			PreOrderResult preOrderResult = wxOrderService.placeOrder(body, out_trade_no, total_fee);
			qrCodeUrl = preOrderResult.getCode_url();
		}

		PaymentInfoVO paymentInfoVO = new PaymentInfoVO();
		paymentInfoVO.setAmount(waitPayOrder.getAmount());
		paymentInfoVO.setMerchantOrderId(merchantOrderId);
		paymentInfoVO.setMerchantUserId(merchantUserId);
		paymentInfoVO.setQrCodeUrl(qrCodeUrl);

		redis.set(wxPayResource.getQrcodeKey() + ":" + merchantOrderId, qrCodeUrl, wxPayResource.getQrcodeExpire());

		return JSONResult.ok(paymentInfoVO);
	} else {
		return JSONResult.errorMsg("该订单不存在,或已经支付");
	}
}
@Transactional(propagation=Propagation.SUPPORTS)
@Override
public Orders queryOrderByStatus(String merchantUserId, String merchantOrderId, Integer orderStatus) {

	Orders queryOrder = new Orders();
	queryOrder.setMerchantOrderId(merchantOrderId);
	queryOrder.setMerchantUserId(merchantUserId);
	queryOrder.setPayStatus(orderStatus);
	Orders waitPayOrder = ordersMapper.selectOne(queryOrder);

	return waitPayOrder;
}
/**
 * @Description: 支付中心的支付状态 10:未支付 20:已支付 30:支付失败 40:已退款
 */
public enum PaymentStatus {

	WAIT_PAY(10, "未支付"),
	PAID(20, "已支付"),
	PAY_FAILED(30, "支付失败"),
	SUCCESS(40, "已退款");

	public final Integer type;
	public final String value;

	PaymentStatus(Integer type, String value){
		this.type = type;
		this.value = value;
	}

}
wxpay.qrcodeExpire=7000
@Override
public PreOrderResult placeOrder(String body, String out_trade_no, String total_fee) throws Exception {
	// 生成预付单对象
	PreOrder o = new PreOrder();
	// 生成随机字符串
	String nonce_str = UUID.randomUUID().toString().trim().replaceAll("-", "");
	o.setAppid(wxPayResource.getAppId());
	o.setBody(body);
	o.setMch_id(wxPayResource.getMerchantId());
	o.setNotify_url(wxPayResource.getNotifyUrl());
	o.setOut_trade_no(out_trade_no);
	// 判断有没有输入订单总金额,没有输入默认1分钱
	if (total_fee != null && !total_fee.equals("")) {
		o.setTotal_fee(Integer.parseInt(total_fee));
	} else {
		o.setTotal_fee(1);
	}
	o.setNonce_str(nonce_str);
	o.setTrade_type(wxPayResource.getTradeType());
	o.setSpbill_create_ip(wxPayResource.getSpbillCreateIp());
	SortedMap<Object, Object> p = new TreeMap<Object, Object>();
	p.put("appid", wxPayResource.getAppId());
	p.put("mch_id", wxPayResource.getMerchantId());
	p.put("body", body);
	p.put("nonce_str", nonce_str);
	p.put("out_trade_no", out_trade_no);
	p.put("total_fee", total_fee);
	p.put("spbill_create_ip", wxPayResource.getSpbillCreateIp());
	p.put("notify_url", wxPayResource.getNotifyUrl());
	p.put("trade_type", wxPayResource.getTradeType());
	// 获得签名
	String sign = Sign.createSign("utf-8", p, wxPayResource.getSecrectKey());
	o.setSign(sign);
	// Object转换为XML
	String xml = XmlUtil.object2Xml(o, PreOrder.class);
	// 统一下单地址
	String url = wxPayResource.getPlaceOrderUrl();
	// 调用微信统一下单地址
	String returnXml = HttpUtil.sendPost(url, xml);
	
	// XML转换为Object
	PreOrderResult preOrderResult = (PreOrderResult) XmlUtil.xml2Object(returnXml, PreOrderResult.class);
	
	return preOrderResult;
}
@Component
@ConfigurationProperties(prefix="wxpay")
@PropertySource("classpath:wxpay.properties")
public class WXPayResource {

	private String qrcodeKey;
	private long qrcodeExpire;

	private String appId;
	private String merchantId;
	private String secrectKey;

	private String spbillCreateIp;
	private String notifyUrl;

	private String tradeType;
	private String placeOrderUrl;

	public String getQrcodeKey() {
		return qrcodeKey;
	}

	public void setQrcodeKey(String qrcodeKey) {
		this.qrcodeKey = qrcodeKey;
	}

	public long getQrcodeExpire() {
		return qrcodeExpire;
	}

	public void setQrcodeExpire(long qrcodeExpire) {
		this.qrcodeExpire = qrcodeExpire;
	}

	public String getAppId() {
		return appId;
	}

	public void setAppId(String appId) {
		this.appId = appId;
	}

	public String getMerchantId() {
		return merchantId;
	}

	public void setMerchantId(String merchantId) {
		this.merchantId = merchantId;
	}

	public String getSecrectKey() {
		return secrectKey;
	}

	public void setSecrectKey(String secrectKey) {
		this.secrectKey = secrectKey;
	}

	public String getSpbillCreateIp() {
		return spbillCreateIp;
	}

	public void setSpbillCreateIp(String spbillCreateIp) {
		this.spbillCreateIp = spbillCreateIp;
	}

	public String getNotifyUrl() {
		return notifyUrl;
	}

	public void setNotifyUrl(String notifyUrl) {
		this.notifyUrl = notifyUrl;
	}

	public String getTradeType() {
		return tradeType;
	}

	public void setTradeType(String tradeType) {
		this.tradeType = tradeType;
	}

	public String getPlaceOrderUrl() {
		return placeOrderUrl;
	}

	public void setPlaceOrderUrl(String placeOrderUrl) {
		this.placeOrderUrl = placeOrderUrl;
	}
}
wxpay.appId=wx10516asde1h8ki
wxpay.tradeType=NATIVE
wxpay.spbillCreateIp=127.0.0.1
wxpay.secrectKey=4fkbcKhMcSxSXYZQc369nP1SI
wxpay.placeOrderUrl=https://api.mch.weixin.qq.com/pay/unifiedorder
/**
 * @Description: 微信支付 - 统一下单返回结果的封装entity
 */
public class PreOrderResult {
	
	private String return_code;				// 返回状态码
	private String return_msg;				// 返回信息
	private String appid;					// 公众账号ID
	private String mch_id;					// 商户号
	private String device_info;				// 设备号
	private String nonce_str;				// 随机字符串
	private String sign;					// 签名
	private String result_code;				// 业务结果
	private String err_code;				// 错误代码
	private String err_code_des;			// 错误代码描述
	private String trade_type;				// 交易类型
	private String prepay_id;				// 预支付交易会话标识
	private String code_url;				// 二维码链接
	
	public String getReturn_code() {
		return return_code;
	}
	public void setReturn_code(String return_code) {
		this.return_code = return_code;
	}
	public String getReturn_msg() {
		return return_msg;
	}
	public void setReturn_msg(String return_msg) {
		this.return_msg = return_msg;
	}
	public String getAppid() {
		return appid;
	}
	public void setAppid(String appid) {
		this.appid = appid;
	}
	public String getMch_id() {
		return mch_id;
	}
	public void setMch_id(String mch_id) {
		this.mch_id = mch_id;
	}
	public String getDevice_info() {
		return device_info;
	}
	public void setDevice_info(String device_info) {
		this.device_info = device_info;
	}
	public String getNonce_str() {
		return nonce_str;
	}
	public void setNonce_str(String nonce_str) {
		this.nonce_str = nonce_str;
	}
	public String getSign() {
		return sign;
	}
	public void setSign(String sign) {
		this.sign = sign;
	}
	public String getResult_code() {
		return result_code;
	}
	public void setResult_code(String result_code) {
		this.result_code = result_code;
	}
	public String getErr_code() {
		return err_code;
	}
	public void setErr_code(String err_code) {
		this.err_code = err_code;
	}
	public String getErr_code_des() {
		return err_code_des;
	}
	public void setErr_code_des(String err_code_des) {
		this.err_code_des = err_code_des;
	}
	public String getTrade_type() {
		return trade_type;
	}
	public void setTrade_type(String trade_type) {
		this.trade_type = trade_type;
	}
	public String getPrepay_id() {
		return prepay_id;
	}
	public void setPrepay_id(String prepay_id) {
		this.prepay_id = prepay_id;
	}
	public String getCode_url() {
		return code_url;
	}
	public void setCode_url(String code_url) {
		this.code_url = code_url;
	}
	
	@Override
	public String toString() {
		return "OrderReturn [return_code=" + return_code + ", return_msg="
				+ return_msg + ", appid=" + appid + ", mch_id=" + mch_id
				+ ", device_info=" + device_info + ", nonce_str=" + nonce_str
				+ ", sign=" + sign + ", result_code=" + result_code
				+ ", err_code=" + err_code + ", err_code_des=" + err_code_des
				+ ", trade_type=" + trade_type + ", prepay_id=" + prepay_id
				+ ", code_url=" + code_url + "]";
	}
	
}

 

<think>嗯,用户问的是关于uni-app生成微信支付二维码的问题。首先,我需要确认用户的需求是什么。他们可能是在开发一个基于uni-app的应用,需要集成微信支付功能,并且希望生成支付二维码让用户扫描完成支付。 接下来,我得回忆一下uni-app中微信支付的流程。通常来说,微信支付在移动端分为APP支付、H5支付、小程序支付等不同场景。但用户提到的是二维码生成,可能指的是Native支付(即扫码支付),这种场景下用户展示二维码,他人扫码后完成支付。不过,在uni-app中,如果是APP端,可能需要调用原生插件或者使用微信的SDK;如果是H5,可能需要通过后端生成支付链接再生成二维码。 然后,我需要考虑uni-app的多端兼容性。比如,如果用户是要在APP内生成微信支付二维码,可能需要使用Native支付方式,这需要商户号开通相关权限,并且后端生成支付二维码的参数,前端拿到参数后生成二维码图片。或者,如果是微信小程序环境,可能无法直接生成外部支付二维码,因为小程序的支付通常是JSAPI支付,需要用户在微信内完成。 另外,用户可能对微信支付的流程不太熟悉,需要简要说明整个流程:商户系统调用微信支付统一下单接口生成支付交易单,获取到支付链接(code_url),然后根据这个链接生成二维码。前端可能需要将这个code_url转换成二维码图片显示出来。 需要注意的是,生成二维码本身可以使用前端的库,比如qrcode.js,或者在uni-app中使用插件如uqrcode。但关键点在于如何获取code_url,这部分需要后端与微信API交互,前端不应处理敏感信息如商户密钥等。 可能用户遇到的难点在于如何将uni-app与微信支付接口对接,特别是生成二维码的步骤。需要分步骤说明:后端生成支付参数,前端获取后生成二维码,用户扫码后支付,前端轮询支付状态。 还要提醒用户注意安全,确保支付参数如appid、mch_id、key等保存在后端,不要暴露在前端代码中。同时,处理支付结果通知时,微信会通过回调接口通知后端,需要正确配置并验证签名。 总结回答的结构应该是:先介绍基本流程,分前后端步骤,然后给出示例代码片段,说明如何调用统一下单接口,生成二维码,最后处理支付结果。同时,指出不同端的注意事项,比如APP、H5、小程序的差异,以及安全方面的建议。</think>在 UniApp 中实现微信支付二维码生成,主要分为以下几个步骤(以 Native 支付为例): 1. **支付流程概述** - 用户发起支付请求 - 服务端调用微信支付统一下单接口 - 获取支付二维码链接(code_url) - 前端生成二维码并展示 - 用户扫码完成支付 2. **核心代码示例** ```javascript // 前端调用支付接口 async function createPayment(orderNo) { const res = await uni.request({ url: '/api/createWxPay', method: 'POST', data: { orderNo } }); if(res.data.code === 200) { const codeUrl = res.data.data.code_url; // 生成二维码 this.qrcode = await this.generateQRCode(codeUrl); } } // 生成二维码(使用uqrcode组件示例) generateQRCode(text) { return new Promise((resolve) => { const qr = uqrcode.create({ size: 200, text: text, foreground: '#000000' }); resolve(qr); }); } ``` 3. **注意事项** - **安全规范**:所有涉及微信支付密钥的操作必须在服务端完成 - **二维码有效期**:微信支付二维码默认有效期为2小时 - **支付结果通知**:需配置微信支付回调接口处理支付结果 - **多端适配**: * APP端需要配置微信开放平台应用 * H5支付需要特殊域名备案 * 小程序使用自有支付体系 4. **常见问题** - Q:为什么生成二维码无法支付? A:检查商户号是否开通Native支付权限,订单金额是否符合最低要求(≥1元) - Q:如何测试支付功能? A:可使用微信沙箱环境,或使用真实支付但设置小金额(如0.01元) 实际开发中需要: 1. 在微信商户平台配置支付目录 2. 服务端实现签名算法(示例伪代码): ```python # Python签名示例 def create_sign(params, key): sorted_params = sorted(params.items()) sign_str = '&'.join([f"{k}={v}" for k,v in sorted_params]) sign_str += '&key=' + key return hashlib.md5(sign_str.encode()).hexdigest().upper() ``` 建议开发时: 1. 使用官方提供的SDK简化开发 2. 添加支付状态轮询机制 3. 做好支付异常处理(超时、取消支付等场景) 4. 遵循PCI DSS安全标准处理支付数据 不同场景的二维码生成方式可能有所不同,实际开发请以微信支付最新文档为准。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值