相比Android应用添加支付宝支付功能来说,iOS更加麻烦
签名生成方式
根据支付宝的要求,在向支付宝服务器发送相关参数(即订单数据)的时候,需要针对参数生成签名
并携带这个签名
,浏览器和Android应用,只需要使用MD5
方式生成签名,iOS必须使用RSA
方式生成签名。
谁来生成签名
由于RSA签名的时候需要用到支付宝商户私钥,所以安全起见,最好由服务器端生成RSA签名,如果你不在乎安全的话也可以在iOS端生成。
容易忽略的几点
以下内容容易被忽略并导致iOS应用调起支付宝支付失败,并报ALI64
错误。
引号
PHP生成签名之前需要对参数排序并拼接成字符串,参数的值如果没有引号的话,那么iOS也不能带引号。
拼接字符串顺序
如果iOS需要拼接字符串的话(建议签名后拼接字符串这个步骤也放在服务器端,减少出错的概率),要注意参数的顺序要和服务器端签名时的字符串顺序保持一致,例如
- (NSString*)description {
NSMutableString* description = [NSMutableString string];
if (self._input_charset) {
[description appendFormat:@"_input_charset=%@", self._input_charset];
}
if (self.body) {
[description appendFormat:@"&body=%@", self.body];
}
if (self.notify_url) {
[description appendFormat:@"¬ify_url=%@", self.notify_url];
}
if (self.out_trade_no) {
[description appendFormat:@"&out_trade_no=%@", self.out_trade_no];
}
if (self.partner) {
[description appendFormat:@"&partner=%@", self.partner];
}
if (self.seller_id) {
[description appendFormat:@"&seller_id=%@", self.seller_id]; // mobile.securitypay.pay
}
if (self.service) {
[description appendFormat:@"&service=%@", self.service]; // 1
}
if (self.subject) {
[description appendFormat:@"&subject=%@", self.subject]; // utf-8
}
if (self.total_fee) {
[description appendFormat:@"&total_fee=%@", self.total_fee]; // 30m
}
if (self.sign) {
[description appendFormat:@"&sign=%@", self.sign]; // m.alipay.com
}
if (self.sign_type) {
[description appendFormat:@"&sign_type=%@", self.sign_type]; // m.alipay.com
}
return description;
}
urlencode
生成base64处理后的RSA签名后,还要对其进行urlencode
处理,这个步骤可以放在服务器端,也可以放在iOS端,iOS端的代码如下
- (NSString*)urlEncodedString:(NSString *)string
{
NSString * encodedString = (__bridge_transfer NSString*) CFURLCreateStringByAddingPercentEscapes(kCFAllocatorDefault, (__bridge CFStringRef)string, NULL, (__bridge CFStringRef)@"!*'();:@&=+$,/?%#[]", kCFStringEncodingUTF8 );
return encodedString;
}
私钥的格式
私钥一定要是pkcs8
格式,具体操作如下
openssl genrsa -out rsa_private_key.pem 1024
openssl rsa -in rsa_private_key.pem -pubout -out rsa_public_key.pem
openssl pkcs8 -topk8 -inform PEM -in rsa_private_key.pem -outform PEM -nocrypt
公钥和私钥填写正确
一定要再三检查支付宝商户后台填写的商户公钥
和代码签名所使用的商户私钥pkcs8
是否匹配。