软件编程
位置:首页>> 软件编程>> java编程>> 教你用Java在个人电脑上实现微信扫码支付

教你用Java在个人电脑上实现微信扫码支付

作者:记或往  发布时间:2023-07-22 20:52:15 

标签:Java,微信,扫码支付

Java实现PC微信扫码支付

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

微信支付官方网站

教你用Java在个人电脑上实现微信扫码支付

业务流程:

开发指引文档

教你用Java在个人电脑上实现微信扫码支付

支付服务开发前提准备:

1.SDK下载:SDK

2.利用外网穿透,获得一个外网域名:natapp

教你用Java在个人电脑上实现微信扫码支付

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
   @Override
   public String getAppID() {
       return "wx307113892f15a42e";
   }
   //商户ID
   @Override
   public String getMchID() {
       return "1508236581";
   }
   //秘钥
   @Override
   public String getKey() {
       return "HJd7sHGHd6djgdgFG5778GFfhghghgfg";
   }
   @Override
   public InputStream getCertStream() {
       return null;
   }
   @Override
   public IWXPayDomain getWXPayDomain() {
       return new WXPayDomain();
   }
   class WXPayDomain implements IWXPayDomain{
       @Override
       public void report(String domain, long elapsedTimeMillis, Exception ex) {
       }
       @Override
       public 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 {
@Bean
   public 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;
//建立和前台页面连接后的回调方法
   @OnOpen
   public void onOpen(Session session){
       System.out.println("建立连接"+session);
       //给连接赋值
       WebSocketUtils.session = session;
   }
@OnMessage
   public void onMessage(String message, Session session){
       System.out.println("收到前台消息:" + message);
   }
@OnClose
   public 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 {
@Autowired
   private 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转换为Map
       Map<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" rel="external nofollow"  rel="external nofollow" >
   <link rel="stylesheet" type="text/css" href="css/webbase.css" rel="external nofollow"  rel="external nofollow"  />
   <link rel="stylesheet" type="text/css" href="css/pages-weixinpay.css" rel="external nofollow"  />
</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" rel="external nofollow"  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;
//判断当前浏览器是否支持WebSocket
if('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>

教你用Java在个人电脑上实现微信扫码支付

成功页面:


<!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" rel="external nofollow"  rel="external nofollow" >
   <link rel="stylesheet" type="text/css" href="css/webbase.css" rel="external nofollow"  rel="external nofollow"  />
   <link rel="stylesheet" type="text/css" href="css/pages-paysuccess.css" rel="external nofollow"  />
</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" rel="external nofollow"  class="sui-btn btn-xlarge btn-danger">查看订单</a>&nbsp;&nbsp;&nbsp;&nbsp;<a href="index.html" rel="external nofollow"  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后台显示

教你用Java在个人电脑上实现微信扫码支付

来源:https://blog.csdn.net/xiaozhuzhuyang/article/details/117789776

0
投稿

猜你喜欢

手机版 软件编程 asp之家 www.aspxhome.com