微信二维码支付快速入门

目录

一、二维码生成插件qrious

二、HttpClient

三.微信扫码支付

1.申请步骤

2.开发文档

四、入门Demo

1.工程搭建

2.myStudy-pay-interface

3.myStudy--pay-service

(1)引入pom依赖

(2)创建配置文件

(3)导入上文提到的HttpClient工具类

(4)创建WeixinPayService的实现类

4.myStudy--pay-web

(1)引入pom依赖

(2)创建配置文件

(3)创建返回结果集对象

(4)创建Controller层对象

(5)编写前端

(6)具体流程


一、二维码生成插件qrious

​ qrious是一款基于HTML5 Canvas的纯JS二维码生成插件。通过qrious.js可以快速生成各种二维码,你可以控制二维码的尺寸颜色,还可以将生成的二维码进行Base64编码。

qrious.js二维码插件的可用配置参数如下:

参数类型默认值描述
backgroundString"white"二维码的背景颜色。
foregroundString"black"二维码的前景颜色。
levelString"L"二维码的误差校正级别(L, M, Q, H)。
mimeString"image/png"二维码输出为图片时的MIME类型。
sizeNumber100二维码的尺寸,单位像素。
valueString""需要编码为二维码的值

二维码容错级别介绍

  • 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.申请步骤

https://pay.weixin.qq.com

2.开发文档

在线微信支付开发文档:

https://pay.weixin.qq.com/wiki/doc/api/index.html

  1. appid:微信公众账号或开放平台APP的唯一标识

  1. mch_id:商户号 (配置文件中的partner)

  1. partnerkey:商户密钥

  1. 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分钟二维码会重新生成一个,若关闭了页面没有支付,前端也就不会访问支付订单的交易详情了

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值