iOS APP接入微信支付功能的实现(小白篇)

    iOS中APP的支付最常见的有三种(支付宝,微信,银联),百度钱包等没有太接触就不说了。这片博客先说下微信支付:

    1.首先申请微信商家以及对应的平台等等,大多数APP已经在做微信支付的时候已经做了微信分享,所以在微信开放平台上的APP_ID,APP_KEY,APP_SECRET之类的拿来就能用,需要在商家平台上生成对应的密钥(微信支付商户密钥, 32位, 这个, 不是微信开放平台给提供的, 这个是需要自己提供的 ,自己百度密钥生成器),如果需要做批量退款之类的就牵扯到微信证书之类的。

    2.把需要准备的账号信息弄好之后就下载对应的sdk然后导入自己的工程,在导入的工程中需要注意的是,lib文件夹全部导入工程,SDKExport文件夹下需要看你的项目,如果你已经做了微信分享(不管是友盟的还是share的)里面就有这个文件夹里的.a静态库以及两个.h文件就不需要再导入了,如果没有做分享就需要导入。另外就是MRC与ARC之间的转换。其他的话根据自己工程里的具体情况具体分析,每个人的工程都不一样。我就遇到了DeBug情况下自定义的NSLog输出行数的宏与Foundation的NSObjCRuntime中方法NSLog冲突的问题。不要怕一点一点找原因。

   3.当导入工程成功之后就按照微信的文档首先在AppDelegate里注册微信[WXApiregisterApp:APP_IDwithDescription:@"demo 2.0"];写微信的代理方法-(void) onResp:(BaseResp*)resp(用来支付成功后回调的,直接从demo复制)然后在工程的info选项里URL Types里添加微信选项(这个不会可以参考官方文档),接下来开始配置基本的支付参数等等(根据自己情况来修改)

#define APP_ID          @"wx9999999999999"               //APPID
#define APP_SECRET      @"f562ddddd4044b45f2ad642525ac258da" //appsecret
//商户号,填写商户对应参数
#define MCH_ID          @"123124344534"
//商户API密钥,填写相应参数
#define PARTNER_ID      @"asdasdsaddkgjhgafrwbmhfeudrgfzqfj"
//支付结果回调页面
#define NOTIFY_URL      @"http://wxpay.weixin.qq.com/forumWXPayReturn.html"
//获取服务器端支付数据地址(商户自定义)
#define SP_URL          @"http://wxpay.weixin.qq.com/pub_v2/app/app_pay.php"

   4.在需要支付的地方导入对应的头文件可参考官方文档,准备妥当(有些方法直接从demo里面复制)之后,看下微信的支付方法

- (void)sendPay
{
    
    //从服务器获取支付参数,服务端自定义处理逻辑和格式
    //订单标题
    NSString *ORDER_NAME    = @"Ios服务器端签名支付 测试";
    //订单金额,单位(元)
    NSString *ORDER_PRICE   = @"0.01";
    
    //根据服务器端编码确定是否转码
    NSStringEncoding enc;
    //if UTF8编码
    //enc = NSUTF8StringEncoding;
    //if GBK编码
    enc = CFStringConvertEncodingToNSStringEncoding(kCFStringEncodingGB_18030_2000);
    NSString *urlString = [NSString stringWithFormat:@"%@?plat=ios&order_no=%@&product_name=%@&order_price=%@",
                           SP_URL,
                           [[NSString stringWithFormat:@"%ld",time(0)] stringByAddingPercentEscapesUsingEncoding:enc],
                           [ORDER_NAME stringByAddingPercentEscapesUsingEncoding:enc],
                           ORDER_PRICE];
    
    //解析服务端返回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(@"%@",dict);
        NSLog(@"url:%@",urlString);
        if(dict != nil){
            NSMutableString *retcode = [dict objectForKey:@"retcode"];
            NSLog(@"retcode%@",retcode);
            if (retcode.intValue == 0){
                NSMutableString *stamp  = [dict objectForKey:@"timestamp"];//???
                
                //调起微信支付
                PayReq* req             = [[[PayReq alloc] init] autorelease];
                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(@"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:@"服务器返回错误"];
    }
}

微信的支付参数加密方式有两种,一种是自己将价格商品名字传入自己的后台然后后台返回你对应的参数(相对安全),一种是本地的参数加密,上面的方法是支付参数上传后台的方法,我用的是本地加密支付参数的方法,接下来看本地支付参数加密对应的支付方法:

- (void)sendPay
{
    if ([WXApi isWXAppInstalled]) {//检查是否安装微信
        NSLog(@"开始微信支付");
        //微信支付
        payRequsestHandler *payHandler = [[payRequsestHandler alloc] init];
        [payHandler init:APP_ID mch_id:MCH_ID];
        [payHandler setKey:PARTNER_ID];
        //        NSMutableDictionary *dic = [payHandler sendPay_demoWithProductName:@"萝卜" price:@"1" deviceInfo:@"APP-001"];//返回支付数据
        NSMutableDictionary *dic = [payHandler sendPay_demo];
        //发起支付
        if (dic) {
            PayReq *request = [[PayReq alloc] init];
            request.openID = dic[@"appid"];
            request.partnerId = dic[@"partnerid"];
            request.prepayId = dic[@"prepayid"];
            request.package = dic[@"package"];
            request.nonceStr = dic[@"noncestr"];
            request.timeStamp = [dic[@"timestamp"] intValue];
            request.sign = dic[@"sign"];
            //日志输出
            NSLog(@"appid=%@\npartid=%@\nprepayid=%@\nnoncestr=%@\ntimestamp=%ld\npackage=%@\nsign=%@",request.openID,request.partnerId,request.prepayId,request.nonceStr,(long)request.timeStamp,request.package,request.sign );
            [WXApi sendReq:request];
        }
    } else {
        UIAlertController *alertC = [UIAlertController alertControllerWithTitle:nil message:@"设备没有安装微信" preferredStyle:(UIAlertControllerStyleAlert)];
        [alertC addAction:[UIAlertAction actionWithTitle:@"取消" style:(UIAlertActionStyleCancel) handler:nil]];
        [alertC addAction:[UIAlertAction actionWithTitle:@"安装" style:(UIAlertActionStyleDefault) handler:^(UIAlertAction *action) {
            [[UIApplication sharedApplication] openURL:[NSURL URLWithString:@"http://itunes.apple.com/cn/app/wei-xin/id414478124?mt=8"]];
        }]];
//        [self presentViewController:alertC animated:YES completion:nil];
    }
}


然后看lib文件夹下 payRequsestHandler类中加密的方法,这个地方需要修改一下sendPay_demo 放法把商品名字和价格传进去,然后查看下对应的参数是否都按照自己的工程对应,支付方法就完成了。

5.回调方法,当支付完成后需要一个回调方法来刷新数据或者做一些其他的事情,微信的回调方法是

//支付完成之后回调方法,可更新数据
-(void) onResp:(BaseResp*)resp
{
    NSString *strMsg = [NSString stringWithFormat:@"errcode:%d", resp.errCode];
    NSString *strTitle;
    //SendMessageToWXResp类需根据具体情况修改
    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];
    [alert release];
}

自己可根据情况具体修改。然后就可以测试你的支付了。想要深层次的学习 就需要自己看下官方文档和示例demo。另外如果手机没有安装微信客户端的情况下,不要提示用户去安装,因为可能遇到审核的人不小心把你的应用拒了。

                             不要怂,就是干。



你可能感兴趣的:(知识学习)