目录
一、二维码生成插件qrious
qrious是一款基于HTML5 Canvas的纯JS二维码生成插件。通过qrious.js可以快速生成各种二维码,你可以控制二维码的尺寸颜色,还可以将生成的二维码进行Base64编码。
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 | "" | 需要编码为二维码的值 |
二维码容错级别介绍
-
L级(低) 7%的码字可以被恢复。
-
M级(中) 的码字的15%可以被恢复。
-
Q级(四分)的码字的25%可以被恢复。
-
H级(高) 的码字的30%可以被恢复。
下面的代码即可生成一个简单的二维码:
<html>
<head>
<title>二维码入门小demo</title>
</head>
<body>
<img id="qrious">
<script src="qrious.min.js"></script>
<script>
var qr = new QRious({
element:document.getElementById('qrious'),
size:250, level:'H', value:'http://www.baidu.com'
});
</script>
</body>
</html>
二、HttpClient
HttpClient是Apache Jakarta Common下的子项目,用来提供高效的、最新的、功能丰富的支持HTTP协议的客户端编程工具包,并且它支持HTTP协议最新的版本和建议。HttpClient已经应用在很多的项目中,比如Apache Jakarta上很著名的另外两个开源项目Cactus和HTMLUnit都使用了HttpClient。
HttpClient通俗的讲就是模拟了浏览器的行为,如果我们需要在后端向某一地址提交数据获取结果,就可以使用HttpClient.
我们这里这里为了简化HttpClient的使用,提供了工具类HttpClient(对原生HttpClient进行了封装)
public class HttpClient {
private String url;
private Map<String, String> 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<String, String> param) {
this.url = url;
this.param = param;
}
public HttpClient(String url) {
this.url = url;
}
public void setParameter(Map<String, String> map) {
param = map;
}
public void addParameter(String key, String value) {
if (param == null)
param = new HashMap<String, String>();
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<NameValuePair> nvps = new LinkedList<NameValuePair>();
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;
}
该工具类的使用步骤:
HttpClient client=new HttpClient(请求的url地址);
client.setHttps(true);//是否是https协议
client.setXmlParam(xmlParam);//发送的xml数据
client.post();//执行post请求
String result = client.getContent(); //获取结果
三.微信扫码支付
微信扫码支付是商户系统按微信支付协议生成支付二维码,用户再用微信“扫一扫”完成支付的模式。该模式适用于PC网站支付、实体店单品或订单支付、媒体广告支付等场景。
1.申请步骤
2.开发文档
在线微信支付开发文档:
https://pay.weixin.qq.com/wiki/doc/api/index.html
-
appid:微信公众账号或开放平台APP的唯一标识
-
mch_id:商户号 (配置文件中的partner)
-
partnerkey:商户密钥
-
sign:数字签名, 根据微信官方提供的密钥和一套算法生成的一个加密信息, 就是为了保证交易的安全性
微信支付SDK
微信支付提供了SDK, 下载后打开源码,install到本地Maven仓库即可使用。
SDK中有以下功能较为常用:
(1)获取随机字符串
WXPayUtil.generateNonceStr()
(2)Map转换为XML字符串(自动添加签名)
WXPayUtil.generateSignedXml(param, partnerkey)
(3)XML字符串转换为Map
WXPayUtil.xmlToMap(result)
注意:
-
微信二维码需要接受xml格式的数据,所以我们可以将数据封装到Map中并用SDK的方法转为xml字符串
-
在查询订单状态时,返回的也是xml格式的数据,需要将xml字符串转换为Map进行处理
四、入门Demo
1.工程搭建
这里我们将微信二维码服务搭建在dubbo服务中,并由web模块通过zookeeper进行调用
(1)建立支付服务接口模块myStudy-pay-interface (jar)
(2)建立支付服务实现模块myStudy--pay-service (war)
(3)建立支付调用模块myStudy--pay-web (war)
2.myStudy-pay-interface
WeiXinPayService.java
/**
* 微信支付接口
*
* @author Administrator
*/
public interface WeixinPayService {
/**
* 生成微信支付二维码
*
* @param out_trade_no 订单号
* @param total_fee 金额(分)
* @return
*/
public Map createNative(String out_trade_no, String total_fee);
/**
* 查询支付状态
* @param out_trade_no
*/
public Map queryPayStatus(String out_trade_no);
}
3.myStudy--pay-service
(1)引入pom依赖
<!-- 集中定义依赖版本号 -->
<properties>
<junit.version>4.12</junit.version>
<spring.version>4.2.4.RELEASE</spring.version>
<servlet-api.version>2.5</servlet-api.version>
<dubbo.version>2.8.4</dubbo.version>
<zookeeper.version>3.4.7</zookeeper.version>
<zkclient.version>0.1</zkclient.version>
</properties>
<dependencies>
<!-- 微信SDK -->
<dependency>
<groupId>com.github.wxpay</groupId>
<artifactId>wxpay-sdk</artifactId>
<version>0.0.3</version>
</dependency>
<!-- httpclient -->
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.5.3</version>
</dependency>
<dependency>
<groupId>com.yfy</groupId>
<artifactId>myStudy-pay-interface</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<!-- Spring -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aspects</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jms</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context-support</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>${spring.version}</version>
</dependency>
<!-- dubbo相关 -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>dubbo</artifactId>
<version>${dubbo.version}</version>
</dependency>
<dependency>
<groupId>org.apache.zookeeper</groupId>
<artifactId>zookeeper</artifactId>
<version>${zookeeper.version}</version>
</dependency>
<dependency>
<groupId>com.github.sgroschupf</groupId>
<artifactId>zkclient</artifactId>
<version>${zkclient.version}</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>${junit.version}</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
<scope>provided</scope>
<version>${servlet-api.version}</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.28</version>
</dependency>
<dependency>
<groupId>javassist</groupId>
<artifactId>javassist</artifactId>
<version>3.11.0.GA</version>
</dependency>
<dependency>
<groupId>commons-codec</groupId>
<artifactId>commons-codec</artifactId>
<version>1.10</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.tomcat.maven</groupId>
<artifactId>tomcat7-maven-plugin</artifactId>
<version>2.2</version>
<configuration>
<!-- 指定端口 -->
<port>9000</port>
<!-- 请求路径 -->
<path>/</path>
</configuration>
</plugin>
</plugins>
</build>
(2)创建配置文件
applicationContext-service.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:dubbo="http://code.alibabatech.com/schema/dubbo" xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd
http://code.alibabatech.com/schema/dubbo http://code.alibabatech.com/schema/dubbo/dubbo.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
<context:property-placeholder location="classpath*:config/weixinpay.properties" />
<dubbo:protocol name="dubbo" port="20880"></dubbo:protocol>
<dubbo:application name="myStudy-pay-service"/>
<dubbo:registry address="zookeeper://192.168.25.132:2181"/>
<dubbo:annotation package="com.yfy.service.impl"/>
<dubbo:provider timeout="50000"></dubbo:provider>
</beans>
web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://java.sun.com/xml/ns/javaee"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
version="2.5">
<!-- 加载spring容器 -->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath*:spring/applicationContext*.xml</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
</web-app>
wexinpay.properties
#appid: 微信公众账号或开放平台APP的唯一标识
#partner:财付通平台的商户账号
#partnerkey:财付通平台的商户密钥
appid=wx8397f8696b538317
partner=1473426802
partnerkey=T6m9iK73b0kn9g5v426MKfHQH7X8rKwb
(3)导入上文提到的HttpClient工具类
此处代码略
(4)创建WeixinPayService的实现类
package com.yfy.service.impl;
import com.alibaba.dubbo.config.annotation.Service;
import com.github.wxpay.sdk.WXPayUtil;
import com.yfy.service.WeixinPayService;
import com.yfy.util.HttpClient;
import org.springframework.beans.factory.annotation.Value;
import java.util.HashMap;
import java.util.Map;
@Service
public class WeixinPayServiceImpl implements WeixinPayService {
@Value("${appid}")
private String appid;
@Value("${partner}")
private String partner;
@Value("${partnerkey}")
private String partnerkey;
/**
* 生成二维码
*
* @return
*/
public Map createNative(String out_trade_no, String total_fee) {
//1.创建参数
Map<String, String> param = new HashMap();//创建参数
param.put("appid", appid);//公众号
param.put("mch_id", partner);//商户号
param.put("nonce_str", WXPayUtil.generateNonceStr());//随机字符串
param.put("body", "QQ会员充值");//商品描述
param.put("out_trade_no", out_trade_no);//商户订单号
param.put("total_fee", total_fee);//总金额(分)
param.put("spbill_create_ip", "127.0.0.1");//IP
param.put("notify_url", "http://www.baidu.com");//回调地址(随便写)
param.put("trade_type", "NATIVE");//交易类型
try {
//2.生成要发送的xml
String xmlParam = WXPayUtil.generateSignedXml(param, partnerkey);
System.out.println(xmlParam);
HttpClient client = new HttpClient("https://api.mch.weixin.qq.com/pay/unifiedorder");
client.setHttps(true);
client.setXmlParam(xmlParam);
client.post();
//3.获得结果,此处我们只需要其中的几个参数,自定义一个Map接收
String result = client.getContent();
Map<String, String> resultMap = WXPayUtil.xmlToMap(result);
Map<String, String> 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 new HashMap<>();
}
}
/**
* 查询状态
* @param out_trade_no
* @return
*/
@Override
public Map queryPayStatus(String out_trade_no) {
Map param = new HashMap();
param.put("appid", appid);//公众账号ID
param.put("mch_id", partner);//商户号
param.put("out_trade_no", out_trade_no);//订单号
param.put("nonce_str", WXPayUtil.generateNonceStr());//随机字符串
String url = "https://api.mch.weixin.qq.com/pay/orderquery";
try {
String xmlParam = WXPayUtil.generateSignedXml(param, partnerkey);
HttpClient client = new HttpClient(url);
client.setHttps(true);
client.setXmlParam(xmlParam);
client.post();
String result = client.getContent();
Map<String, String> map = WXPayUtil.xmlToMap(result);
System.out.println(map);
return map;
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
}
4.myStudy--pay-web
(1)引入pom依赖
<dependencies>
<dependency>
<groupId>com.yfy</groupId>
<artifactId>myStudy-pay-interface</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<!-- Spring -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>4.2.4.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
<version>4.2.4.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>4.2.4.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>4.2.4.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context-support</artifactId>
<version>4.2.4.RELEASE</version>
</dependency>
<!-- dubbo相关 -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>dubbo</artifactId>
<version>2.8.4</version>
</dependency>
<dependency>
<groupId>org.apache.zookeeper</groupId>
<artifactId>zookeeper</artifactId>
<version>3.4.7</version>
</dependency>
<dependency>
<groupId>com.github.sgroschupf</groupId>
<artifactId>zkclient</artifactId>
<version>0.1</version>
</dependency>
<!-- fastjson -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.28</version>
</dependency>
<dependency>
<groupId>javassist</groupId>
<artifactId>javassist</artifactId>
<version>3.11.0.GA</version>
</dependency>
<dependency>
<groupId>commons-codec</groupId>
<artifactId>commons-codec</artifactId>
<version>1.10</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
<version>2.5</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.tomcat.maven</groupId>
<artifactId>tomcat7-maven-plugin</artifactId>
<version>2.2</version>
<configuration>
<!-- 指定端口 -->
<port>9100</port>
<!-- 请求路径 -->
<path>/</path>
</configuration>
</plugin>
</plugins>
</build>
(2)创建配置文件
springmvc.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:dubbo="http://code.alibabatech.com/schema/dubbo" xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd
http://code.alibabatech.com/schema/dubbo http://code.alibabatech.com/schema/dubbo/dubbo.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
<mvc:annotation-driven>
<mvc:message-converters register-defaults="true">
<bean class="com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter">
<property name="supportedMediaTypes" value="application/json"/>
<property name="features">
<array>
<value>WriteMapNullValue</value>
<value>WriteDateUseDateFormat</value>
</array>
</property>
</bean>
</mvc:message-converters>
</mvc:annotation-driven>
<!-- 引用dubbo 服务 -->
<dubbo:application name="myStudy-pay-web" />
<dubbo:registry address="zookeeper://192.168.25.132:2181"/>
<dubbo:annotation package="com.yfy.controller" />
</beans>
web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://java.sun.com/xml/ns/javaee"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
version="2.5">
<!-- 解决post乱码 -->
<filter>
<filter-name>CharacterEncodingFilter</filter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>utf-8</param-value>
</init-param>
<init-param>
<param-name>forceEncoding</param-name>
<param-value>true</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>CharacterEncodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<servlet>
<servlet-name>springmvc</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<!-- 指定加载的配置文件 ,通过参数contextConfigLocation加载-->
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:spring/springmvc.xml</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>springmvc</servlet-name>
<url-pattern>*.do</url-pattern>
</servlet-mapping>
</web-app>
(3)创建返回结果集对象
Result.java
public class Result implements Serializable{
private boolean success;
private String message;
//...get()、set()方法
}
(4)创建Controller层对象
PayController.java
/**
* 支付控制层
*
* @author Administrator
*/
@RestController
@RequestMapping("/pay")
public class PayController {
@Reference
private WeixinPayService weixinPayService;
/**
* 生成二维码
*
* @return
*/
@RequestMapping("/createNative")
public Map createNative() {
//这里我们订单号通过uuid生成,金额为1分
UUID uuid = UUID.randomUUID();
System.out.println(uuid);
return weixinPayService.createNative(uuid.toString().substring(0, 18), "1");
}
/**
* 查询支付状态
*
* @param out_trade_no
* @return
*/
@RequestMapping("/queryPayStatus")
public Result queryPayStatus(String out_trade_no) {
Result result = null;
int x = 0;
while (true) {
//调用查询接口
Map<String, String> map = weixinPayService.queryPayStatus(out_trade_no);
if (map == null) {//出错
result = new Result(false, "支付出错");
break;
}
if (map.get("trade_state").equals("SUCCESS")) {//如果成功
result = new Result(true, "支付成功");
break;
}
try {
Thread.sleep(3000);//间隔三秒
} catch (InterruptedException e) {
e.printStackTrace();
}
//为了不让循环无休止地运行,我们定义一个循环变量
//如果这个变量超过了这个值则退出循环,设置时间为5分钟
x++;
if (x >= 100) {
result = new Result(false, "二维码超时");
break;
}
}
return result;
}
}
(5)编写前端
这里我们使用angularjs+qrious插件,先导入这两个插件
1)分层创建angularjs
base.js
var app = angular.module("myApp", []);
payService.js
app.service("payService", function ($http) {
//生成支付的二维码
this.createNative=function () {
return $http.get('pay/createNative.do');
}
//查询验证码的支付状态
this.queryPayStatus = function (out_trade_no) {
return $http.get('pay/queryPayStatus.do?out_trade_no=' + out_trade_no);
}
})
payController.js
app.controller('payController', function ($scope, payService,$location) {
//本地生成二维码
$scope.createNative = function () {
payService.createNative().success(
function (response) {
$scope.money = (response.total_fee / 100).toFixed(2); //金额
$scope.out_trade_no = response.out_trade_no;//订单号
//二维码
var qr = new QRious({
element: document.getElementById('qrious'),
size: 250,
level: 'H',
value: response.code_url
});
//查询订单状态
queryPayStatus(response.out_trade_no);
}
);
}
//查询支付状态
queryPayStatus=function(out_trade_no){
payService.queryPayStatus(out_trade_no).success(
function(response){
if(response.success){
location.href="paySuccess.html#?money="+$scope.money;
}else{
if(response.message=='二维码超时'){
$scope.createNative();//重新生成二维码
}else{
location.href="payFail.html";
}
}
}
);
}
//获取金额
$scope.getMoney=function(){
return $location.search()['money'];
}
});
2)展示页面
pay.html
<script src="js/angular.js"></script>
<script src="js/base.js"></script>
<script src="js/service/payService.js"></script>
<script src="js/controller/payController.js"></script>
<script src="plugins/qrious.min.js"></script>
<body ng-app="myApp" ng-controller="payController">
<input type="button" value="提交订单" ng-click="createNative()"><br/>
<!-- 二维码图片 -->
<img id="qrious"><br/>
订单号:{{out_trade_no}} <br/>
<em class="orange money">¥{{money}}</em>元
</body>
paySuccess.html
<script src="js/angular.js"></script>
<script src="js/base.js"></script>
<script src="js/service/payService.js"></script>
<script src="js/controller/payController.js"></script>
<body ng-app="myApp" ng-controller="payController">
<h3>支付成功</h3>
<p>支付金额:¥{{getMoney()}}元</p>
</body>
(6)具体流程
1)访问 http://localhost:9100/pay.html
2)点击提交订单 生成二维码
3)扫描二维码支付,页面跳转至 http://localhost:9100/paySuccess.html#?money=0.01(代码中将支付金额设置为了1分钱)
注意:如果一直没有扫描二维码且没有跳转页面,每隔5分钟二维码会重新生成一个,若关闭了页面没有支付,前端也就不会访问支付订单的交易详情了