微信支付

关于集成的部分按照微信集成文档进行

1.#pragma mark 获取当前设备的ip

// Get IP Address  (获取本地的ip地址)

- (NSString *)getIPAddress {

    NSString *address = @"error";

    struct ifaddrs *interfaces = NULL;

    struct ifaddrs *temp_addr = NULL;

    int success = 0;

    // retrieve the current interfaces - returns 0 on success

    success = getifaddrs(&interfaces);

    if (success == 0) {

        // Loop through linked list of interfaces

        temp_addr = interfaces;

        while(temp_addr != NULL) {

            if(temp_addr->ifa_addr->sa_family == AF_INET) {

                // Check if interface is en0 which is the wifi connection on the iPhone

                if([[NSString stringWithUTF8String:temp_addr->ifa_name] isEqualToString:@"en0"]) {

                    // Get NSString from C String

                    address = [NSString stringWithUTF8String:inet_ntoa(((struct sockaddr_in *)temp_addr->ifa_addr)->sin_addr)];

                }

            }

            temp_addr = temp_addr->ifa_next;

        }

    }

    // Free memory

    freeifaddrs(interfaces);

    return address;

}


2.#pragma mark 微信支付统一下单,可以将签名生成算法封装起来,以便于二次签名时使用(MD5转码,转换为大写)

-(void)clickWX:(UIButton *)btn

{

    NSLog(@"微信支付");

    self.muDic = [NSMutableDictionary dictionary];

    //.统一下单

   //1. nonce_str 随机字符串

    NSInteger nonceInt = arc4random();

    NSString *nonceStr = [NSString stringWithFormat:@"%ld",nonceInt];

    NSLog(@"生成的随机数:%@",nonceStr);

    //3.商品描述body

    NSString *body = @"weProtect";

    //4.out_trade_no  商户订单号(建议当前系统时间加随机序列)

    NSDate *date = [NSDate date];

    NSDateFormatter  *dateformatter = [[NSDateFormatter alloc] init];

    [dateformatter setDateFormat:@"yyyyMMddHHmmss"];

    NSString *  locationString = [dateformatter stringFromDate:date];

    NSLog(@"当前时间:%@",locationString);

    //将系统时间中的-和:去掉

    NSInteger da = arc4random();

    NSString *outTrade = [NSString stringWithFormat:@"%@%ld",locationString,da];

    NSLog(@"订单号:%@",outTrade);

    // total_fee  订单总金额(单位为分,不带小数点)

    NSInteger totalFee = 1;

    //spbill_create_ip 终端的ip

    NSString *ip = [self getIPAddress];

    NSLog(@"本机的ip地址:%@",ip);

    //通知地址

    NSString *notifyUrl = @"www.baidu.com";

    //支付类型

    NSString *tradeType = @"APP";

     //2.1签名生成算法 sign(将所有发送给wx的数据拼接在一起,进行MD5加密)                   stringA之后拼接一个key值(商户提供)

        NSString *stringA = [NSString stringWithFormat:@"appid=你的APPId&body=%@&mch_id=商户号&nonce_str=%@¬ify_url=%@&out_trade_no=%@&spbill_create_ip=%@&total_fee=%ld&trade_type=%@",body,nonceStr,notifyUrl,outTrade,ip,totalFee,tradeType];

    NSLog(@"stringA:%@",stringA);

    //2.2 key值拼接在stringA之后

    NSString *strSign = [NSString stringWithFormat:@"%@&key=%@",stringA,@"你的key"];

    NSLog(@"连接key:%@",strSign);

    //2.3 MD5转码

    NSString *signValue = [self getmd5WithString:strSign];

    NSLog(@"签名变大写之前:%@",signValue);

    //2.4签名转换为大写

    NSString *signUpper = [signValue uppercaseStringWithLocale:[NSLocale currentLocale]];

    NSLog(@"签名:%@",signUpper);

    

#pragma mark body

    [self.muDic setObject:@"" forKey:@"appid"];

    [self.muDic setObject:body forKey:@"body"];

    [self.muDic setObject:@"" forKey:@"mch_id"];

    [self.muDic setObject:nonceStr forKey:@"nonce_str"];

    [self.muDic setObject:notifyUrl forKey:@"notify_url"];

    [self.muDic setObject:outTrade forKey:@"out_trade_no"];

    [self.muDic setObject:ip forKey:@"spbill_create_ip"];

    [self.muDic setObject:@1 forKey:@"total_fee"];

    [self.muDic setObject:tradeType forKey:@"trade_type"];

    NSLog(@"body:%@",self.muDic);

    //签名不参与排序

    NSMutableString *reqPars =  [NSMutableString string];

     NSArray *keys = [self.muDic allKeys];

    //将字典中的key值按字母排序

    NSArray *sortedArray = [keys sortedArrayUsingComparator:^NSComparisonResult(id obj1, id obj2) {

        return [obj1 compare:obj2 options:NSNumericSearch];

    }];

    //转成xml格式

    [reqPars appendString:@"\n"];

    for (NSString *categoryId in sortedArray) {

        [reqPars appendFormat:@"<%@>%@\n", categoryId, [self.muDic objectForKey:categoryId],categoryId];

    }

    //   把签名拼接在后面

    [reqPars appendFormat:@"%@\n", signUpper];

    NSString *xml = [NSString stringWithString:reqPars];

    NSLog(@"xml:%@",xml);

    

#pragma mark 请求

    AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];

    //这里传入的xml字符串只是形似xml,但是不是正确是xml格式,需要使用af方法进行转义

        manager.responseSerializer = [[AFHTTPResponseSerializer alloc] init];

        [manager.requestSerializer setValue:@"text/xml; charset=GBK" forHTTPHeaderField:@"Content-Type"];

    [manager.requestSerializer setQueryStringSerializationWithBlock:^NSString *(NSURLRequest *request, NSDictionary *parameters, NSError *__autoreleasing *error) {

                 return xml;

             }];

    NSLog(@"转义之后的XML:%@",xml);

    [manager POST:@"https://api.mch.weixin.qq.com/pay/unifiedorder" parameters:xml success:^(AFHTTPRequestOperation * _Nonnull operation, id  _Nonnull responseObject) {

        NSString *responseString = [[NSString alloc] initWithData:responseObject encoding:NSUTF8StringEncoding];

                NSLog(@"responseString is %@",responseString);

                 //将微信返回的xml数据解析转义成字典

                 NSDictionary *dic = [NSDictionary dictionaryWithXMLString:responseString];

        NSLog(@"统一下单返回的dic:%@",dic);

        //调用吊起支付的方法

        [self payreq:dic[@"prepay_id"]];


    } failure:^(AFHTTPRequestOperation * _Nullable operation, NSError * _Nonnull error) {

    }];

}


3.#pragma mark 掉起支付API,进行第二次签名

-(void)payreq:(NSString *)prepayId

{

    //获取时间戳

    NSDate* dat = [NSDate dateWithTimeIntervalSinceNow:0];

    NSTimeInterval a = [dat timeIntervalSince1970];

      int date = (int)a;

    NSLog(@"时间戳%d",date);

    //生成随机数

    NSInteger nonceInt = arc4random();

    NSString *nonceStr = [NSString stringWithFormat:@"%ld",nonceInt];

    NSLog(@"生成的随机数:%@",nonceStr);

      PayReq *request = [[PayReq alloc] init];

        request.partnerId = @"1316654801";

        request.prepayId = prepayId;

    //package暂时填写固定值

        request.package = @"Sign=WXPay";

        request.nonceStr= nonceStr;

        request.timeStamp = date;

    //进行第二次签名

    NSString *signTwo = [NSString stringWithFormat:@"appid=%@&noncestr=%@&package=%@&partnerid=%@&prepayid=%@×tamp=%d",@"",nonceStr,@"Sign=WXPay",@"",prepayId,date];

    NSString *strSignTwo = [NSString stringWithFormat:@"%@&key=%@",signTwo,@""];

    NSLog(@"连接key:%@",strSignTwo);

    //2.3 MD5转码

    NSString *signValue = [self getmd5WithString:strSignTwo];

    NSLog(@"签名变大写之前:%@",signValue);

    //2.4签名转换为大写

    NSString *signUpper = [signValue uppercaseStringWithLocale:[NSLocale currentLocale]];

        request.sign = signUpper;

        [WXApi sendReq: request];

}

4.#pragma mark 密码的MD5转码

-(NSString*)getmd5WithString:(NSString *)string

{

    const char* original_str = [string UTF8String];

    unsigned  char digist[CC_MD5_DIGEST_LENGTH]; //CC_MD5_DIGEST_LENGTH = 16

    CC_MD5(original_str, (unsigned int)strlen(original_str), digist);

    NSMutableString *outPutStr = [NSMutableString stringWithCapacity:10];

    for(int  i =0; i

        [outPutStr appendFormat:@"%02x", digist[i]];//小写x表示输出的是小写MD5,大写X表示输出的是大写MD5

    }

    return [outPutStr lowercaseString];

}





你可能感兴趣的:(微信支付)