iOS:集成支付寶支付

1、介紹

支付寶的集成仍是比較簡單的,按照文檔來一步步操做,基本上很順利。不過,仍然有兩個地方會是坑。這裏我集成成功了,在此整理一下。說先說一下我遇到的坑以下:git

 

第一個坑:下載的SDK文件AliPay.bundle和AliPay.framework一直報錯,找不到庫,無法使用。什麼緣由,我暫時還不知道。github

解決辦法:將官方提供的demo中SDK文件拖入項目中,替換掉本身下載的SDK便可express

 

第二個坑:拖入的openssl目錄下的全部#include <openssl/xxx.h>找不到路徑。緣由是在demo中openssl目錄直接被放到了項目根目錄下,而咱們拖入是被放到了工程目錄下,路徑不一致,須要更改路徑。xcode

解決辦法:在Build setting下設置Header Search Path路徑。網絡

例如個人路經設置圖爲,是根據下面圖顯示的openssl設置的:app

 

2、看看個人項目圖

 

3、準備

(1)在支付寶開發者平臺註冊登陸帳號建立應用獲取appid,螞蟻金服開放平臺(open.alipay.com工具

(2)配置密鑰,開發者調用接口前須要先生成RSA密鑰,RSA密鑰包含應用私鑰(APP_PRIVATE_KEY)、應用公鑰(APP_PUBLIC_KEY)。生成密鑰後在開放平臺管理中心進行密鑰配置,配置完成後能夠獲取支付寶公鑰(ALIPAY_PUBLIC_KEY)。詳細步驟請參考《配置應用環境》測試

(3)集成並配置sdk,要將庫添加完整(下面有一個libPods-xxx這個是使用cocopods開發項目自動生成的,沒有使用cocoPods開發的不用管)ui

注意:在xcode8.0後,須要再多添加一個依賴庫SystemConfiguration.framework,否則要報錯了。this

(4)設置URL Schemes,這個必須保證惟一性,由於支付完成後會根據這個調回到咱們本身的app,我將這個在pch中作了定義,值必須保持同樣

 

4、使用

在pch設置宏定義並導入頭文件

//  Prefix header
//  夏遠全
//  The contents of this file are implicitly included at the beginning of every source file.
//

#import <Availability.h>

#ifndef __IPHONE_5_0
#warning "This project uses features only available in iOS SDK 5.0 and later."
#endif

#ifdef __OBJC__
    #import <UIKit/UIKit.h>
    #import <Foundation/Foundation.h>
    #import <AlipaySDK/AlipaySDK.h> //支付寶SDK
    #import "PayManager.h"          //支付寶調起支付類
    #import "DataSigner.h"          //支付寶簽名類
    #import "Order.h"               //訂單模型
    #import "APAuthV2Info.h"        //受權模型

/**
 -----------------------------------
 支付寶支付須要配置的參數
 -----------------------------------
 */

//開放平臺登陸https://openhome.alipay.com/platform/appManage.htm

//管理中心獲取APPID
#define AlipayAPPID       @"xxxxxxxxx"

//管理中心獲取PIDID
#define PIDID             @"xxxxxxxxx"

//支付寶私鑰(用戶自主生成,使用pkcs8格式的私鑰,文檔上提供了兩種生成方式,本身去選擇吧)
#define AlipayPrivateKey  @"xxxxxxxxx"

//應用註冊scheme,在AliSDKDemo-Info.plist定義URL types  
#define URLScheme         @"AliPayKit"

//支付寶支付接口
#define AlipayUrl         @"alipay.trade.app.pay"

#endif

在AppDelegate.m中回調

- (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);
        }];
        
        // 受權跳轉支付寶錢包進行支付,處理支付結果
        [[AlipaySDK defaultService] processAuth_V2Result:url standbyCallback:^(NSDictionary *resultDic) {
            NSLog(@"result = %@",resultDic);
            //解析 auth code
            NSString *result = resultDic[@"result"];
            NSString *authCode = nil;
            if (result.length>0) {
                NSArray *resultArr = [result componentsSeparatedByString:@"&"];
                for (NSString *subResult in resultArr) {
                    if (subResult.length > 10 && [subResult hasPrefix:@"auth_code="]) {
                        authCode = [subResult substringFromIndex:10];
                        break;
                    }
                }
            }
            NSLog(@"受權結果 authCode = %@", authCode?:@"");
        }];
    }
    return YES;
}

// NOTE: 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);
        }];
        
        // 受權跳轉支付寶錢包進行支付,處理支付結果
        [[AlipaySDK defaultService] processAuth_V2Result:url standbyCallback:^(NSDictionary *resultDic) {
            NSLog(@"result = %@",resultDic);
            // 解析 auth code
            NSString *result = resultDic[@"result"];
            NSString *authCode = nil;
            if (result.length>0) {
                NSArray *resultArr = [result componentsSeparatedByString:@"&"];
                for (NSString *subResult in resultArr) {
                    if (subResult.length > 10 && [subResult hasPrefix:@"auth_code="]) {
                        authCode = [subResult substringFromIndex:10];
                        break;
                    }
                }
            }
            NSLog(@"受權結果 authCode = %@", authCode?:@"");
        }];
    }
    return YES;
}

在工具類PayManager.m中實現支付

//  PayManager.m
//  AliPayKit
//
//  Created by 夏遠全 on 16/12/20.
//  Copyright © 2016年 廣州市東德網絡科技有限公司. All rights reserved.
//

#import "PayManager.h"

@implementation PayManager

#pragma mark - 進行支付

+(void)openAliPayForPaying{
    
    /*=========================================================*/
    /*====客戶端調用支付寶支付(實際操做請放到服務端)=================*/
    /*=========================================================*/
    

    //AppId和PrivateKey沒有配置下的提示
    if ([AlipayAPPID length] == 0 || [AlipayPrivateKey length] == 0)
    {
        [self alertShow];
        return;
    }

    //將商品信息賦予AlixPayOrder的成員變量
    Order* order    = [Order new];
    order.app_id    = AlipayAPPID;  // NOTE: app_id設置
    order.method    = AlipayUrl;    // NOTE: 支付接口名稱
    order.charset = @"utf-8";       // NOTE: 參數編碼格式
    
    NSDateFormatter* formatter = [NSDateFormatter new];
    [formatter setDateFormat:@"yyyy-MM-dd HH:mm:ss"];
    order.timestamp = [formatter stringFromDate:[NSDate date]];// NOTE: 當前時間點
    
    order.version   = @"1.0";       // NOTE: 支付版本
    order.sign_type = @"RSA";       // NOTE: sign_type設置
    
    // NOTE: 商品數據
    order.biz_content                   = [BizContent new];
    order.biz_content.body              = @"我是測試數據";
    order.biz_content.subject           = @"1";
    order.biz_content.out_trade_no      = [self generateTradeNO];   //訂單ID(由商家自行制定)
    order.biz_content.timeout_express   = @"30m";                   //超時時間設置
    order.biz_content.total_amount      = [NSString stringWithFormat:@"%.2f", 0.01];//商品價格
    
    //將商品信息拼接成字符串
    NSString *orderInfo         = [order orderInfoEncoded:NO];
    NSString *orderInfoEncoded  = [order orderInfoEncoded:YES];
    NSLog(@"orderSpec = %@",orderInfo);
    
    // NOTE: 獲取私鑰並將商戶信息簽名,外部商戶的加簽過程請務必放在服務端,防止公私鑰數據泄露;
    //       須要遵循RSA簽名規範,並將簽名字符串base64編碼和UrlEncode
    id<DataSigner> signer = CreateRSADataSigner(AlipayPrivateKey);
    NSString *signedString = [signer signString:orderInfo];
    
    // NOTE: 若是加簽成功,則繼續執行支付
    if (signedString != nil) {
        //應用註冊scheme,在AliSDKDemo-Info.plist定義URL types
        NSString *appScheme = URLScheme;
        
        // NOTE: 將簽名成功字符串格式化爲訂單字符串,請嚴格按照該格式
        NSString *orderString = [NSString stringWithFormat:@"%@&sign=%@",
                                 orderInfoEncoded, signedString];
        
        // NOTE: 調用支付結果開始支付
        [[AlipaySDK defaultService] payOrder:orderString fromScheme:appScheme callback:^(NSDictionary *resultDic) {
            NSLog(@"reslut = %@",resultDic);
        }];
    }
}

#pragma mark - 隨機字符串
//==============產生隨機訂單號==============
+ (NSString *)generateTradeNO
{
    static int kNumber = 15;
    NSString *sourceStr = @"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
    NSMutableString *resultStr = [[NSMutableString alloc] init];
    srand((unsigned)time(0));
    for (int i = 0; i < kNumber; i++)
    {
        unsigned index = rand() % [sourceStr length];
        NSString *oneStr = [sourceStr substringWithRange:NSMakeRange(index, 1)];
        [resultStr appendString:oneStr];
    }
    return resultStr;
}


#pragma mark - 提示信息
+(void)alertShow{
    
//去除警告
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
    
    //AppId和PrivateKey沒有配置下的提示
    if ([AlipayAPPID length] == 0 || [AlipayPrivateKey length] == 0)
    {
        UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"提示"
                                                        message:@"缺乏appId或者私鑰。"
                                                       delegate:self
                                              cancelButtonTitle:@"肯定"
                                              otherButtonTitles:nil];
        [alert show];
    }
#pragma clang diagnostic pop
}

@end

 

5、模擬器和真機演示的截圖以下:

首先我生成的私鑰以下:

支付截圖:

 

 

完成的demo地址,github:https://github.com/xiayuanquan/AliPaykit,但願有幫助

相關文章
相關標籤/搜索