Java实现PC微信扫码支付

做一个电商网站支付功能必不可少,那我们今天就来盘一盘微信支付。

微信支付官方网站

业务流程:

开发指引文档

支付服务开发前提准备:

1.SDK下载:SDK

2.利用外网穿透,获得一个外网域名:natapp
3.APPID,商户ID,密钥
注:上面三个参数需要自己申请

开发阶段:

导入依赖:

<!--eureka的客户端依赖--><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-netflix-eureka-client</artifactId></dependency><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><!-- http客户端 --><dependency><groupId>org.apache.httpcomponents</groupId><artifactId>httpclient</artifactId><version>4.5.3</version></dependency><!-- 二维码 --><dependency><groupId>com.google.zxing</groupId><artifactId>core</artifactId><version>3.3.3</version></dependency><!-- 生成二维码 --><dependency><groupId>com.google.zxing</groupId><artifactId>javase</artifactId><version>3.3.3</version></dependency><!--websocket 服务器主动发送请求给websocket--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-websocket</artifactId></dependency>

微信支付配置类

/*** 微信支付配置*/
public class MyWXConfig extends WXPayConfig {//账户的APPID@Overridepublic String getAppID() {return "wx307113892f15a42e";}//商户ID@Overridepublic String getMchID() {return "1508236581";}//秘钥@Overridepublic String getKey() {return "HJd7sHGHd6djgdgFG5778GFfhghghgfg";}@Overridepublic InputStream getCertStream() {return null;}@Overridepublic IWXPayDomain getWXPayDomain() {return new WXPayDomain();}class WXPayDomain implements IWXPayDomain{@Overridepublic void report(String domain, long elapsedTimeMillis, Exception ex) {}@Overridepublic DomainInfo getDomain(WXPayConfig config) {return new DomainInfo("api.mch.weixin.qq.com",true);}}
}

websocket配置类:

package com.cloud.config;import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.socket.server.standard.ServerEndpointExporter;@Configuration
public class WebSocketConfig {@Beanpublic ServerEndpointExporter serverEndpointExporter(){return new ServerEndpointExporter();}
}

wensocket工具类:

package com.cloud.config;import org.springframework.stereotype.Component;import javax.websocket.OnClose;
import javax.websocket.OnMessage;
import javax.websocket.OnOpen;
import javax.websocket.Session;
import javax.websocket.server.ServerEndpoint;
import java.io.IOException;/*** WebSocket工具类* ServerEndpoint配置websocket的名称,和前台页面对应*/
@ServerEndpoint(value = "/eshop")
@Component
public class WebSocketUtils {//WebSocket的对话对象private static Session session = null;//建立和前台页面连接后的回调方法@OnOpenpublic void onOpen(Session session){System.out.println("建立连接"+session);//给连接赋值WebSocketUtils.session = session;}@OnMessagepublic void onMessage(String message, Session session){System.out.println("收到前台消息:" + message);}@OnClosepublic void onClose(Session session) throws IOException {System.out.println("连接关闭");session.close();}/*** 向前台发消息* @param message* @throws IOException*/public static void sendMessage(String message) throws IOException {System.out.println("发送消息:" + message);if( WebSocketUtils.session != null) {WebSocketUtils.session.getBasicRemote().sendText(message);}}
}

service:

package com.cloud.service;import com.cloud.utils.MyWXConfig;
import com.cloud.utils.WXPay;
import com.cloud.utils.WXPayUtil;
import com.google.zxing.BarcodeFormat;
import com.google.zxing.EncodeHintType;
import com.google.zxing.MultiFormatWriter;
import com.google.zxing.client.j2se.MatrixToImageWriter;
import com.google.zxing.common.BitMatrix;
import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;
import org.springframework.stereotype.Service;import javax.servlet.http.HttpServletResponse;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;/*** 微信支付Service*/
@Service
public class PayService {/*** 下单* @param goodsId 商品id* @param price 价格* @return 二维码的URL*/public Map<String, String> makeOrder(String goodsId, Long price) throws Exception {//创建支付对象MyWXConfig config = new MyWXConfig();WXPay wxPay = new WXPay(config);Map<String,String> map = new HashMap<>();map.put("appid",config.getAppID());map.put("mch_id",config.getMchID());map.put("device_info","WEB");map.put("nonce_str", UUID.randomUUID().toString().replace("-",""));map.put("body","商城购物");String tradeNo = UUID.randomUUID().toString().replace("-", "");map.put("out_trade_no", tradeNo);map.put("fee_type","CNY");map.put("total_fee",String.valueOf(price));map.put("notify_url","http://68dhbz.natappfree.cc/pay/rollback"); //微信对商户后台的回调接口map.put("trade_type","NATIVE");map.put("product_id",goodsId);//执行统一下单Map<String, String> result = wxPay.unifiedOrder(map);System.out.println("result:"+result);//保存订单号result.put("trade_no",tradeNo);return result;}/*** 生成二维码* @param url* @param response*/public void makeQRCode(String url, HttpServletResponse response){//通过支付链接生成二维码HashMap<EncodeHintType, Object> hints = new HashMap<>();hints.put(EncodeHintType.CHARACTER_SET, "UTF-8");hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.M);hints.put(EncodeHintType.MARGIN, 2);try {BitMatrix bitMatrix = new MultiFormatWriter().encode(url, BarcodeFormat.QR_CODE, 200, 200, hints);MatrixToImageWriter.writeToStream(bitMatrix, "PNG", response.getOutputStream());System.out.println("创建二维码完成");} catch (Exception e) {e.printStackTrace();}}/*** 检查订单状态* @param tradeNo* @return* @throws Exception*/public String checkOrder(String tradeNo) throws Exception {MyWXConfig config = new MyWXConfig();String str ="<xml>"+"<appid>"+config.getAppID()+"</appid>"+"<mch_id>"+config.getMchID()+"</mch_id>"+"<nonce_str>"+UUID.randomUUID().toString().replace("-","")+"</nonce_str>"+"<out_trade_no>"+tradeNo+"</out_trade_no>"+"<sign>5E00F9F72173C9449F802411E36208734B8138870ED3F66D8E2821D55B317078</sign>"+"</xml>";WXPay pay = new WXPay(config);Map<String,String> map = WXPayUtil.xmlToMap(str);Map<String, String> map2 = pay.orderQuery(map);String state = map2.get("trade_state");System.out.println("订单"+tradeNo+",状态"+state);return state;}
}

controller:

package com.cloud.controller;import com.cloud.config.WebSocketUtils;
import com.cloud.service.PayService;
import com.cloud.utils.WXPayUtil;
import org.apache.tomcat.util.http.fileupload.util.Streams;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Map;/*** @author yanglihu*/
@RestController
@RequestMapping("/pay")
public class PayController {@Autowiredprivate PayService payService;private String tradeNo;/*** 二维码生成*/@GetMapping("/code")public void qrcode(@RequestParam("goodsId")String goodsId,@RequestParam("price")Long price,HttpServletResponse response){try {Map<String,String> map = payService.makeOrder(goodsId, price);payService.makeQRCode(map.get("code_url"),response);System.out.println("生成订单号:" + map.get("trade_no"));tradeNo = map.get("trade_no");} catch (Exception e) {e.printStackTrace();}}/*** 支付后通知*/@PostMapping("/rollback")public void notify(HttpServletRequest request, HttpServletResponse response) throws Exception {//获得微信传来的xml字符串String str = Streams.asString(request.getInputStream());//将字符串xml转换为MapMap<String, String> map = WXPayUtil.xmlToMap(str);//读取订单号String no = map.get("out_trade_no");//模拟修改商户后台数据库订单状态System.out.println("更新订单状态:"+no);//给微信发送消息response.getWriter().println("<xml>\n" +"   <return_code><![CDATA[SUCCESS]]></return_code>\n" +"   <return_msg><![CDATA[OK]]></return_msg>\n" +"   <appid><![CDATA["+map.get("appid")+"]]></appid>\n" +"   <mch_id><![CDATA["+map.get("mch_id")+"]]></mch_id>\n" +"   <nonce_str><![CDATA["+map.get("nonce_str")+"]]></nonce_str>\n" +"   <openid><![CDATA["+map.get("openid")+"]]></openid>\n" +"   <sign><![CDATA["+map.get("sign")+"]]></sign>\n" +"   <result_code><![CDATA[SUCCESS]]></result_code>\n" +"   <prepay_id><![CDATA["+map.get("prepay_id")+"]]></prepay_id>\n" +"   <trade_type><![CDATA[NATIVE]]></trade_type>\n" +"</xml>");WebSocketUtils.sendMessage("ok");}/*** 检查订单状态*/@PostMapping("checkOrder")public String checkOrder() throws Exception {System.out.println("trade_no:" + tradeNo);if(StringUtils.isEmpty(tradeNo)){return null;}String success = payService.checkOrder(tradeNo);System.out.println("check:" + success);return success;}
}

支付页面:

<!DOCTYPE html>
<html><head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=9; IE=8; IE=7; IE=EDGE"><meta http-equiv="X-UA-Compatible" content="IE=EmulateIE7" /><title>乐优商城--微信支付页</title><link rel="icon" href="/assets/img/favicon.ico"><link rel="stylesheet" type="text/css" href="css/webbase.css" /><link rel="stylesheet" type="text/css" href="css/pages-weixinpay.css" />
</head><body><!--页面顶部白条条,由js动态加载--><script type="text/javascript" src="plugins/jquery/jquery.min.js"></script><div class="top"></div><script type="text/javascript">$(".top").load("shortcut.html");</script>      <div class="checkout py-container  pay">       <div class="checkout-steps"><div class="fl weixin">微信支付</div><div class="fl sao"> <p class="red">二维码已过期,刷新页面重新获取二维码。</p>                      <div class="fl code"><img src="http://api.eshop.com/pay/code?goodsId=11&price=1" alt=""><div class="saosao"><p>请使用微信扫一扫</p><p>扫描二维码支付</p></div></div><div class="fl phone"></div></div><div class="clearfix"></div><p><a href="pay.html" target="_blank">> 其他支付方式</a></p></div></div></div>
<script type="text/javascript" src="js/plugins/jquery/jquery.min.js"></script>
<script type="text/javascript" src="js/plugins/jquery.easing/jquery.easing.min.js"></script>
<script type="text/javascript" src="js/plugins/sui/sui.min.js"></script>
<script type="text/javascript" src="js/widget/nav.js"></script>
<script type="text/javascript">$(function(){$("ul.payType li").click(function(){$(this).css("border","2px solid #E4393C").siblings().css("border-color","#ddd");})})
</script>
<script>var websocket = null;//判断当前浏览器是否支持WebSocketif('WebSocket' in window){websocket = new WebSocket("ws://localhost:8888/eshop");}else{alert('Not support websocket')}//接收到消息的回调方法websocket.onmessage = function(event){console.log(event.data);if(event.data == "ok"){location.href = "paysuccess.html";}}
</script>
</body></html>

成功页面:

<!DOCTYPE html>
<html><head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=9; IE=8; IE=7; IE=EDGE"><meta http-equiv="X-UA-Compatible" content="IE=EmulateIE7" /><title>乐优商城--支付页-成功</title><link rel="icon" href="/assets/img/favicon.ico"><link rel="stylesheet" type="text/css" href="css/webbase.css" /><link rel="stylesheet" type="text/css" href="css/pages-paysuccess.css" />
</head><body><!--head-->  <!--页面顶部白条条,由js动态加载--><script type="text/javascript" src="plugins/jquery/jquery.min.js"></script><div class="top"></div><script type="text/javascript">$(".top").load("shortcut.html");</script>   <div class="cart py-container">        <!--主内容--><div class="paysuccess"><div class="success"><h3><img src="img/_/right.png" width="48" height="48"> 恭喜您,支付成功啦!</h3><div class="paydetail"><p>支付方式:微信支付</p><p>支付金额:¥1006.00元</p><p class="button"><a href="home-index.html" class="sui-btn btn-xlarge btn-danger">查看订单</a>&nbsp;&nbsp;&nbsp;&nbsp;<a href="index.html" class="sui-btn btn-xlarge ">继续购物</a></p></div></div></div></div><script type="text/javascript" src="js/plugins/jquery/jquery.min.js"></script>
<script type="text/javascript" src="js/plugins/jquery.easing/jquery.easing.min.js"></script>
<script type="text/javascript" src="js/plugins/sui/sui.min.js"></script>
<script type="text/javascript" src="components/ui-modules/nav/nav-portal-top.js"></script>
</body></html>


java后台显示

Java实现PC微信扫码支付相关推荐

  1. java 实时监控微信扫码支付,支付成功跳转到成功页面

    **原文链接:https://www.blog-china.cn/liuzaiqingshan/home/39/1510305872502 欢迎访问个人博客,分享更多技术码上中国博客(CodeChin ...

  2. 企业实战, java、spingboot微信扫码支付,页面生成微信二维码,微信扫码付款,websocket通知,处理订单!复制粘贴代码直接开干

    一  功能描述:    前端选择商品后生成二维码,用户微信扫码支付 备注: 红色为后台给前端的接口 1.前端 选择确认商品 2.调后台生成订单接口 (状态未付款) 3.返回订单的详情(订单确认页面  ...

  3. 微信PC端扫码支付 java 模式二的扫码支付

    前言 这次分享的是java对接微信的支付接口,实现电脑端扫码支付后,跳转支付成功页面的例子.之所以分享是微信的Api太坑了.留下的文档也少,对接过程中容易出现各种各样的问题,在实现这扫码支付功能的时候 ...

  4. 微信支付—微信H5支付「PC端扫码支付」

    前言 微信支付-微信H5外部浏览器支付 微信支付-微信H5内部浏览器支付 微信支付-PC端扫码支付「本文」 本篇是微信支付系列的第三篇,PC端扫码支付. 开发环境:Java + SpringBoot ...

  5. PC网站微信扫码支付,Native支付,“当前商户号暂不支持关联该类型的appid“,“签名错误,请检查后再试““springBoot 微信支付“

    springBoot 微信支付 PC网站微信扫码支付-Native支付 一.采坑大合集 1.当前商户号暂不支持关联该类型的appid 2.签名错误,请检查后再试 二.springboot集成微信支付D ...

  6. PC网站微信扫码支付之Native支付(模式二)

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

  7. c#版在pc端发起微信扫码支付

    c#版在pc端发起微信扫码支付 参考此连接(https://www.cnblogs.com/vinsonLu/p/5166214.html#!comments) posted on 2019-01-0 ...

  8. JAVA微信扫码支付模式二功能实现完整例子

    概述 本例子实现微信扫码支付模式二的支付功能,应用场景是,web网站微信扫码支付.实现从点击付费按钮.到弹出二维码.到用户用手机微信扫码支付.到手机上用户付费成功.web网页再自动调整到支付成功后的页 ...

  9. 微信扫码支付---模式一(PC端,解决中文乱码)

    近期公司调完银联,调支付宝,调完支付宝调微信.说实话微信的帮助文档确实是烂,而且有没有技术支持,害的我头发都掉了一桌.不说废话了,看代码. 首先登陆微信的公众平台(微信的服务号不是订阅号),然后选择微 ...

最新文章

  1. 北京科技大学转专业到计算机,北科大学生全可转专业
  2. linux只有上传文件到站点,史上最简单的上传文件到linux系统方法
  3. spring中type转换框架设计与实现
  4. C++STL的map/ multimap容器
  5. 关于VLC无法播放rtsp的问题分析
  6. SAP CRM, C4C和Hybris Commerce的数据迁移策略
  7. php查询sql2008数据库操作系统,使用 PHP 进行查询 - Azure SQL Database SQL Managed Instance | Microsoft Docs...
  8. Spring Boot微服务的黑匣子测试是如此简单
  9. 【渝粤教育】国家开放大学2018年春季 0674-22T财务管理 参考试题
  10. wince6下usb摄像头(UVC)使用指南
  11. 人工智能(2)---从0开始搭建产品经理的AI知识框架:计算机视觉
  12. Hibernate入门案例及增删改查
  13. CentOS下ELK基于ElastAlert实现日志的微信报警
  14. 泰山OFFICE正式在UOS应用商店上架
  15. Hadoop安装目录
  16. 正点原子STM32F103(精英版)------电容触摸按键
  17. python 月初 月末
  18. 嵌入式Linux 串口编程系列1——基本知识、termios结构体
  19. 【FederatedLearning】联邦学习类别详述(横向、纵向、迁移)
  20. oracle禁止用户做DDL操作

热门文章

  1. Android App优化:内存优化、电量优化、网络优化等 (2)
  2. C# winform程序打包安装(图解)
  3. Apache Sentry详细讲解
  4. Qt界面开发资料汇总
  5. CSS 压缩 提高性能的群聊天记录
  6. Unity GIF播放插件 (支持安卓)
  7. iOS view层的组织和调用
  8. 什么是AMF?AMF0和AMF3
  9. 【MIUI9_7.12.05】小米6 sagit 高通骁龙835 基于安卓N(Android 7.1)时间刺客修改精简优化版本
  10. 微信公众号 测试号配置