关于集成的部分按照微信集成文档进行
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:@"
for (NSString *categoryId in sortedArray) {
[reqPars appendFormat:@"<%@>%@%@>\n", categoryId, [self.muDic objectForKey:categoryId],categoryId];
}
// 把签名拼接在后面
[reqPars appendFormat:@"
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]; }