700字范文,内容丰富有趣,生活中的好帮手!
700字范文 > Java-SSM+AngularJS-1实现微信扫码支付功能

Java-SSM+AngularJS-1实现微信扫码支付功能

时间:2023-03-13 14:56:20

相关推荐

Java-SSM+AngularJS-1实现微信扫码支付功能

微信扫码支付是商户系统按微信支付协议生成支付二维码,用户再用微信“扫一扫”完成支付的模式。该模式适用于PC网站支付、实体店单品或订单支付、媒体广告支付等场景

文章目录

1. 微信支付开发文档整体思路2. 环境准备3. 接口编写-Maven-SSM

1. 微信支付开发文档整体思路

微信支付接口调用的整体思路:

按API要求组装参数,以XML方式发送(POST)给微信支付接口(URL),微信支付接口也是以XML方式给予响应。程序根据返回的结果(其中包括支付URL)生成二维码或判断订单状态

在线微信支付开发文档:https://pay./wiki/doc/api/index.html

本Demo涉及到 统一下单和查询订单两组API,流程介绍看上面链接扫码支付,会有介绍

appid:微信公众账号或开放平台APP的唯一标识mch_id:商户号 (配置文件中的partner)partnerkey:商户密钥sign:数字签名, 根据微信官方提供的密钥和一套算法生成的一个加密信息, 就是为了保证交易的安全性

2. 环境准备

引入微信支付的Maven坐标

<dependency><groupId>com.github.wxpay</groupId><artifactId>wxpay-sdk</artifactId><version>0.0.3</version></dependency>

使用HttpClient模拟浏览器发送请求,这里提供工具类

package utils;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.entity.UrlEncodedFormEntity;import org.apache.http.client.methods.*;import org.apache.http.conn.ssl.SSLConnectionSocketFactory;import org.apache.http.conn.ssl.SSLContextBuilder;import org.apache.http.conn.ssl.TrustStrategy;import org.apache.http.entity.StringEntity;import org.apache.http.impl.client.CloseableHttpClient;import org.apache.http.impl.client.HttpClients;import org.apache.http.message.BasicNameValuePair;import org.apache.http.util.EntityUtils;import .ssl.SSLContext;import java.io.IOException;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;/*** http请求客户端* * @author Administrator* */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("?");elseurl.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;}}

我们主要会用到微信支付SDK的以下功能:

获取随机字符串 : WXPayUtil.generateNonceStr()MAP转换为XML字符串(自动添加签名): WXPayUtil.generateSignedXml(param, partnerkey)XML字符串转换为MAP: WXPayUtil.xmlToMap(result)

3. 接口编写-Maven-SSM

WxPayService 接口定义

package com.pyg.pay.service;import java.util.Map;/*** @ Description* @ auther宁宁小可爱* @ create-02-10 14:53*/public interface WxPayService {/** 需求 : 向微信平台下单,申请获取支付功能,返回URL支付地址 ,生成二维码* 参数: 订单号 支付金额* 返回值: Map* */public Map creatQrCode(String order_no,String total_fee);/** 需求: 根据订单号查询支付状态* 参数: String order_no* 返回值: map* */public Map queryOrderPayStatus(String orderNo);}

WxPayServiceImpl实现类代码

package com.pyg.pay.service.impl;import com.alibaba.dubbo.config.annotation.Service;import com.github.wxpay.sdk.WXPayUtil;import com.pyg.pay.service.WxPayService;import org.springframework.beans.factory.annotation.Value;import utils.HttpClient;import java.util.HashMap;import java.util.Map;/*** @ Description* @ auther宁宁小可爱* @ create-02-10 15:13*/@Servicepublic class WxPayServiceImpl implements WxPayService {/** 需求 : 向微信平台下单,申请获取支付功能,返回URL支付地址 ,生成二维码* 参数: 订单号 支付金额* 返回值: Map* 支付凭证;: 统一放入properties中* appid: 唯一标识* mch_id: 商户号* parterner: 支付秘钥* sign: 签名* 统一下单接口地址 https://api.mch./pay/unifiedorder* *//** 支付流程:* 1. 创建httpClient对象,向微信支付平台发送请求* 2. 准备传递的参数* 3. 获取返回值* 4. 返回支付地址* */// 注入唯一标识@Value("${appid}")private String appid;// 注入商户号@Value("${partner}")private String partner;// 注入秘钥@Value("${partnerkey}")private String partnerkey;// 注入统一下单地址@Value("${payUrl}")private String payUrl;@Overridepublic Map creatQrCode(String order_no, String total_fee) {try {// 创建MAP对象 封装参数Map paramMap = new HashMap();// appidparamMap.put("appid",appid);// 商户号paramMap.put("mch_id",partner);// 随机字符串 这是微信sdk提供的工具类paramMap.put("nonce_str", WXPayUtil.generateNonceStr());// 支付描述paramMap.put("body","微信扫码支付");// 商户订单号paramMap.put("out_trade_no",order_no);// 支付金额paramMap.put("total_fee",total_fee);// 终端IPparamMap.put("spbill_create_ip","127.0.0.1");// 设置通知地址paramMap.put("notify_url","");// 交易类型paramMap.put("trade_type","NATIVE ");// 生成具有签名的XML格式参数String xmlParam = WXPayUtil.generateSignedXml(paramMap, partnerkey);// 创建httpclient对象 ,向微信支付平台发送下单请求HttpClient httpClient = new HttpClient(payUrl);// 设置请求方式 httpshttpClient.setHttps(true);// 设置请求参数httpClient.setXmlParam(xmlParam);// 设置请求方式 posthttpClient.post();// 获取请求结果 返回XML格式String result = httpClient.getContent();// 返回支付地址 我们需要结果中的code_url 把返回值的xml转换Map 用sdk的utilsMap<String, String> resultMap = WXPayUtil.xmlToMap(result);// 返回支付页面需要的数据 支付地址 支付金额 订单号 前台页面需要显示resultMap.put("order_no",order_no);resultMap.put("total_fee",total_fee);return resultMap;} catch (Exception e) {e.printStackTrace();}return null;}/** 需求: 根据订单号查询支付状态* 参数: String order_no* 返回值: map** 业务步骤:* 1. 组装要传递的参数* 2. 使用HttpClient调用微信平台提供的查询接口* 3. 获取返回值* 4. 返回支付状态* */// 注入查询地址@Value("${queryUrl}")private String queryUrl;@Overridepublic Map queryOrderPayStatus(String orderNo) {try {// 创建MAP对象 封装参数Map paramMap = new HashMap();// appidparamMap.put("appid",appid);// 商户号paramMap.put("mch_id",partner);// 随机字符串 这是微信sdk提供的工具类paramMap.put("nonce_str", WXPayUtil.generateNonceStr());// 商户订单号paramMap.put("out_trade_no",orderNo);// 生成具有签名的XML参数String xmlParam = WXPayUtil.generateSignedXml(paramMap, partnerkey);// 创建httpclient对象 ,向微信支付平台发送下单请求HttpClient httpClient = new HttpClient(queryUrl);// 设置请求方式 httpshttpClient.setHttps(true);// 设置请求参数httpClient.setXmlParam(xmlParam);// 设置请求方式 posthttpClient.post();// 获取请求结果 返回XML格式String result = httpClient.getContent();// 返回支付地址 我们需要结果中的code_url 把返回值的xml转换Map 用sdk的utilsMap<String, String> resultMap = WXPayUtil.xmlToMap(result);return resultMap;} catch (Exception e) {e.printStackTrace();}return null;}}

properties配置文件

appid=你的唯一标识partner=商户号partnerkey=秘钥notifyurl=http://a31ef7db.ngrok.io/WeChatPay/WeChatPayNotify# 统一下单接口地址payUrl=https://api.mch./pay/unifiedorder# 查询接口queryUrl=https://api.mch./pay/orderquery

controller层代码 ,我这里用了dubbo所以用refrence远程注入了

package com.pyg.pay.controller;import com.alibaba.dubbo.config.annotation.Reference;import com.pyg.order.service.OrderService;import com.pyg.pay.service.WxPayService;import com.pyg.pojo.TbOrder;import entity.Result;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.bind.annotation.RestController;import utils.IdWorker;import javax.servlet.http.HttpServletRequest;import java.util.List;import java.util.Map;/*** @ Description* @ auther宁宁小可爱* @ create-02-10 15:46*/@RestController@RequestMapping("/wxpay")public class WxPayController {/** 需求 : 向微信平台下单,申请获取支付功能,返回URL支付地址 ,生成二维码* 参数: 订单号 支付金额* 返回值: Map* 支付凭证;: 统一放入properties中* appid: 唯一标识* mch_id: 商户号* parterner: 支付秘钥* sign: 签名* 统一下单接口地址 https://api.mch./pay/unifiedorder* */@Referenceprivate WxPayService wxPayService;// 注入订单服务@Referenceprivate OrderService orderService;@RequestMapping("creatQrCode")public Map creatQrCode(HttpServletRequest request){String userId = request.getRemoteUser();// 根据用户名查询订单, 一个用户多个订单List<TbOrder> orderList = orderService.findOrderByUserId(userId);// 调用服务层 统一下单 生成支付号IdWorker idWorker = new IdWorker();double totalFee = 0;// 计算总金额for (TbOrder tbOrder : orderList) {totalFee += tbOrder.getPayment().doubleValue();}// 由于是测试 支付金额就设置一分钱Map map = wxPayService.creatQrCode(idWorker.nextId() + "", "1");return map;}/** 需求: 根据订单号查询支付状态* 参数: String order_no* 返回值: map* 请求; /queryOrderPayStatus*/@RequestMapping("queryOrderPayStatus")public Result queryOrderPayStatus(String orderNo){try {int count = 0;// 循环检测二维码的支付状态 每隔三秒检测一次while (true){Map map = wxPayService.queryOrderPayStatus(orderNo);if (map == null){return new Result(false,"支付失败");}if (map.get("trade_state").equals("SUCCESS")){return new Result(true,"支付成功");}// 每隔三秒循环一次Thread.sleep(3000);// 超过五分钟未支付 支付超时count++;if (count >100 ){return new Result(false,"支付超时");}}} catch (Exception e) {e.printStackTrace();return new Result(false,"支付失败");}}}

AngularJs1 controller代码

//控制层app.controller('payController', function ($scope, $controller, payService) {//搜索$scope.createNative = function () {payService.creatQrCode().success(function (response) {if (response.result_code == 'SUCCESS'){// 支付订单号$scope.out_trade_no = response.order_no;// 支付金额$scope.totolFee = response.total_fee;// 成功后生成二维码new QRious({element:document.getElementById('qrious'),size:200,background:'white',foreground:'black',level:'H',value:response.code_url});// 调用查询二维码支付状态this.queryOrderPayStatus($scope.out_trade_no);}});}// 定义查询二维码状态方法queryOrderPayStatus = function (out_trade_no) {// 调用服务层代码payService.queryOrderPayStatus(out_trade_no).success(function (response) {if (response.success){location.href = "paysuccess.html"}else {location.href = "payfail.html"}})}});

AngularJs1 service代码

//服务层app.service('payService', function ($http) {//搜索this.creatQrCode = function () {return $http.get('../wxpay/creatQrCode');}this.queryOrderPayStatus = function (out_trade_no) {return $http.get("../wxpay/queryOrderPayStatus?orderNo="+out_trade_no);}});

结果展示

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。