qrious.js 二维码插件的可用配置参数如下:
参数 | 类型 | 默认值 | 描述 |
---|---|---|---|
background | String | “white” | 二维码的背景颜色。 |
foreground | String | “black” | 二维码的前景颜色。 |
level | String | “L” | 二维码的误差校正级别(L, M, Q, H)。 |
mime | String | “image/png” | 二维码输出为图片时的 MIME 类型。 |
size | Number | 100 | 二维码的尺寸,单位像素。 |
value | String | “” | 需要编码为二维码的值 |
下面的代码即可生成一张二维码
<html>
<head>
<title>二维码入门小 demotitle>
head>
<body>
<img id="qrious">
<script src="qrious.min.js">script>
<script>
var qr = new QRious({
element: document.getElementById('qrious'),
size: 250,
value: 'http://www.baidu.com'
});
script>
body>
html>
<dependency>
<groupId>com.github.wxpaygroupId>
<artifactId>wxpay-sdkartifactId>
<version>0.0.3version>
dependency>
// 获取随机字符串
String str = WXPayUtil.generateNonceStr()
// MAP 转换为 XML 字符串(自动添加签名)
// 参数: maps: 需要传递的参数 Map 集合, partnerkey : 商户密钥
String xmlParam = WXPayUtil.generateSignedXml(maps, partnerkey);
//XML字符串转换为 Map 对象
Map<String, String> stringStringMap = WXPayUtil.xmlToMap(xmlMap);
关于 HttpClient(原生)具体的使用不属于我们本章的学习内容,我们这里这里为了简化 HttpClient 的使用,提供了工具类 HttpClient(对原生 HttpClient 进行了封装)
// 创建客户端
HttpClient client = new HttpClient(请求的 url 地址);
//是否是 https 协议
client.setHttps(true);
//发送的 xml 数据(String类型)
client.setXmlParam(xmlParam);
//执行 post 请求
client.post();
//获取结果
String result = client.getContent();
<dependency>
<groupId>org.apache.httpcomponentsgroupId>
<artifactId>httpclientartifactId>
dependency>
<dependency>
<groupId>com.github.wxpaygroupId>
<artifactId>wxpay-sdkartifactId>
<version>0.0.3version>
dependency>
<dependency>
<groupId>org.apache.httpcomponentsgroupId>
<artifactId>httpclientartifactId>
dependency>
# appid:微信公众账号或开放平台 APP 的唯一标识
appid=wx8397f8696b5
# partner:财付通平台的商户账号 (mch_id:商户号)
partner=1473426802
# partnerkey:财付通平台的商户密钥
partnerkey=T6m9iK73b0kn9g5v426MKfHQ
# notifyurl: 回调地址, 支付成功后微信服务器向回调地址发送信息
notifyurl=http://********/WeChatPay/WeChatP
# payUrl : 远程支付接口, 用于生成支付的 url
payUrl=https://api.mch.weixin.qq.com/pay/unifiedorder
<script type="text/javascript" src="plugins/angularjs/angular.min.js"> script>
<script type="text/javascript" src="js/base.js"> script>
<script type="text/javascript" src="js/service/payService.js"> script>
<script type="text/javascript" src="plugins/qrious.min.js">script>
<script type="text/javascript" src="js/controller/payController.js"> script>
<body ng-app="pyg" ng-controller="payController" ng-init="createQrCode()">
<div class="fl code">
<img id="qrious" >
<div class="saosao">
<p>请使用微信扫一扫p>
<p>扫描二维码支付p>
div>
div>
<span class="success-info">
订单提交成功,请您及时付款!订单号:{{out_trade_no}}
span>
<span class="fr">
<em class="sui-lead">应付金额:em>
<em class="orange money">¥{{total_fee}}em>元
span>
//控制层
app.controller('payController', function ($scope, $location,payService) {
//生成二维码
//1,向支付系统发送生成二维码请求
//2,支付系统调用微信支付品台支付下单接口
//3,微信支付品台返回支付地址
//4,根据此地址生成二维码
$scope.createQrCode = function () {
//调用服务层方法,向微信支付品台下单,获取支付地址
payService.createQrCode().success(function (data) {
//获取支付地址
var code_url = data.code_url;
//支付金额
$scope.total_fee = data.total_fee;
//订单号
$scope.out_trade_no = data.out_trade_no;
//使用qrious插件生成二维码
var qr = new QRious({
element: document.getElementById('qrious'),
size: 300,
background: 'white',
foreground: 'black',
level: 'H',
value: code_url
});
//调用方法
queryStatus($scope.out_trade_no);
})
};
//实时监控二维码支付状态
//每3秒查询一次二维码支付状态,如果支付成功,跳转到支付成功页面,否则跳转到支付失败页面
queryStatus = function (out_trade_no) {
//调用服务层方法,查询订单状态
payService.queryStatus(out_trade_no).success(function (data) {
//判断
if (data.success) {
//跳转到支付成功页面
location.href = "paysuccess.html#?money="+$scope.total_fee;
} else if (data.message == "timeout") {
//重新生成二维码
$scope.createQrCode();
}
else {
location.href = "payfail.html";
}
})
};
//获取支付成功后金额
$scope.loadTotalFee = function () {
$scope.money = $location.search()["money"];
}
});
//服务层
app.service('payService', function ($http) {
//生成二维码
this.createQrCode = function () {
return $http.get('../pay/createQrCode');
};
//监控二维码支付状态
this.queryStatus = function (out_trade_no) {
return $http.get('../pay/queryStatus/'+out_trade_no);
}
});
import com.alibaba.dubbo.config.annotation.Reference;
import com.pyg.pay.service.PayService;
import com.pyg.utils.PygResult;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.servlet.http.HttpServletRequest;
import java.util.Map;
@RestController
@RequestMapping("/pay")
public class PayController {
//注入远程支付对象
@Reference(timeout = 10000000)
private PayService payService;
//生成二维码
//1,向支付系统发送生成二维码请求
//2,支付系统调用微信支付品台支付下单接口
//3,微信支付品台返回支付地址
//4,根据此地址生成二维码
/**
* 生成二维码
*
* @return
*/
@RequestMapping("createQrCode")
public Map createQrCode(HttpServletRequest request) {
//获取用户名
String userId = request.getRemoteUser();
//调用服务层方法,向微信支付品台下单
Map maps = payService.createQrCode(userId);
return maps;
}
/**
* 需求:实时监控二维码状态,及时发现二维码是否支付成功
*/
@RequestMapping("queryStatus/{out_trade_no}")
public PygResult queryStatus(@PathVariable String out_trade_no) {
PygResult result = null;
int i = 0;
while (true) {
//调用查询接口
Map map = payService.queryStatus(out_trade_no);
if (map == null) {//出错
result = new PygResult(false, "支付出错");
break;
}
if (map.get("trade_state").equals("SUCCESS")) {//如果成功
result = new PygResult(true, "支付成功");
break;
}
try {
Thread.sleep(3000);//间隔三秒
} catch (InterruptedException e) {
e.printStackTrace();
}
i++;
if (i >= 100) {
result = new PygResult(false, "timeout");
break;
}
}
return result;
}
}
import java.util.Map;
public interface PayService {
/**
* 需求:生成二维码
* @param userId
* @return Map
*/
public Map createQrCode(String userId);
/**
* 需求:查询支付二维码状态,查询是否支付成功
* @param out_trade_no
* @return
*/
public Map queryStatus(String out_trade_no);
}
import com.alibaba.dubbo.config.annotation.Service;
import com.alibaba.fastjson.JSON;
import com.github.wxpay.sdk.WXPayUtil;
import com.pyg.mapper.TbOrderMapper;
import com.pyg.pay.service.PayService;
import com.pyg.pojo.TbOrder;
import com.pyg.pojo.TbOrderExample;
import com.pyg.utils.HttpClient;
import com.pyg.utils.IdWorker;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@Service
public class PayServiceImpl implements PayService {
//注入商户appid
@Value("${appid}")
private String appid;
//注入商户号
@Value("${partner}")
private String partner;
//注入商户秘钥
@Value("${partnerkey}")
private String partnerkey;
//注入微信支付接口
@Value("${payUrl}")
private String payUrl;
// 回调地址
@Value("${notifyurl}")
private String notifyurl;
//注入订单mapper接口代理对象
@Autowired
private TbOrderMapper orderMapper;
/**
* 需求:生成二维码
*
* @param userId 用户名
* @return Map 封装的数据
* 商户订单号和保存的订单订单号有关系没有? 支付订单
*/
public Map createQrCode(String userId) {
try {
//查询支付金额
//创建订单example对象
TbOrderExample example = new TbOrderExample();
//创建criteria对象
TbOrderExample.Criteria criteria = example.createCriteria();
//设置参数
criteria.andUserIdEqualTo(userId);
//执行查询
List orderList = orderMapper.selectByExample(example);
//定义记录总金额变量
Double totalFee = 0d;
//循环多个订单,计算总金额
for (TbOrder tbOrder : orderList) {
totalFee += tbOrder.getPayment().doubleValue();
}
//创建一个map对象,封装支付下单参数
Map maps = new HashMap<>();
//公众账号ID
maps.put("appid", appid);
//商户号
maps.put("mch_id", partner);
//随机字符串
maps.put("nonce_str", WXPayUtil.generateNonceStr());
//商品描述
maps.put("body", "十里堡");
//创建idworker对象,生成支付订单号
IdWorker idWorker = new IdWorker();
long payId = idWorker.nextId();
//out_trade_no
maps.put("out_trade_no", payId + "");
//设置支付金额
maps.put("total_fee", total_fee * 100);
maps.put("spbill_create_ip", "127.0.0.1");
maps.put("notify_url", notify_url);
maps.put("trade_type", "NATIVE");
//使用微信支付工具类对象,生成一个具有签名 sign 的xml格式参数(String类型)
String xmlparam = WXPayUtil.generateSignedXml(maps, partnerkey);
//创建httpClient对象,向微信支付品台发送请求,获取支付地址
HttpClient httpClient = new HttpClient(payUrl);
//设置请求方式
httpClient.setHttps(true);
//设置请求参数
httpClient.setXmlParam(xmlparam);
//设置请求方式
httpClient.post();
//获取回调结果
String content = httpClient.getContent();
//把xml格式转换成对象
//返回支付地址
Map stringStringMap = WXPayUtil.xmlToMap(content);
//金额
stringStringMap.put("total_fee", totalFee + "");
//支付订单号
stringStringMap.put("out_trade_no", payId + "");
return stringStringMap;
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
/**
* 需求:查询支付二维码状态,查询是否支付成功
*
* @param out_trade_no 支付订单号
* @return 向微信支付品台发送请求,查询订单状态
* 1,封装向微信传递参数
* 2,把map参数转换为xml格式(此格式必须带签名)
* 3,使用httpClient发送请求(向微信支付品台)
* 4,获取微信支付返回结果
* 5,把结果返回给表现层
* 6,判断是否支付成功
*/
public Map queryStatus(String out_trade_no) {
try {
//创建map对象,封装查询微信支付状态参数
Map maps = new HashMap<>();
//商户appid 唯一标识
maps.put("appid", appid);
//商户号 唯一标识
maps.put("mch_id", partner);
//设置订单号
maps.put("out_trade_no", out_trade_no);
//随机字符串
maps.put("nonce_str", WXPayUtil.generateNonceStr());
//具有签名的xml格式参数
String xmlParam = WXPayUtil.generateSignedXml(maps, partnerkey);
//使用httpClient向微信支付品台发送查询订单请求
HttpClient httpClient = new HttpClient("https://api.mch.weixin.qq.com/pay/orderquery");
//设置请求方式
httpClient.setHttps(true);
//设置参数
httpClient.setXmlParam(xmlParam);
//请求方式
httpClient.post();
//获取查询结果
String xmlMap = httpClient.getContent();
//把返回结果xml转换成map对象
Map stringStringMap = WXPayUtil.xmlToMap(xmlMap);
//返回支付状态
return stringStringMap;
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
}
import java.io.IOException;
import java.security.GeneralSecurityException;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.text.ParseException;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLException;
import javax.net.ssl.SSLSession;
import javax.net.ssl.SSLSocket;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
import org.apache.http.Consts;
import org.apache.http.HttpEntity;
import org.apache.http.NameValuePair;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpEntityEnclosingRequestBase;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.methods.HttpPut;
import org.apache.http.client.methods.HttpUriRequest;
import org.apache.http.conn.scheme.Scheme;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.conn.ssl.SSLContextBuilder;
import org.apache.http.conn.ssl.SSLSocketFactory;
import org.apache.http.conn.ssl.TrustStrategy;
import org.apache.http.conn.ssl.X509HostnameVerifier;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;
/**
* http请求客户端
*
* @author Administrator
*
*/
public class HttpClient {
private String url;
private Map param;
private int statusCode;
private String content;
private String xmlParam;
private boolean isHttps;
public boolean isHttps() {
return isHttps;
}
public void setHttps(boolean isHttps) {
this.isHttps = isHttps;
}
public String getXmlParam() {
return xmlParam;
}
public void setXmlParam(String xmlParam) {
this.xmlParam = xmlParam;
}
public HttpClient(String url, Map param) {
this.url = url;
this.param = param;
}
public HttpClient(String url) {
this.url = url;
}
public void setParameter(Map map) {
param = map;
}
public void addParameter(String key, String value) {
if (param == null)
param = new HashMap();
param.put(key, value);
}
public void post() throws ClientProtocolException, IOException {
HttpPost http = new HttpPost(url);
setEntity(http);
execute(http);
}
public void put() throws ClientProtocolException, IOException {
HttpPut http = new HttpPut(url);
setEntity(http);
execute(http);
}
public void get() throws ClientProtocolException, IOException {
if (param != null) {
StringBuilder url = new StringBuilder(this.url);
boolean isFirst = true;
for (String key : param.keySet()) {
if (isFirst)
url.append("?");
else
url.append("&");
url.append(key).append("=").append(param.get(key));
}
this.url = url.toString();
}
HttpGet http = new HttpGet(url);
execute(http);
}
/**
* set http post,put param
*/
private void setEntity(HttpEntityEnclosingRequestBase http) {
if (param != null) {
List nvps = new LinkedList();
for (String key : param.keySet())
nvps.add(new BasicNameValuePair(key, param.get(key))); // 参数
http.setEntity(new UrlEncodedFormEntity(nvps, Consts.UTF_8)); // 设置参数
}
if (xmlParam != null) {
http.setEntity(new StringEntity(xmlParam, Consts.UTF_8));
}
}
private void execute(HttpUriRequest http) throws ClientProtocolException,
IOException {
CloseableHttpClient httpClient = null;
try {
if (isHttps) {
SSLContext sslContext = new SSLContextBuilder()
.loadTrustMaterial(null, new TrustStrategy() {
// 信任所有
public boolean isTrusted(X509Certificate[] chain,
String authType)
throws CertificateException {
return true;
}
}).build();
SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(
sslContext);
httpClient = HttpClients.custom().setSSLSocketFactory(sslsf)
.build();
} else {
httpClient = HttpClients.createDefault();
}
CloseableHttpResponse response = httpClient.execute(http);
try {
if (response != null) {
if (response.getStatusLine() != null)
statusCode = response.getStatusLine().getStatusCode();
HttpEntity entity = response.getEntity();
// 响应内容
content = EntityUtils.toString(entity, Consts.UTF_8);
}
} finally {
response.close();
}
} catch (Exception e) {
e.printStackTrace();
} finally {
httpClient.close();
}
}
public int getStatusCode() {
return statusCode;
}
public String getContent() throws ParseException, IOException {
return content;
}
}