IOS支付宝集成总结
以下是IOS项目中集成支付宝的过程总结,如有冲突,请以支付宝的文档为准
一、集成大致流程:
1、商户服务端使用openssl生成自己的公钥和私钥,
2、商户真正使用的是:商户私钥,支付付公钥
3、APP端使用是服务端openssl生成的公钥和私钥的内容字符串(私钥需是PKS8格式)
4、商户上传公钥给支付宝,支付宝把公钥给商户,完成公钥交换操作
5、使用时,APP端使用用私钥做签名,发起商品支付,支付宝根据商户上传的公钥做验证签名,
6、商户使用支付宝公钥接收支付宝访问的 kNotifyURL做验证签名认证,确认一次订单流程处理完成时
二、涉及角色:
1)、商户服务端(JAVA或PHP后台服务器):
2)、商户客户端(IOS)
3)、支付宝:
三、服务器端操作流程
1、先生成私钥rsa_private_key.pem:
OpenSSL> genrsa -out rsa_private_key.pem 1024
Generating RSA private key, 1024 bit long modulus
.................++++++
.......++++++
e is 65537 (0x10001)
OpenSSL>
2、生成公钥rsa_public_key.pem:()
OpenSSL> rsa -in rsa_private_key.pem -pubout -out rsa_public_key.pem
writing RSA key
OpenSSL>
3、生成PKCS编码的私钥:(APP端要用)
OpenSSL> pkcs8 -topk8 -inform PEM -in rsa_private_key.pem -outform PEM -nocrypt
-----BEGIN PRIVATE KEY-----
MIICdwIBADANBgkqhkiG9w0BAQEFAASCAmEwggJdAgEAAoGBAMB1Cx+PSty0aJYx
rQTz3ecmQ4DsCqKjytK3ip7iG+0jAGedlbSXURQIxebBEClXy1og0gb76iLpm6pv
I4K7ZVPJtcteHk0Glhivqq+16tnivjaq9V89BR6iJoepFyRHobJ1jqBptzgyGc/s
J+7d6iFex27tG3IUz7DYNVgFzkYtAgMBAAECgYAmvKgzfvz7dViDupXvpEIqz1nQ
7jGp0Lv3M7g0CKDEV0IymNZUFgzcsnNa4csl9yTYDDkZ7MSQqGKLqHkGTD+1hyH3
CTq7a5LQ8h7aAdzFhibtQsZu8eM/MP5nHZCCYACYfbu64Dg+8fZ/pnZQ1Ri13w7H
4wf7L1UAxjPhgnHWwQJBAOw86NQgeBkBSMBcMrGcnHXoYEPsC834jqC/UatqRyL9
9COuV1QSbjcKtgaC3OFWpjTGROWC8hxihncXKf0wCr0CQQDQjo84Y40xdoboJjdK
2uBPnmcRv3LAL83t2T7NarmyGVxYljJNL0Z+OTPsPnB91jQecdLqHme5iyXGn8Rf
7JgxAkEA0XdYgu6fTpyi411c3budx7ZZ1R/xf5pK7SF2yuUbWl2PIiwt5q/I5ikr
KS7Tp0JrcRP0dwTapGyACgySAJueiQJAJxgiFsLqi7QZM9k+EiUXWTVrQrNtkkMj
ygsoL59q8cy5N83n3foXr7+PUSCfO6d0m6RgkgxjCy/fQ+1dBVI3cQJBALs9IuQ/
1lPJV+8CWm6wDjtNg1SWE2kxI3X5Ym8nkmXijY+pf9MtIRiVX1gQvWVp3S9sVFlk
w3hN3ldmCXcCnlI=
-----END PRIVATE KEY-----
MIICdwIBADANBgkqhkiG9w0BAQEFAASCAmEwggJdAgEAAoGBAMB1Cx+PSty0aJYx
rQTz3ecmQ4DsCqKjytK3ip7iG+0jAGedlbSXURQIxebBEClXy1og0gb76iLpm6pv
I4K7ZVPJtcteHk0Glhivqq+16tnivjaq9V89BR6iJoepFyRHobJ1jqBptzgyGc/s
J+7d6iFex27tG3IUz7DYNVgFzkYtAgMBAAECgYAmvKgzfvz7dViDupXvpEIqz1nQ
7jGp0Lv3M7g0CKDEV0IymNZUFgzcsnNa4csl9yTYDDkZ7MSQqGKLqHkGTD+1hyH3
CTq7a5LQ8h7aAdzFhibtQsZu8eM/MP5nHZCCYACYfbu64Dg+8fZ/pnZQ1Ri13w7H
4wf7L1UAxjPhgnHWwQJBAOw86NQgeBkBSMBcMrGcnHXoYEPsC834jqC/UatqRyL9
9COuV1QSbjcKtgaC3OFWpjTGROWC8hxihncXKf0wCr0CQQDQjo84Y40xdoboJjdK
2uBPnmcRv3LAL83t2T7NarmyGVxYljJNL0Z+OTPsPnB91jQecdLqHme5iyXGn8Rf
7JgxAkEA0XdYgu6fTpyi411c3budx7ZZ1R/xf5pK7SF2yuUbWl2PIiwt5q/I5ikr
KS7Tp0JrcRP0dwTapGyACgySAJueiQJAJxgiFsLqi7QZM9k+EiUXWTVrQrNtkkMj
ygsoL59q8cy5N83n3foXr7+PUSCfO6d0m6RgkgxjCy/fQ+1dBVI3cQJBALs9IuQ/
1lPJV+8CWm6wDjtNg1SWE2kxI3X5Ym8nkmXijY+pf9MtIRiVX1gQvWVp3S9sVFlk
w3hN3ldmCXcCnlI=
-----END PRIVATE KEY-----
OpenSSL>
4、查看公钥内容:(APP端要用,BEGIN 和END之间的内容)
localhost:bin zhisheshe$ openssl rsa -inform PEM -in rsa_public_key.pem -pubin -text
Modulus (1024 bit):
00:c0:75:0b:1f:8f:4a:dc:b4:68:96:31:ad:04:f3:
dd:e7:26:43:80:ec:0a:a2:a3:ca:d2:b7:8a:9e:e2:
1b:ed:23:00:67:9d:95:b4:97:51:14:08:c5:e6:c1:
10:29:57:cb:5a:20:d2:06:fb:ea:22:e9:9b:aa:6f:
23:82:bb:65:53:c9:b5:cb:5e:1e:4d:06:96:18:af:
aa:af:b5:ea:d9:e2:be:36:aa:f5:5f:3d:05:1e:a2:
26:87:a9:17:24:47:a1:b2:75:8e:a0:69:b7:38:32:
19:cf:ec:27:ee:dd:ea:21:5e:c7:6e:ed:1b:72:14:
cf:b0:d8:35:58:05:ce:46:2d
Exponent: 65537 (0x10001)
writing RSA key
-----BEGIN PUBLIC KEY-----
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDAdQsfj0rctGiWMa0E893nJkOA
7Aqio8rSt4qe4hvtIwBnnZW0l1EUCMXmwRApV8taINIG++oi6ZuqbyOCu2VTybXL
Xh5NBpYYr6qvterZ4r42qvVfPQUeoiaHqRckR6GydY6gabc4MhnP7Cfu3eohXsdu
7RtyFM+w2DVYBc5GLQIDAQAB
00:c0:75:0b:1f:8f:4a:dc:b4:68:96:31:ad:04:f3:
dd:e7:26:43:80:ec:0a:a2:a3:ca:d2:b7:8a:9e:e2:
1b:ed:23:00:67:9d:95:b4:97:51:14:08:c5:e6:c1:
10:29:57:cb:5a:20:d2:06:fb:ea:22:e9:9b:aa:6f:
23:82:bb:65:53:c9:b5:cb:5e:1e:4d:06:96:18:af:
aa:af:b5:ea:d9:e2:be:36:aa:f5:5f:3d:05:1e:a2:
26:87:a9:17:24:47:a1:b2:75:8e:a0:69:b7:38:32:
19:cf:ec:27:ee:dd:ea:21:5e:c7:6e:ed:1b:72:14:
cf:b0:d8:35:58:05:ce:46:2d
Exponent: 65537 (0x10001)
writing RSA key
-----BEGIN PUBLIC KEY-----
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDAdQsfj0rctGiWMa0E893nJkOA
7Aqio8rSt4qe4hvtIwBnnZW0l1EUCMXmwRApV8taINIG++oi6ZuqbyOCu2VTybXL
Xh5NBpYYr6qvterZ4r42qvVfPQUeoiaHqRckR6GydY6gabc4MhnP7Cfu3eohXsdu
7RtyFM+w2DVYBc5GLQIDAQAB
-----END PUBLIC KEY-----
5、把BEGIN 和END之间的内容(整理成一行,前后不能有回车、换行)上传到服务器,换回支付宝的公钥
四、APP端
1、添加相关信息,一般写一个头文件 AlipayHeader.h
/**
* partner:合作身份者ID,以2088 开头由 16 位纯数字组成的字符串。
*
*/
#define kPartnerID @"2088811123293271"
/**
* seller:支付宝收款账号,手机号码或邮箱格式。
* partner:合作身份者ID,以2088 开头由 16 位纯数字组成的字符串。
*
*/
#define kPartnerID @"2088811123293271"
/**
* seller:支付宝收款账号,手机号码或邮箱格式。
*/
/**
* 支付宝服务器主动通知商户网站里指定的页面 http 路径。
*/
#define kNotifyURL @"http://www.test.com/Home/Pay/notify_src"
/**
* appSckeme:应用注册scheme,在Info.plist定义URLtypes,处理支付宝回调
*/
#define kAppScheme @“test1111"
/**
* private_key:商户方的私钥,pkcs8格式。
*/
#define kPartnerPrivateKey @"MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBAMKpx/mf1PdrZ5QxbDd0qUOZ143Msyne4DH0fhXwKXh3I/1TO258e5gObaoLKCBF3sP8Fp0AUmSnKL3fiovC9JUv0at/s/Q+zw4h/ZbgSCqsvAxZE52eukFlpZn1SgDW65qhwzt9u6N4iYPmVF+RdS3lwAs163C0jRKLcMPGO1MZAgMBAAECgYBgqKlxnBnFmYFfJoNTrgv2U0ejU4eLPO4aIAsTnaMZ/B7UxSV3oTxFrrRpgQy1qbwJmP0pjGVdMVubnIpRB8cmBx5vZZGfNUBFCOddevJASNzHP2ILSxXpVlLHU+fxuHtjaq+gscCT+kxGjUs81hoAwZK2Kj+QNfVPF9+5M6qIgWp0RJFSsMe3w5SAYSRVYQJAMOnk+yP0I6EzT/gjVo85eoBK4/Gm7Vl5S+JZfvbQEwng8OILW0EVCHno3lm+lzR3t2oZhLlFz0zktUUGsqrbzA=="
/**
* public_key:
1、移动端用服务器产生的公钥
2、服务端的公钥使用支付宝产生的公钥,
*/
#define kAliPayPubliceKey @"MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDCqcf5n9T3a2eUMWw3dKlDmdeNzLMp3uAx9H4V8Cl4dyP9UztufHuYDm2qCyggRd7D/BadAFJkpyi934qLwvSVL9Grf7P0Ps8OIf2W4EgqrLwMWROdnrpBZaWZ9UoA1uuaocM7fbujeImD5lRfkXUt5cALNetwtI0Si3DDxjtTGQIDAQAB"
2、封装订单信息,单独封装一个类,比如AlipayRequestConfig
// 仅含有变化的参数
+ (void)alipayWithPartner:(NSString*)partner
seller:(NSString*)seller
tradeNO:(NSString*)tradeNO
productName:(NSString*)productName
productDescription:(NSString*)productDescription
amount:(NSString*)amount
notifyURL:(NSString*)notifyURL
itBPay:(NSString*)itBPay {
[self alipayWithPartner:partner seller:seller
tradeNO:tradeNO
productName:productName
productDescription:productDescription
amount:amount
notifyURL:notifyURL
service:@"mobile.securitypay.pay"
paymentType:@"1"inputCharset:@"UTF-8"
itBPay:itBPayprivateKey:kPartnerPrivateKey
appScheme:kAppScheme];
}
// 包含所有必要的参数
+ (void)alipayWithPartner:(NSString*)partner
seller:(NSString*)seller
tradeNO:(NSString*)tradeNO
productName:(NSString*)productName
productDescription:(NSString*)productDescription
amount:(NSString*)amount
notifyURL:(NSString*)notifyURL
service:(NSString*)service
paymentType:(NSString*)paymentType
inputCharset:(NSString*)inputCharset
itBPay:(NSString*)itBPay
privateKey:(NSString*)privateKey
appScheme:(NSString*)appScheme {
Order *order = [Order order];
order.partner = partner;
order.seller = seller;
order.tradeNO = tradeNO;
order.productName= productName;
order.productDescription= productDescription;
order.amount = amount;
order.notifyURL = notifyURL;
order.service = service;
order.paymentType= paymentType;
order.inputCharset= inputCharset;
order.itBPay = itBPay;
// 将商品信息拼接成字符串
NSString *orderSpec = [order description];
// 获取私钥并将商户信息签名,外部商户可以根据情况存放私钥和签名,只需要遵循RSA 签名规范, 并将签名字符串 base64 编码和 UrlEncode
NSString *signedString = [selfgenSignedStringWithPrivateKey:kPartnerPrivateKeyOrderSpec:orderSpec];
// 调用支付接口
[self payWithAppScheme:appScheme orderSpec:orderSpec signedString:signedString];
}
// 生成signedString
+ (NSString *)genSignedStringWithPrivateKey:(NSString*)privateKey OrderSpec:(NSString*)orderSpec {
// 获取私钥并将商户信息签名,外部商户可以根据情况存放私钥和签名,只需要遵循RSA 签名规范, 并将签名字符串 base64 编码和 UrlEncode
id<DataSigner> signer =CreateRSADataSigner(privateKey);
return [signer signString:orderSpec];
}
// 支付
+ (void)payWithAppScheme:(NSString*)appScheme orderSpec:(NSString*)orderSpec signedString:(NSString*)signedString {
// 将签名成功字符串格式化为订单字符串,请严格按照该格式
NSString *orderString = nil;
if (signedString != nil) {
orderString = [NSStringstringWithFormat:@"%@&sign=\"%@\"&sign_type=\"%@\"", orderSpec, signedString,@"RSA"];
[[AlipaySDK defaultService] payOrder:orderString fromScheme:appScheme callback:^(NSDictionary*resultDic) {
NSLog(@"AliPay-reslut = %@",resultDic);
}];
}
}
+ (void)alipayWithPartner:(NSString*)partner
seller:(NSString*)seller
tradeNO:(NSString*)tradeNO
productName:(NSString*)productName
productDescription:(NSString*)productDescription
amount:(NSString*)amount
notifyURL:(NSString*)notifyURL
itBPay:(NSString*)itBPay {
[self alipayWithPartner:partner seller:seller
tradeNO:tradeNO
productName:productName
productDescription:productDescription
amount:amount
notifyURL:notifyURL
service:@"mobile.securitypay.pay"
paymentType:@"1"inputCharset:@"UTF-8"
itBPay:itBPayprivateKey:kPartnerPrivateKey
appScheme:kAppScheme];
}
// 包含所有必要的参数
+ (void)alipayWithPartner:(NSString*)partner
seller:(NSString*)seller
tradeNO:(NSString*)tradeNO
productName:(NSString*)productName
productDescription:(NSString*)productDescription
amount:(NSString*)amount
notifyURL:(NSString*)notifyURL
service:(NSString*)service
paymentType:(NSString*)paymentType
inputCharset:(NSString*)inputCharset
itBPay:(NSString*)itBPay
privateKey:(NSString*)privateKey
appScheme:(NSString*)appScheme {
Order *order = [Order order];
order.partner = partner;
order.seller = seller;
order.tradeNO = tradeNO;
order.productName= productName;
order.productDescription= productDescription;
order.amount = amount;
order.notifyURL = notifyURL;
order.service = service;
order.paymentType= paymentType;
order.inputCharset= inputCharset;
order.itBPay = itBPay;
// 将商品信息拼接成字符串
NSString *orderSpec = [order description];
// 获取私钥并将商户信息签名,外部商户可以根据情况存放私钥和签名,只需要遵循RSA 签名规范, 并将签名字符串 base64 编码和 UrlEncode
NSString *signedString = [selfgenSignedStringWithPrivateKey:kPartnerPrivateKeyOrderSpec:orderSpec];
// 调用支付接口
[self payWithAppScheme:appScheme orderSpec:orderSpec signedString:signedString];
}
// 生成signedString
+ (NSString *)genSignedStringWithPrivateKey:(NSString*)privateKey OrderSpec:(NSString*)orderSpec {
// 获取私钥并将商户信息签名,外部商户可以根据情况存放私钥和签名,只需要遵循RSA 签名规范, 并将签名字符串 base64 编码和 UrlEncode
id<DataSigner> signer =CreateRSADataSigner(privateKey);
return [signer signString:orderSpec];
}
// 支付
+ (void)payWithAppScheme:(NSString*)appScheme orderSpec:(NSString*)orderSpec signedString:(NSString*)signedString {
// 将签名成功字符串格式化为订单字符串,请严格按照该格式
NSString *orderString = nil;
if (signedString != nil) {
orderString = [NSStringstringWithFormat:@"%@&sign=\"%@\"&sign_type=\"%@\"", orderSpec, signedString,@"RSA"];
[[AlipaySDK defaultService] payOrder:orderString fromScheme:appScheme callback:^(NSDictionary*resultDic) {
NSLog(@"AliPay-reslut = %@",resultDic);
}];
}
}
3、封装支付接口,可以写在业务层,也可单独封装起来,此处写在业务层
- (void)aliPayWithOderID:(NSString*)orderID price:(NSString*)price{
[AlipayRequestConfigalipayWithPartner:kPartnerID
seller:kSellerID
[AlipayRequestConfigalipayWithPartner:kPartnerID
seller:kSellerID
tradeNO:orderID
productName:@“商品名"
productDescription:@"二手车"
amount:price
notifyURL:kNotifyURL
amount:price
notifyURL:kNotifyURL
itBPay:@"30m"];
}
4、发起支付
[selfaliPayWithOderID:@"fwrwr131313154141"price:@"8000"];

浙公网安备 33010602011771号