一、微信扫码支付流程
1、微信支付开发文档:微信支付开发文档
2、微信扫码支付业务流程
3、个人理解的支付流程
①用户在商户平台下单
②商户生成商户订单,并调起微信统一下单接口
③微信生成预支付订单,返回预支付的交易连接(code_url),我们根据code_url 生成二维码,提供给消费者扫码。值得注意的是:微信对于同一商户订单号且同一价格的商品可以生成多个预付单,我们可以设置预付单的有效时间(time_expire),预付单过期后,刷新二维码支付页面便会生成一个预付单,此时会发现二维码变了,即返回的预支付的交易连接(code_url)变了。
④用户扫描二维码,跳出支付页面
⑤用户确认支付,输入密码,支付成功
⑥交易成功后,微信返回支付成功页面。
前台界面编写
文档结构
支付页面:wxpay.html
qruous.js下载:
二维码生成工具及vue工具类-Node.js文档类资源-CSDN下载
请使用微信扫一扫
扫描二维码支付
支付成功!#buy { float: none; } .erweima { width: 0px; height: 500px; background-color: gray; opacity: 0.98; position: absolute; left: 50%; top: 50%; transform: translate(-50%, -50%); z-index: 99; visibility: hidden; opacity: 0; transition: 0.45s all; } .hr { height: 30px; background-color: #333; color: #fff; } .tc::after { content: "X"; position: absolute; right: 0px; padding: 5px 8px; font-size: 15px; transition: 0.4s all; } .tc:hover::after { background-color: #f00; } #qrious { width: 250px; height: 250px; position: absolute; left: 50%; top: 50%; transform: translate(-50%, -50%); background-image: url(./images/jiaz.gif); background-position: center; } .saosao { position: absolute; left: 50%; top: 85%; transform: translate(-50%, -50%); text-align: center; color: #fff; } .saosao p { margin-top: 10px; } #zfcg { width: 250px; height: 250px; color: #0cdd0c; background-color: black; position: absolute; left: 50%; top: 50%; transform: translate(-50%, -50%); text-align: center; line-height: 250px; font-size: 28px; opacity: 0.85; font-weight: 600; display: none; } .bottom { height: 100px; width: 100%; float: left; }
说明:上面静态代码已将订单编号写死,应根据实际业务动态填写相应订单编号;设置10秒自动跳转,无法判断是否已支付。
成功后跳转页面:
支付成功跳转页面
后台代码:
引入依赖:
org.springframework.boot spring-boot-starterorg.springframework.boot spring-boot-starter-weborg.projectlombok lombokcom.github.wxpay wxpay-sdk0.0.3 org.apache.httpcomponents httpclient
vo类:
支付定义实体
package com.weiah.wxpay.vo;
import lombok.Data;
@Data
public class PayVo {
private String orderId;//订单编号
private String fee; //金额
private Integer expirTime; //失效时间
}
定义返回结果:
package com.weiah.wxpay.vo;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.experimental.Accessors;
import java.io.Serializable;
@Data
@Accessors(chain = true)
@NoArgsConstructor
@AllArgsConstructor
public class BusiResult implements Serializable {
private Integer status; //200成功 201失败
private String msg; //提示信息
private Object data; //服务器返回值数据
public static BusiResult fail(){
return new BusiResult(201,"业务调用失败!!",null);
}
public static BusiResult fail(int code, String msg){
return new BusiResult(code, msg, null);
}
public static BusiResult success(){
return new BusiResult(200,"业务调用成功!!",null);
}
public static BusiResult success(Object data){
return new BusiResult(200,"业务调用成功!!",data);
}
public static BusiResult success(String msg,Object data){
return new BusiResult(200,msg,data);
}
}
新建Http请求工具类:
package com.weiah.wxpay.vo;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.experimental.Accessors;
import java.io.Serializable;
@Data
@Accessors(chain = true)
@NoArgsConstructor
@AllArgsConstructor
public class BusiResult implements Serializable {
private Integer status; //200成功 201失败
private String msg; //提示信息
private Object data; //服务器返回值数据
public static BusiResult fail(){
return new BusiResult(201,"业务调用失败!!",null);
}
public static BusiResult fail(int code, String msg){
return new BusiResult(code, msg, null);
}
public static BusiResult success(){
return new BusiResult(200,"业务调用成功!!",null);
}
public static BusiResult success(Object data){
return new BusiResult(200,"业务调用成功!!",data);
}
public static BusiResult success(String msg,Object data){
return new BusiResult(200,msg,data);
}
}
定义微信支付公共工具类:
package com.weiah.wxpay.util;
import com.github.wxpay.sdk.WXPayUtil;
import org.springframework.beans.factory.annotation.Value;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.ResourceBundle;
public class WXPayPubUtil {
private static final String APP_ID = "wx8397f8696b538317";
private static final String PARTNER = "1473426802";
private static final String PARTNER_KEY = "T6m9iK73b0kn9g5v426MKfHQH7X8rKwb";
private static final String PAY_URL = "https://api.mch.weixin.qq.com/pay/unifiedorder";
private static final String QRY_URL = "https://api.mch.weixin.qq.com/pay/orderquery";
public static Map createNative(String out_trade_no, String total_fee , Integer expireTimeMin) {
Map param = new HashMap();
param.put("appid", APP_ID);
param.put("mch_id", PARTNER);
param.put("nonce_str", WXPayUtil.generateNonceStr());
param.put("body", "测试支付功能"); //定义订单内容
param.put("out_trade_no", out_trade_no); //商户订单编号
param.put("total_fee", total_fee); //总金额
param.put("spbill_create_ip", "127.0.0.1");
param.put("notify_url", "http://www.tedu.cn"); //回调地址
param.put("trade_type", "NATIVE");
Date date = new Date();
long time = date.getTime();
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyyMMddHHmmss");
String timeStart = simpleDateFormat.format(time);
String timeEnd = simpleDateFormat.format(time + expireTimeMin * 60000);
param.put("time_start", timeStart); //订单创建时间
param.put("time_expire", timeEnd); //定义失效时间
try {
String xmlParam = WXPayUtil.generateSignedXml(param, PARTNER_KEY); //参数转换
HttpUtil client = new HttpUtil(PAY_URL);
client.setHttps(true);
client.setXmlParam(xmlParam);
client.post();
String result = client.getContent();
Map resultMap = WXPayUtil.xmlToMap(result);
if (resultMap.get("err_code") != null && resultMap.get("err_code").equals("ORDERPAID")) {
System.out.println("<--"+out_trade_no+"--> :订单已经支付!");
}
Map map = new HashMap<>();
map.put("code_url", resultMap.get("code_url"));
map.put("total_fee", total_fee);
map.put("out_trade_no", out_trade_no);
return map;
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
public static Map queryPayStatus(String out_trade_no) {
Map param = new HashMap();
param.put("appid", APP_ID);
param.put("mch_id", PARTNER);
param.put("out_trade_no", out_trade_no);
param.put("nonce_str", WXPayUtil.generateNonceStr());
try {
String xmlParam = WXPayUtil.generateSignedXml(param, PARTNER_KEY);
HttpUtil client = new HttpUtil(QRY_URL);
client.setHttps(true);
client.setXmlParam(xmlParam);
client.post();
String result = client.getContent();
Map map = WXPayUtil.xmlToMap(result);
if (map.get("err_code") != null && map.get("err_code").equals("ORDERNOTEXIST")) {
System.out.println("订单不存在!");
}
if (map.get("trade_state").equals("SUCCESS")) {
//支付成功,未支付为:NOTPAY
}
return map;
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
}
controller类:
package com.weiah.wxpay.controller;
import com.weiah.wxpay.util.WXPayPubUtil;
import com.weiah.wxpay.vo.BusiResult;
import com.weiah.wxpay.vo.PayVo;
import org.springframework.web.bind.annotation.*;
import java.util.Map;
@RestController
@CrossOrigin
@RequestMapping("/order")
public class PayController {
@PostMapping("/createPay")
public BusiResult createPayOrder(@RequestBody PayVo payVo){
//向微信发起调用生成预付链接
Map res = WXPayPubUtil.createNative(payVo.getOrderId(),
payVo.getFee(),
payVo.getExpirTime());
System.out.println(res);
return BusiResult.success(res);
}
@PostMapping("/queryPayStatus")
public BusiResult queryPayStatus(@RequestBody PayVo payVo){
//向微信发起调用生成预付链接
Map res = WXPayPubUtil.queryPayStatus(payVo.getOrderId());
System.out.println(res);
return BusiResult.success(res);
}
}
以上可实现简单支付查询功能。



