App接入支付宝支付
1、App支付简介
买家在手机、掌上电脑等无线设备的应用程序内,可通过支付宝进行付款购买特定服务或商品,资金即时到账。
2、App支付申请条件
1.申请前必须拥有经过实名认证的支付宝账户;
2.企业或个体工商户可申请;
3.需提供真实有效的营业执照,且支付宝账户名称需与营业执照主体一致;
4.如应用开发者与支付宝账户名称不一致需提供开发合作协议;
5.如应用已上架,需提供应用名称和下载链接;若应用未上架,需提供demo或产品说明文档;
6.古玩、珠宝等奢侈品、投资类行业无法申请本产品;
3、签约费率说明
费率按单笔计算;
一般行业费率:一般行业新签手续费率将优惠至0.55%(优惠日至2017年6月30日)
特殊行业费率:1.2%,行业范围包括:手机、通讯设备销售;家用电器;数码产品及配件;休闲游戏;网络游戏点卡、渠道代理;游戏系统商;网游周边服务、交易平台;网游运营商(含网页游戏)。
非营利性机构:需要提交资料进行审核,以支付宝官方审核通过为准。
4、提现收费标准和限额
当日到账 单笔金额
0-10万元(含10万元):0.2% (最低2元,最高25元)
10万元-500万元(不含10万元):0.025% (无上、下限)
次日到账 0元(无上、下限)
限额 单笔:500万元
当日:500万元
5、场景介绍
适用于商家在App应用中集成支付宝支付功能。
商家APP调用支付宝提供的SDK调用支付宝客户端内的支付模块,商家APP会跳转到支付宝中完成支付,支付完后跳回到商家APP内,最后展示支付结果。
目前支持手机系统有:iOS(苹果)、Android(安卓)。
5.1用户已安装支付宝支付流程
步骤1:用户在商家App中选择商品下单、确认购买,进入支付环节,选择支付宝,用户点击确认支付,如图5.1.1;
步骤2:进入到支付宝页面,调起支付宝支付,出现确认支付界面,如图5.1.2;
步骤3:用户确认收款方和金额,点击立即支付后出现输入密码界面,如图5.1.3;
步骤4:输入正确密码后,支付宝端显示支付结果,如图5.1.4;
步骤5:自动回跳到商家App中,商家根据付款结果个性化展示订单处理结果,如图5.1.5。
5.2用户未安装支付宝支付流程,跳转到H5支付
步骤1:用户在商家App中选择商品下单、确认购买,进入支付环节,选择支付宝,用户点击确认支付,如图5.2.1;
步骤2:用户未安装支付宝客户端,则调起支付宝网页支付收银台,用户登录支付宝账户,如图5.2.2和图5.2.3;
步骤3:登录成功后,进入付款确认页面,如图5.2.4;
步骤4:用户点击确认付款,进入支付密码页面,如下图5.2.5;用户输入密码,完成支付,展示支付结果,如图5.2.6。
6、案例及规范
- 目前已上线支付案例,商家可进行实际体验。
饿了么app、优酷app、携程app。 - 支付宝收银台界面规范
列表首位+默认勾选+Logo+推荐标签+标语,最低标准为“Logo+支付宝”,并将作为审核依据。 - 支付宝Logo、收银台素材下载
7、App支付接入
7.1创建应用
接入App支付能力,需要在开放平台创建一个应用,通过该应用来接入各种能力。
7.1.1成为开放平台的入驻服务商或者商户
入驻前准备
1、公司联系方式:包含联系人姓名、联系手机、联系邮箱。
2、未注册企业支付宝账号的企业,请提前准备:法定代表人信息、身份证照片、实际控制人信息、常用联系手机号码;企业证照(营业执照、组织机构代码证)照片;企业银行账号信息。
支付宝账户注册及认证
个人用户可注册个人账号,企业用户请注册企业类型账号。推荐服务商注册企业类型支付宝账户,部分功能仅针对企业开放。
企业账号注册及认证流程请见:
1):打开www.alipay.com,点击【免费注册】,选择【企业账户】,输入对应邮箱及验证码,点击【下一步】
2)验证手机号码,点击【下一步】,点击【立即查收邮件】
3)打开邮箱接收支付宝激活邮件,点击【继续注册】
4)填写账户相关信息,点击【确定】
5)点击【企业实名信息填写】,填写企业相关信息,上传对应证件及对公银行信息
6)证件审核通过以后,按照认证页面的提示向支付宝收款账户打款,打款金额为页面提示的金额。认证结果会短信及邮箱的方式通知。(认证成功后款项会退回汇款)
使用支付宝账号登录
企业请使用企业支付宝账号登录,个人可使用个人支付宝账号登录。
填写公司联系人信息
请提供公司常用联系人的姓名、电子邮箱及手机号码,及时掌握开放平台最新动态。
查阅并一键签署开放平台主要协议,完成后即成为蚂蚁金服服务商
7.1.2创建应用
应用基础信息在开发应用过程中可以无需审核随时完善。
需要完善的内容 作用
应用名称 应用名称和应用图标会在授权、分享的场景中露
出,请准确填写相关信息
注意:应用名称和应用图标会在应用申请上线时进行审核,所以在配置时,建议先了解相关审核规则,点此了解。
7.2配置应用
7.2.1添加应用功能
开发者在开发过程中,可以添加自己需要的功能到“功能列表”。
不同的功能会有不同的使用条件,如果某个功能的使用条件为签约,则使用者在使用此功能前,需要签约对应的产品,具体签约方式,可参考“如何使用应用”。
7.2.2配置应用环境
开发者所需配置内容请参考:
字段名称 字段描述
应用网关 用于接收支付宝异步通知,例如口碑开店中,需要配置此网关来接收开发者门店被动通知。
授权回调地址 第三方授权或用户信息授权后回调地址。授权链接中配置的redirect_uri的值必须与此值保持一致。(如:https://www.alipay.com) 注:当填入该地址时,系统会自动进行安全检测,详情请参考安全检测。
RSA(SHA256)密钥 开发者要保证接口中使用的私钥与此处的公钥匹配,否则无法调用接口。可参考密钥的生成与配置,且接口参数sign_type=RSA2。
RSA(SHA1)密钥 同上,且接口参数sign_type=RSA。
7.2.3应用申请上线
应用开发完成后,请开发者自行进行验收并完成安全性检查(安全性检查可参考《开放平台第三方应用安全开发指南》),验收检查完成后,可“提交审核”。应用上线成功后,状态变为已上线,该状态下的应用能够调用生产环境的接口。
开发者点击“提交审核”后,预计会有1个工作日的审核时间,请耐心等待。如需更快收到通知,请使用支付宝客户端扫码接收审核结果。
应用上线后可新增功能、删除功能,操作后实时生效。删除功能时请谨慎操作,如果线上已经有用户使用此功能,删除功能后会导致无法使用。
7.2.4签约
应用上线后,开发者可以点击“概览”页签中“功能选项”右侧的“立即签约”按钮,如下图。
7.2.5生成RSA秘钥
支付宝提供一键生成工具便于开发者生成一对RSA密钥,可通过下方链接下载密钥生成工具:
下载该工具后,解压打开文件夹,运行“RSA签名验签工具.bat”(WINDOWS)或“RSA签名验签工具.command”(MAC_OSX)。
详细步骤:
1.根据开发语言选择密钥格式。
2.选择密钥长度,建议使用2048位。
3.点击 “生成密钥”,会自动生成商户应用公钥和应用私钥。
4.点击“打开密钥文件路径”,即可找到生成的公私钥。如图:
生成的私钥需妥善保管,避免遗失,不要泄露。应用私钥需填写到代码中供签名时使用。应用公钥需提供给支付宝账号管理者上传到支付宝开放平台。
7.2.6配置秘钥
为了保证交易双方的身份和数据安全,需要配置双方密钥。
在“我的应用”中,选择要配置密钥的应用,点击“查看”。记录对应的APPID(下图红框处),在代码中使用。
在“应用环境”-“接口加签方式”下方点击“设置应用公钥”。
注:接口中的sign_type参数应与上传密钥的加签方式一致。例如接口参数中sign_type=RSA2,请求时就会使用此处设置的RSA2(SHA256)公钥验签。
建议使用RSA2加签方式。
根据开发者的条件设置应用公钥或上传公钥证书,常规请点击设置应用公钥。
把签名验签工具里“公钥”的内容复制到此处,点击“保存”完成密钥设置。
保存成功后,在同一页面查看或修改应用公钥或上传应用公钥证书。
保存支付宝公钥内容,在代码中验签使用。
7.3开发
App支付为开发者提供了Android和iOS的客户端SDK, 为了验证交易数据的来源,开发者需要在商家后台对交易数据进行加签, 验签,那么就需要集成开放平台服务端SDK
下载客户端SDK | 下载服务端SDK
7.3.1集成客户端SDK
在集成App支付能力时,为主流移动平台的App提供集成方式
了解更多Android平台集成 | 了解更多iOS平台集成
此处以iOS为例:
步骤1:启动IDE(如Xcode),把iOS包中的压缩文件中以下文件拷贝到项目文件夹下,并导入到项目工程中。
AlipaySDK.bundle
AlipaySDK.framework
在Build Phases选项卡的Link Binary With Libraries中,增加以下依赖:
步骤2:封装方法,用于商户客户端与商户服务端通信:发生支付时客户端上送订单详细信息给服务器,服务器签名后返回给客户端。
/*
*生成订单信息
*/
//将商品信息赋予AlixPayOrder的成员变量
Order* order = [Order new];
// NOTE: app_id设置
order.app_id = appID;
// NOTE: 支付接口名称
order.method = @"alipay.trade.app.pay";
// NOTE: 参数编码格式
order.charset = @"utf-8";
// NOTE: 当前时间点
NSDateFormatter* formatter = [NSDateFormatter new];
[formatter setDateFormat:@"yyyy-MM-dd HH:mm:ss"];
order.timestamp = [formatter stringFromDate:[NSDate date]];
// NOTE: 支付版本
order.version = @"1.0";
// NOTE: sign_type 根据商户设置的私钥来决定
order.sign_type = (rsa2PrivateKey.length > 1)?@"RSA2":@"RSA";
// NOTE: 商品数据
order.biz_content = [BizContent new];
order.biz_content.body = @"我是测试数据";
order.biz_content.subject = @"1";
order.biz_content.out_trade_no = [self generateTradeNO]; //订单ID(由商家自行制定)
order.biz_content.timeout_express = @"30m"; //超时时间设置
order.biz_content.total_amount = [NSString stringWithFormat:@"%.2f", 0.01]; //商品价格
步骤3:订单支付调用方法
方法原型:-(void)payOrder:(NSString )orderStr fromScheme:(NSString )schemeStr callback:(CompletionBlock)completionBlock;
参数名称 参数描述
NSString scheme 商户程序注册的URL protocol,供支付完成后回调商户程序使用。
(CompletionBlock)completionBlock 快捷支付开发包回调函数,返回免登、支付结果。本地未安装支付宝客户端,或未成功调用支付宝客户端进行支付的情况下(走H5收银台),会通过该completionBlock返回支付结果。相应的结果参考"客户端同步返回"。
NSString orderString app支付请求参数字符串,主要包含商户的订单信息,key=value形式,以&连接。
步骤4:处理客户端返回URL
方法原型:-(void)processOrderWithPaymentResult:(NSURL*)resultUrl standbyCallback:(CompletionBlock)completionBlock;
参数名称 参数描述
NSURL *resultUrl 支付宝客户端回传的url
(CompletionBlock)completionBlock 本地安装了支付宝客户端,且成功调用支付宝客户端进行支付的情况下,会通过该completionBlock返回支付结果
备注:请在APPDelegate的- (BOOL)application:(UIApplication *)app openURL:(NSURL )url options:(NSDictionary<NSString, id> *)options 中调用该方法。
在支付过程结束后,会通过callbackBlock同步返回支付结果(callbackBlock是调用支付同步的回调)。支付结果中参数的提取,必须通过CompletionBlock获取,禁止开发者私自解析支付结果返回的URL,参数说明见"客户端同步返回"。
7.3.2集成服务端SDK
JAVA服务端SDK生成APP支付订单信息示例
//实例化客户端
AlipayClient alipayClient = new DefaultAlipayClient("https://openapi.alipay.com/gateway.do", APP_ID, APP_PRIVATE_KEY, "json", CHARSET, ALIPAY_PUBLIC_KEY, "RSA2");
//实例化具体API对应的request类,类名称和接口名称对应,当前调用接口名称:alipay.trade.app.pay
AlipayTradeAppPayRequest request = new AlipayTradeAppPayRequest();
//SDK已经封装掉了公共参数,这里只需要传入业务参数。以下方法为sdk的model入参方式(model和biz_content同时存在的情况下取biz_content)。
AlipayTradeAppPayModel model = new AlipayTradeAppPayModel();
model.setBody("我是测试数据");
model.setSubject("App支付测试Java");
model.setOutTradeNo(outtradeno);
model.setTimeoutExpress("30m");
model.setTotalAmount("0.01");
model.setProductCode("QUICK_MSECURITY_PAY");
request.setBizModel(model);
request.setNotifyUrl("商户外网可以访问的异步地址");
try {
//这里和普通的接口调用不同,使用的是sdkExecute
AlipayTradeAppPayResponse response = alipayClient.sdkExecute(request);
System.out.println(response.getBody());//就是orderString 可以直接给客户端请求,无需再做处理。
} catch (AlipayApiException e) {
e.printStackTrace();
}
JAVA服务端验证异步通知信息参数示例
//获取支付宝POST过来反馈信息
Map<String,String> params = new HashMap<String,String>();
Map requestParams = request.getParameterMap();
for (Iterator iter = requestParams.keySet().iterator(); iter.hasNext();) {
String name = (String) iter.next();
String[] values = (String[]) requestParams.get(name);
String valueStr = "";
for (int i = 0; i < values.length; i++) {
valueStr = (i == values.length - 1) ? valueStr + values[i]
: valueStr + values[i] + ",";
}
//乱码解决,这段代码在出现乱码时使用。
//valueStr = new String(valueStr.getBytes("ISO-8859-1"), "utf-8");
params.put(name, valueStr);
}
//切记alipaypublickey是支付宝的公钥,请去open.alipay.com对应应用下查看。
//boolean AlipaySignature.rsaCheckV1(Map<String, String> params, String publicKey, String charset, String sign_type)
boolean flag = AlipaySignature.rsaCheckV1(params, alipaypublicKey, charset, "RSA2")
8、系统交互流程
系统交互流程如图,以Android平台为例:
第2步:请求商户服务端,获取签名后的订单信息。使用签名是为了在商户与支付宝之间的数据传输时,防止数据内容被篡改。开放平台下载的sdk已将RSA(SHA1)签名验签方法封装,开发者只需要调用sdk配置业务入参即可,用sdk封装的方法发送请求到开放平台时,sdk会自动签名。如开发者不用sdk,可根据SHA1规则自己拼写签名方法。
第4步:调用支付接口:此消息就是本接口所描述的支付宝客户端SDK提供的支付对象PayTask,将商户签名后的订单信息传进payv2方法唤起支付宝收银台,交易数据格式具体参见请求参数说明。
第5步:支付请求:支付宝客户端SDK将会按照商户客户端提供的请求参数发送支付请求。
第8步:接口返回支付结果:商户客户端在第4步中调用的支付接口,会返回最终的支付结果(即同步通知),参见客户端同步返回。
第13步:用户在支付宝APP或H5收银台完成支付后,会根据商户在手机网站支付API中传入的前台回跳地址return_url自动跳转回商户页面,同时在URL请求中附带上支付结果参数。同时,支付宝还会根据原始支付API中传入的异步通知地址notify_url,通过POST请求的形式将支付结果作为参数通知到商户系统,详情见支付结果异步通知。
9.交易辅助接口:
API英文名 API中文名 完整文档
alipay.trade.query 交易查询接口 查看文档
alipay.trade.close 交易关闭接口 查看文档
alipay.trade.refund 交易退款接口 查看文档
alipay.trade.fastpay.refund.query 交易退款查询接口 查看文档
alipay.data.dataservice.bill.downloadurl.query 查询账单下载地址接口 查看文档
10、接口对账功能
账单生成时间:每日账单一般会在次日10点或之前生成。每月账单一般会在次月4日或之前生成。
10.1对账场景介绍
商户/系统商可通过接口下载指定日期(当天除外)的业务明细账单文件,并结合自身业务系统实现自动对账。
10.2调用流程
商户系统调用查询对账单下载地址接口alipay.data.dataservice.bill.downloadurl.query,传入指定日期,获得该日期账单文件的下载地址。查看接口详情
商户系统通过HTTP方式后台访问账单下载链接,将账单csv文件下载到本地后自行处理。注意该下载链接仅30秒,在得到链接后系统需要立刻请求下载账单文件。
10.3使用SDK快速接入
查询对账单下载地址接口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();
}
}