第一章-微信支付概述

1微信支付的分类

1公众号接入支付

公众号接入支付后,可以通过JSAPI支付产品来完成在公众号、朋友圈、聊天窗口等微信内的收款需求。


2App接入

APP接入支付后,商户通过微信提供的SDK调用微信支付模块完成收款需求。目前微信支付支持手机系统有:IOS(苹果)、Android(安卓)和WP(Windows Phone)。


3PC网站接入支付

微信支付支持完成域名ICP备案的网站接入支付功能。PC网站接入支付后,可以通过JSAPI支付或Native支付,自行开发生成二维码,用户使用微信“扫一扫”来完成支付。

2快速入门native方式

image-20200506143052677

一般网站上所使用的是PC网站接入。(native自然)生成支付二维码。

先去API文档中找到开发文档(2020年5月4日选择V2版本),然后下载对应的SDK与DEMO。这是一个maven项目,导入到开发软件中.

1在SDK基础上进行编写(注意pom.xml文件)

2继承WXPayConfig类,生成MyWXPayConfig,配置账号信息。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
package com.github.wxpay.sdk;

import java.io.InputStream;

public class MyWXPayConfig extends WXPayConfig {
 //微信支付的配置类,包含收款商家的账号ID等
 //这些账号和ID需要公司注册,商家注册微信支付后会生成一个应用ID

 @Override
 String getAppID() {
 //对于测试号信息中的appID
     return "wx632c8f211f8122c6";
 }

 @Override
 String getMchID() {
     //商户ID
     return "1497984412";
 }

 @Override
 String getKey() {

     return "sbNCm1JnevqI36LrEaxFwcaT0hkGxFnC";
 }

 @Override
 InputStream getCertStream() {
     //证书
     return null;
 }

 @Override
 IWXPayDomain getWXPayDomain() {
     //是一个域
     MyWXPayDomain wxPayDomain=new MyWXPayDomain();
     return wxPayDomain;
 }
}

3实现IWXPayDomain接口

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
package com.github.wxpay.sdk;

public class MyWXPayDomain implements IWXPayDomain  {
 @Override
 public void report(String domain, long elapsedTimeMillis, Exception ex) {

 }

 @Override
 public DomainInfo getDomain(WXPayConfig config) {
     //需要两个参数。参数1 微信支付域名 参数2 是否主域名
     DomainInfo domainInfo=new DomainInfo("api.mch.weixin.qq.com",true);
     return domainInfo;
 }
}

4新建一个com.lsl.example包(此例为com.qf.wxpay)

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
package com.qf.wxpay;

import com.github.wxpay.sdk.MyWXPayConfig;
import com.github.wxpay.sdk.WXPay;

import java.util.HashMap;
import java.util.Map;

public class Example {
    public static void main(String[] args)throws Exception {
        MyWXPayConfig myWXPayConfig = new MyWXPayConfig();
        WXPay wxPay=new WXPay(myWXPayConfig);

        Map<String,String> data=new HashMap<String,String>();
        data.put("body","充值测试");
        data.put("out_trade_no","20190701160459000000026");//订单编号,
        data.put("device_info","");//设备信息
        data.put("fee_type","CNY");//货币信息
        data.put("total_fee","1");//1分
        data.put("spbill_create_ip","123.12.12.123");
        //回调接口,获取此次微信支付的信息
        data.put("notify_url","http://aejpge.natappfree.cc/wx_pay/notify");
        data.put("trade_type","NATIVE");//指定此处为扫码支付
        data.put("product_id","12");//商品id
        try {
            //向微信后台发起支付请求,
            Map<String,String> resp=wxPay.unifiedOrder(data);
            //获得响应数据,得到二维码链接
            System.out.println(resp);
        } catch (Exception e) {
            e.printStackTrace();
        }

    }
}

运行这个Example:会有以下信息(return_msg=OK,result_code=SUCCESS)

{nonce_str=ERc7YmIU2W0jSVqR, code_url=weixin://wxpay/bizpayurl?pr=Mt7KPty, appid=wx632c8f211f8122c6, sign=30084FDE7476833D5A892FE95F2CE0AE042B5446FACE8892A7372736FF360079, trade_type=NATIVE, return_msg=OK, result_code=SUCCESS, mch_id=1497984412, return_code=SUCCESS, prepay_id=wx06103007111030145b56ce4a1339305000}

把code_url进行复制,去网上搜索二维码生成器,进行二维码生成,微信已有提示了。

5编写场景类实现支付 重要步骤是回调接口的调用。

5编写回调接口

搭建一个SSM后台项目 提供一个回调的接口(微信调用,需要有服务器,或者进行内网穿透,内网穿透工具natapp.cn)。

内网穿透的实现:

建立一个免费隧道,本地端口号为新创建项目的端口号。 下载客户端,解压后在当前目录下打开cmd窗口,输入如下命令natapp -authtoken=c486538cadbfb834就是隧道中的authtoken,然后会生成一个网址,就可以使用了。

把这个网址放到example中的notify_url中,作为支付成功后,微信支付回调的函数。比如:http://aejpge.natappfree.cc/wx_pay/notify

提供的接口为:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
@Controller
@RequestMapping("/wx_pay")
public class WXPayController {

    @RequestMapping("/notify")
    @ResponseBody
    public String getNotifyURL(HttpServletResponse response){
        System.out.println(response+"我是支付成功后的回调函数");
        return "成功了success";
    }
  /*
  微信发起的请求会携带信息,可以用输出流打印一下
  ServletInputStream is request.getInputStream();
  byte[] b=new byte[1024];
  int len=0;
  while((len=is.read(b))!=-1{
    String s=new String(b,0,len);
    System.out.print(s);
  }
  */
  
   //给微信返回一个标准的回信
   //参考文档https://pay.weixin.qq.com/wiki/doc/api/native.php?chapter=9_7&index=8
   response.getWriter().write("<xml><return_code><![CDATA[SUCCESS]]></return_code><return_msg><![CDATA[OK]]></return_msg></xml>");

}

支付测试一分钱后,会发现这个方法被微信调用了。

第二章-微信支付练习

image-20200531224412818

1完整的支付(ssm)

-1构建环境(待编写)

1把下载的sdk的包下的java文件进行复制(注意修改路径) 2构建一个ssm项目。 3注意导入微信pom.xml的日志以及,依赖

第三章-依赖技术

QR code QR全称Quick Response

1Zxing二维码图片

1google.zxing导包

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
<dependency>
    <groupId>com.google.zxing</groupId>
    <artifactId>core</artifactId>
    <version>3.4.0</version>
</dependency>

<dependency>
    <groupId>com.google.zxing</groupId>
    <artifactId>javase</artifactId>
    <version>3.4.0</version>
</dependency>

2java类生成二维码

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
//生成二维码
    @RequestMapping("qrcode")
    public void qrcode(HttpServletResponse response) {
        // 二维码的宽度
        int WIDTH = 300;
        // 二维码的高度
        int HEIGHT = 300;
        // 二维码的格式
        String FORMAT = "png";
        // 二维码的内容
        String TEXT = "Hello!二维码!!!";

         /*
           定义二维码的参数
        */
        HashMap hashMap = new HashMap();
        // 设置二维码字符编码
        hashMap.put(EncodeHintType.CHARACTER_SET, "UTF-8");
        // 设置二维码纠错等级
        hashMap.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.M);
        // 设置二维码边距
        hashMap.put(EncodeHintType.MARGIN, 2);
        try {
            // 开始生成二维码
            BitMatrix bitMatrix = new MultiFormatWriter().encode(TEXT, BarcodeFormat.QR_CODE, WIDTH, HEIGHT, hashMap);
            // 导出到指定目录
          //  MatrixToImageWriter.writeToPath(bitMatrix, FORMAT, new File("D://erweima.png").toPath());
            //导出到响应流  页面上可以,<img src="这个方法路径" />
            MatrixToImageWriter.writeToStream(bitMatrix, FORMAT,response.getOutputStream());

        } catch (Exception e) {
            e.printStackTrace();
        }

    }

2GoEasy

官方文档:https://www.goeasy.io/cn/doc/client/get-goeasy-js.html 通过java服务端发送:https://www.goeasy.io/cn/doc/server/publish-java.html

账号:13277112287 密码:Goeasy19970520


创建应用,获得两个key。

image-20200602112826836

-1发送消息

java服务端发送消息

1导入依赖

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
<!--添加goeasy仓库到您的pom.xml文件:-->
<repositories>
    <repository>
        <id>goeasy</id>
        <name>goeasy</name>
        <url>
            http://maven.goeasy.io/content/repositories/releases/
        </url>
    </repository>
</repositories>
然后添加依赖:

<dependencies>
    <dependency>
        <groupId>io.goeasy</groupId>
        <artifactId>goeasy-sdk</artifactId>
        <version>0.3.8</version>
    </dependency>
</dependencies>
  1. 请不要将goeasy.js下载到本地,GoEasy动态为不同浏览器提供不同内容的goeasy.js,使用下载到本地的goeasy.js,将会导致某些浏览器 不能发送和接收消息。

2编写java代码

1
2
3
4
//发布消息 第一个参数是,rest服务器地址。  第二个是APP Keys的Common key
GoEasy goEasy = new GoEasy( "http://rest-hangzhou.goeasy.io", "BC-7625c34de6644992991801e2e7f482b9");
// channel隧道名称 往这个隧道推送消息,各个隧道互不影响(可以用订单编号来生成隧道名,用以区分每个用户)
goEasy.publish("my_channel","Hello, GoEasy!");

-2接收消息

1初始化GoEasy对象

1
2
3
4
5
6
7
<script type="text/javascript" src="https://cdn.goeasy.io/goeasy-1.0.6.js"></script>
var goEasy = new GoEasy({
    host:'hangzhou.goeasy.io', //应用所在的区域地址: 【hangzhou.goeasy.io |singapore.goeasy.io】
    appkey: "my_appkey", //替换为您的应用appkey
    otp:'您服务器端生成的OTP'
});
//GoEasy-OTP可以对appkey进行有效保护

2调用GoEasy对象接收消息

1
2
3
4
5
6
goEasy.subscribe({
    channel: "my_channel", //替换为您自己的channel隧道名
    onMessage: function (message) {
        console.log("Channel:" + message.channel + " content:" + message.content);
    }
});

3内网穿透

官网:natapp.cn 账号:13277112287/1115759748@qq.com 密码:Natapp19970520

搭建一个SSM后台项目 提供一个回调的接口(微信调用,需要有服务器,或者进行内网穿透,内网穿透工具natapp.cn)。

内网穿透的实现:

建立一个免费隧道,本地端口号为新创建项目的端口号。 下载客户端,解压后在当前目录下打开cmd窗口,输入如下命令natapp -authtoken=c486538cadbfb834就是隧道中的authtoken,然后会生成一个网址,就可以使用了。