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-----
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
-----END PUBLIC KEY-----
               5、把BEGIN 和END之间的内容(整理成一行,前后不能有回车、换行)上传到服务器,换回支付宝的公钥
 
四、APP端
 
     1、添加相关信息,一般写一个头文件 AlipayHeader.h
           /**
 *  partner:
合作身份者ID,2088 开头由 16 位纯数字组成的字符串。
 *
 */

#define kPartnerID @"2088811123293271"


/**
 *  seller:
支付宝收款账号,手机号码或邮箱格式。
 */
#define kSellerID @xxxx@fcihpy.com"

/**
 * 
支付宝服务器主动通知商户网站里指定的页面 http 路径。
 */


/**
 *  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);

        }];
    }
}
 
 
     3、封装支付接口,可以写在业务层,也可单独封装起来,此处写在业务层
 
- (void)aliPayWithOderID:(NSString*)orderID price:(NSString*)price{
   
    [AlipayRequestConfigalipayWithPartner:kPartnerID
                                    seller:kSellerID
                                  tradeNO:orderID
                              productName:@商品名"
                        productDescription:@"二手车"
                                    amount:price
                                 notifyURL:kNotifyURL
                                   itBPay:@"30m"];
 
}
     4、发起支付
[selfaliPayWithOderID:@"fwrwr131313154141"price:@"8000"];

 

 

 
 
posted @ 2015-07-15 13:52  fcihpy  阅读(564)  评论(0)    收藏  举报