iOS 集成微信支付【轉載】

      目前項目裏有微信支付的需求,調研過一段時間後,發現其實並無想象中的那麼困難。若是你只是想實現該功能,一個方法足以,可是若你想深刻了解實現原理。就須要花費更多的功夫了。目前我只清楚微信支付須要作簽名,一種是在後臺簽名,一種是本身在前端簽名。其實這對前端來講代碼量並無多大的改變,最大的區別是在後臺簽名邏輯更容易理解,而在前端簽名邏輯有些混亂。php

小技巧:我在項目中集成相似的第三方功能時,若是須要對delegate進行操做,我會爲這個功能,單首創建一個category類,這樣避免項目出現多個第三方功能後,delegate裏的代碼十分混亂。前端

 微信支付開發文檔     http://mch.weixin.qq.com/wiki/doc/api/app.php?chapter=8_1   api

正文:安全

微信支付用到的文件 微信

  

PS: 若是你在app內集成了微信分享功能,在分享的那個框架裏,都能找到這些文件的,因此不須要在下載,直接用就行。app

 2.設置URL types框架

 

三、在Appdelegate中註冊微信支付,我我的建議將註冊後的內容輸出一下,以便查看是否註冊成功。ide

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
 
    [WXApi registerApp:@"你的key值" withDescription:@"你的描述信息"];

    

    BOOL isSuccess = [WXApi registerApp:@"你的key值" withDescription:@"你的描述信息"];post


    return YES;
}

 4.微信回調測試

複製代碼
//處理微信經過URL啓動App時傳遞的數據

- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation {
    
    return [WXApi handleOpenURL:url delegate:self];
}

//微信回調
- (void)onResp:(BaseResp *)resp {
    //errCode
    switch (resp.errCode) {
        case WXSuccess:
            //成功回調
            break;
        default:
            break;
    }
}
複製代碼

 5.調用微信支付(主要代碼,後臺簽名)

 1      PayReq* req = [[PayReq alloc] init];
 2         
 3         req.partnerId   = dict[@"entity"][@"partnerid"]; //商戶號
 4         req.prepayId    = dict[@"entity"][@"prepayid"];  //預支付交易會話
 5         req.nonceStr    = dict[@"entity"][@"noncestr"];  //隨機字符串
 6         
 7         req.timeStamp   = [dict[@"entity"][@"timestamp"] intValue]; //時間戳
 8         req.package     = dict[@"entity"][@"package"];  //擴展字段
 9         req.sign        = dict[@"entity"][@"sign"];  //簽名
10         
11         NSNumber *payOrder = dict[@"entity"][@"outTradeNo"];
12         
13         SAVEUSERDEFAULT(payOrder, @"訂單號");
14         
15         
16         //這一點坑比較大,在微信的官方文檔裏,有兩種申請調用微信支付的方法sendReq和safeSendReq(安全方式),這兩個方法不能肯定何時哪一個管用,我這裏的解決辦法就是這個不行換另外一個。哈哈
17         [WXApi safeSendReq:req];
18         
19         DLog(@"微信支付==%d",[WXApi sendReq:req]);

 

 

 6.若是要在程序簽名(這部分的有些難理解,我本身尚未理解透,有機會研究一下,在更新)

 

#import "ViewController.h"
#import "payRequsestHandler.h"
#import "WXApi.h"

@interface ViewController () {
    enum WXScene _scene;
    NSString *Token;
    long token_time;
}

@end

@implementation ViewController

- (instancetype)init
{
    self = [super init];
    if (self) {
        _scene = WXSceneSession;
    }
    token_time = 0;
    return self;
}

- (void)viewDidLoad {
    [super viewDidLoad];
    //向微信註冊
    
    
    //微信支付
    UIButton *but2 = [[UIButton alloc]initWithFrame:CGRectMake(200, 100, 100, 40)];
    [but2 setTitle:@"微信支付" forState:UIControlStateNormal];
    but2.backgroundColor = [UIColor lightGrayColor];
    [but2 addTarget:self action:@selector(wxpay) forControlEvents:UIControlEventTouchUpInside];
    [but2 setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
    [self.view addSubview:but2];
    
}

//微信支付
- (void)wxpay
{
    //商戶號
    NSString *PARTNER_ID    = @"1900000109";
    //商戶密鑰
    NSString *PARTNER_KEY   = @"8934e7d15453e97507ef794cf7b0519d";
    //APPID
    NSString *APPI_ID       = @"wxd930ea5d5a258f4f";
    //appsecret
    NSString *APP_SECRET    = @"db426a9829e4b49a0dcac7b4162da6b6";
    //支付密鑰
    NSString *APP_KEY       = @"L8LrMqqeGRxST5reouB0K66CaYAWpqhAVsq7ggKkxHCOastWksvuX1uvmvQclxaHoYd3ElNBrNO2DHnnzgfVG9Qs473M3DTOZug5er46FhuGofumV8H2FVR9qkjSlC5K";
    
    //支付結果回調頁面
    NSString *NOTIFY_URL    = @"http://localhost/pay/wx/notify_url.asp";
    //訂單標題
    NSString *ORDER_NAME    = @"Ios客戶端簽名支付 測試";
    //訂單金額,單位(分)
    NSString *ORDER_PRICE   = @"1";
    
    //建立支付簽名對象
    payRequsestHandler *req = [payRequsestHandler alloc];
    //初始化支付簽名對象
    [req init:APPI_ID app_secret:APP_SECRET partner_key:PARTNER_KEY app_key:APP_KEY];
    
    //判斷Token過時時間,10分鐘內不重複獲取,測試賬號多個使用,可能形成其餘地方獲取後不能用,須要即時獲取
    time_t  now;
    time(&now);
    //if ( (now - token_time) > 0 )//非測試賬號調試請啓用該條件判斷
    {
        //獲取Token
        Token                   = [req GetToken];
        //設置Token有效期爲10分鐘
        token_time              = now + 600;
        //日誌輸出
        NSLog(@"獲取Token: %@\n",[req getDebugifo]);
    }
    if ( Token != nil){
        //================================
        //預付單參數訂單設置
        //================================
        NSMutableDictionary *packageParams = [NSMutableDictionary dictionary];
        [packageParams setObject: @"WX"                                             forKey:@"bank_type"];
        [packageParams setObject: ORDER_NAME                                        forKey:@"body"];
        [packageParams setObject: @"1"                                              forKey:@"fee_type"];
        [packageParams setObject: @"UTF-8"                                          forKey:@"input_charset"];
        [packageParams setObject: NOTIFY_URL                                        forKey:@"notify_url"];
        [packageParams setObject: [NSString stringWithFormat:@"%ld",time(0)]        forKey:@"out_trade_no"];
        [packageParams setObject: PARTNER_ID                                        forKey:@"partner"];
        [packageParams setObject: @"196.168.1.1"                                    forKey:@"spbill_create_ip"];
        [packageParams setObject: ORDER_PRICE                                       forKey:@"total_fee"];
        
        NSString    *package, *time_stamp, *nonce_str, *traceid;
        //獲取package包
        package        = [req genPackage:packageParams];
        
        //輸出debug info
        NSString *debug     = [req getDebugifo];
        NSLog(@"gen package: %@\n",package);
        NSLog(@"生成package: %@\n",debug);
        
        //設置支付參數
        time_stamp  = [NSString stringWithFormat:@"%ld", now];
        nonce_str    = [TenpayUtil md5:time_stamp];
        traceid        = @"mytestid_001";
        NSMutableDictionary *prePayParams = [NSMutableDictionary dictionary];
        [prePayParams setObject: APPI_ID                                            forKey:@"appid"];
        [prePayParams setObject: APP_KEY                                            forKey:@"appkey"];
        [prePayParams setObject: nonce_str                                          forKey:@"noncestr"];
        [prePayParams setObject: package                                            forKey:@"package"];
        [prePayParams setObject: time_stamp                                         forKey:@"timestamp"];
        [prePayParams setObject: traceid                                            forKey:@"traceid"];
        
        //生成支付簽名
        NSString    *sign;
        sign        = [req createSHA1Sign:prePayParams];
        //增長非參與簽名的額外參數
        [prePayParams setObject: @"sha1"                                            forKey:@"sign_method"];
        [prePayParams setObject: sign                                               forKey:@"app_signature"];
        
        //獲取prepayId
        NSString *prePayid;
        prePayid            = [req sendPrepay:prePayParams];
        //輸出debug info
        debug               = [req getDebugifo];
        NSLog(@"提交預付單: %@\n",debug);
        
        if ( prePayid != nil) {
            //從新按提交格式組包,微信客戶端5.0.3之前版本只支持package=Sign=***格式,須考慮升級後支持攜帶package具體參數的狀況
            //package       = [NSString stringWithFormat:@"Sign=%@",package];
            package         = @"Sign=WXPay";
            //簽名參數列表
            NSMutableDictionary *signParams = [NSMutableDictionary dictionary];
            [signParams setObject: APPI_ID                                          forKey:@"appid"];
            [signParams setObject: APP_KEY                                          forKey:@"appkey"];
            [signParams setObject: nonce_str                                        forKey:@"noncestr"];
            [signParams setObject: package                                          forKey:@"package"];
            [signParams setObject: PARTNER_ID                                       forKey:@"partnerid"];
            [signParams setObject: time_stamp                                       forKey:@"timestamp"];
            [signParams setObject: prePayid                                         forKey:@"prepayid"];
            
            //生成簽名
            sign        = [req createSHA1Sign:signParams];
            
            //輸出debug info
            debug     = [req getDebugifo];
            NSLog(@"調起支付簽名: %@\n",debug);
            
            //調起微信支付
            PayReq* req = [[PayReq alloc] init];
            req.openID      = APPI_ID;
            req.partnerId   = PARTNER_ID;
            req.prepayId    = prePayid;
            req.nonceStr    = nonce_str;
            req.timeStamp   = now;
            req.package     = package;
            req.sign        = sign;
            [WXApi safeSendReq:req];
        }else{
            /*long errcode = [req getLasterrCode];
             if ( errcode == 40001 )
             {//Token實效,從新獲取
             Token                   = [req GetToken];
             token_time              = now + 600;
             NSLog(@"獲取Token: %@\n",[req getDebugifo]);
             };*/
            NSLog(@"獲取prepayid失敗\n");
            [self alert:@"提示信息" msg:debug];
        }
    }else{
        NSLog(@"獲取Token失敗\n");
        [self alert:@"提示信息" msg:@"獲取Token失敗"];
    }
    
}

//客戶端提示信息
- (void)alert:(NSString *)title msg:(NSString *)msg
{
    UIAlertView *alter = [[UIAlertView alloc] initWithTitle:title message:msg delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil];
    
    [alter show];
}

//- (void)onReq:(BaseReq *)req {
//    NSLog(@"qwe123");
//}

- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

@end
複製代碼
相關文章
相關標籤/搜索