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