支付宝
App支付产品介绍更新时间:2020-06-01 11:08:15获取能力
场景介绍
APP支付适用于商家在 App 应用中集成支付宝支付功能。 商家APP调用支付宝提供的 SDK,SDK 再调用支付宝APP内的支付模块。如果用户已安装支付宝 APP,商家 APP 会跳转到支付宝中完成支付,支付完后跳回到商家APP内,最后展示支付结果。如果用户没有安装支付宝 APP,商家 APP 内会调起支付宝网页支付收银台,用户登录支付宝账户,支付完后展示支付结果。 目前支持手机系统有:iOS(苹果)、Android(安卓)。
产品流程
用户已安装支付宝支付流程
1.用户在商家 App 中选择商品下单、确认购买,进入支付环节,选择支付宝,用户点击确认支付,如图1;
2.进入到支付宝页面,调起支付宝支付,出现确认支付界面,如图2;
3.用户确认收款方和金额,点击立即支付后出现输入密码界面,如图3;
4.输入正确密码后,支付宝端显示支付结果,如图 4; 5.自动回跳到商家 App 中,商家根据付款结果个性化展示订单处理结果,如图 5。
用户未安装支付宝支付流程
1.用户在商家 App 中选择商品下单、确认购买,进入支付环节,选择支付宝,用户点击确认支付,如图 6;
2.用户未安装支付宝客户端,则调起支付宝网页支付收银台,用户登录支付宝账户,如图 7;
3.登录成功后,进入确认付款页面,如图 8;
4.用户点击确认付款,进入支付密码页面,如下图 9; 5.用户输入密码,完成支付,展示支付结果,如图 10。
应用案例
目前已上线支付案例,商家可进行实际体验:饿了么 app、优酷 app、携程 app。
准入条件
- 申请前必须拥有经过实名认证的支付宝账户;
- 企业或个体工商户可申请;
- 需提供真实有效的营业执照,且支付宝账户名称需与营业执照主体一致;
- 网站能正常访问且页面显示完整,网站需要明确经营内容且有完整的商品信息;
- 网站必须通过ICP备案。如为个体工商户,网站备案主体需要与支付宝账户主体名称一致;
- 如为个体工商户,则团购不开放,且古玩、珠宝等奢侈品、投资类行业无法申请本产品。
计费模式
- 费率按单笔计算;
- 一般行业费率:0.6%;自2018年5月9日起,特殊行业新签约费率从 1.2% 调整为 1%,特殊行业范围包括:休闲游戏;网络游戏点卡、渠道代理;游戏系统商;网游周边服务、交易平台; 网游运营商(含网页游戏)。
官方入门地址QuickStart: https://opendocs.alipay.com/open/204/105297/
第一步:创建应用并获取APPID
要在您的应用中接入支付宝 App 支付能力,您需要登录支付宝开放平台(open.alipay.com),在开发者中心中创建您的应用,应用审核通过后会生成应用唯一标识(APPID),并且可以申请开通开放产品使用权限。通过 APPID 您的应用才能调用开放产品的接口能力。需要详细了解开放平台创建应用步骤请参考《开放平台应用创建指南》。
第二步:配置应用
添加功能并签约
应用创建完成后,系统会自动跳转到应用详情页面。开发者可以点击 添加功能 来 添加 App支付 功能。添加功能后开发者需要在开放平台里进行 签约,第三方应用开发者可以代替商户签约。
配置密钥
为了保证交易双方(商户和支付宝)的身份和数据安全,开发者在调用接口前,需要配置双方密钥,对交易数据进行双方校验。RSA 密钥包含应用私钥(APP_PRIVATE_KEY)、应用公钥(APP_PUBLIC_KEY)。生成密钥后,开发者需要在开放平台开发者中心进行密钥配置,配置完成后可以获取支付宝公钥(ALIPAY_PUBLIC_KEY),配置的详细步骤请参考《配置应用环境》。您还可以通过观看快速签名教程学习密钥的配置。
说明:
支付宝开放平台 SDK 封装了签名和验签过程,只需配置账号及密钥参数,建议开发者使用。开发者还可以通过 自助排查流程 和 验签教程 自助排查配置应用过程中遇到的问题。
第三步:集成和开发
接入移动支付需要集成两个 SDK:客户端 SDK 需要集成在商户自己的 APP 中,用于唤起支付宝 APP 并发送交易数据,并在支付宝APP返回商户APP时获得支付结果;服务端SDK需要商户集成在自己的服务端系统中,用于协助解析并验证客户端同步返回的支付结果和异步通知。
集成前提
开发者在集成和开发前需要了解一下常用的接入方式和架构建议,如下图所示:
集成客户端 SDK
在集成 App 支付能力时,支付宝提供主流移动平台的 App 提供集成方式。点击下载客户端SDK。
更多集成说明参见 客户端 Android 集成说明 和 客户端 iOS 集成说明。
集成服务端 SDK
为了帮助开发者调用开放接口,我们提供了开放平台服务端 SDK,包含 JAVA, PHP, PYTHON, NodeJS 和 .NET 版本,封装了签名&验签、HTTP接口请求等基础功能(下单请求参数 orderStr 在服务端 SDK 封装,客户端 SDK 直接使用)。建议开发者先下载对应语言版本的 SDK 并引入您的开发工程进行快速接入。
SDK 调用前需要进行初始化,代码示例如下:
AlipayClient alipayClient = new DefaultAlipayClient(URL, APP_ID, APP_PRIVATE_KEY, FORMAT, CHARSET, ALIPAY_PUBLIC_KEY, SIGN_TYPE);
关键参数说明:
配置参数 | 示例值解释 | 获取方式/示例值 | |
URL | 支付宝网关(固定) | | |
APP_ID | APPID 即创建应用后生成 | 获取见 第一步:创建应用并获取 APPID | |
APP_PRIVATE_KEY | 开发者应用私钥,由开发者自己生成 | 获取见 第二步:配置应用 > 配置密钥 | |
FORMAT | 参数返回格式,只支持 json | json(固定) | |
CHARSET | 请求和签名使用的字符编码格式,支持 GBK 和 UTF-8 | 开发者根据实际工程编码配置 | |
ALIPAY_PUBLIC_KEY | 支付宝公钥,由支付宝生成 | 获取详见 第二步:配置应用 > 配置密钥 | |
SIGN_TYPE | 商户生成签名字符串所使用的签名算法类型,目前支持 RSA2 和 RSA,推荐使用 RSA2 | RSA2 | |
接下来,就可以用 alipayClient 来调用具体的 API 了。alipayClient 只需要初始化一次,后续调用不同的API都可以使用同一个 alipayClient 对象。
第四步:调用接口
为了避免在线上生产环境联调过程中遇到问题,建议在沙箱环境中联调通过后再在线上生产环境进行联调,具体操作步骤见 沙箱联调指南。如果需要在线上调用接口,需要参考下面步骤:应用上线后再进行接口调用,不然会出现“无权限错误”的报错信息。
系统交互流程如下图所示:
以 Android 平台为例: 图中虚线标识商户链路,实线标识支付宝链路。
- 第4步调用支付接口:此消息就是本接口所描述的支付宝客户端SDK提供的支付对象 PayTask,将商户签名后的订单信息传进 payv2 方法唤起支付宝收银台,交易数据格式具体参见请求参数说明。
- 第5步支付请求:支付宝客户端 SDK 将会按照商户客户端提供的请求参数发送支付请求。
- 第8步接口返回支付结果:商户客户端在第4步中调用的支付接口,会返回最终的支付结果(即同步通知),参见客户端同步返回。
- 第13步用户在支付宝 APP 或 H5 收银台完成支付后,会根据商户在手机网站支付 API 中传入的前台回跳地址 return_url 自动跳转回商户页面,同时在 URL 请求中附带上支付结果参数。同时,支付宝还会根据原始支付 API 中传入的异步通知地址 notify_url,通过 POST 请求的形式将支付结果作为参数通知到商户系统,详情见支付结果异步通知。
除了正向支付流程外,支付宝也提供交易查询、关闭、退款、退款查询以及对账等配套 API。
特别注意:
- 构造交易数据并签名必须在商户服务端完成,商户的应用私钥绝对不能保存在商户 APP 客户端中,也不能从服务端下发。
- 同步返回的数据,只是一个简单的结果通知,商户确定该笔交易付款是否成功需要依赖服务端收到支付宝异步通知的结果进行判断。
- 商户系统接收到通知以后,必须通过验签(验证通知中的 sign 参数)来确保支付通知是由支付宝发送的。建议使用支付宝提供的 SDK 来完成,详细验签规则参考异步通知验签。
使用SDK快速接入
App支付 API 必须通过支付宝提供的移动端 SDK 来调用。
交易操作
外部商户APP唤起快捷 SDK 创建订单并支付,具体的接口参数和示例代码可详见 alipay.trade.app.pay (app支付接口2.0) 请求参数说明 。
1.交易查询接口 alipay.trade.query:
AlipayClient alipayClient = new DefaultAlipayClient ( "https://openapi.alipay.com/gateway.do" , APP_ID , APP_PRIVATE_KEY , "json" , CHARSET , ALIPAY_PUBLIC_KEY , "RSA2" ); //获得初始化的AlipayClient
AlipayTradeQueryRequest request = new AlipayTradeQueryRequest (); //创建API对应的request类
request . setBizContent ( "{" +
" \"out_trade_no\":\"20150320010101001\"," +
" \"trade_no\":\"2014112611001004680073956707\"" +
" }" ); //设置业务参数
AlipayTradeQueryResponse response = alipayClient . execute ( request ); //通过alipayClient调用API,获得对应的response类
System . out . print ( response . getBody ());
//根据response中的结果继续业务逻辑处理
关键入参:
参数名称 | 参数说明 |
out_trade_no | 支付时传入的商户订单号,与 trade_no 必填一个 |
trade_no | 支付时返回的支付宝交易号,与 out_trade_no 必填一个 |
关键出参:
参数名称 | 参数说明 |
trade_no | 支付宝28位交易号 |
out_trade_no | 支付时传入的商户订单号 |
trade_status | 交易当前状态 |
2.交易退款接口 alipay.trade.refund: 商户由于业务原因如金额错误、用户退货、对账不平等情况可能需要退款,退款的途径按照支付途径原路返回。支付渠道为花呗、余额等退款即时到账。银行卡的退款时间以银行退款时间为准,一般情况下2小时内可到账。可在商户门户(b.alipay.com)中退款;也可使用交易成功的商户订单号或支付宝交易号进行退款 , 支持全额和部分退款,其过程如下图所示:
退款接口调用示例如下:
AlipayClient alipayClient = new DefaultAlipayClient ( "https://openapi.alipay.com/gateway.do" , APP_ID , APP_PRIVATE_KEY , "json" , CHARSET , ALIPAY_PUBLIC_KEY , "RSA2" ); //获得初始化的AlipayClient
AlipayTradeRefundRequest request = new AlipayTradeRefundRequest (); //创建API对应的request类
request . setBizContent ( "{" +
" \"out_trade_no\":\"20150320010101001\"," +
" \"trade_no\":\"2014112611001004680073956707\"," +
" \"out_request_no\":\"1000001\"," +
" \"refund_amount\":\"1\"" +
" }" ); //设置业务参数
AlipayTradeRefundResponse response = alipayClient . execute ( request ); //通过alipayClient调用API,获得对应的response类
System . out . print ( response . getBody ());
// 根据response中的结果继续业务逻辑处理
关键入参:
参数名称 | 参数说明 |
out_trade_no | 支付时传入的商户订单号,与 trade_no 必填一个 |
trade_no | 支付时返回的支付宝交易号,与 out_trade_no 必填一个 |
out_request_no | 本次退款请求流水号,部分退款时必传 |
refund_amount | 本次退款金额 |
关键出参:
参数名称 | 参数说明 |
refund_fee | 该笔交易已退款的总金额 |
3.查询对账单下载地址接口alipay.data.dataservice.bill.downloadurl.query: 为了保障交易的正确性,支付宝提供了交易账单数据提供给商户对账,对账说明。
AlipayClient alipayClient = new DefaultAlipayClient ( "https://openapi.alipay.com/gateway.do" , APP_ID , APP_PRIVATE_KEY , "json" , CHARSET , ALIPAY_PUBLIC_KEY , "RSA2" ); //获得初始化的AlipayClient
AlipayDataDataserviceBillDownloadurlQueryRequest request = new AlipayDataDataserviceBillDownloadurlQueryRequest (); //创建API对应的request类
request . setBizContent ( "{" +
" \"bill_type\":\"trade\"," +
" \"bill_date\":\"2016-04-05\"" +
" }" ); //设置业务参数
AlipayDataDataserviceBillDownloadurlQueryResponse response = alipayClient . execute ( request );
System . out . print ( response . getBody ());
//根据response中的结果继续业务逻辑处理
关键入参:
参数名称 | 参数说明 |
bill_type | 固定传入 trade |
bill_date | 需要下载的账单日期,最晚是当期日期的前一天 |
关键出参:
参数名称 | 参数说明 |
bill_download_url | 账单文件下载地址,30秒有效 |
下载账单文件:
//将接口返回的对账单下载地址传入urlStr
String urlStr = "http://dwbillcenter.alipay.com/downloadBillFile.resource?bizType=X&userId=X&fileType=X&bizDates=X&downloadFileName=X&fileId=X" ;
//指定希望保存的文件路径
String filePath = "/Users/fund_bill_20160405.csv" ;
URL url = null ;
HttpURLConnection httpUrlConnection = null ;
InputStream fis = null ;
FileOutputStream fos = null ;
try {
url = new URL ( urlStr );
httpUrlConnection = ( HttpURLConnection ) url . openConnection ();
httpUrlConnection . setConnectTimeout ( 5 * 1000 );
httpUrlConnection . setDoInput ( true );
httpUrlConnection . setDoOutput ( true );
httpUrlConnection . setUseCaches ( false );
httpUrlConnection . setRequestMethod ( "GET" );
httpUrlConnection . setRequestProperty ( "Charsert" , "UTF-8" );
httpUrlConnection . connect ();
fis = httpUrlConnection . getInputStream ();
byte [] temp = new byte [ 1024 ];
int b ;
fos = new FileOutputStream ( new File ( filePath ));
while (( b = fis . read ( temp )) != - 1 ) {
fos . write ( temp , 0 , b );
fos . flush ();
}
} catch ( MalformedURLException e ) {
e . printStackTrace ();
} catch ( IOException e ) {
e . printStackTrace ();
} finally {
try {
fis . close ();
fos . close ();
httpUrlConnection . disconnect ();
} catch ( NullPointerException e ) {
e . printStackTrace ();
} catch ( IOException e ) {
e . printStackTrace ();
}
}
第五步:调试应用
支付能力直接涉及到交易与资金,为了方便开放者调试支付能力,我们已经准备好沙箱环境,包括沙箱环境账号和沙箱版支付宝钱包,这样就可以在沙箱环境调试了。具体操作步骤见沙箱联调指南。
目前 Android 的 APP 支付开发支持沙箱环境而 iOS 版的 APP 支付开发暂不支持沙箱环境。
第六步:上线应用
商户本身应用上线时候,也要把支付宝开放平台的应用上线。 应用开发完成后,请开发者自行进行验收和安全性检查(安全性检查可参考《开放平台第三方应用安全开发指南》),验收检查完成后可申请上线。应用申请上线后,会同时申请此列表的功能,接口即生效,这个状态下的应用能够调用生产环境的接口。
API 列表更新时间:2020-05-13 10:14:39
此列表包含该产品所涉及的所有接口,点击 查看文档 可查看接口的公共请求参数,业务请求参数,返回参数,其他语言请求示例以及错误码等。
API英文名 | API中文名 | 完整文档 |
alipay.trade.query | 交易查询接口 | |
alipay.trade.close | 交易关闭接口 | |
alipay.trade.refund | 交易退款接口 | |
alipay.trade.fastpay.refund.query | 交易退款查询接口 | |
alipay.trade.app.pay | app 支付接口 2.0 | |
alipay.data.dataservice.bill.downloadurl.query | 查询账单下载地址接口 |
maven
<!--支付宝sdk-->
<dependency>
<groupId>com.alipay.sdk</groupId>
<artifactId>alipay-sdk-java</artifactId>
<version>4.9.11.ALL</version>
</dependency>
<!--application.yml 配置-->
alipay:
url: https://openapi.alipaydev.com/gateway.do # 支付宝网关地址
appId: 2016******* #应用appId
appPrivateKey: #应用私钥
format: json
charset: UTF-8
publicKey: #公钥
signType: RSA2
callbackUrl: http://10.10.10.10:30000/pay/ali/callback #支付宝回调通知接口,必须对外网可见
1.app支付接口 https://opendocs.alipay.com/apis/api_1/alipay.trade.app.pay
AlipayTradeAppPayRequest request = new AlipayTradeAppPayRequest();
AlipayTradeAppPayModel model = new AlipayTradeAppPayModel();
setSubjectByOrderType(order.getOrderType(), model);
model.setStoreId(order.getBusinessId());
model.setOutTradeNo(tradeNo);
// 最晚付款时间
model.setTimeoutExpress("90m");
model.setTotalAmount(totalPayAmount.toString());
model.setProductCode("QUICK_MSECURITY_PAY");
request.setBizModel(model);
//商户外网可以访问的异步地址
request.setNotifyUrl(aliPayProperties.getCallbackUrl());
try {
AlipayTradeAppPayResponse response = alipayClient.sdkExecute(request);
//就是orderString 可以直接给客户端请求,无需再做处理
return response.getBody();
} catch (AlipayApiException e) {
log.error("get AliPay orderString fail: {}", e.getMessage());
return "";
}
客户端根据后端返回的支付字符串,唤起第三方支付,用户付款。
2. 支付通知接口 https://opendocs.alipay.com/open/204/105301
用户进行支付交易后,支付宝服务会异步通知配置的 callbackUrl
通知触发条件
触发条件名 | 触发条件描述 | 触发条件默认值 |
TRADE_FINISHED | 交易完成 | true(触发通知) |
TRADE_SUCCESS | 支付成功 | true(触发通知) |
WAIT_BUYER_PAY | 交易创建 | false(不触发通知) |
TRADE_CLOSED | 交易关闭 | true(触发通知) |
实测部分退款也会触发通知,需要特殊处理,接收通知后服务端应该记录交易信息和退款信息
Map<String, String> paramsMap = ... //将异步通知中收到的待验证所有参数都存放到map中
boolean signVerified = AlipaySignature.rsaCheckV1(paramsMap, ALIPAY_PUBLIC_KEY, CHARSET) //调用SDK验证签名
if (signVerified){
// TODO 验签成功后
//按照支付结果异步通知中的描述,对支付结果中的业务内容进行1\2\3\4二次校验,校验成功后在response中返回success,校验失败返回failure
} else {
// TODO 验签失败则记录异常日志,并在response中返回failure.
}
3. 对账说明 https://opendocs.alipay.com/open/204/106262
思路:
1.下载账单
2.解析下载的账单与数据库记录的交易进行比对,平账
3. 多账或者少账需要人工解决, 边界值的账单(23时59分59秒的情况),系统应该自动判断修复数据创建时间,时间已支付宝端为准。