1、支付宝支付申请
1.1 支付宝 APP 支付申请步骤
APP 支付:APP 支付是商户通过在移动端应用 APP 中集成开放 SDK 调起支付宝支付模块完成支付的模式。买家在手机、掌上电脑等无线设备的应用程序内,可通过支付宝进行付款购买特定服务或商品,资金即时到账。旧的接口叫 移动支付。
- 申请条件:
- 1) 申请前必须拥有经过实名认证的支付宝账户;
- 2) 企业或个体工商户可申请;
- 3) 需提供真实有效的营业执照,且支付宝账户名称需与营业执照主体一致;
- 4) 如应用开发者与支付宝账户名称不一致需提供开发合作协议;
- 5) 如应用已上架,需提供应用名称和下载链接;若应用未上架,需提供 demo 或产品说明文档;
- 6) 古玩、珠宝等奢侈品、投资类行业无法申请本产品;
- 费率说明:
- 助力中小商户,从签约日至 2017.6.30 日优惠费率为 0.55%(不包含特殊行业)
- 特殊行业费率:1.2%,行业范围包括:手机、通讯设备销售;家用电器;数码产品及配件;休闲游戏;网络游戏点卡、游戏渠道代理;游戏系统商;网游周边服务、交易平台;网游运营商(含网页游戏)
1.1.1 创建应用并获取 APPID
要在您的应用中使用支付宝开放产品的接口能力,您需要先去蚂蚁金服开放平台,在管理中心中创建登记您的应用,并提交审核,审核通过后会为您生成应用唯一标识 APPID,并且可以申请开通开放产品使用权限,通过 APPID 您的应用才能调用开放产品的接口能力。需要详细了解开放平台创建应用步骤请参考《开放平台应用创建指南》。
-
1、开发者使用支付宝账号登录开放平台(需实名认证的支付宝账号),并创建应用。
- 创建应用时只需填写应用名称,此时的应用状态为开发中,无法在线上正式调用接口。
-
2、创建应用后,点击 “修改” 可跳转到完善应用信息页面。
-
应用信息在开发应用过程中可以无需审核随时完善。应用名称和应用图标会在应用申请上线时进行审核,所以在配置时,建议先了解相关审核规则。
需要完善的内容 作用 应用名称 应用名称和应用图标会在授权、分享的场景中露出,请准确填写相关信息 应用图标 应用说明文档 用于审核人员了解应用覆盖场景和应用实现的功能,请准确填写
-
-
3、配置应用环境,开发者所需配置内容请参考:
字段名称 字段描述 应用网关(对应下图1) 用于接收支付宝异步通知,例如口碑开店中,需要配置此网关来接收开发者门店被动通知。 授权回调地址(对应下图2) 第三方授权或用户信息授权后回调地址。授权链接中配置的redirect_uri的值必须与此值保持一致。(如:https://www.alipay.com) RSA(SHA1)密钥(对应下图3) 开发者要保证接口中使用的私钥与此处的公钥匹配,否则无法调用接口。可参考密钥的生成与配置。
1.1.2 配置密钥
开发者调用接口前需要先生成 RSA 密钥,RSA 密钥包含应用私钥 (APP_PRIVATE_KEY)、应用公钥 (APP_PUBLIC_KEY)。生成密钥后在开放平台管理中心进行密钥配置,配置完成后可以获取支付宝公钥 (ALIPAY_PUBLIC_KEY)。详细步骤请参考《配置应用环境》。
-
1、生成 RSA 密钥
-
生成方式一(推荐):使用支付宝提供的一键生成工具(内附使用说明)
-
生成方式二:也可以使用 OpenSSL 工具命令生成
-
首先进入 OpenSSL 工具,再输入以下命令。
OpenSSL> genrsa -out app_private_key.pem 1024 #生成私钥 OpenSSL> pkcs8 -topk8 -inform PEM -in app_private_key.pem -outform PEM -nocrypt -out app_private_key_pkcs8.pem #Java开发者需要将私钥转换成PKCS8格式 OpenSSL> rsa -in app_private_key.pem -pubout -out app_public_key.pem #生成公钥 OpenSSL> exit #退出OpenSSL程序
经过以上步骤,开发者可以在当前文件夹中(OpenSSL 运行文件夹),看到
app_private_key.pem
(开发者 RSA 私钥)、app_private_key_pkcs8.pem
(pkcs8 格式开发者 RSA 私钥)和app_public_key.pem
(开发者 RSA 公钥)3 个文件。开发者将私钥保留,将公钥提交给支付宝配置到开发平台,用于验证签名。以下为私钥文件和公钥文件示例。注意:对于使用 Java 的开发者,将 pkcs8 在 console 中输出的私钥去除头尾、换行和空格,作为开发者私钥,对于 .NET 和 PHP 的开发者来说,无需进行 pkcs8 命令行操作。
-
标准的私钥文件示例(PHP、.NET使用)
-----BEGIN RSA PRIVATE KEY----- MIICXQIBAAKBgQC+L0rfjLl3neHleNMOsYTW8r0QXZ5RVb2p/vvY3fJNNugvJ7lo4+fdBz+LN4mDxTz4MTOhi5e2yeAqx+v3nKpNmPzC5LmDjhHZURhwbqFtIpZD51mOfno2c3MDwlrsVi6mTypbNu4uaQzw/TOpwufSLWF7k6p2pLoVmmqJzQiD0QIDAQABAoGAakB1risquv9D4zX7hCv9MTFwGyKSfpJOYhkIjwKAik7wrNeeqFEbisqv35FpjGq3Q1oJpGkem4pxaLVEyZOHONefZ9MGVChT/MNH5b0FJYWl392RZy8KCdq376Vt4gKVlABvaV1DkapL+nLh7LMo/bENudARsxD55IGObMU19lkCQQDwHmzWPMHfc3kdY6AqiLrOss+MVIAhQqZOHhDe0aW2gZtwiWeYK1wB/fRxJ5esk1sScOWgzvCN/oGJLhU3kipHAkEAysNoSdG2oWADxlIt4W9kUiiiqNgimHGMHPwp4JMxupHMTm7D9XtGUIiDijZxunHv3kvktNfWj3Yji0661zHVJwJBAM8TDf077F4NsVc9AXVs8N0sq3xzqwQD/HPFzfq6hdR8tVY5yRMb4X7+SX4EDPORKKsgnYcur5lk8MUi7r072iUCQQC8xQvUne+fcdpRyrR4StJlQvucogwjTKMbYRBDygXkIlTJOIorgudFlrKP/HwJDoY4uQNl8gQJb/1LdrKwIe7FAkBl0TNtfodGrDXBHwBgtN/t3pyi+sz7OpJdUklKE7zMSBuLd1E3O4JMzvWP9wEE7JDb+brjgK4/cxxUHUTkk592 -----END RSA PRIVATE KEY-----
-
PKCS8处理后的私钥文件示例(Java 使用)
-----BEGIN PRIVATE KEY----- MIICeAIBADANBgkqhkiG9w0BAQEFAASCAmIwggJeAgEAAoGBAN0yqPkLXlnhM+2H/57aHsYHaHXazr9pFQun907TMvmbR04wHChVsKVgGUF1hC0FN9hfeYT5v2SXg1WJSg2tSgk7F29SpsF0I36oSLCIszxdu7ClO7c22mxEVuCjmYpJdqb6XweAZzv4Is661jXP4PdrCTHRdVTU5zR9xUByiLSVAgMBAAECgYEAhznORRonHylm9oKaygEsqQGkYdBXbnsOS6busLi6xA+iovEUdbAVIrTCG9t854z2HAgaISoRUKyztJoOtJfI1wJaQU+XL+U3JIh4jmNx/k5UzJijfvfpT7Cv3ueMtqyAGBJrkLvXjiS7O5ylaCGuB0Qz711bWGkRrVoosPM3N6ECQQD8hVQUgnHEVHZYtvFqfcoq2g/onPbSqyjdrRu35a7PvgDAZx69Mr/XggGNTgT3jJn7+2XmiGkHM1fd1Ob/3uAdAkEA4D7aE3ZgXG/PQqlm3VbE/+4MvNl8xhjqOkByBOY2ZFfWKhlRziLEPSSAh16xEJ79WgY9iti+guLRAMravGrs2QJBAOmKWYeaWKNNxiIoF7/4VDgrcpkcSf3uRB44UjFSn8kLnWBUPo6WV+x1FQBdjqRviZ4NFGIP+KqrJnFHzNgJhVUCQFzCAukMDV4PLfeQJSmna8PFz2UKva8fvTutTryyEYu+PauaX5laDjyQbc4RIEMU0Q29CRX3BA8WDYg7YPGRdTkCQQCG+pjU2FB17ZLuKRlKEdtXNV6zQFTmFc1TKhlsDTtCkWs/xwkoCfZKstuV3Uc5J4BNJDkQOGm38pDRPcUDUh2/ -----END PRIVATE KEY-----
-
公钥文件示例
-----BEGIN PUBLIC KEY----- MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDQWiDVZ7XYxa4CQsZoB3n7bfxLDkeGKjyQPt2FUtm4TWX9OYrd523iw6UUqnQ+Evfw88JgRnhyXadp+vnPKP7unormYQAfsM/CxzrfMoVdtwSiGtIJB4pfyRXjA+KL8nIa2hdQy5nLfgPVGZN4WidfUY/QpkddCVXnZ4bAUaQjXQIDAQAB -----END PUBLIC KEY-----
-
-
-
2、密钥配置
-
开发者登录开放平台后,找到并进入应用。点击 “RSA(SHA1)密钥” 处的 “设置应用公钥”(如已设置则显示 “查看应用公钥”,可修改),将公钥文件去除头尾、换行和空格,仅需填入字符串。
-
例如转换前公钥 pem 文件格式:
-----BEGIN PUBLIC KEY----- MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDQWiDVZ7XYxa4CQsZoB3n7bfxLDkeGKjyQPt2FUtm4TWX9OYrd523iw6UUqnQ+Evfw88JgRnhyXadp+vnPKP7unormYQAfsM/CxzrfMoVdtwSiGtIJB4pfyRXjA+KL8nIa2hdQy5nLfgPVGZN4WidfUY/QpkddCVXnZ4bAUaQjXQIDAQAB -----END PUBLIC KEY-----
-
转换后得到的字符串为:
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDQWiDVZ7XYxa4CQsZoB3n7bfxLDkeGKjyQPt2FUtm4TWX9OYrd523iw6UUqnQ+Evfw88JgRnhyXadp+vnPKP7unormYQAfsM/CxzrfMoVdtwSiGtIJB4pfyRXjA+KL8nIa2hdQy5nLfgPVGZN4WidfUY/QpkddCVXnZ4bAUaQjXQIDAQAB
-
-
-
3、获取支付宝公钥
-
应用上线后点击 “查看支付宝公钥”,即可获取支付宝公钥,用于支付宝返回数据的验签。
-
对于支付宝公钥,看到的是一个字符串,如下:
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDDI6d306Q8fIfCOaTXyiUeJHkrIvYISRcc73s3vF1ZT7XN8RNPwJxo8pWaJMmvyTn9N4HQ632qJBVHf8sxHi/fEsraprwCtzvzQETrNRwVxLO5jVmRGi60j8Ue1efIlzPXV9je9mkjzOmdssymZkh2QhUrCmZYI/FCEa3/cNMW0QIDAQAB
-
如果需要使用文件方式(如使用服务端 SDK 的 PHP/.NET 版本)读取支付宝公钥,需要在头尾加入标示后保存至文件,文件内容如下:
-----BEGIN PUBLIC KEY----- MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDDI6d306Q8fIfCOaTXyiUeJHkrIvYISRcc73s3vF1ZT7XN8RNPwJxo8pWaJMmvyTn9N4HQ632qJBVHf8sxHi/fEsraprwCtzvzQETrNRwVxLO5jVmRGi60j8Ue1efIlzPXV9je9mkjzOmdssymZkh2QhUrCmZYI/FCEa3/cNMW0QIDAQAB -----END PUBLIC KEY-----
-
-
1.1.3 支付宝 APP 支付功能申请签约
- 1、准备签约资料
- 请提前准备以下资料:1)营业执照 2)APP 说明文档 3)如开发者与签约者不一致,需提供开发合作协议。
- 2、提交签约信息
- 填写商户经营信息、APP 说明文档、商户联系人信息。
-
3、应用创建完成后点击查看我的应用详情,功能信息中进行 APP 支付功能的签约。
-
或者进入蚂蚁金服商家中心 选择 APP 支付功能进行签约。
-
APP 说明文档相关格式。
-
1.2 支付宝 APP 支付集成并配置 SDK
接入移动支付需要集成两个 SDK,客户端 SDK 需要集成在商户自己的 APP 中,用于唤起支付宝 APP 并发送交易数据,并在支付宝 APP 返回商户 APP 时获得支付结果。服务端 SDK 需要商户集成在自己的服务端系统中,用于协助解析并验证客户端同步返回的支付结果和异步通知。
-
如何集成客户端 SDK
- 点击查看 iOS 集成流程详解,Android 集成流程详解。
-
如何集成服务端 SDK
- 为了帮助开发者调用开放接口,我们提供了开放平台服务端 SDK,包含 JAVA、PHP 和 .NET 三语言版本,封装了签名&验签、HTTP 接口请求等基础功能。请先下载对应语言版本的 SDK 并引入您的开发工程。
1.3 支付宝 APP 支付上线应用
应用开发完成后,请开发者自行进行验收和安全性检查(安全性检查可参考《开放平台第三方应用安全开发指南》),验收检查完成后,可申请上线,上线成功后,状态变为已上线,这个状态下的应用能够调用生产环境的接口。
应用申请上线后,预计会有1个工作日的审核时间,请耐心等待。
-
步骤一:确认功能
-
步骤二:完善应用信息
-
步骤三:申请上线
-
应用上线后可新增功能、删除功能,操作后实时生效。删除功能时请谨慎操作,如果线上已经有用户使用此功能,删除功能后会导致无法使用。
1.4 支付宝 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 来完成,详细验签规则参考异步通知验签。
- 如图,以 Android 平台为例:
2、支付宝 APP 支付开发
-
说明:
- 商户服务端:
- 负责生成订单及签名,及接受支付异步通知。
- APP 客户端:
- 负责使用服务端传来的订单信息调用支付宝支付接口,及根据 SDK 同步返回的支付结果展示结果页。
- 服务端接入:
- 私钥必须放在商户服务端,签名过程必须放在商户服务端。
- 商户服务端:
2.1 支付宝 APP 支付集成设置
-
1、下载 iOS 端开发工具包 AlipaySDK,并添加到创建的工程中。AlipaySDK 中有 2 个文件,分别为:
AlipaySDK.bundle AlipaySDK.framework
-
2、添加 SDK 的依赖库和框架。在 项目设置 => TARGETS => Build Phases => Link Binary With Libraries 中依次添加以下库或框架:
SystemConfiguration.framework CoreTelephony.framework QuartzCore.framework CoreText.framework CoreGraphics.framework CoreMotion.framework CFNetwork.framework AlipaySDK.framework // 导入 SDK 时已自动添加 libz.dylib libc++.tbd
-
其中,需要注意的是:
- 如果是 Xcode 7.0 之后的版本,需要添加 libc++.tbd、libz.tbd
-
如果是 Xcode 7.0 之前的版本,需要添加 libc++.dylib、libz.dylib
-
-
3、在 项目设置 => TARGETS => Info => URL Types 中点击加号按钮添加,在 “URL Schemes” 中输入 “alisdkdemo”。
-
注意:“alisdkdemo” 即为调起支付宝开始支付时使用的参数 appScheme。这里的 URL Schemes 中输入的 alisdkdemo,为测试 demo,实际商户的 app 中要填写独立的 scheme,建议跟商户的 app 有一定的标示度,要做到和其他的商户 app 不重复,否则可能会导致支付宝返回的结果无法正确跳回商户 app。
NSString *appScheme = @"alisdkdemo"; [[AlipaySDK defaultService] payOrder:orderString fromScheme:appScheme callback:^(NSDictionary *resultDic) { NSLog(@"reslut = %@", resultDic); }];
-
-
4、iOS 9 + 系统策略更新,限制了 http 协议的访问,受此影响,当你的应用在 iOS 9 + 中需要使用支付宝 SDK 的相关能力时,需要在 “Info.plist” 里增加如下代码:
<key>NSAppTransportSecurity</key> <dict> <key>NSAllowsArbitraryLoads</key> <true/> </dict>
-
5、若将 openssl 文件夹随意拉进项目中,即使添加头文件链接,也可能会出现找不到头文件的问题,在 项目设置 => TARGETS => Build Settings => Search Paths => Header Search Paths 中添加 openssl 文件夹所在的路径即可解决。
2.2 支付宝 APP 支付集成
详细代码见 GitHub
-
Objective-C
-
AppDelegate.m
// 支付宝支付回调,当用户通过其他应用启动本应用时,会回调这个方法 // NS_DEPRECATED_IOS(2_0, 9_0) - (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation { if ([url.host isEqualToString:@"safepay"]) { // 支付跳转支付宝钱包进行支付,处理支付结果 [[AlipaySDK defaultService] processOrderWithPaymentResult:url standbyCallback:^(NSDictionary *resultDic) { NSLog(@"result = %@",resultDic); }]; return YES; } // NS_AVAILABLE_IOS(9_0) 9.0 以后使用新 API 接口 - (BOOL)application:(UIApplication *)app openURL:(NSURL *)url options:(NSDictionary<NSString*, id> *)options { if ([url.host isEqualToString:@"safepay"]) { // 支付跳转支付宝钱包进行支付,处理支付结果 [[AlipaySDK defaultService] processOrderWithPaymentResult:url standbyCallback:^(NSDictionary *resultDic) { NSLog(@"result = %@",resultDic); }]; return YES; }
-
ViewController.m
NSMutableDictionary *params = [NSMutableDictionary dictionary]; // 在此设置商户服务端需要的参数 params[@"totalFee"] = @"10"; params[@"bodyID"] = @"1"; // 向商户支付宝支付服务器端请求组装和签名后的请求串 orderString AFHTTPSessionManager *sessionManager = [AFHTTPSessionManager manager]; [sessionManager POST:@"test 商户支付宝支付后台接口" parameters:params progress:nil success:^(NSURLSessionDataTask * _Nonnull task, id _Nullable responseObject) { // 解析商户支付宝支付服务器端返回的数据,获得组装和签名后的请求串 orderString NSLog(@"responseObject = %@", responseObject); NSString *orderString = responseObject[@"signedString"]; if (orderString != nil) { // 应用注册的 scheme,在 Info.plist 定义 URL types NSString *appScheme = @"alisdkdemo"; // 调用支付结果开始支付 [[AlipaySDK defaultService] payOrder:orderString fromScheme:appScheme callback:^(NSDictionary *resultDic) { NSLog(@"reslut = %@", resultDic); }]; } } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) { NSLog(@"向商户支付宝支付服务器端请求信息失败:%@", error.localizedDescription); }];
-