1. 程式人生 > >iOS 整合微信支付

iOS 整合微信支付

      微信支付現在是移動支付領域一支不可忽視的力量,我們移動開發人員在開發app的時候,也不可避免的用到各種支付,支付寶支付我們用的最多了,我這裡就不講解了,我現在給大家講解一個iOS微信支付,首先 我們需要在微信開放平臺註冊商戶資訊(記住是微信開放平臺不是公眾平臺),微信開放平臺支援的銀行卡有限,所以在確定用微信支付的時候先看看,支不支援公司的銀行卡,比如廣大銀行卡是不支援的。(程式碼下載地址)

      在微信開放平臺弄好app支付以後,下載iOS SDK,我們需要配置6個引數 如下圖 它在微信支付SDK lib資料夾下的payRequestHandler.h檔案中


       把上面那幾引數配置好,最下面那2個引數,如果伺服器端沒配置好可以先不修改,就用微信預設的引數就可以。

      因為微信支付的SDK程式碼是ARC的,所以我們需要在配置檔案裡面設定一下,新增-fno-objc-arc  如下圖

   

        我們還需要配置一下info裡面的URL Types    , URL Schemes裡面填寫的是APP_ID的值

    

     我們在代理檔案(APPDelegate.h)裡面匯入微信支付的標頭檔案    payRequsestHandler.h、WXApi.h   如下圖


 我們在AppDelegate.m 實現檔案中 寫上相應的程式碼

//
//  AppDelegate.m
//  微信支付
//
//  Created by lairen on 15/8/18.
//  Copyright (c) 2015年 lairen. All rights reserved.
//

#import "AppDelegate.h"



//服務端簽名只需要用到下面一個頭檔案
//#import "ApiXml.h"
#import <QuartzCore/QuartzCore.h>


@interface AppDelegate ()

@end

@implementation AppDelegate

@synthesize window = _window;

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


- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    // 註冊微信
    [WXApi registerApp:APP_ID withDescription:@"demo 2.0"];
    //新增通知
    [self addObserver];
    
    return YES;
}

#pragma mark 新增通知
-(void)addObserver
{
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(sendPay_demo) name:@"weixinPay" object:nil];
}

-(void) changeScene:(NSInteger )scene
{
    _scene = (enum WXScene)scene;
}



-(void) onResp:(BaseResp*)resp
{
    NSString *strMsg = [NSString stringWithFormat:@"errcode:%d", resp.errCode];
    NSString *strTitle;
    
    if([resp isKindOfClass:[SendMessageToWXResp class]])
    {
        strTitle = [NSString stringWithFormat:@"傳送媒體訊息結果"];
    }
    if([resp isKindOfClass:[PayResp class]]){
        //支付返回結果,實際支付結果需要去微信伺服器端查詢
        strTitle = [NSString stringWithFormat:@"支付結果"];
        
        switch (resp.errCode) {
            case WXSuccess:
                strMsg = @"支付結果:成功!";
                NSLog(@"支付成功-PaySuccess,retcode = %d", resp.errCode);
                break;
                
            default:
                strMsg = [NSString stringWithFormat:@"支付結果:失敗!retcode = %d, retstr = %@", resp.errCode,resp.errStr];
                NSLog(@"錯誤,retcode = %d, retstr = %@", resp.errCode,resp.errStr);
                break;
        }
    }
    UIAlertView *alert = [[UIAlertView alloc] initWithTitle:strTitle message:strMsg delegate:self cancelButtonTitle:@"OK" otherButtonTitles:nil, nil];
    [alert show];
}


#pragma mark  微信支付  這個適合自己伺服器互動呼叫的方法
- (void)sendPay
{
    //從伺服器獲取支付引數,服務端自定義處理邏輯和格式
    //訂單標題
    NSString *ORDER_NAME    = @"ios 微信支付";
    //訂單金額,單位(元)
    NSString *ORDER_PRICE   = @"0.01";
    
    //根據伺服器端編碼確定是否轉碼
    NSStringEncoding enc;
    //if UTF8編碼
    //enc = NSUTF8StringEncoding;  SP_URL,
    //if GBK編碼
    enc = CFStringConvertEncodingToNSStringEncoding(kCFStringEncodingGB_18030_2000);
    NSString *urlString = [NSString stringWithFormat:@"?plat=ios&order_no=%@&product_name=%@&order_price=%@",
                           
                           [[NSString stringWithFormat:@"%ld",time(0)] stringByAddingPercentEscapesUsingEncoding:enc],
                           [ORDER_NAME stringByAddingPercentEscapesUsingEncoding:enc],
                           ORDER_PRICE];
    NSLog(@"%@",urlString);
    
    //解析服務端返回json資料
    NSError *error;
    //載入一個NSURL物件
    NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:urlString]];
    //將請求的url資料放到NSData物件中
    NSData *response = [NSURLConnection sendSynchronousRequest:request returningResponse:nil error:nil];
    if ( response != nil) {
        NSMutableDictionary *dict =NULL;
        //IOS5自帶解析類NSJSONSerialization從response中解析出資料放到字典中
        dict = [NSJSONSerialization JSONObjectWithData:response options:NSJSONReadingMutableLeaves error:&error];
        
        NSLog(@"url:%@",dict);
        if(dict != nil){
            NSMutableString *retcode = [dict objectForKey:@"retcode"];
            if (retcode.intValue == 0){
                NSMutableString *stamp  = [dict objectForKey:@"timestamp"];
                
                //調起微信支付
                PayReq* req             = [[PayReq alloc] init];
                req.openID              = [dict objectForKey:@"appid"];
                req.partnerId           = [dict objectForKey:@"partnerid"];
                req.prepayId            = [dict objectForKey:@"prepayid"];
                req.nonceStr            = [dict objectForKey:@"noncestr"];
                req.timeStamp           = stamp.intValue;
                req.package             = [dict objectForKey:@"package"];
                req.sign                = [dict objectForKey:@"sign"];
                [WXApi sendReq:req];
                
                
                //日誌輸出
                // NSLog(@"%@",req.openID);
                NSLog(@"appid=%@\npartid=%@\nprepayid=%@\nnoncestr=%@\ntimestamp=%ld\npackage=%@\nsign=%@",req.openID,req.partnerId,req.prepayId,req.nonceStr,(long)req.timeStamp,req.package,req.sign );
            }else{
                [self alert:@"提示資訊" msg:[dict objectForKey:@"retmsg"]];
            }
        }else{
            [self alert:@"提示資訊" msg:@"伺服器返回錯誤,未獲取到json物件"];
        }
    }else{
        [self alert:@"提示資訊" msg:@"伺服器返回錯誤"];
    }
}

#pragma mark 微信測試支付  這個是呼叫的微信伺服器的支付介面

- (void)sendPay_demo
{
    NSLog(@"微信支付 demo");

    //{{{
    //本例項只是演示簽名過程, 請將該過程在商戶伺服器上實現
    
    //建立支付簽名物件
    payRequsestHandler *req = [payRequsestHandler alloc];
    //初始化支付簽名物件
    [req init:APP_ID mch_id:MCH_ID];
    //設定金鑰
    [req setKey:PARTNER_ID];
    
    //}}}
    
    //獲取到實際調起微信支付的引數後,在app端調起支付
    NSMutableDictionary *dict = [req sendPay_demo];
    
    if(dict == nil){
        //錯誤提示
        NSString *debug = [req getDebugifo];
        
        [self alert:@"提示資訊" msg:debug];
        
        NSLog(@"%@\n\n",debug);
    }else{
        NSLog(@"%@\n\n",[req getDebugifo]);
        //[self alert:@"確認" msg:@"下單成功,點選OK後調起支付!"];
        
        NSMutableString *stamp  = [dict objectForKey:@"timestamp"];
        
        //調起微信支付
        PayReq* req             = [[PayReq alloc] init];
        req.openID              = [dict objectForKey:@"appid"];
        req.partnerId           = [dict objectForKey:@"partnerid"];
        req.prepayId            = [dict objectForKey:@"prepayid"];
        req.nonceStr            = [dict objectForKey:@"noncestr"];
        req.timeStamp           = stamp.intValue;
        req.package             = [dict objectForKey:@"package"];
        req.sign                = [dict objectForKey:@"sign"];
        
        [WXApi sendReq:req];
    }
}

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

}

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

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






@end

    我們再在ViewController檔案中   新增支付按鈕。直接在故事版上面拖上2個按鈕就可以。第一個按鈕是用的微信伺服器返回的json資料 第二個按鈕返回的是自己伺服器返回的json資料,自己伺服器返回的資料包括簽名證書一些相關的東西,我們做操作演示  就使用微信的伺服器

 

 給按鈕加上點選方法。方法在ViewController.m檔案中   點選方法的時候會發送一個通知給AppDelegate.m檔案

#pragma mark 新增通知

-(void)addObserver

{

    [[NSNotificationCenterdefaultCenter]addObserver

:selfselector:@selector(sendPay_demo)name:@"weixinPay"object:nil];

}


#import "ViewController.h"

@interface ViewController ()
- (IBAction)testPay:(id)sender;

- (IBAction)realPay:(id)sender;


@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.
}


//微信支付測試簽名
- (IBAction)testPay:(id)sender {
     [[NSNotificationCenter defaultCenter] postNotificationName:@"weixinPay" object:nil];
}

//微信支付測試簽名
- (IBAction)realPay:(id)sender {
   UIAlertView *alert= [[UIAlertView alloc]initWithTitle:@"友情提示" message:@"伺服器端介面還沒開放,請稍後再試" delegate:nil cancelButtonTitle:@"好的" otherButtonTitles:nil, nil];
    [alert show];
}


@end
傳送通知以後,在AppDelegate.h檔案的監聽方法會呼叫微信支付  如圖

呼叫起微信支付後,就會開啟微信  


 ok,到這裡我們的微信支付Demo,就已經做完了,同學們,加油啊。