zoukankan      html  css  js  c++  java
  • iOS 集成微信支付【转载】

          目前项目里有微信支付的需求,调研过一段时间后,发现其实并没有想象中的那么困难。如果你只是想实现该功能,一个方法足以,但是若你想深入了解实现原理。就需要花费更多的功夫了。目前我只清楚微信支付需要做签名,一种是在后台签名,一种是自己在前端签名。其实这对前端来说代码量并没有多大的改变,最大的区别是在后台签名逻辑更容易理解,而在前端签名逻辑有些混乱。

    小技巧:我在项目中集成类似的第三方功能时,如果需要对delegate进行操作,我会为这个功能,单独创建一个category类,这样避免项目出现多个第三方功能后,delegate里的代码十分混乱。

     微信支付开发文档     http://mch.weixin.qq.com/wiki/doc/api/app.php?chapter=8_1   

    正文:

    微信支付用到的文件 

      

    PS: 如果你在app内集成了微信分享功能,在分享的那个框架里,都能找到这些文件的,所以不需要在下载,直接用就行。

     2.设置URL types

     

    3、在Appdelegate中注册微信支付,我个人建议将注册后的内容输出一下,以便查看是否注册成功。

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

        

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


        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: %@ ",[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: %@ ",package);
            NSLog(@"生成package: %@ ",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(@"提交预付单: %@ ",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(@"调起支付签名: %@ ",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: %@ ",[req getDebugifo]);
                 };*/
                NSLog(@"获取prepayid失败 ");
                [self alert:@"提示信息" msg:debug];
            }
        }else{
            NSLog(@"获取Token失败 ");
            [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
    复制代码

     

  • 相关阅读:
    python之----------字符编码具体原理
    python ---------函数
    python爬虫
    python str 与repr区别
    python 正则表达式
    python 正则表达式里使用 split()方法
    python 基础介绍
    python 数据类型--列表
    python 字符串操作
    django(1.6)操作自带的数据库
  • 原文地址:https://www.cnblogs.com/g-ios/p/4609341.html
Copyright © 2011-2022 走看看