ios 微信支付

關(guān)于微信支付疾掰,我就忍不住要吐槽兩句,因?yàn)轫?xiàng)目中要用到微信支付徐紧,所以就從官方下載了微信支付的demo静檬,自我感覺微信支付的demo和官方文檔寫的挺讓人回味的,因?yàn)槟憧戳艘院蟪燥埖臅r候也會忍不住罵上兩句并级。

好了拂檩,廢話不多說,接下來我們直接上代碼
在appdelegate中代碼如下

#import "AppDelegate.h"

//微信支付
#import "WXApi.h"

@interface AppDelegate ()<WXApiDelegate>

@end

@implementation AppDelegate


- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    // Override point for customization after application launch.
    
    //注冊微信支付
    [WXApi registerApp:APP_id withDescription:@"demo"];
    
    return YES;
}

//iOS9 之后使用這個回調(diào)方法嘲碧。
- (BOOL)application:(UIApplication *)app openURL:(NSURL *)url options:(NSDictionary<NSString *,id> *)options
{
    if ([url.host isEqualToString:@"pay"]) {
        
        return [WXApi handleOpenURL:url delegate:self];
    }
    
    return YES;
}


#pragma mark - 微信支付的代理方法
- (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
{

    if ([url.host isEqualToString:@"pay"]) {
        
        return [WXApi handleOpenURL:url delegate:self];
    }
    
    return YES;
    
}

#pragma mark - 微信支付成功的回調(diào)函數(shù)(這個方法必須寫在delegate.m文件中)
-(void)onResp:(BaseResp*)resp
{
    if ([resp isKindOfClass:[PayResp class]]){
        
        PayResp *response = (PayResp*)resp;
        
        switch(response.errCode){
                
            case WXSuccess:
                //服務(wù)器端查詢支付通知或查詢API返回的結(jié)果再提示成功
                //NSLog(@"支付成功");
                
                //發(fā)送通知給帶有微信支付功能的視圖控制器稻励,告訴他支付成功了,請求后臺訂單狀態(tài)愈涩,如果后臺返回的訂單也是成功的狀態(tài)望抽,那么可以進(jìn)行下一步操作
                [[NSNotificationCenter defaultCenter] postNotificationName:WEIXINPAYSUCCESSED object:nil userInfo:nil];
                
                
                break;
                
            default:
                
                /*
                 
                 resp.errCode = 2 用戶取消支付
                 resp.errCode = -1 錯誤
                 */
                NSLog(@"支付失敗,retcode=%d ---- %@",resp.errCode,resp.errStr);
                
                break;
        }
    }
}//微信支付成功的回調(diào)方法(回調(diào)函數(shù))

上面有兩個系統(tǒng)回調(diào)的方法履婉,第一個是針對ios9.0以后煤篙,第二個是針對ios9.0之前的
在帶有微信支付的頁面我們做如下處理

#import "ViewController.h"
//微信支付
#import "WXApi.h"
#import "payRequsestHandler.h"
#import "WXUtil.h"

@interface ViewController ()

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.
    
    UIButton *button = [[UIButton alloc] initWithFrame:CGRectMake(60, 100, 180, 100)];
    button.backgroundColor = [UIColor redColor];
    [button setTitle:@"微信支付" forState:UIControlStateNormal];
    [button addTarget:self action:@selector(test) forControlEvents:UIControlEventTouchUpInside];
    [self.view addSubview:button];
    
    //接受成功的通知
    [[NSNotificationCenter defaultCenter]addObserver:self selector:@selector(succeed) name:WEIXINPAYSUCCESSED object:nil];
}

#pragma mark - ASction Methods
- (void)test
{
    
    payRequsestHandler *handle = [[payRequsestHandler alloc]init];
    
    if ( [handle  init:APP_id mch_id:MCH_id]) {
        
        NSLog(@"初始化成功");
        
    }
    
    //設(shè)置商戶密鑰
    [handle setKey:PARTNER_id];
    
    //提交預(yù)支付,獲得prepape_id
    NSString *order_name = @"測試";   //訂單標(biāo)題
    NSString *order_price = @"1";//測試價格 分為單位
    NSString *nocify_URL = nocify_url;    //回調(diào)借口
    NSString *noncestr  = [NSString stringWithFormat:@"%d", rand()]; //隨機(jī)串
    NSString *orderno   = [NSString stringWithFormat:@"%ld",time(0)];
    NSMutableDictionary *params = [@{@"appid":APP_id,
                                     @"mch_id":MCH_id,
                                     @"device_info":[[[UIDevice currentDevice] identifierForVendor] UUIDString],
                                     @"nonce_str":noncestr,
                                     @"trade_type":@"APP",
                                     @"body":order_name,
                                     @"notify_url":nocify_URL,
                                     @"out_trade_no":orderno,//商戶訂單號:這個必須用后臺的訂單號
                                     @"spbill_create_ip":@"8.8.8.8",
                                     @"total_fee":order_price}mutableCopy];
    
    //提交預(yù)支付兩次簽名得到預(yù)支付訂單的id(每次的請求得到的預(yù)支付訂單id都不同)
    NSString *prepate_id = [handle sendPrepay:params];
    
    //提交預(yù)訂單成功
    if (prepate_id != nil) {
        
        PayReq *request = [[PayReq alloc]init];
        
        //商家id
        request.partnerId = MCH_id;
        
        //訂單id
        request.prepayId = prepate_id;
        
        //擴(kuò)展字段(官方文檔:暫時填寫固定值)
        request.package = @"Sign=WXPay";
        
        //隨機(jī)字符串
        request.nonceStr = noncestr;
        
        //時間戳
        request.timeStamp = (UInt32)[[NSDate date] timeIntervalSince1970];
        
        //sign參數(shù)(很經(jīng)常出現(xiàn)的問題:就是調(diào)起支付到微信那邊只出現(xiàn)一個確定按鈕毁腿,單擊確認(rèn)按鈕直接返回到app辑奈,出現(xiàn)這個問題100%是sign參數(shù)的問題)
        /*
         參數(shù)依次是: appid_key、partnerid_key已烤、prepayid_key鸠窗、固定值Sign=WXPay、預(yù)支付的隨機(jī)數(shù)(跟上面得到預(yù)支付訂單的隨機(jī)數(shù)要一致)胯究、支付時間(秒)
         
         */
        request.sign = [self createMD5SingForPay:APP_id partnerid:MCH_id prepayid:prepate_id package:@"Sign=WXPay" noncestr:noncestr timestamp:(UInt32)[[NSDate date] timeIntervalSince1970]];
        
        
        
        //帶起微信支付
        if ([WXApi sendReq:request]) {
            
            
            // NSLog(@"走這里啊");
            
        }else{
            
            //NSLog(@"走之類");
            //未安裝微信客戶端
//            [[[UIAlertView alloc]initWithTitle:@"測試demo" message:@"您還未安裝微信客戶端,請前往Appstore下載或者選擇其他支付方式!" delegate:nil cancelButtonTitle:@"知道了" otherButtonTitles:nil, nil]show];
            
        }
        
    }
    
}//點(diǎn)擊微信支付


#pragma mark - Private Methods
-(NSString *)createMD5SingForPay:(NSString *)appid_key partnerid:(NSString *)partnerid_key prepayid:(NSString *)prepayid_key package:(NSString *)package_key noncestr:(NSString *)noncestr_key timestamp:(UInt32)timestamp_key
{
    NSMutableDictionary *signParams = [NSMutableDictionary dictionary];
    [signParams setObject:appid_key forKey:@"appid"];
    [signParams setObject:noncestr_key forKey:@"noncestr"];
    [signParams setObject:package_key forKey:@"package"];
    [signParams setObject:partnerid_key forKey:@"partnerid"];
    [signParams setObject:prepayid_key forKey:@"prepayid"];
    [signParams setObject:[NSString stringWithFormat:@"%u",(unsigned int)timestamp_key] forKey:@"timestamp"];
    NSMutableString *contentString  =[NSMutableString string];
    NSArray *keys = [signParams allKeys];
    //按字母順序排序
    NSArray *sortedArray = [keys sortedArrayUsingComparator:^NSComparisonResult(id obj1, id obj2) {
        return [obj1 compare:obj2 options:NSNumericSearch];
    }];
    //拼接字符串
    for (NSString *categoryId in sortedArray) {
        if (   ![[signParams objectForKey:categoryId] isEqualToString:@""]
            && ![[signParams objectForKey:categoryId] isEqualToString:@"sign"]
            && ![[signParams objectForKey:categoryId] isEqualToString:@"key"]
            )
        {
            [contentString appendFormat:@"%@=%@&", categoryId, [signParams objectForKey:categoryId]];
        }
    }
    //添加商戶密鑰key字段
    [contentString appendFormat:@"key=%@",PARTNER_id];
    NSString *result = [self md5:contentString];
    return result;
    
}//創(chuàng)建發(fā)起支付時的sige簽名


-(NSString *)md5:(NSString *)str
{
    const char *cStr = [str UTF8String];
    unsigned char result[16]= "0123456789abcdef";
    CC_MD5(cStr, (CC_LONG)strlen(cStr), result);
    //這里的x是小寫則產(chǎn)生的md5也是小寫稍计,x是大寫則md5是大寫,這里只能用大寫裕循,微信的大小寫驗(yàn)證很逗
    return [NSString stringWithFormat:
            @"%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X",
            result[0], result[1], result[2], result[3],
            result[4], result[5], result[6], result[7],
            result[8], result[9], result[10], result[11],
            result[12], result[13], result[14], result[15]
            ];
}//MD5 加密


- (void)succeed
{
    
    NSLog(@"支付成功");
    
    
}//支付成功的監(jiān)聽方法


#pragma mark - OverRide Methods
- (void)dealloc
{
    
    [[NSNotificationCenter defaultCenter] removeObserver:self name:WEIXINPAYSUCCESSED object:nil];
    
    
}//移除通知


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

@end

這里面有幾個名字我給大家解釋一下丙猬,PARTNER_id是從商戶中心那里獲取的,當(dāng)你在微信開放平臺創(chuàng)建的應(yīng)用申請微信支付成功以后费韭,進(jìn)入到商戶中心那里自己設(shè)置一個32位的字符串茧球。MCH_id是商家的id,也就是商戶號星持。

APP_id是在微信開放平臺創(chuàng)建應(yīng)用的appid抢埋。notify_url是回調(diào)接口,也就是一個url鏈接督暂,是由服務(wù)器給你的

最后還有一點(diǎn)揪垄,大家通常會遇到一個問題,在調(diào)起微信以后逻翁,發(fā)現(xiàn)只有一個空白的頁面饥努,中間有一個確定的按鈕,這種情況是sign簽名的問題

下面附上微信支付的demo八回,里面的一些相關(guān)信息需要換成自己開放平臺中自己應(yīng)用的信息
https://github.com/EngineerLXK/WeiXinPay

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末酷愧,一起剝皮案震驚了整個濱河市驾诈,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌溶浴,老刑警劉巖乍迄,帶你破解...
    沈念sama閱讀 206,839評論 6 482
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異士败,居然都是意外死亡闯两,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,543評論 2 382
  • 文/潘曉璐 我一進(jìn)店門谅将,熙熙樓的掌柜王于貴愁眉苦臉地迎上來漾狼,“玉大人,你說我怎么就攤上這事饥臂⊙吩辏” “怎么了?”我有些...
    開封第一講書人閱讀 153,116評論 0 344
  • 文/不壞的土叔 我叫張陵擅笔,是天一觀的道長志衣。 經(jīng)常有香客問我,道長猛们,這世上最難降的妖魔是什么念脯? 我笑而不...
    開封第一講書人閱讀 55,371評論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮弯淘,結(jié)果婚禮上绿店,老公的妹妹穿的比我還像新娘。我一直安慰自己庐橙,他們只是感情好假勿,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,384評論 5 374
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著态鳖,像睡著了一般转培。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上浆竭,一...
    開封第一講書人閱讀 49,111評論 1 285
  • 那天浸须,我揣著相機(jī)與錄音,去河邊找鬼邦泄。 笑死删窒,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的顺囊。 我是一名探鬼主播肌索,決...
    沈念sama閱讀 38,416評論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼特碳!你這毒婦竟也來了诚亚?” 一聲冷哼從身側(cè)響起晕换,我...
    開封第一講書人閱讀 37,053評論 0 259
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎亡电,沒想到半個月后届巩,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體硅瞧,經(jīng)...
    沈念sama閱讀 43,558評論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡份乒,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,007評論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了腕唧。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片或辖。...
    茶點(diǎn)故事閱讀 38,117評論 1 334
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖枣接,靈堂內(nèi)的尸體忽然破棺而出颂暇,到底是詐尸還是另有隱情,我是刑警寧澤但惶,帶...
    沈念sama閱讀 33,756評論 4 324
  • 正文 年R本政府宣布耳鸯,位于F島的核電站,受9級特大地震影響膀曾,放射性物質(zhì)發(fā)生泄漏县爬。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,324評論 3 307
  • 文/蒙蒙 一添谊、第九天 我趴在偏房一處隱蔽的房頂上張望财喳。 院中可真熱鬧,春花似錦斩狱、人聲如沸耳高。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,315評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽泌枪。三九已至,卻和暖如春秕岛,著一層夾襖步出監(jiān)牢的瞬間碌燕,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,539評論 1 262
  • 我被黑心中介騙來泰國打工瓣蛀, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留陆蟆,地道東北人。 一個月前我還...
    沈念sama閱讀 45,578評論 2 355
  • 正文 我出身青樓惋增,卻偏偏與公主長得像叠殷,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子诈皿,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,877評論 2 345

推薦閱讀更多精彩內(nèi)容

  • 前言:本篇文章目的在于梳理知識林束,鞏固思想像棘,學(xué)習(xí)總結(jié)。有什么好的建議壶冒,都可以留言缕题。互相促進(jìn)胖腾!總觀烟零,微信支付,也沒心思...
    麥穗0615閱讀 10,014評論 8 70
  • 最近公司需要開發(fā)支付功能咸作,經(jīng)過這兩天的工作成功集成了app微信支付锨阿、支付寶支付。本文主要講述微信支付的流程和在集成...
    予獨(dú)愛秋天的梅花閱讀 2,055評論 0 5
  • 微信支付的流程 注冊微信開放平臺记罚,創(chuàng)建應(yīng)用獲取appid墅诡,appSecret,申請支付功能桐智,申請成功之后會返回一些...
    管家頗閱讀 1,529評論 2 5
  • 一:介紹 項(xiàng)目中要用到支付功能末早,需要支付寶支付、支付寶網(wǎng)頁支付说庭、微信支付然磷、銀聯(lián)支付、Apple_pay口渔,所以打算總...
    Swift社區(qū)閱讀 10,507評論 5 25
  • 前提是已經(jīng)創(chuàng)建完應(yīng)用了在微信的官網(wǎng)上样屠。根據(jù)上一篇的微信獲得支付能力的步驟,這一篇主要制作微信支付的demo缺脉』居回顧上...
    陽光的大男孩兒閱讀 24,256評論 25 50