转载自http://www.iashes.com/2015-08-762.html 感谢感谢~
模拟器支付:
ios支付宝支付官方写的比微信好多了,至少有备注,难道微信给自己写sdk的备注怕公司不给钱?
先上一个官方的文档吧:http://pan.baidu.com/s/1jWGEE
支付宝的申请资格和流程:
1
2
3
|
1.企业支付宝账号注册企业账号,您可以提供产品介绍文档或者手机
demo
.
apk
.
doc
.
docx
.
pdf格式,内容要求包含产品说明、接口使用场景、资费说明等,文件大小不超过
5M) 文档内容示例;如果已经在
appstore、
googleplay、豌豆荚上架,可不提供文档
demo,直接提供应用名称;
2.个体工商户,您可以提供产品介绍文档或者手机
demo
.
apk
.
doc
.
docx
.
pdf格式,内容要求包含产品说明、接口使用场景、资费说明等,文件大小不超过
5M) 文档内容示例;个体工商户申请需要上传营业执照。
3.本产品不支持仅填写网址申请;
|
申请分两种,一种企业级的,企业级的得提供企业介绍文档等。一种个人商户的,上午必须上传营业执照。
这里有申请流程以及一些开发指南,还有支付宝前几天加的-分享到支付宝朋友。
1,首先注册公钥,完了在支付宝生成私钥。
2,通过公钥私钥进行创建应用。
3,通过商户的支付宝账号支付宝会绑定一个唯一的key。
所以ios支付需要三个东西,第一个私钥,第二个支付宝账号,第三个支付宝账号绑定唯一应用的唯一key。
这里有支付宝移动端的skd可申请教程等:
https://b.alipay.com/order/productDetail.htm?productId=2014110308141993&tabId=4#ps-tabinfo-hash
网盘下载官方的skd,含安卓和ios:
http://pan.baidu.com/s/1pJrDESN
现在开始正儿八经支付吧。先看看官方给出的流程
1
2
3
4
|
//应用注册scheme,在AlixPayDemo-Info.plist定义URL types NSString *appScheme = @"alisdkdemo";
//将商品信息拼接成字符串
//获取私钥并将商户信息签名,外部商户可以根据情况存放私钥和签名,只需要遵循 RSA 签名规范, 并将签名字符串 base64 编码和 UrlEncode
//将签名成功字符串格式化为订单字符串,请严格按照该格式
|
集成:
1,首先导入系统类库:
SystemConfiguration.framework
然后导入alipay官方skd:
AlipaySDK.bundle
AlipaySDK.framework
第一个包含了,支付界面的资源文件,第二个包含了skd得一些头文件。
2,添加URL Types ,在TARGETS->PROJECTNAME->INFO->URL Types
这个scheme自己随便写,但是要和代码支付中得scheme相同:
NSString *appScheme = @”myPayDemo”;
3,添加私钥,签名,等规范,签名需要遵循 RSA 签名规范,并将签名字符串 base64 编码和 UrlEncode。
所以加签得算法还有调用官网SDK里边的东西,这里我整理了以下,下载地址:
http://pan.baidu.com/s/1o6wzCXs
下载完之后add Files to ‘you project’…选择copy
所包含文件:
里边包含了支付宝支付的静态库,加密头文件,价签头文件。
签名是RSA 签名规范, 加密是将签名字符串 base64 编码和 UrlEncode了。
添加进去之后其实系统会自动将.h和.a文件添加到项目库中,如果出现错误,例如:
1
|
Cannot
find
interface
declaration
for
'NSObject'
,
superclass
of
'Base64'
|
就将.a和.h手动添加到library里边。
添加:
TARGETS->YouProjectName->Build Settings->Search Path
里边注意三个地方就行,第一个framework search paths 这个是动态库,也就是后缀为.framework的库,支付宝这里不用管了,header search paths是头文件库,也就是.h文件,看看刚才AlipayInclude路径是不在里边,如果没有,则添加:$(PROJECT_DIR)/AlipayInclude
Library search paths 是静态库路径保存,添加:$(PROJECT_DIR)/AlipayInclude
因为下载完的静态库和动态都在AlipayInclude下边。
然后操作,支付需要的头文件:
appdelegate.h里边添加:
#import <AlipaySDK/AlipaySDK.h>
appdelegate.m加一个方法:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
//官方demo里边的一段代码
-
(
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
)
;
}
]
;
}
if
(
[
url
.
host
isEqualToString
:
@
"platformapi"
]
)
{
//支付宝钱包快登授权返回 authCode
[
[
AlipaySDK
defaultService
]
processAuthResult
:
url
standbyCallback
:
^
(
NSDictionary *
resultDic
)
{
NSLog
(
@
"result = %@"
,
resultDic
)
;
}
]
;
}
return
YES
;
}
|
这个测了好久但是总是好像不回调完成的方法,但是如果安装了支付宝钱包可以回调,我自己写的:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
-
(
BOOL
)
application
:
(
UIApplication *
)
application
openURL
:
(
NSURL *
)
url
sourceApplication
:
(
NSString *
)
sourceApplication
annotation
:
(
id
)
annotation
{
//跳转支付宝钱包进行支付,处理支付结果,如果支付错误则resultdic是空,否则会出现支付结果
[
[
AlipaySDK
defaultService
]
processAuthResult
:
url
standbyCallback
:
^
(
NSDictionary *
resultDic
)
{
NSLog
(
@
"appdelegate - - -- - %@"
,
resultDic
)
;
}
]
;
return
YES
;
}
|
支付宝支付的时候需要将商品的信息拼成一个字符串,类似于URLget请求一样的字符串,例如?name=sky&price=100这种形式的,所以直接拿demo里边订单的model类了:
order.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
|
//
// Order.h
// AlixPayDemo
//
// Created by 方彬 on 11/2/13.
//
//
#import <Foundation/Foundation.h>
@
interface
Order
:
NSObject
@
property
(
nonatomic
,
copy
)
NSString *
partner
;
@
property
(
nonatomic
,
copy
)
NSString *
seller
;
@
property
(
nonatomic
,
copy
)
NSString *
tradeNO
;
@
property
(
nonatomic
,
copy
)
NSString *
productName
;
@
property
(
nonatomic
,
copy
)
NSString *
productDescription
;
@
property
(
nonatomic
,
copy
)
NSString *
amount
;
@
property
(
nonatomic
,
copy
)
NSString *
notifyURL
;
@
property
(
nonatomic
,
copy
)
NSString *
service
;
@
property
(
nonatomic
,
copy
)
NSString *
paymentType
;
@
property
(
nonatomic
,
copy
)
NSString *
inputCharset
;
@
property
(
nonatomic
,
copy
)
NSString *
itBPay
;
@
property
(
nonatomic
,
copy
)
NSString *
showUrl
;
@
property
(
nonatomic
,
copy
)
NSString *
rsaDate
;
//可选
@
property
(
nonatomic
,
copy
)
NSString *
appID
;
//可选
@
property
(
nonatomic
,
readonly
)
NSMutableDictionary *
extraParams
;
@
end
|
order.m
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
|
//
// Order.m
// AlixPayDemo
//
// Created by 方彬 on 11/2/13.
//
//
#import "Order.h"
@
implementation
Order
//将商品信息拼接成字符串
-
(
NSString *
)
description
{
NSMutableString *
discription
=
[
NSMutableString
string
]
;
if
(
self
.
partner
)
{
[
discription
appendFormat
:
@
"partner=\"%@\""
,
self
.
partner
]
;
}
if
(
self
.
seller
)
{
[
discription
appendFormat
:
@
"&seller_id=\"%@\""
,
self
.
seller
]
;
}
if
(
self
.
tradeNO
)
{
[
discription
appendFormat
:
@
"&out_trade_no=\"%@\""
,
self
.
tradeNO
]
;
}
if
(
self
.
productName
)
{
[
discription
appendFormat
:
@
"&subject=\"%@\""
,
self
.
productName
]
;
}
if
(
self
.
productDescription
)
{
[
discription
appendFormat
:
@
"&body=\"%@\""
,
self
.
productDescription
]
;
}
if
(
self
.
amount
)
{
[
discription
appendFormat
:
@
"&total_fee=\"%@\""
,
self
.
amount
]
;
}
if
(
self
.
notifyURL
)
{
[
discription
appendFormat
:
@
"¬ify_url=\"%@\""
,
self
.
notifyURL
]
;
}
if
(
self
.
service
)
{
[
discription
appendFormat
:
@
"&service=\"%@\""
,
self
.
service
]
;
//mobile.securitypay.pay
}
if
(
self
.
paymentType
)
{
[
discription
appendFormat
:
@
"&payment_type=\"%@\""
,
self
.
paymentType
]
;
//1
}
if
(
self
.
inputCharset
)
{
[
discription
appendFormat
:
@
"&_input_charset=\"%@\""
,
self
.
inputCharset
]
;
//utf-8
}
if
(
self
.
itBPay
)
{
[
discription
appendFormat
:
@
"&it_b_pay=\"%@\""
,
self
.
itBPay
]
;
//30m
}
if
(
self
.
showUrl
)
{
[
discription
appendFormat
:
@
"&show_url=\"%@\""
,
self
.
showUrl
]
;
//m.alipay.com
}
if
(
self
.
rsaDate
)
{
[
discription
appendFormat
:
@
"&sign_date=\"%@\""
,
self
.
rsaDate
]
;
}
if
(
self
.
appID
)
{
[
discription
appendFormat
:
@
"&app_id=\"%@\""
,
self
.
appID
]
;
}
for
(
NSString *
key
in
[
self
.
extraParams
allKeys
]
)
{
[
discription
appendFormat
:
@
"&%@=\"%@\""
,
key
,
[
self
.
extraParams
objectForKey
:
key
]
]
;
}
return
discription
;
}
@
end
//就用了一个description方法给拼接起来了。
|
order.h,order.m下载地址:http://pan.baidu.com/s/1pJtFSZT
支付其实是对刚才order拼接的字符串进行加签加密,对商户生成的私有key进行加签。
1
2
3
4
5
|
NSString *
privateKey
=
PartnerPrivKey
;
id
<
DataSigner
>
signer
=
CreateRSADataSigner
(
privateKey
)
;
NSString *
signedString
=
[
signer
signString
:
orderSpec
]
;
|
直接支付,controller.m:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
|
//
// ViewController.m
// TouchLabelDemo
//
// Created by skyzizhu on 15/7/13.
// Copyright (c) 2015年 skyzizhu. All rights reserved.
//
#import "ViewController.h"
#import "UITouchLabel.h"
#import <AlipaySDK/AlipaySDK.h>
#import "Order.h"
#import "DataSigner.h"
@
interface
ViewController
(
)
@
end
@
implementation
ViewController
-
(
void
)
viewDidLoad
{
[
super
viewDidLoad
]
;
UITouchLabel *
touchLabel
=
[
[
UITouchLabel
alloc
]
initWithFrame
:
CGRectMake
(
100
,
100
,
200
,
100
)
]
;
touchLabel
.
text
=
@
"点击支付1分钱"
;
[
touchLabel
addTarget
:
self
atAction
:
@
selector
(
pay
:
)
]
;
[
self
.
view
addSubview
:
touchLabel
]
;
// Do any additional setup after loading the view, typically from a nib.
}
#pragma mark alipay
#define PartnerPrivKey @"MIICdQIBADANBgkqhkiG9w0BAQEFAASCAl8wggJbAgEAAoGBAL0M8jaJCm9bMb7PjgI0wR9+mpzWTcNTwTyYBEXmrJg3MjRVluUezDjQhQBSrgaMTeM40cz+1Nt/f1OlS/vB9PzGSF+MDty6zS0NQEEvVjUUge7PsOtbPDIEmuPppKIj4wETfavaZt7j4/kVuABDC2P1DpPRP686dJsNTkSO5qrNAgMBAAECgYApxEVy9P3gMkagQFzAcgVEvwTLp7EQeV2U1IUFKHxzOKaX11z6C77UwoTP2HRoL/E5RSFc5+QBBn8L7NYHrgdAu4L5Kl048saM53QyXJviQs7lgxDSBbo+EHDY9OJJsVRalpqKSirgBZmce/M4/tNhDxUfV5yXvxOC43JEr92UIQJBAPXbahDDMN+D0MqG1y0zPyU5bJwopXsSLIxpqp4vRmHokMxlber5HGMgSSnVQ9x9j974G1RSamqV34xwnqPzIlUCQQDE2ZPgtKd9Te19kGpmmCs64iqlkUVabAuKI8wMyx4hGZx6/EpeufFiTpF3F3YDN37JOenBefLL9UIkrOrjXI6ZAkBmpX75FKV5DG3FwNph0r2QaxM/d3DvmzziOtOzS4WVJyYdUFO+ANerQzWIs7OrgPjqXKf8YpRvf7dfyT1SshYpAkAhj0qDw6jOVwvHHWjWZtjv6AEHSxX8zXDGM0YlZDeVww0Hdp2jOqYpcWWhXRGUiNCHs+TjREwdc4m8QPKmom/5AkAYGRw6TLB/XWfEvlGLMHMmbZWMXDBdBmlIN+JK2oRjIoTryG35KlXzAHWcAq2xVhvCd6gJjz9arUmqewOLBMWn"
-
(
void
)
pay
:
(
id
)
touchLabel
{
//判断是否登录
if
(
[
[
AlipaySDK
defaultService
]
isLogined
]
)
{
NSLog
(
@
" - -- - islogin - -- "
)
;
}
NSLog
(
@
"alipay"
)
;
//
NSString *
partner
=
@
"2088511933544308"
;
NSString *
seller
=
@
"yingtehua8@sina.com"
;
Order *
order
=
[
[
Order
alloc
]
init
]
;
order
.
partner
=
partner
;
order
.
seller
=
seller
;
order
.
tradeNO
=
@
"789ABCDlmaa123456aa"
;
//订单ID(由商家□自□行制定)
//支付宝会判断这个订单号在当前账号是否已经支付,如果支付则无法进行第二次支付
order
.
productName
=
@
"测试商品标题"
;
order
.
productDescription
=
@
"测试商品描述"
;
order
.
amount
=
[
NSString
stringWithFormat
:
@
"%.2f"
,
0.01
]
;
//商品价格
order
.
notifyURL
=
@
"http://www.xxx.com"
;
//回调URL
order
.
service
=
@
"mobile.securitypay.pay"
;
//默认这么写
order
.
paymentType
=
@
"1"
;
order
.
inputCharset
=
@
"utf-8"
;
order
.
itBPay
=
@
"30m"
;
NSString *
orderSpec
=
[
order
description
]
;
NSString *
privateKey
=
PartnerPrivKey
;
id
<
DataSigner
>
signer
=
CreateRSADataSigner
(
privateKey
)
;
NSString *
signedString
=
[
signer
signString
:
orderSpec
]
;
NSString *
orderString
=
nil
;
NSString *
appScheme
=
@
"myPayDemo"
;
if
(
signedString
!=
nil
)
{
orderString
=
[
NSString
stringWithFormat
:
@
"%@&sign=\"%@\"&sign_type=\"%@\""
,
orderSpec
,
signedString
,
@
"RSA"
]
;
//支付
[
[
AlipaySDK
defaultService
]
payOrder
:
orderString
fromScheme
:
appScheme
callback
:
^
(
NSDictionary *
resultDic
)
{
//支付成功返回当前app回调的block
NSLog
(
@
"viewcontroller - - - -- - - - -- -reslut = %@"
,
resultDic
)
;
}
]
;
}
}
-
(
void
)
didReceiveMemoryWarning
{
[
super
didReceiveMemoryWarning
]
;
// Dispose of any resources that can be recreated.
}
@
end
|
最后给一个demo吧。
http://pan.baidu.com/s/1bnlWPFx