美文网首页
iOS集成微信支付

iOS集成微信支付

作者: 超C | 来源:发表于2015-12-31 11:36 被阅读342次

    微信支付流程

    官方说明

    Paste_Image.png
    https://pay.weixin.qq.com/wiki/doc/api/app.php?chapter=8_5

    环境设置

    1. 拖入我附件中的SDK(可以将我附件中的SDK替换为官方的, 只为你放心)

    2. 设置URL Schemes : 微信应用注册后的 : AppID


      Snip20151231_10.png
    Snip20151231_11.png

    3 . 需要导入的框架
    libc++.tbd libz.tbd libsqlite3.0.tbd SystemConfiguration.framework CoreTelephony.framework

    4 . 为了以防万一 : 备用

    // 设置URLSchemes白名单
    <key>LSApplicationQueriesSchemes</key>
    <array>
    <string>weixin</string>
    </array>
    
    //设置退回Http
    <key>NSAppTransportSecurity</key>
    <dict>
    <key>NSAllowsArbitraryLoads</key>
    <true/>
    </dict>
    

    AppDelegate中

    #import "WXApi.h"
    
    @interface AppDelegate ()<WXApiDelegate>
    
    - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
        
        [WXApi registerApp:AppID withDescription:@"demo 2.0"];
        
        return YES;
    }
    
    //微信支付返回程序
    - (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];
    }
    
    // 并且将下面方法添加到上面设置的delegate中, 支付完成微信会回调代理的这个方法
    - (void)onResp:(BaseResp*)resp{
        if ([resp isKindOfClass:[PayResp class]]){
            PayResp *response = (PayResp*)resp;
            switch(response.errCode){
                case WXSuccess:
                    //服务器端查询支付通知或查询API返回的结果再提示成功
                    NSLog(@"支付成功");
                    break;
                default:
                    NSLog(@"支付失败,retcode=%d",resp.errCode);
                    break;
            }
        }
    }
    
    // 使用CCPay, 修改自己需要的即可
    

    CCPay中封装的代码 主要流程

    一. 预支付 : 发送商品信息到预支付地址获取prepay_id
    1. 收集预付单参数
    参数 noncestr 与 orderno 都是随机生成的
        [orderParas setObject: CCAppID           forKey:@"appid"];       //开放平台appid
        [orderParas setObject: CCMchID           forKey:@"mch_id"];      //商户号
        [orderParas setObject: @"iPhone10X"        forKey:@"device_info"]; //支付设备号或门店号
        [orderParas setObject: noncestr          forKey:@"nonce_str"];   //随机串
        [orderParas setObject: @"APP"            forKey:@"trade_type"];  //支付类型,固定为APP
        [orderParas setObject: @"大宝SOD咪咪"        forKey:@"body"];        //订单描述,展示给用户
        [orderParas setObject: @"You_Custom"    forKey:@"notify_url"];  //支付结果异步通知
        [orderParas setObject: orderno           forKey:@"out_trade_no"];//商户订单号
        [orderParas setObject: [CCDevice deviceIPAdress]    forKey:@"spbill_create_ip"];//发起支付的机器ip
        [orderParas setObject: @"1"       forKey:@"total_fee"];       //订单金额,单位为分
    
    1. 通过上面的参数按照官方的要求生成XML格式的参数
        NSMutableString *reqPars = [NSMutableString string];
    
        //生成xml的package
        NSArray *keys = [paras allKeys];
        [reqPars appendString:@"<xml>\n"];
        for (NSString *categoryId in keys) {
            [reqPars appendFormat:@"<%@>%@</%@>\n", categoryId, [paras objectForKey:categoryId],categoryId];
        }
        
        //生成签名,并将签名添加到签名包中
        sign = [self createMd5Sign:paras];
        [reqPars appendFormat:@"<sign>%@</sign>\n</xml>", sign];
    
        return [NSString stringWithString:reqPars];
    
    1. 将该参数转换为Data数据,通过POST发出请求
        NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL:[NSURL URLWithString:url] cachePolicy:NSURLRequestReloadIgnoringLocalCacheData timeoutInterval:5];
        //设置提交方式
        [request setHTTPMethod:method];
        //设置数据类型
        [request addValue:@"text/xml" forHTTPHeaderField:@"Content-Type"];
        //设置编码
        [request setValue:@"UTF-8" forHTTPHeaderField:@"charset"];
        //如果是POST
        [request setHTTPBody:[data dataUsingEncoding:NSUTF8StringEncoding]];
        
        NSError *error;
        //将请求的url数据放到NSData对象中
        NSData *response = [NSURLConnection sendSynchronousRequest:request returningResponse:nil error:&error];
        return response;
    
    1. 解析响应的NSData数据, 获得prepayid
        dictionary =[NSMutableDictionary dictionary];
        contentString=[NSMutableString string];
        
        // XML解析实例
        xmlElements = [[NSMutableArray alloc] init];
        
        xmlParser = [[NSXMLParser alloc] initWithData:data];
        
        [xmlParser setDelegate:self];
        [xmlParser parse];
    

    代理中得到数据, 获取 prepayid

    二. 真正的支付 : 发送PayReq(官方类)请求
    1. 生成确认支付的参数
        //获取到prepayid后进行第二次签名
        
        //设置支付参数
        time_t now;
        time(&now);
        NSString *time_stamp  = [NSString stringWithFormat:@"%ld", now];
        NSString *nonce_str = [CCUtil stringMd5WithString:time_stamp];
        NSString *package     = @"Sign=WXPay";    // 官方要求
        
        // 第二次签名参数列表
        NSMutableDictionary *signParas = [NSMutableDictionary dictionary];
        [signParas setObject: CCAppID        forKey:@"appid"];
        [signParas setObject: nonce_str    forKey:@"noncestr"];
        [signParas setObject: package      forKey:@"package"];
        [signParas setObject: CCMchID        forKey:@"partnerid"];
        [signParas setObject: time_stamp   forKey:@"timestamp"];
        [signParas setObject: prepayID     forKey:@"prepayid"];
        //[signParams setObject: @"MD5"       forKey:@"signType"];
        
        // 生成签名
        NSString *sign  = [self createMd5Sign:signParas];
        
        // 添加签名
        [signParas setObject: sign         forKey:@"sign"];
        
        return signParas;
    
    1. 调用微信进行支付
        PayReq* req             = [[PayReq alloc] init];
        req.openID              = [paras objectForKey:@"appid"];
        req.partnerId           = [paras objectForKey:@"partnerid"];
        req.prepayId            = [paras objectForKey:@"prepayid"];
        req.nonceStr            = [paras objectForKey:@"noncestr"];
        req.timeStamp           = [[paras objectForKey:@"timestamp"] intValue];
        req.package             = [paras objectForKey:@"package"];
        req.sign                = [paras objectForKey:@"sign"];
        
        // 发起微信支付
        [WXApi sendReq:req];
    

    代码

    http://pan.baidu.com/s/1qXt463y

    封装为传入参数 : 订单名与价格即可开始支付, 有自己的需求, 到.m中自行修改
    /**
     *  通过微信支付
     *
     *  @param orderName 订单名
     *  @param price     价格
     */
    + (void)payWXWithOrderName:(NSString *)orderName price:(NSString *)price;
    

    最后

    上面流程为自己从头开始完成支付, 并不是说必须按照上面步骤. 这里不同公司可能如何处理方式会有差异.
    例如: 第一步预支付验证可以后台实现, 前台只需要请求公司内部服务器, 内部服务器发送对应的预支付请求, 并且将返回的数据简析完成后返回给前台, 前台直接执行支付操作.

    相关文章

      网友评论

          本文标题:iOS集成微信支付

          本文链接:https://www.haomeiwen.com/subject/synihttx.html