今天公司让实现支付宝刷脸支付对接自己的程序实现刷脸,在网上看了一些博客发现大部分都有点乱,现在我来总结一下自己的实现方法,整个文章分为四个部分:流程分析、客户端实现、服务端实现、实现程序所必须的数据。

当然,在看该文章时最好先浏览一下官方文档,结合理解,同时下载相应的sdk等。
这个官方文档流程说的比较清晰↓
https://docs.alipay.com/pre-open/20180402104715814204/quickstart
这个官方文档的代码比较清晰↓
https://docs.alipay.com/pre-open/20171214172813219030/qs8myr

一:流程分析

首先我们先来看一下官方的时序图,明确一下接入流程。
分析时序图一方面是为了能够弄清楚整个接入的运行流程,另一方面则是为了明确什么是我们应该做的,什么是支付宝以及给我们实现好的。

从时序图上看,我们需要重点关注的只有从商户APP和商户服务端发出和接收的箭头
也就是说橙色块的是需要我们自己实现的。蓝色色块的全部都是支付宝已经实现的部分。
从我的实践上来讲,刷脸SDK和刷脸APP我们也需要在意一下。
当然我们并不需要了解这两个部分是怎么实现的,但是我们需要注意下我们的要开发的程序与这两个部分的关系。
刷脸SDK:我们的程序内部必须含有该部分,官方文档有相应下载。
刷脸APP:这东西需要看你要开发的产品中是否已经安装了,如果没安装考虑是内嵌的自己的程序中一起安装还是先在相应的设备进行安装。

下面我们开始结合时序图和官方demo代码来进行分析。
(我步骤的标号和时序图上的步骤标号一一对应。)

二:客户端

0.服务的初始化

Zoloz Zoloz; // 单例
Zoloz = com.alipay.zoloz.smile2pay.service.Zoloz.getInstance(getApplicationContext());
Zoloz.zolozInstall(mockInfo());

在官方时序图上没有这个步骤,可是这个代码必须在你所有步骤之前就先进行调用。
以下是官方文档的对于这步骤的解释:开发者通过该接口启动蚂蚁佐罗的服务初始化,进而使用刷脸识别用户的服务。
按我的理解就是说:在开始时先调用这段代码就是向刷脸服务器提交一个申请告诉对方,我需要使用你的扫脸服务了,请批准。然后将自己的的申请表发过去。

其中这个 mockInfo() 就是你的申请表,我们来看一下这个方法的内容:

 Map mockInfo() {Map merchantInfo = new HashMap();merchantInfo.put("partnerId", "2088201820182018");merchantInfo.put("merchantId", "2088201820182018");merchantInfo.put("appId", "2088201820182018");        merchantInfo.put("storeCode", "我是门店编码");merchantInfo.put("brandCode", "我是品牌编码");merchantInfo.put("areaCode", "");merchantInfo.put("geo", "0.000000,0.000000");merchantInfo.put("wifiMac", "");merchantInfo.put("wifiName", "");merchantInfo.put("deviceNum", "990000001212");merchantInfo.put("deviceMac", "CC:B8:A8:0F:63:3C");return merchantInfo;}

这段代码相当简单,就是返回一个Map数据。
这个Map中的key是固定的字符串,value是你的具体数值。

我们来看一下这些key分别代表的含义:

string merchantId;      // 必选,商户ID,来自蚂蚁开放平台,示例:"2088011211821038"
string partnerId;       // 必选,合作商户ID,来自蚂蚁开放平台,示例:"2088011211821038"
string deviceNum;       // 必选,设备唯一编号,商户自定义
string deviceMac;       // 必选,设备Mac 地址,例如:"CC:B8:A8:0F:63:3C"
string brandCode;       // 必选,品牌编码,商户自定义
string appId;           // 可选,商户应用ID,来自蚂蚁开发平台
string storeCode;       // 可选,门店编码,商户自定义
string areaCode;        // 可选,区域编码,商户自定义
string geo;             // 可选,机具坐标,例如"0.000000,0.000000"
string wifiMac;         // 可选,wifi Mac地址
string wifiName;        // 可选,wifi Mac名字

从列表中我们可以很清楚这些key分别对应了什么value。
什么是必选的什么是可选的。我们先来总结一下必选的数据有哪些:
商户ID、合作商户ID、设备唯一编号、设备Mac 地址、品牌编码
以上就是我们所必须的一部分资料。

2.1代码执行对应的时序图

现在,服务初始化已经完成了,我们开始时序图第一步1. 设备信息相关操作,使用刷脸SDK获取设备信息。
先来看一下官方API:

/*** zoloz getMetaInfo,zoloz获取metaInfo* @param info* @param zolozCallback* @return*/public void zolozGetMetaInfo(final Map info, final ZolozCallback zolozCallback)

支付宝的API做的并不好,我们先来分析一下这个API。
这个方法有两个参数,其中第一个Map就是我们上面提到的mockInfo()。我们需要将自己的设备信息通过该函数发送到刷脸SDK执行了就是在执行 1.获取设备信息 的过程。
第二个ZolozCallback是一个官方的回调方法,它就是在执行时序图中 1.1返回设备信息 这个过程。
zoloz getMetaInfo,zoloz获取metaInfo,而这句话的意思就是说支付宝通过zoloz对象和这个方法可以获得设备信息。

现在我们来看一下官方的代码:

这一段就是判断传过去mockInfo()是否是空值。如果是空值就不必再执行下面的流程了。

如果如果我们传过去的设备信息不是空值得话,获得刷脸APP返回的的设备信息。
这个信息包含两个数据:code和metainfo。
其中code是用来判断我们传入的设备信息是否顺利通过了。
关于code值所代表的含义详细的可以去查看官方文档。我们只需要知道“1000”这个值是检查成功的意思,其余的值都代表各种各样的错误。

而metainfo代表的是我们设备的信息(暂不确定,清明过后测试一下,再作确定。)

现在我们来审视一下这一整段代码:
经过前面的过程我们已经可以顺利判断,该设备可以是否可以使用刷脸功能。
接下来我们就开始准备执行人脸初始化,当我们判断code是否等于“1000”的时候其实就是在执行2.人脸初始化(可用性判断) 这个过程。

红色箭头指向的位置需要写上我们向服务器进行请求获得zinInit与zimIntiClienData。这两个关键值的代码,下面是我自己实现的连接服务器客户端的代码:
这里我使用Socket来进行网络编程:
客户端

//连接商户服务器,获得zinInit与zimIntiClienData。
//这里填写商户服务端的Ip地址
String host="";
//创建Socket,不用分配端口号客户端会自动分配限制的端口。
Socket socket=new Socket(InAddress.getByName(host));
//创建输入流对象
InputStream in=socket.getInputStream();
byte[] bys=new byte[1024];
int len=in.read (bys);// 返回的值为 bys 所存储了字节的大小
String string=new String (bys,0,len);// 这个构造函数的作用为将 bys 中从 0 到 len 长度的字节转换为 String 同时拷贝到 string;
//我们将这段字符串转换为JSON对象JSONObject json = new JSONObject(string);  String zimId=json.get("zimId");String zimInitClientData=json.get("zimInitClientData");//至此客户端获得了调用人脸支付的必要信息,关闭输入流in.close();

接下来的人脸初始化开放请求发生在服务端,了解这一过程,请点击这里跳转到相应的位置.
现在假设我们已经假设我们已经通过服务器获得了相应的关键信息。
其中最重要的是zimId和zimInitClientData这两个参数。因为我们需要这两个参数来进行下面的唤醒人脸的操作。

现在来执行3.唤起人脸识别。唤起人脸识别的过程直接由我们的前端执行相应的代码调用SDK就可以。

下面为官方唤起人脸识别的API:
/*** zoloz verify,zoloz调用smile2pay* @param zimId* @param params* @param zolozCallback* @return*/public void zolozVerify(final String zimId, final Map params, ZolozCallback zolozCallback)

我们现在分析一下这个方法的参数。这个方法有三个参数,分别是zimId,params、zolozCallback.其中zimId,params是由我们的服务器端返回的初始化结果。zolozCallback照例是一个回调函数。zoloz verify,zoloz调用smile2pay,这句话就是说我们可以通过zoloz对象的这个方法调出刷脸支付的效果。.
通过代码我们可以看出,除了方法上的不同唤起人脸识别的过程与人脸的初始化没有太大的差别。只不过人脸识别传回来的是参数“ftoken”。
关于这个参数官方的解释是ftoken
标识刷脸认证成功,作为查询接口的入參。由此可以这个参数是刷脸认证成功的返回值也就是3.1返回人脸识别的结果中的结果。而那个所谓的查询接口是指“当面付”的接口。我们的服务器可以使用foken来作为从支付宝扣钱的凭证。

最后一行代码为 服务释放 表示此刻使用扫脸付的功能完毕。

   @Overrideprotected void onDestroy() {super.onDestroy();Zoloz.zolozUninstall();}

最后我们总结一下客户端运行起来所必须的参数包含哪些。
其中“商户ID、合作商户ID、设备唯一编号、设备Mac 地址、品牌编码”这些为在客户端就必须交给客户端的信息。初次之外我们还需要获得从服务器传来的zimId,params这两个数据。

那么服务器怎么获得这些数据呢?我们来看下服务器端的代码。

支付功能
现在假设我们已经获得了所有应得的数据了,那么我们怎么进行支付呢?

//根据时序图,我们需要向服务器端发起收单请求
void pay(String ftoken)
{
//必要入参:我们需要向服务器提供ftoken
//我们依旧使用Scoket编程java5之后的语法,只不过我们这次是向服务器端发送数据
//这里填写商户服务端的Ip地址
String host="";
//创建Socket,不用分配端口号客户端会自动分配限制的端口。
Socket socket=new Socket(InAddress.getByName(host));
//创建一个输出流对象
OutputStream out=socket.getOutputStream();//再将String对象转换成Byte类型的数据byte[] ftokenByte = ftoken.getBytes();
//再将该数据发送出去
out.write(ftokenByte);//接下来我们需接收到相应的收单结果并将结果返回//..根据获得结果会进行不同的反应,这里再写下去就超出刷脸支付的范围了,等以后有机会了在补上//最后关闭输出流out.close();
}

三:服务器

从时序图上可以看出我们服务器只需要负责两件事情就行了。

我们先来看看第一件 :向支付宝网关发送人脸初始化请求
我们来看一下官方的代码↓

//实例化客户端
AlipayClient alipayClient = new DefaultAlipayClient(
"https://openapi.alipay.com/gateway.do",
"app_id",
"your private_key",
"json",
"GBK",
"alipay_public_key",
"RSA2");
/*实例化具体API对应的request类,类名称和接口名称对应,当前调用接口名称:zoloz.authentication.customer.smilepay.initialize.该接口可以获取刷脸服务的初始化信息。*/
ZolozAuthenticationCustomerSmilepayInitializeRequest request = new ZolozAuthenticationCustomerSmilepayInitializeRequest();
//SDK已经封装掉了公共参数,这里只需要传入业务参数
request.setBizContent("{" +"\"zimmetainfo\":\"{\\\"apdidToken\\\":  \\\"设备指纹\\\", \\\"appName\\\": \\\"应用名称\\\",\\\"appVersion\\\": \\\"应用版本\\\",\\\"bioMetaInfo\\\": \\\"生物信息如2.3.0:3,-4\\\" }\"" +"  }");//可能只有支付宝自己知道这是干啥的。反正具体就是大概就是将我们的参数传给支付宝,再返回我们我们所需要的结果。
ZolozAuthenticationCustomerSmilepayInitializeResponse response = alipayClient.execute(request);
if(response.isSuccess()){
System.out.println("调用成功");
//使用人脸初始化方法
FaceInitialization(response);
//使用支付功能SeverPay(alipayClient);
} else {
System.out.println("调用失败");
} //我们使用这个方法用来接收客户端的必要信息同时用来发送相应的zimId与zimInitClientData
//因此该方法需要一个reponse的入参
void FaceInitialization(ZolozAuthenticationCustomerSmilepayInitializeResponse  zolozResponse)
{
//这里需要打开一个异步线程,用来接收客户端的数据。这里我们使用java5之后的语法Executor executor = Executors.newFixedThreadPool(10);executor.execute(new Runnable() {public void run() {
//这这里将相应的数据传回客户端
//发送数据//使用9955端口来接收数据
ServerSocket severSocket=new ServerSocket(9955);
//先获得相应的zimId和,zimInitClientDataString zimId = zolozResponse.getZimId();String zimInitClientData = zolozResponse.getZimInitClientData();
//服务端进行监听
Socket socket=severSocket.accept();
//创建一个输出流对象
OutputStream out=socket.getOutputStream();//先将相应的数据转换转成json类型方便传输
Map IdClientData=new HashMap();
IdClientData.put("zimId ",zimId );
IdClientData.put("zimInitClientData",zimInitClientData);JSONObject json = new JSONObject(IdClientData);  //将JSON对象转换成String类型String jsonString=json.toString();  //再将String对象转换成Byte类型的数据byte[] jsonByte = jsonString.getBytes();  //再将该数据发送出去out.write(jsonByte);//最后关闭输出流out.close();}});
}//向刷脸服务端发送收单请求,并将收单结果发送给客户端
//根据官方demo我们需要一个客户端实例,这里我将其作为参数直接传入
void SeverPay(AlipayClient alipayClient)
{
//另起一个线程
//这里需要打开一个异步线程,用来接收客户端的数据。这里我们使用java5之后的语法Executor executor = Executors.newFixedThreadPool(10);executor.execute(new Runnable() {public void run() {//先创建一个Socket来接收ftoken//使用9955端口来接收数据
ServerSocket severSocket=new ServerSocket(9955);
//服务端进行监听
Socket socket=severSocket.accept();
//创建输入流对象
InputStream in=severSocket.getInputStream();
byte[] bys=new byte[1024];
int len=in.read (bys);// 返回的值为 bys 所存储了字节的大小
String string=new String (bys,0,len);// 这个构造函数的作用为将 bys 中从 0 到 len 长度的字节转换为 String 同时拷贝到 string;
//我们将这段字符串转换为JSON对象JSONObject json = new JSONObject(string);  //获得ftokenString  ftoken=json.get("auth_code");//发送一个交易请求
AlipayTradePayRequest alipayTradePayRequest = new AlipayTradePayRequest();
//没有找到这个对象的官方文档,根据类名与下面的代码判断应该是用来添加交易参数的
TradepayParam tradepayParam = new TradepayParam();
tradepayParam.setOut_trade_no(UUID.randomUUID().toString());//auth_code和scene填写需要注意
//下面为这些参数的含义
//out_trade_no  商户订单号,需要保证不重复
//scene 刷脸支付固定传入 security_code
//auth_code 用户付款码,刷脸支付传入 ftoken
//subject   订单标题
//store_id  商户门店编号
//total_amount  订单金额
//timeout_express   交易超时时间
tradepayParam.setAuth_code(ftoken); // 人脸zolozVerify接口返回的ftoken
tradepayParam.setScene("security_code");//对于刷脸付,必须写为security_code
//下面的数据不是必填项
//tradepayParam.setSubject("smilepay");
//tradepayParam.setStore_id("smilepay test");
//tradepayParam.setTimeout_express("5m");
//tradepayParam.setTotal_amount(amount);
//接收到请求的结果
AlipayTradePayResponse response = alipayTradePayRequest.setBizContent(JSON.toJSONString(tradepayParam));
if (response != null && SMILEPAY_CODE_SUCCESS.equals(response.getCode())) {
//支付成功后将结果返回给客户端
//这里不再写这些内容只对支付结果返回值有兴趣的可以查看官方的这个网站
//https://docs.open.alipay.com/api_1/alipay.trade.pay
}
//最后关闭该线程
severSocket.close();
}
});
}

实际上这段代码中每句代码的功能我们并不需要强行理解。我们只知道在这段代码中放入我们的“入参”就会得到相应的“出参就可以了。”
现在我们就来分析一下段代码中哪些是必须的“入参”,我们又会得到怎么样的“出参”呢?
这些“出参”能够干什么呢?

首先我们需要"app_id",“your private_key”,“alipay_public_key”。也就是你的应用ID,你的开发者密钥,支付宝公钥。而那些业务参数是可有可无的,如果你是在做实际项目请
填上真实数据,如果测试就不用理他们了。
那我们的“出参”是什么?
出参是一个String类型的result其内容为:
{“retCode”:“返回码”,
“retMessage”:“返回信息”,
“result”:
{ “zimId”:“唤起人脸关键参数”,
“type”:“zimInit”}
}
这是一串用String类型存起来的json数据。我可以通过解析这些数据将必要的值返回我们的客户端,也可以直接发给客户端由客户端进行解析。再由客户端来执行下面的操作

至此扫脸的过程执行完毕。接下来是支付的客户端服务器 端的实现.
我先来写客户端的实现

四:实现程序所必须的数据

经过我上面的总结该程序所必须的数据:
客户端:商户ID、合作商户ID、设备唯一编号、设备Mac 地址、品牌编码
服务端:应用ID,你的开发者密钥,支付宝公钥

我们必须有这些数据才能进行测试,当然这些数据可以是真实的也可以是隔离沙箱生成的。

经验证,本文代码上有好几处较小的错误,暂时没来得及修正,如果你看到了这句话并且写的程序出现了错误可以发送留言交流。但是整个程序的流程解释是没问题的可以放心按照相应的解释理解

支付宝刷脸支付对接自己的程序相关推荐

  1. 支付宝刷脸支付对接流程

    因为现在的支付基本都使用支付宝微信了,刷脸也应用的越来越多,所以需要写一个对接支付宝刷脸支付的接口 支付宝刷脸主要提供了两种不同的接口,一个是生活类的刷脸接口,一个是支付类的刷脸接口 生活类的刷脸接口 ...

  2. 智慧物业小程序_刷脸支付+电商小程序+智慧酒店营销方案

    我们这边刷脸支付+电商小程序+智慧酒店行业解决方案,支付宝微信订房小程序,芝麻信用免押住,数字化经营发券引流,未来酒店:0押金 0房费 退房扣款,不占用资金,用户增长信用分,线上订房小程序,无接触服务 ...

  3. 【程序源代码】刷脸支付系统、小程序

    " 关键字:  "刷脸支付系统 小程序 后台管理端 " 01 ---- [总体介绍] 微信青蛙刷脸支付后台和小程序 包含:配套支付宝Iot小程序:支付宝蜻蜓刷脸支付小程序 ...

  4. JavaWEB后端支付银联,支付宝,微信对接

    注:本文来源于:<  JavaWEB后端支付银联,支付宝,微信对接  > JavaWEB后端支付银联,支付宝,微信对接 标签(空格分隔): java 项目概述 最近项目需要后端打通支付,所 ...

  5. java对接支付宝微信银联_JavaWEB后端支付银联,支付宝,微信对接

    JavaWEB后端支付银联,支付宝,微信对接 标签(空格分隔): java 项目概述 最近项目需要后端打通支付,所以对接部分做成了一个小模块. 先说下项目要求: 后端要对接银联无跳转Token支付,支 ...

  6. uni-app开发经验分享十九: uni-app对接微信小程序直播

    uni-app对接微信小程序直播 1.登录微信小程序后台-点击>设置->第三方设置->添加直播插件 2.添加直播组件后->点击<详情>      记录这两个参数直播 ...

  7. 帝国CMS对接百度小程序实现文章自动收录的方法

    我们在开发帝国CMS对接百度小程序的时候为了提升百度小程序的收录和关键词权重,需要注意一定要确保每个页面都要有小程序规定的SEO的TDK标签实现动态同步,自动收录,这样就可以给我们省下很多时间和精力. ...

  8. 实现中英文对接翻译小程序—最终版

    实现中英文对接翻译小程序-最终版 在原有界面上增加了新的标签和按钮 #encoding=utf-8 import json import requests import sys from tkinte ...

  9. SpringBoot对接微信小程序支付功能开发(一,下单功能)

    1,接入前准备: 接入模式选择直连模式: 申请小程序,得到APPID,并开通微信支付: 申请微信商户号,得到mchid,并绑定APPID: 配置商户API key,下载并配置商户证书,根据微信官方文档 ...

最新文章

  1. cesium 加载bim模型_构建统一CIM数字底盘,实现基于BIM的全流程管控
  2. java线程四种状态
  3. ubuntu下最简单的MySQL安装教程
  4. Python之旅:列表
  5. Python教程:切片、迭代、列表生成式
  6. Linux文件目录结构一览表
  7. 拳王公社:知识付费项目!个体操作可年入千万!简单可复制!
  8. android edittext最多输入,android 中如何限制 EditText 最大输入字符数
  9. Android新手之旅(12) URL解码
  10. 完成端口(CompletionPort)之客户端篇
  11. java打印sscil码_2018最新发布 |SSCI收录语言学学科期刊目录
  12. 电力-开闭所/配电房/变电所/变电站
  13. Photoshop:PS如何实现放大图片不模糊
  14. Rxjava:interval的使用
  15. jbX和finss的一些问题
  16. 三维重建(一)外极几何,基础矩阵及求解
  17. 基于C++的AGV机器人无线控制
  18. SpringMVC 自动注入 Request 和 Response 对象
  19. STATA如何查找命令的帮助文件
  20. hadoop2.7.4在windows系统IDEA远程测试

热门文章

  1. aix ntp 配置_IBM AIX系统NTP配置方法
  2. .net 用QQ邮箱发邮件
  3. 好上手操作的网站设计软件,打造惊艳网站效果
  4. 机器学习实战之特征工程
  5. 中国分光计市场现状研究分析与发展前景预测报告(2022)
  6. C语言中对结构体排序
  7. 金蝶web前端一面(已挂)
  8. UEFI PCD分析
  9. RuntimeError: wrapped C/C++ object of type QToolButton has been deleted
  10. windows操作系统未启用登录失败处理功能引发的威胁