ios 微信支付

关于微信支付,我就忍不住要吐槽两句,因为项目中要用到微信支付,所以就从官方下载了微信支付的demo,自我感觉微信支付的demo和官方文档写的挺让人回味的,因为你看了以后吃饭的时候也会忍不住骂上两句。

好了,废话不多说,接下来我们直接上代码
在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 之后使用这个回调方法。
- (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 - 微信支付成功的回调函数(这个方法必须写在delegate.m文件中)
-(void)onResp:(BaseResp*)resp
{
    if ([resp isKindOfClass:[PayResp class]]){
        
        PayResp *response = (PayResp*)resp;
        
        switch(response.errCode){
                
            case WXSuccess:
                //服务器端查询支付通知或查询API返回的结果再提示成功
                //NSLog(@"支付成功");
                
                //发送通知给带有微信支付功能的视图控制器,告诉他支付成功了,请求后台订单状态,如果后台返回的订单也是成功的状态,那么可以进行下一步操作
                [[NSNotificationCenter defaultCenter] postNotificationName:WEIXINPAYSUCCESSED object:nil userInfo:nil];
                
                
                break;
                
            default:
                
                /*
                 
                 resp.errCode = 2 用户取消支付
                 resp.errCode = -1 错误
                 */
                NSLog(@"支付失败,retcode=%d ---- %@",resp.errCode,resp.errStr);
                
                break;
        }
    }
}//微信支付成功的回调方法(回调函数)

上面有两个系统回调的方法,第一个是针对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(@"初始化成功");
        
    }
    
    //设置商户密钥
    [handle setKey:PARTNER_id];
    
    //提交预支付,获得prepape_id
    NSString *order_name = @"测试";   //订单标题
    NSString *order_price = @"1";//测试价格 分为单位
    NSString *nocify_URL = nocify_url;    //回调借口
    NSString *noncestr  = [NSString stringWithFormat:@"%d", rand()]; //随机串
    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];
    
    //提交预支付两次签名得到预支付订单的id(每次的请求得到的预支付订单id都不同)
    NSString *prepate_id = [handle sendPrepay:params];
    
    //提交预订单成功
    if (prepate_id != nil) {
        
        PayReq *request = [[PayReq alloc]init];
        
        //商家id
        request.partnerId = MCH_id;
        
        //订单id
        request.prepayId = prepate_id;
        
        //扩展字段(官方文档:暂时填写固定值)
        request.package = @"Sign=WXPay";
        
        //随机字符串
        request.nonceStr = noncestr;
        
        //时间戳
        request.timeStamp = (UInt32)[[NSDate date] timeIntervalSince1970];
        
        //sign参数(很经常出现的问题:就是调起支付到微信那边只出现一个确定按钮,单击确认按钮直接返回到app,出现这个问题100%是sign参数的问题)
        /*
         参数依次是: appid_key、partnerid_key、prepayid_key、固定值Sign=WXPay、预支付的随机数(跟上面得到预支付订单的随机数要一致)、支付时间(秒)
         
         */
        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];
            
        }
        
    }
    
}//点击微信支付


#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;
    
}//创建发起支付时的sige签名


-(NSString *)md5:(NSString *)str
{
    const char *cStr = [str UTF8String];
    unsigned char result[16]= "0123456789abcdef";
    CC_MD5(cStr, (CC_LONG)strlen(cStr), result);
    //这里的x是小写则产生的md5也是小写,x是大写则md5是大写,这里只能用大写,微信的大小写验证很逗
    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(@"支付成功");
    
    
}//支付成功的监听方法


#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是从商户中心那里获取的,当你在微信开放平台创建的应用申请微信支付成功以后,进入到商户中心那里自己设置一个32位的字符串。MCH_id是商家的id,也就是商户号。

APP_id是在微信开放平台创建应用的appid。notify_url是回调接口,也就是一个url链接,是由服务器给你的

最后还有一点,大家通常会遇到一个问题,在调起微信以后,发现只有一个空白的页面,中间有一个确定的按钮,这种情况是sign签名的问题

下面附上微信支付的demo,里面的一些相关信息需要换成自己开放平台中自己应用的信息
https://github.com/EngineerLXK/WeiXinPay

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,372评论 6 498
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,368评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 162,415评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,157评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,171评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,125评论 1 297
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,028评论 3 417
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,887评论 0 274
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,310评论 1 310
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,533评论 2 332
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,690评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,411评论 5 343
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,004评论 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,659评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,812评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,693评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,577评论 2 353

推荐阅读更多精彩内容

  • 前言:本篇文章目的在于梳理知识,巩固思想,学习总结。有什么好的建议,都可以留言。互相促进!总观,微信支付,也没心思...
    麦穗0615阅读 10,041评论 8 70
  • 最近公司需要开发支付功能,经过这两天的工作成功集成了app微信支付、支付宝支付。本文主要讲述微信支付的流程和在集成...
    予独爱秋天的梅花阅读 2,071评论 0 5
  • 微信支付的流程 注册微信开放平台,创建应用获取appid,appSecret,申请支付功能,申请成功之后会返回一些...
    管家頗阅读 1,530评论 2 5
  • 一:介绍 项目中要用到支付功能,需要支付宝支付、支付宝网页支付、微信支付、银联支付、Apple_pay,所以打算总...
    Swift社区阅读 10,518评论 5 25
  • 前提是已经创建完应用了在微信的官网上。根据上一篇的微信获得支付能力的步骤,这一篇主要制作微信支付的demo。回顾上...
    阳光的大男孩儿阅读 24,272评论 25 50