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

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
    @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>

成功页面:

<!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微信扫码支付内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • Java微信支付之公众号支付、扫码支付实例

    微信支付现在已经变得越来越流行了,随之也出现了很多以可以快速接入微信支付为噱头的产品,不过方便之余也使得我们做东西慢慢依赖第三方,丧失了独立思考的能力,这次打算分享下我之前开发过的微信支付. 一 .H5公众号支付 要点:正确获取openId以及统一下单接口,正确处理支付结果通知,正确配置支付授权目录 H5的支付方式是使用较为广泛的方式,这种支付方式主要用于微信内自定义菜单的网页,依赖手机上安装的微信客户端,高版本的微信才支持微信支付,下面按我的流程注意说明 1  编写用于支付的页面,由于是测试用

  • java实现网站微信扫码支付

    一.网站微信扫码支付开发并没有现成的java示例,总结一下自己微信扫码支付心得 二.首先去微信公众平台申请账户 https://mp.weixin.qq.com ** 三.账户开通.开发者认证之后就可以进行微信支付开发了 1.微信统一下单接口调用获取预支付id,以及生成二维码所需的codeUrl /** * 保存订单,并生成二维码所需的codeUrl * * @param request * @param response * @param notifyURLBuf * @param order

  • 微信、支付宝二码合一扫码支付实现思路(java)

    一.支付二维码(预订单) 根据需要购买的信息创建预订单,将订单信息保存到Redis中,并设置有效期,注意生产二维码的链接后的参数可以关联到Redis中的key: QRCode  为servlet扫码请求的URL: UUIDUtils.getUUID()  为预订单单号,在servlet请求中截取,然后在Redis中查找对应的Key的数据: 二维码地址:http://kung900519.qicp.io/interface/QRCode/UUIDUtils.getUUID(): 二.创建二维码扫码

  • java实现微信扫码支付功能

    本文实例为大家分享了java实现微信扫码支付的具体代码,供大家参考,具体内容如下 1.maven项目的pom.xml中添加如下jar包: <dependency> <groupId>com.github.wxpay</groupId> <artifactId>wxpay-sdk</artifactId> <version>0.0.3</version> </dependency> 2.编写WeWxConfig类

  • Java SpringMVC实现PC端网页微信扫码支付(完整版)

    一:前期微信支付扫盲知识 前提条件是已经有申请了微信支付功能的公众号,然后我们需要得到公众号APPID和微信商户号,这个分别在微信公众号和微信支付商家平台上面可以发现.其实在你申请成功支付功能之后,微信会通过邮件把Mail转给你的,有了这些信息之后,我们就可以去微信支付服务支持页面:https://pay.weixin.qq.com/service_provider/index.shtml 打开这个页面,点击右上方的链接[开发文档]会进入到API文档说明页面,看起来如下 选择红色圆圈的扫码支付就

  • 详解JAVA后端实现统一扫码支付:微信篇

    最近做完了一个项目,正好没事做,产品经理就给我安排了一个任务. 做一个像收钱吧这样可以统一扫码收钱的功能. 一开始并不知道是怎么实现的,咨询了好几个朋友,才知道大概的业务流程:先是开一个网页用来判断支付平台,是微信还是支付宝,判断过后就好办了,直接照搬微信支付和支付宝的官方文档.不过微信的文档感觉有点坑,得多花点心思. 现在讲讲怎么实现微信支付网页支付,也就是公众号支付: 1.判断支付平台,在判断是微信平台时,必须使用window.location打开网页,使用其他方法在IOS版微信无法打开网页

  • JAVA微信扫码支付模式二线上支付功能实现以及回调

     一.准备工作 首先吐槽一下微信关于支付这块,本身支持的支付模式就好几种,但是官方文档特别零散,连像样的Java相关的demo也没几个.本人之前没有搞过微信支付,一开始真是被它搞晕,折腾两天终于调通了,特此写下来,以享后人吧! 关于准备工作,就"微信扫码支付模式二"官方文档地址在这 https://pay.weixin.qq.com/wiki/doc/api/native.php?chapter=6_1 可以先看看,实际上需要准备的东西有以下几个: 其中APP_ID和APP_SECRE

  • JAVA微信扫码支付模式一线下支付功能实现

    一.准备工作 无数人来追问模式一的开发,所以在这就贴出来,仅供参考.关于模式一和模式二的区别,我有解释过很多次,无非就是模式一的二维码是针对商品的,模式二的二维码是针对订单的,其他具体细节我就不费口舌了,各位可以自行去官方查看文档,然后是选模式一还是模式二就得看自己的业务了. 1.1.有关配置参数 还是之前那四样,APP_ID和APP_SECRET可以在公众平台找着,MCH_ID和API_KEY则在商户平台找到,特别是API_KEY要在商户平台设置好,这个东东关系到参数校验的正确与否,所以一定要

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

    Java实现PC微信扫码支付 做一个电商网站支付功能必不可少,那我们今天就来盘一盘微信支付. 微信支付官方网站 业务流程: 开发指引文档 支付服务开发前提准备: 1.SDK下载:SDK 2.利用外网穿透,获得一个外网域名:natapp 3.APPID,商户ID,密钥 注:上面三个参数需要自己申请 开发阶段: 导入依赖: <!--eureka的客户端依赖--> <dependency> <groupId>org.springframework.cloud</grou

  • Java利用沙箱支付实现电脑扫码支付教程

    目录 一.准备工作 二.效果展示 三.实现代码 3.1 后台代码 3.2 前台代码 一.准备工作 1.注册支付宝开放平台账号,成为开发者. 地址:https://open.alipay.com/platform/home.htm 2.进入沙箱,进行配置. 3.我们可以看到这个界面 4.后面需要使用的参数 APPID 商户私钥(使用系统默认密钥的公钥模式,点击查看获取) 支付宝公钥 支付宝网关 5.手机上下载沙箱支付宝 (到时候支付用这个支付宝支付) 6.下载好支付宝沙箱版后,登录支付宝提供的账号

  • java实现微信扫码登录第三方网站功能(原理和代码)

    目录 一.查看微信扫码登录官方文档 二.实现微信第三方登录流程: 三.代码实现: 为避免繁琐的注册登陆,很多平台和网站都会实现三方登陆的功能,增强用户的粘性.这篇文章主要介绍了java实现微信扫码登录第三方网站功能(原理和代码),避免做微信登录开发的朋友们少走弯路. 一.查看微信扫码登录官方文档 官方文档:https://open.weixin.qq.com/cgi-bin/showdocument?action=dir_list&t=resource/res_list&verify=1&

  • java实现在SSM下使用支付宝扫码支付功能

    本文实例为大家分享了java使用支付宝扫码支付的具体代码,供大家参考,具体内容如下 准备工作 首先开通支付宝沙箱的测试账号,里面会有消费者账户和收款方账户 手机扫码下载手机端app 基础配置 所需jar包 AlipayConfig package com.alipay.config; import java.io.FileWriter; import java.io.IOException; import java.util.ResourceBundle; /* * *类名:AlipayConf

随机推荐