快速接入

本文档展示了如何从零开始,使用支付宝开放平台服务端 SDK 快速接入App支付产品,完成与支付宝对接的部分。

如您使用的是旧版接口,请点击旧版移动支付文档查看。若您希望从移动支付老版本升级为App支付新版本,请参考以下步骤完成App支付新版本的接入工作。若想了解更多关于新版本的升级改造内容,可参考移动支付与App支付对比

注意:
App支付不支持第三方授权,不能代商家发起请求。文档中的代码示例和 Demo 仅阐述 API 基本使用方法,仅针对大众场景,供 ISV 参考。特殊情况还请 ISV 自行扩展,确保符合自身业务需求。

第一步:创建应用并获取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

为了帮助开发者调用开放接口,我们提供了开放平台服务端DEMO & 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 支付宝网关(固定) https://openapi.alipay.com/gateway.do
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 对象。

注意:
App支付不支持第三方授权,不能代商家发起请求。

第四步:调用接口

为了避免在线上生产环境联调过程中遇到问题,建议在沙箱环境中联调通过后再在线上生产环境进行联调,具体操作步骤见沙箱联调指南。如果需要在线上调用接口,需要参考下面步骤:应用上线后再进行接口调用,不然会出现“无权限错误”的报错信息。

系统交互流程如下图所示:

以 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 来调用。

交易操作

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();
    }
}

第五步:调试应用

支付能力直接涉及到交易与资金,为了方便开放者调试支付能力,我们已经准备好沙箱环境,包括沙箱环境账号和沙箱版支付宝钱包,这样就可以在沙箱环境调试了。具体操作步骤见沙箱联调指南

第六步:上线应用

商户本身应用上线时候,也要把支付宝开放平台的应用上线
应用开发完成后,请开发者自行进行验收和安全性检查(安全性检查可参考《开放平台第三方应用安全开发指南》),验收检查完成后可申请上线。应用申请上线后,会同时申请此列表的功能,接口即生效,这个状态下的应用能够调用生产环境的接口。

onlineServer