扫码支付java版完整demo
扫码⽀付java版完整demo ⽰例说明:
⽀付接⼝官⽅⽂档地址:pay.weixin.qq/wiki/doc/api/native.php?chapter=6_5
本 demo 使⽤的⽀付⽅式为: 模式⼆
⽂章最下⽅有可以直接运⾏的demo的百度云下载地址
项⽬结构:
项⽬代码:
pom⽂件
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="/POM/4.0.0" xmlns:xsi="/2001/XMLSchema-instance"
xsi:schemaLocation="/POM/4.0.0 /xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.zhangye</groupId>
<artifactId>wxpay</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>wxpay</name>
<packaging>jar</packaging>
<description>Demo project for Spring Boot</description>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.0.3.RELEASE</version>
<relativePath/><!-- lookup parent from repository -->
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
&porting.outputEncoding>UTF-8</porting.outputEncoding>
<java.version>1.8</java.version>
<commons-lang3.version>3.7</commons-lang3.version>
<commons-collections.version>3.2.2</commons-collections.version>
&le.zxing.version>3.3.3</ing.version>
<fastjson.version>1.2.46</fastjson.version>
</properties>
<dependencies>
<!-- mvc⽀持-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<!-- 热部署模块 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<!-- Commons utils begin -->
<dependency>
<groupId>org.apachemons</groupId>
<artifactId>commons-lang3</artifactId>
<version>${commons-lang3.version}</version>
</dependency>
<dependency>
<groupId>commons-collections</groupId>
<artifactId>commons-collections</artifactId>
<version>${commons-collections.version}</version>
</dependency>
<!-- Commons utils end -->
<!-- google ⽣成⼆维码 begin-->
<dependency>
<groupId&le.zxing</groupId>
<artifactId>javase</artifactId>
<version>${ing.version}</version>
</dependency>
<!-- google ⽣成⼆维码 end-->
<!-- JSONObject JSONArray begin -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>${fastjson.version}</version>
</dependency>
<!-- JSONObject JSONArray end -->
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<fork>true</fork>
</configuration>
</plugin>
</plugins>
</build>
</project>
controller--WxPayController
package com.ller;
import com.alibaba.fastjson.JSONObject;
import com.dulesmon.wx.WxConfig; import com.dulesmon.wx.WxConstants; import com.dulesmon.wx.WxUtil; import com.del.Order;
import com.dules.service.WxMenuService; import org.apachemons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.
bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.ResponseBody; import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
SimpleDateFormat;
import java.util.Date;
import java.util.Map;
/**
* @author zhangye
* @version 1.0
* @description 扫码⽀付接⼝
* @date 2019/12/19
* <p>
* ⽀付接⼝官⽅⽂档地址:pay.weixin.qq/wiki/doc/api/native.php?chapter=6_5
* 本 demo 使⽤的⽀付⽅式为: 模式⼆
* <p>
* 扫码⽀付流程说明:
* 1.需要商户⽣成订单
* 2.商户调⽤统⼀下单接⼝获取⼆维码链接 code_url (请求参数请见官⽅⽂档)
* 请求参数中的 notify_url 为⽤户⽀付成功后, 服务端回调商户的接⼝地址
* 3.商户根据 code_url ⽣成⼆维码
* 4.⽤户使⽤扫码进⾏⽀付
* 5.⽀付成功后, 服务端会调⽤ notify_url 通知商户⽀付结果
* 6.商户接到通知后, 执⾏业务操作(修改订单状态等)并告知服务端接收通知成功
* <p>
* 查询⽀付订单、关闭⽀付订单流程较为简单,请⾃⾏查阅官⽅⽂档
*/
@Controller
public class WxPayController {
@Autowired
private WxMenuService wxMenuService;
/**
* ⼆维码⾸页测试⽤
*/
@RequestMapping(value = {"/"}, method = RequestMethod.GET)
public String wxPayList(Model model) {
//商户订单号
model.addAttribute("outTradeNo", hOrderNo());
return "/wxPayList";
}
/**
* 获取订单流⽔号测试⽤
*/
@RequestMapping(value = {"/wxPay/outTradeNo"})
@ResponseBody
public String getOutTradeNo(Model model) {
//商户订单号
hOrderNo();
}
/**
* 默认 signType 为 md5
谭松韵新剧*/
final private String signType = WxConstants.SING_MD5;
/**
* ⽀付统⼀下单-⽣成⼆维码
* 1.请求预下单接⼝
* 2.根据预下单返回的 code_url ⽣成⼆维码
* 3.将⼆维码 write 到前台页⾯
*/
@RequestMapping(value = {"/wxPay/payUrl"})
public void payUrl(HttpServletRequest request, HttpServletResponse response,
@RequestParam(value = "totalFee") int totalFee,
@RequestParam(value = "outTradeNo") String outTradeNo,
@RequestParam(value = "productId") String productId) throws Exception { //模拟测试订单信息
Order order = new Order();
order.setClintIp("123.12.12.123");
order.setOrderNo(outTradeNo);
order.setProductId(productId);美术教师个人总结
order.setSubject("ESM365充值卡");网上报考
order.setTotalFee(totalFee);
//获取⼆维码链接
String codeUrl = wxMenuService.wxPayUrl(order, signType);
if (!StringUtils.isNotBlank(codeUrl)) {
System.out.println("----⽣成⼆维码失败----");
WxConfig.setPayMap(outTradeNo, "CODE_URL_ERROR");
} else {
//根据链接⽣成⼆维码
WxUtil.writerPayImage(response, codeUrl);
}
}
/**
* ⽀付统⼀下单-通知链接
* 1.⽤户⽀付成功后
* 2.回调该⽅法
* 3.商户最终通知已经收到结果
*/
@RequestMapping(value = {"/wxPay/unifiedorderNotify"})
public void unifiedorderNotify(HttpServletRequest request, HttpServletResponse response) throws Exception {
//商户订单号
String outTradeNo = null;
String xmlContent = "<xml>" +
"<return_code><![CDATA[FAIL]]></return_code>" +
"<return_msg><![CDATA[签名失败]]></return_msg>" +
"</xml>";
try {
String requestXml = InputStream());
System.out.println("requestXml : " + requestXml);
Map<String, String> map = lToMap(requestXml);
String returnCode = (WxConstants.RETURN_CODE);
//校验⼀下,判断是否已经⽀付成功
if (StringUtils.isNotBlank(returnCode) && StringUtils.equals(returnCode, "SUCCESS") && WxUtil.isSignatureValid(map, WxConfig.key, signType)) { //商户订单号
outTradeNo = ("out_trade_no");
System.out.println("outTradeNo : " + outTradeNo);
描写春草的诗句
//⽀付订单号
String transactionId = ("transaction_id");
System.out.println("transactionId : " + transactionId);农行开通网上银行
//⽀付完成时间
SimpleDateFormat payFormat = new SimpleDateFormat("yyyyMMddHHmmss");
Date payDate = payFormat.("time_end"));
SimpleDateFormat systemFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
System.out.println("⽀付时间:" + systemFormat.format(payDate));
//临时缓存
WxConfig.setPayMap(outTradeNo, "SUCCESS");
//根据⽀付结果修改数据库订单状态
//其他操作
//......
//给的应答 xml, 通过 response 回写
xmlContent = "<xml>" +
"<return_code><![CDATA[SUCCESS]]></return_code>" +
"<return_msg><![CDATA[OK]]></return_msg>" +
"</xml>";
}
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 前台页⾯定时器查询是否已⽀付
* 1.前台页⾯轮询
* 2.查询订单⽀付状态
*/
@RequestMapping(value = {"/wxPay/payStatus"})
@ResponseBody
public String payStatus(@RequestParam(value = "outTradeNo") String outTradeNo) {
JSONObject responseObject = new JSONObject();
//从临时缓存中取
String outTradeNoValue = PayMap(outTradeNo);
String status = "200";
//判断是否已经⽀付成功
if (StringUtils.isNotBlank(outTradeNoValue)) {
if (StringUtils.equals(outTradeNoValue, "SUCCESS")) {
status = "0";
} else if (StringUtils.equals(outTradeNoValue, "CODE_URL_ERROR")) {
/
/⽣成⼆维码失败
status = "1";
}
} else {
//如果临时缓存中没有去数据库读取
//......
}
responseObject.put("status", status);
JSONString();
}
/**
* ⽀付订单查询
* 1.如果由于⽹络通信问题导致没有通知到商户⽀付结果
* 2.商户主动去查询⽀付结果⽽后执⾏其他业务操作
*/
@RequestMapping(value = {"/wxPay/orderQuery"})
@ResponseBody
public String orderQuery(@RequestParam(value = "orderNo") String orderNo) throws Exception {
String result = wxMenuService.wxOrderQuery(orderNo, signType);
return result;
}
/**
* 关闭⽀付订单
* 1.商户订单⽀付失败需要⽣成新单号重新发起⽀付,要对原订单号调⽤关单,避免重复⽀付
* 2.系统下单后,⽤户⽀付超时,系统退出不再受理,避免⽤户继续,请调⽤关单接⼝
*/
@RequestMapping(value = {"/wxPay/closeOrder"})
@ResponseBody
public String closeOrder(@RequestParam(value = "orderNo") String orderNo) throws Exception {        String result = wxMenuService.wxCloseOrder(orderNo, signType);
return result;
}
//申请退款
//查询退款
}
service--WxMenuService
package com.dules.service;
import com.del.Order;
/**
* @author zhangye
* @version 1.0
* @description ⽀付接⼝类
* @date 2019/12/19
*/
public interface WxMenuService {
/
**
* ⽣成⽀付⼆维码URL
*
* @param order    订单类
* @param signType 签名类型
* @throws Exception
*/
String wxPayUrl(Order order, String signType) throws Exception;
/**
* 查询订单
*
* @param orderNo  订单号
* @param signType 签名类型
* @return
*/
String wxOrderQuery(String orderNo, String signType) throws Exception;
/**
* 关闭⽀付订单
*
* @param orderNo  订单号
* @param signType 签名类型
* @return
*/
String wxCloseOrder(String orderNo, String signType) throws Exception;
}
service--impl--WxMenuServiceImpl
package com.dules.service.impl;
import com.dulesmon.http.HttpsClient;
import com.dulesmon.wx.WxConfig;
import com.dulesmon.wx.WxConstants;
import com.dulesmon.wx.WxUtil;
import com.del.Order;
import com.dules.service.WxMenuService;
import org.springframework.stereotype.Service;
import java.util.HashMap;
import java.util.Map;
/**
* @author zhangye
护肤品牌子* @version 1.0
* @description ⽀付实现类
* @date 2019/12/19
*/
@Service("wxMenuService")
public class WxMenuServiceImpl implements WxMenuService {
@Override
public String wxPayUrl(Order order, String signType) throws Exception {
HashMap<String, String> data = new HashMap<String, String>();
//公众账号ID
data.put("appid", WxConfig.appID);
//商户号
data.put("mch_id", hID);
//随机字符串
data.put("nonce_str", NonceStr());
//商品描述
data.put("body", Subject());
/
/商户订单号
data.put("out_trade_no", OrderNo());
//标价币种

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。