准备工作-配置支付宝沙箱应用环境

沙箱调试环境说明:

  • 蚂蚁沙箱环境(Beta)是协助开发者进行接口功能开发及主要功能联调的辅助环境。沙箱环境模拟了开放平台部分产品的主要功能和主要逻辑(当前沙箱支持产品请参考“沙箱支持产品列表”)。为保证沙箱稳定,沙箱环境测试数据会进行定期数据清理。Beta测试阶段每周日中午12点至每周一中午12点为维护时间。在此时间内沙箱环境部分功能可能会不可用。

配置支付宝沙箱应用环境:

1.注册支付宝开发者账户,访问以下地址使用支付宝账户登录沙箱:

https://openhome.alipay.com/platform/appDaily.htm

根据自己实际的需求选择一个类型进行入驻,我这里选择自研开发者入驻:
【Java版】接入支付宝当面付功能-沙箱环境

然后填写相关的实名认证资料:
【Java版】接入支付宝当面付功能-沙箱环境

同意蚂蚁金服开发平台协议:
【Java版】接入支付宝当面付功能-沙箱环境

成功完成注册后,进入研发服务:
【Java版】接入支付宝当面付功能-沙箱环境

然后就会进入到沙箱应用的界面:
【Java版】接入支付宝当面付功能-沙箱环境

有时候跳转到沙箱应用的界面的时候会抽风,如果恰巧抽风的话,可以直接访问如下地址:

https://openhome.alipay.com/platform/appDaily.htm?tab=info


2.以上完成了支付宝开发者账户的注册,进入沙箱应用的管理界面后,把页面往下拉,可以看到有支付宝的沙箱环境app提供下载,但是仅支持安卓版的,把这个app下载到手机上:
【Java版】接入支付宝当面付功能-沙箱环境

下载并安装完成后,到沙箱账户页面上,可以看到有提供商家和买家账户,选择买家账户进行登录:
【Java版】接入支付宝当面付功能-沙箱环境

注:当我们使用买家账户付款后,可以在商家账户收到付款金额。


3.完成以上操作后,配置支付宝沙箱应用的RSA2公钥,到如下网址下载支付宝官方提供的RSA签名验签工具:

https://docs.open.alipay.com/291/105971

下载并安装完成之后,运行.bat批处理文件:
【Java版】接入支付宝当面付功能-沙箱环境

生成Java适用的RSA2密钥:
【Java版】接入支付宝当面付功能-沙箱环境

复制生成的商户应用公钥:
【Java版】接入支付宝当面付功能-沙箱环境

然后到沙箱应用管理界面上,配置RSA2密钥:
【Java版】接入支付宝当面付功能-沙箱环境
【Java版】接入支付宝当面付功能-沙箱环境
【Java版】接入支付宝当面付功能-沙箱环境

配置完之后,此时就可以查看我们配置应用公钥以及支付宝公钥了:
【Java版】接入支付宝当面付功能-沙箱环境

使用支付宝官方提供的RSA签名验签工具生成的RSA密钥对,会存放在这个目录下:
【Java版】接入支付宝当面付功能-沙箱环境

要记住这个目录,或者存放在你熟悉的目录下,因为后面对接支付宝当面付功能的时候需要用到。至此,我们就完成了支付宝沙箱环境的整体配置,接下来我们来调试支付宝当面付的Demo。


支付宝沙箱环境与当面付官方文档整理:


支付宝当面付的简要说明

支付宝扫码支付主业务流程:
【Java版】接入支付宝当面付功能-沙箱环境


支付宝扫码支付流程:
【Java版】接入支付宝当面付功能-沙箱环境


支付宝扫码支付重要的字段
【Java版】接入支付宝当面付功能-沙箱环境
【Java版】接入支付宝当面付功能-沙箱环境
【Java版】接入支付宝当面付功能-沙箱环境
【Java版】接入支付宝当面付功能-沙箱环境
【Java版】接入支付宝当面付功能-沙箱环境
【Java版】接入支付宝当面付功能-沙箱环境


支付宝扫码支付重要细节

主动轮询和回调的区别:

  • 主动轮询就是设置一个频率,每隔一段时间就去查询一下订单状态。而回调则是订单支付成功的时候,会回调我们提供的回调地址。说白了就是轮询是自己查,而回调则是等支付宝来进行回调通知。

避免单边账

  • 单边账就是支付宝记到了账,而我们的商城没有记到账。或者反过来,我们的商城记到了账,而支付宝没有记到账,这就是单边账。

同步请求的加签和验证签名:
【Java版】接入支付宝当面付功能-沙箱环境
【Java版】接入支付宝当面付功能-沙箱环境

回调的验证(签名、金额、订单号、订单状态、交易状态、商户id)

一定要验证并确保可接受的异步通知是支付宝发出的:
【Java版】接入支付宝当面付功能-沙箱环境

回调请求的返回:

  • 也就是支付宝调用我们的提供的时候需要返回一些数据,程序执行完后必须打印输出 “success” (不包含引号),如果商户反馈给支付宝的字符不是success这7个字符,支付宝服务器会不断的重发通知,直到超过24小时22分钟,一般情况下,25小时以内完成8次通知。(通知的间隔频率一般是:4m,10m,10m,1h,2h,6h,15h)

调试支付宝当面付的Java版Demo

支付宝当面付的Java版Demo下载地址:

https://support.open.alipay.com/docs/doc.htm?spm=a219a.7386797.0.0.k0rwWc&treeId=193&articleId=105201&docType=1

下载完成后,使用IDEA打开这个Demo:
【Java版】接入支付宝当面付功能-沙箱环境
【Java版】接入支付宝当面付功能-沙箱环境

点击ok即可:
【Java版】接入支付宝当面付功能-沙箱环境

打开之后我们需要把sdk配置一下,点击step sdk,换成你IDEA里配置好的jdk即可:
【Java版】接入支付宝当面付功能-沙箱环境

选择一个jdk,点击ok即可:
【Java版】接入支付宝当面付功能-沙箱环境

完成工程的基本配置后,我们需要编辑该工程中的zfbinfo.properties属性文件,由于都有注释我就不逐一解释了,如下:

# 支付宝支付网关地址,这里要使用沙箱环境的url
open_api_domain = https://openapi.alipaydev.com/gateway.do
# 支付宝云监视器网关地址
mcloud_api_domain = http://mcloudmonitor.com/gateway.do

# 此处请填写你的PID,即商户UID
pid = 2088xxxxxx20043
# 此处请填写你当面付的APPID
appid = 2016xxxxx15934

# RSA私钥、公钥,即我们使用密钥生成工具所生成的商户私钥、公钥
private_key = MIIEvwIBADANBgkqhkiG9w0BAQEFAASCBKkwggSlAgEAAoIBAQCgbmAt2RjQLDRsTLgzS4Y0hH10rTrQMrFMHerN9m4BmGtjgxYuCWps5FL2LiW/PF0bm7KEB2inBkRkTlGXYMzeR6hiLdV5j5z+6yCFcMoAuIbP8vA+3oQQ0gR46AlI44Gtc3I/aI3muXgHYDfhoIcrc1kKngIAnbdMLljdoqvP/DyOF2MlEeSQpjee9lr3uwwhW8Kl6nWbrPhD2V9onbEUeoDoJLhv6eSzxe7WZ6GbDeq//Q/TfUZD/W0s8g5AgqkCnB1hP7oIkHGb0YFzkIDUY/V4Ex1SEUj8gMw9gC0BZEiLXKSSpW19enNHdT09pK9okTRkyZqfP+NfBDbMAp3VAgMBAAECggEBAJ2JpXKAI8iQD+5lK+BbAm9hxtwjG4TEsqt/GUqk+YMhjBqM5+PPJS3Gy9yoljKC8R8iNhtGNzMEiXZCHgbbbHG9xhCa12zmZJFCjI3cotAwY1miQt5JnT/zK6cam7tyhK2xlvfDEM0HRWFgz58FBpbZTw+I94hpV0w8mtERY0v44OSgpFil29WstKLiBqZRyjroNbY4m7vDa8XM0FudSOXPntGRKRyzqPWSvuBLmkgrNrsfp9t44KjiAjYi/8+HRhc8GmlNkCnxmeLL1cu8N8mSNtDr+mp+AhARKByJqtEr19wVZHaQWlr7HlHWaqKe6pTrdl3FzfO/fQuOqPMjb2ECgYEA5UxAAncQaxl18JNRUbDJpGNNq/gnfXfYaPGts1tm00Mv6ZIfp8vMSYUbFpHeHPQ+CJD/mbLdHMX+6qOo+MpCPRkWl8uCzBwvxz80h0pmIzCshjluYQUb4leyox2qykfyxR9WzciLl36xlFwBMNqpSNamP3XqZbU2XWpq8pWSIbkCgYEAsx0YUk9s8cWpwy23jzJoOlr5kF++vKkQCzNxVD2w3Bg/aiVbmCVgJX18wjW8w3vncPZUsI4KL3nWq6bRHAoRQLCdzvrswhq4sqZz5g/frIruFfqzgRhbTzitHHrOSZ/PmnRaAowCk8b35pTXwOGeDbs+kFmefaL5PxKMu+O+mv0CgYEAwr2br3xHqW4aSJQVgHfRCZh9IwzDHUBnv9liWO3LyqlJS+oakHv5qIcvll+UcKrO9J+RNYw/VmyiL82HeKTu1M017v2cvJVDzsjTaAO78y8nl2e3Yxbfs8Afq4FKyDmK6ffP1T35sFSdpQ7uw/sxwvbqgwM2a+MXpQb4hcaaMaECgYA2flye9kE8EZpDoo4dSAXD81fIYAjk1z7lWYJaUeaUH+BzR+hlEsH8xgAGClli1Dim+prrmFtq9FOmp7spH7r+Bn4MsfUEXSLiX5gVX7D6is5C66JfXWyyXpj0eDx40+FSqaGU8sn58egMRC6cJUhz/wra2hlJOiNA2EDvDSw5dQKBgQDFYzRiwFGpsUH3MCpVhvJ/Sf7npkAxBFzfHtty8Vw17EjpsLhdL9ZlhqY7B0/9T7VqPkK9+iXoi5wPMMPG5XeVoC8ey/Qt30HvyGi4bk1ZWZIQ843NjviMKr0j04KBPJc/f87e3mBrWacBWm4M0Mkw8x42E5KOud6X2G3KPLetRA==
public_key = MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAoG5gLdkY0Cw0bEy4M0uGNIR9dK060DKxTB3qzfZuAZhrY4MWLglqbORS9i4lvzxdG5uyhAdopwZEZE5Rl2DM3keoYi3VeY+c/usghXDKALiGz/LwPt6EENIEeOgJSOOBrXNyP2iN5rl4B2A34aCHK3NZCp4CAJ23TC5Y3aKrz/w8jhdjJRHkkKY3nvZa97sMIVvCpep1m6z4Q9lfaJ2xFHqA6CS4b+nks8Xu1mehmw3qv/0P031GQ/1tLPIOQIKpApwdYT+6CJBxm9GBc5CA1GP1eBMdUhFI/IDMPYAtAWRIi1ykkqVtfXpzR3U9PaSvaJE0ZMmanz/jXwQ2zAKd1QIDAQAB

#SHA256withRsa对应支付宝公钥
alipay_public_key = MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAqFUU1sWXsCfo9t4SK99qX/GaUL1ctxuwOUkeEH6IYmtTdPvA1qCkUigcexVQtD2uNaXBM+u83UFj4bDsI8WhY1CNW4N2+V05rMSPayfOVZHxHWzBFiOETHWn5D4XY6xxv0XBdCG4dwhzpTfalGJqzpTWzKwoPSXdIpMpglziP+QbbSsxfZKo2kqY/jsiLlBhAgi/HLdlCVXs47VEsNQg/BrJt4H7z5qYAjpFwdWNxo5jRWVsVfD+lzNUyJHr0NAvT7hNqaNT35PeV/NEQPJ1DdAnmUZvYdsk5mFUrhWCSXbkQPlVG2UTUQ7F76cilLn4a8DmV2fsKAeZ9zDJNHffyQIDAQAB

# 签名类型: RSA->SHA1withRsa,RSA2->SHA256withRsa
sign_type = RSA2
# 当面付最大查询次数和查询间隔(毫秒)
max_query_retry = 5
query_duration = 5000

# 当面付最大撤销次数和撤销间隔(毫秒)
max_cancel_retry = 3
cancel_duration = 2000

# 交易保障线程第一次调度延迟和调度间隔(秒)
heartbeat_delay = 5
heartbeat_duration = 900

注:alipay_public_key所对应的支付宝公钥,在配置RSA密钥的地方获取,如下图:
【Java版】接入支付宝当面付功能-沙箱环境

到此为止,我们就把demo工程所需的配置给配置好了,接下来运行Main类,控制台输出结果如下代表配置成功:
【Java版】接入支付宝当面付功能-沙箱环境

在输出的日志中,我们可以看到支付宝返回的数据,并且可以找到一个qr_code字段的数据,它的值就是扫码支付的二维码:

"qr_code":"https:\/\/qr.alipay.com\/bax068218xxsw0wxmer1009a"

然后随便在网上找一个二维码生成器,看看能否生成二维码。我这里是可以正常生成的,如下:
【Java版】接入支付宝当面付功能-沙箱环境

这时候,打开并登录支付宝提供的沙箱环境APP,使用该app扫描生成的二维码,看看能否正常支付,我这里是正常支付的,如下:
【Java版】接入支付宝当面付功能-沙箱环境
【Java版】接入支付宝当面付功能-沙箱环境


调试支付宝当面付的Java版Demo2

在上一小节中,我们只是纯粹在后端发起了支付,没有涉及回调。而这个demo是一个Web项目,但由于该demo是使用Eclipse开发的,所以我们需要在IDEA中手动配置成web项目,如下:
【Java版】接入支付宝当面付功能-沙箱环境
【Java版】接入支付宝当面付功能-沙箱环境

注意这里的web.xml文件的路径及web根目录需要设置为WebRoot下的:
【Java版】接入支付宝当面付功能-沙箱环境
【Java版】接入支付宝当面付功能-沙箱环境

配置该工程的Tomcat:
【Java版】接入支付宝当面付功能-沙箱环境
【Java版】接入支付宝当面付功能-沙箱环境

配置完成后,工程目录如下:
【Java版】接入支付宝当面付功能-沙箱环境

注:可能根据实际情况还需自行修改index.html等web文件代码,主要是路径相关的。

配置完成后,启动Tomcat运行该项目,页面如下:
【Java版】接入支付宝当面付功能-沙箱环境

点击二维码支付,进入到如下界面,输入一些相关的测试数据:
【Java版】接入支付宝当面付功能-沙箱环境

点击确认后会生成支付的二维码:
【Java版】接入支付宝当面付功能-沙箱环境

使用沙箱app扫描生成的二维码,并进行支付,测试能否支付成功:
【Java版】接入支付宝当面付功能-沙箱环境
【Java版】接入支付宝当面付功能-沙箱环境


测试完web的支付后,接下来我们调试支付宝的回调,在此之前我们需要做一个内网穿透。我这里内网穿透工具使用的是natapp,如果不会使用的话,可参考我之前写的一篇文章:使用natapp开启内网穿透之旅

配置好natapp并运行客户端成功后,在该demo工程中创建一个test_pay.jsp文件,用于模拟一个回调接口,这样我们就可以测试支付宝的回调了,代码如下:

<%@ page import="java.util.Enumeration" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
<%
    System.out.println("测试支付宝回调,回调参数如下:");

    Enumeration enu = request.getParameterNames();
    while (enu.hasMoreElements()) {
        String paraName = (String) enu.nextElement();
        System.out.println(paraName + " : " + request.getParameter(paraName));
    }
%>
</body>
</html>

因为我们是在web上扫码支付,所以需要在支付宝demo工程的trade_precreate.jsp文件中加入回调接口的地址:

...
AlipayTradePrecreateRequestBuilder builder = new AlipayTradePrecreateRequestBuilder()
        .setSubject(subject)
        .setTotalAmount(totalAmount)
        .setOutTradeNo(outTradeNo)
        .setUndiscountableAmount(undiscountableAmount)
        .setSellerId(sellerId)
        .setBody(body)
        .setOperatorId(operatorId)
        .setStoreId(storeId)
        .setExtendParams(extendParams)
        .setTimeoutExpress(timeoutExpress)
        .setNotifyUrl("http://zero.mynatapp.cc/test_pay.jsp")//支付宝服务器主动通知商户服务器里指定的页面http路径,根据需要设置
        .setGoodsDetailList(goodsDetailList);
...        

注:如果是使用后端发起支付的方式,则是在Main类的test_trade_precreate方法中,加上这个回调地址

然后在支付宝沙箱环境管理页面里,配置这个回调地址:
【Java版】接入支付宝当面付功能-沙箱环境

完上如上配置后,启动支付宝demo工程的Tomcat服务器,和之前一样,在页面上输入相应的信息生成支付二维码,然后使用支付宝沙箱app扫描一下这个二维码,付款成功后,从控制台输出的信息来查看这个回调接口是否被成功回调。若成功回调则会输出如下回调信息:

测试支付宝回调,回调参数如下:
gmt_create : 2018-06-13 14:54:05
charset : utf-8
seller_email : surjcl2760@sandbox.com
subject : testPay
sign : ZkleNYq9HZFfAs7R8HJETSkSZ3Q4IbJgCR5yFURcPmOxcebUCJRGoTcdn1SSFjXpusDyefzDZDN4Hgnpa1oVCSqaCbLZfvhqlN8eHKh8NEj7bYD9BIOYgmLbBDOT6IEAwWX0ygqEXo+zbwCXsAmbUCL7IfKPnHZ7jhR0scIoKDRJBpd8hKNtmVr1B0DyppbnvadyMy5IhqBPT1Nu6SkOXXa8beIRxZFVE/3lwxYc9/wcKunTVgYTwHSGcq2/4fxMh0NkK94o+0Lcz/T8VOvOMi3t7VTjn6Vjg+1xu302akz8z0kpFVMTCACpJTblg4u9g55q/YQsOxR9zOt7TwecTg==
body : 购买商品2件共15.00元
buyer_id : 2088102175768847
invoice_amount : 399.00
notify_id : d80164c060cb7e9dc8d54aea21de4f7mhe
fund_bill_list : [{"amount":"399.00","fundChannel":"ALIPAYACCOUNT"}]
notify_type : trade_status_sync
trade_status : TRADE_SUCCESS
receipt_amount : 399.00
app_id : 2016091500515934
buyer_pay_amount : 399.00
sign_type : RSA2
seller_id : 2088102175720043
gmt_payment : 2018-06-13 14:54:14
notify_time : 2018-06-13 14:54:15
version : 1.0
out_trade_no : 156355654
total_amount : 399.00
trade_no : 2018061321001004840200678870
auth_app_id : 2016091500515934
buyer_logon_id : rqi***@sandbox.com
point_amount : 0.00

到此为止,我们就成功在沙箱环境下接入支付宝当面付功能了,对于官方提供的demo,我们也都一一调试成功,那么接下来就可以将demo中所需要的代码,集成到自己的项目中即可实现支付宝扫码付功能了。