第一步: 導入微信SDK
第三步: 設置URL Types
注: 這步操作後運轉, 假如是新建的項目能夠會報這個錯誤
第八步: 創立一個PCH文件 Common.pch
定義三個宏
#define WeChatAppID @"xxxxxxxxxxxxx"//
APPID
#define PartnerID @"xxxxx"//商戶ID
#define APISignKey @"xxxxxxxx商戶平台 -> 賬戶中心 -> API平安 -> API密鑰, 設置密鑰"//
API私鑰
// // ViewController.m // ZHWeChatPay // // Created by 周昊 on 2016/12/28. // Copyright © 2016年 Cloud. All rights reserved. // #import "ViewController.h" #import "WXApi.h" #import <CommonCrypto/CommonDigest.h> // MD5加密需求導此包 // ------------獲取終端IP地址需求以下引入及定義 #include <ifaddrs.h> #include <arpa/.net.h> #include <.net/if.h> #define IOS_CELLULAR @"pdp_ip0" #define IOS_WIFI @"en0" #define IOS_VPN @"utun0" #define IP_ADDR_IPv4 @"ipv4" #define IP_ADDR_IPv6 @"ipv6" // ------------- #import "XmlRss/ target=_blank class=infotextkey>XmlReader.h" @interface ViewController () @end @implementation ViewController - (void)viewDidLoad { [super viewDidLoad]; UIButton *payServerBtn = [UIButton buttonWithType:UIButtonTypeSystem]; [payServerBtn setTitle:@"包括服務器端操作的領取" forState:UIControlStateNormal]; [payServerBtn setTitleColor:[UIColor blackColor] forState:UIControlStateNormal]; [payServerBtn addTarget:self action:@selector(zh_weChatPayIncludeServer) forControlEvents:UIControlEventTouchUpInside]; [self.view addSubview:payServerBtn]; [payServerBtn sizeToFit]; payServerBtn.frame = CGRectMake((self.view.frame.size.width - payServerBtn.frame.size.width) / 2.0, 200, payServerBtn.frame.size.width, payServerBtn.frame.size.height); UIButton *payBtn = [UIButton buttonWithType:UIButtonTypeSystem]; [payBtn setTitle:@"微信領取" forState:UIControlStateNormal]; [payBtn setTitleColor:[UIColor blackColor] forState:UIControlStateNormal]; [payBtn addTarget:self action:@selector(zh_weChatPay) forControlEvents:UIControlEventTouchUpInside]; [self.view addSubview:payBtn]; [payBtn sizeToFit]; payBtn.frame = CGRectMake((self.view.frame.size.width - payBtn.frame.size.width) / 2.0, CGRectGetMaxY(payServerBtn.frame) + 100, payBtn.frame.size.width, payBtn.frame.size.height); [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(zh_handleWeChatPayResult:) name:@"doWeChatPayResult" object:nil]; } - (void)zh_handleWeChatPayResult:(NSNotification *)notification { BaseResp *resp = notification.object; switch (resp.errCode) { case WXSuccess: NSLog(@"領取成功"); break; default: NSLog(@"領取失敗"); break; } } #pragma mark - 微信領取(包括服務器端的操作) - (void)zh_weChatPayIncludeServer { if (![WXApi isWXAppInstalled]) { NSLog(@"未裝置微信客戶端"); return; } if (![WXApi isWXAppSupportApi]) { NSLog(@"不支持微信領取"); return; } NSString *url = @"https://api.mch.weixin.qq.com/pay/unifiedorder"; // 懇求騰訊服務器 // 拼接詳細的訂雙數據 NSDictionary *postDict = [self zh_getProductArgs]; // 服務器端拼接數據及簽名 // 拼接調用領取接口所需求的參數(拼接成XmlRss/ target=_blank class=infotextkey>Xml格式) NSString *string = [NSString stringWithFormat:@"<Xml><sign>%@</sign><appid>%@</appid><body>%@</body><mch_id>%@</mch_id><nonce_str>%@</nonce_str><notify_url>%@</notify_url><out_trade_no>%@</out_trade_no><spbill_create_ip>%@</spbill_create_ip><total_fee>%d</total_fee><trade_type>APP</trade_type></xml>",[postDict objectForKey:@"sign"], WeChatAppID, [postDict objectForKey:@"body"], PartnerID, [postDict objectForKey:@"nonce_str"], [postDict objectForKey:@"notify_url"], [postDict objectForKey:@"out_trade_no"], [postDict objectForKey:@"spbill_create_ip"],[[postDict objectForKey:@"total_fee"] intValue]]; // 創立網絡懇求 NSURL *requestURL = [NSURL URLWithString:url]; NSMutableURLRequest *request = [[NSMutableURLRequest alloc]initWithURL:requestURL]; [request setHTTPMethod:@"POST"]; [request setValue:@"application/xml; charset=utf-8" forHTTPHeaderField:@"Content-Type"]; [request setHTTPBody:[string dataUsingEncoding:NSUTF8StringEncoding]]; NSHTTPURLResponse* urlResponse = nil; NSError *error = [[NSError alloc] init]; NSData *responseData = [NSURLConnection sendSynchronousRequest:request returningResponse:&urlResponse error:&error]; NSString *result = [[NSString alloc] initWithData:responseData encoding:NSUTF8StringEncoding]; if ([urlResponse statusCode] >= 200 && [urlResponse statusCode] < 300) { NSError *error2 = [NSError alloc]; // 從騰訊服務器懇求回來的數據將XML格式解析成字典 NSDictionary *xmlDict = [[XMLReader dictionaryForXMLString:result error:&error2] objectForKey:@"xml"]; // 調用領取接口 PayReq *payRequest = [[PayReq alloc]init]; payRequest.partnerId = [[xmlDict objectForKey:@"mch_id"] objectForKey:@"text"]; payRequest.prepayId = [[xmlDict objectForKey:@"prepay_id"] objectForKey:@"text"]; payRequest.package = @"Sign=WXPay"; payRequest.nonceStr = [[xmlDict objectForKey:@"nonce_str"] objectForKey:@"text"]; payRequest.timeStamp = [[NSString stringWithFormat:@"%ld", (long)[[NSDate date] timeIntervalSince1970]] intValue]; // 結構參數列表,再次簽名 NSMutableDictionary *payDict = [NSMutableDictionary dictionary]; [payDict setObject:WeChatAppID forKey:@"appid"]; [payDict setObject:payRequest.nonceStr forKey:@"noncestr"]; [payDict setObject:payRequest.package forKey:@"package"]; [payDict setObject:payRequest.partnerId forKey:@"partnerid"]; [payDict setObject:payRequest.prepayId forKey:@"prepayid"]; [payDict setObject:[NSString stringWithFormat:@"%u", (unsigned int)payRequest.timeStamp]forKey:@"timestamp"]; payRequest.sign = [self zh_genSign:payDict]; [WXApi sendReq:payRequest]; } } // 結構預付訂單參數列表 - (NSDictionary *)zh_getProductArgs { NSMutableDictionary *params = [NSMutableDictionary dictionary]; NSString *timeStamp = [NSString stringWithFormat:@"%ld", (long)[[NSDate date] timeIntervalSince1970]]; // 獲取時間戳 NSString *nonceStr = [[self zh_md5:[NSString stringWithFormat:@"%d", arc4random() % 10000]] uppercaseString]; // 獲取32位內的隨機串, 防重發 // 獲取商家對用戶的獨一標識 NSString *outTradNo = [NSString stringWithFormat:@"%d", arc4random() % 10000]; NSString *out_trade_no= [NSString stringWithFormat:@"%@%@",timeStamp,outTradNo];//獲取商戶訂單號 [params setObject:WeChatAppID forKey:@"appid"];//必填 [params setObject:nonceStr forKey:@"nonce_str"];//隨機字符串,必填 [params setObject:@"APP" forKey:@"trade_type"]; //買賣類型 必填 [params setObject:@"有逼格的順序員" forKey:@"body"];//商品描繪,必填 [params setObject:@"這裡是你本地接納回調告訴的地址" forKey:@"notify_url"]; // 此處填可以讓後台寫個接口,假如領取成功,則微信後台調用此接口,前往yes,失敗則前往no; [params setObject:out_trade_no forKey:@"out_trade_no"];//商戶訂單號,必填 [params setObject:PartnerID forKey:@"mch_id"]; // 商戶ID [params setObject:[self zh_getIPAddress:YES] forKey:@"spbill_create_ip"];//終端ip,必填 [params setObject:@"1" forKey:@"total_fee"]; //簽名 [params setObject:[self zh_genSign:params] forKey:@"sign"]; return params; } // 將字符串MD5加密 - (NSString *)zh_md5:(NSString *)str { // #import <CommonCrypto/CommonDigest.h> // MD5加密需求導此包 const char *cStr = str.UTF8String; unsigned char digest[CC_MD5_DIGEST_LENGTH]; CC_MD5(cStr, strlen(cStr), digest); NSMutableString *md5Str = [NSMutableString stringWithCapacity:CC_MD5_DIGEST_LENGTH * 2]; for (int i = 0; i < CC_MD5_DIGEST_LENGTH; i++) { [md5Str appendFormat:@"%02x", digest[i]]; } return md5Str; } // 簽名 - (NSString *)zh_genSign:(NSDictionary *)signParams { // 排序 NSArray *keys = [signParams allKeys]; NSArray *sortedKeys = [keys sortedArrayUsingComparator:^NSComparisonResult(id obj1, id obj2) { return [obj1 compare:obj2 options:NSNumericSearch]; }]; // 生成 NSMutableString *sign = [NSMutableString string]; for (NSString *key in sortedKeys) { [sign appendString:key]; [sign appendString:@"="]; [sign appendString:[signParams objectForKey:key]]; [sign appendString:@"&"]; } [sign appendString:@"key="]; [sign appendString:APISignKey];// 留意:不能hardcode在客戶端,建議genPackage這個進程都由服務器端完成 NSString *result = [[self zh_md5:sign] uppercaseString]; return result; } // 獲取終端IP地址 - (NSString *)zh_getIPAddress:(BOOL)preferIPv4 { /* 需求引入一下頭文件及定義宏 #include <ifaddrs.h> #include <arpa/.net.h> #include <net/if.h> #define IOS_CELLULAR @"pdp_ip0" #define IOS_WIFI @"en0" #define IOS_VPN @"utun0" #define IP_ADDR_IPv4 @"ipv4" #define IP_ADDR_IPv6 @"ipv6" */ NSArray *searchArray = preferIPv4 ? @[ IOS_WIFI @"/" IP_ADDR_IPv4, IOS_WIFI @"/" IP_ADDR_IPv6, IOS_CELLULAR @"/" IP_ADDR_IPv4, IOS_CELLULAR @"/" IP_ADDR_IPv6 ] : @[ IOS_WIFI @"/" IP_ADDR_IPv6, IOS_WIFI @"/" IP_ADDR_IPv4, IOS_CELLULAR @"/" IP_ADDR_IPv6, IOS_CELLULAR @"/" IP_ADDR_IPv4 ] ; NSDictionary *addresses = [self zh_getIPAddresses]; __block NSString *address; [searchArray enumerateObjectsUsingBlock:^(NSString *key, NSUInteger idx, BOOL *stop) { address = addresses[key]; if(address) *stop = YES; } ]; return address ? address : @"0.0.0.0"; } - (NSDictionary *)zh_getIPAddresses { NSMutableDictionary *addresses = [NSMutableDictionary dictionaryWithCapacity:8]; // retrieve the current interfaces - returns 0 on success // 導入ifaddrs.h struct ifaddrs *interfaces; if(!getifaddrs(&interfaces)) { // Loop through linked list of interfaces struct ifaddrs *interface; for(interface=interfaces; interface; interface=interface->ifa_next) { if(!(interface->ifa_flags & IFF_UP) || (interface->ifa_flags & IFF_LOOPBACK)) { continue; // deeply nested code harder to read IFF_UP需求導入頭文件 } const struct sockaddr_in *addr = (const struct sockaddr_in*)interface->ifa_addr; if(addr && (addr->sin_family==AF_INET || addr->sin_family==AF_INET6)) { NSString *name = [NSString stringWithUTF8String:interface->ifa_name]; char addrBuf[INET6_ADDRSTRLEN]; if(inet_ntop(addr->sin_family, &addr->sin_addr, addrBuf, sizeof(addrBuf))) { NSString *key = [NSString stringWithFormat:@"%@/%@", name, addr->sin_family == AF_INET ? IP_ADDR_IPv4 : IP_ADDR_IPv6]; addresses[key] = [NSString stringWithUTF8String:addrBuf]; } } } // Free memory freeifaddrs(interfaces); } // The dictionary keys have the form "interface" "/" "ipv4 or ipv6" return [addresses count] ? addresses : nil; } #pragma mark - 微信領取(不包括服務器, 正常的操作流程就需求這一個辦法即可) - (void)zh_weChatPay { if (![WXApi isWXAppInstalled]) { NSLog(@"未裝置微信客戶端"); return; } if (![WXApi isWXAppSupportApi]) { NSLog(@"不支持微信領取"); return; } // 此處的懇求可以交換為AFNetworking的懇求 NSString *urlString = @"http://xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"; // 向自己的服務器懇求訂單生成預領取訂單信息 NSURL *url = [NSURL URLWithString:urlString]; NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url]; [request setHTTPMethod:@"POST"]; // body: 商品描繪 // out_trade_no: 商品訂單流水號 // spbill_create_ip: 終端IP地址 // total_fee: 商品價錢 單位: 分 NSString *outTradNo = [NSString stringWithFormat:@"%d", arc4random() % 10000]; NSString *out_trade_no= [NSString stringWithFormat:@"%@%@",[NSString stringWithFormat:@"%ld", (long)[[NSDate date] timeIntervalSince1970]],outTradNo]; // 隨機生成商戶訂單號 NSString *bodyString = [NSString stringWithFormat:@"body=商品的描繪&out_trade_no=%@&spbill_create_ip=%@&total_fee=1", out_trade_no, [self zh_getIPAddress:YES]]; NSData *bodyData = [bodyString dataUsingEncoding:NSUTF8StringEncoding]; [request setHTTPBody:bodyData]; NSData *data = [NSURLConnection sendSynchronousRequest:request returningResponse:nil error:nil]; NSDictionary *result = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableContainers error:nil]; if ([[NSString stringWithFormat:@"%@", result[@"opflag"]] isEqualToString:@"1"]) { NSError *error = nil; NSDictionary *xmlDict = [[XMLReader dictionaryForXMLString:result[@"weixinPost"] error:&error] objectForKey:@"xml"]; //調用領取接口 PayReq *payRequest = [[PayReq alloc]init]; payRequest.partnerId = [[xmlDict objectForKey:@"mch_id"] objectForKey:@"text"]; payRequest.prepayId = [[xmlDict objectForKey:@"prepay_id"] objectForKey:@"text"]; payRequest.package = @"Sign=WXPay"; payRequest.nonceStr = [[xmlDict objectForKey:@"nonce_str"] objectForKey:@"text"]; payRequest.timeStamp = [[NSString stringWithFormat:@"%ld", (long)[[NSDate date] timeIntervalSince1970]] intValue]; //結構參數列表,再次簽名 NSMutableDictionary *payDict = [NSMutableDictionary dictionary]; [payDict setObject:WeChatAppID forKey:@"appid"]; [payDict setObject:payRequest.nonceStr forKey:@"noncestr"]; [payDict setObject:payRequest.package forKey:@"package"]; [payDict setObject:payRequest.partnerId forKey:@"partnerid"]; [payDict setObject:payRequest.prepayId forKey:@"prepayid"]; [payDict setObject:[NSString stringWithFormat:@"%u", (unsigned int)payRequest.timeStamp] forKey:@"timestamp"]; payRequest.sign = [self zh_genSign:payDict]; if ([WXApi sendReq:payRequest]) // 調起微信客戶端領取 { NSLog(@"調起微信領取成功!"); } else { NSLog(@"調起微信領取失敗!"); } } else { NSLog(@"調起微信領取失敗!"); } } #pragma mark - - (void)didReceiveMemoryWarning { [super didReceiveMemoryWarning]; } @end
// NOTE: 8.0運用API接口 - (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation { if ([url.host isEqualToString:@"pay"]) // 微信後果回調 { return [WXApi handleOpenURL:url delegate:self]; } return YES; } // NOTE: 9.0當前運用新API接口 - (BOOL)application:(UIApplication *)app openURL:(NSURL *)url options:(NSDictionary<NSString*, id> *)options { if ([url.host isEqualToString:@"pay"]) // 微信後果回調 { return [WXApi handleOpenURL:url delegate:self]; } return YES; } // 微信領取 - (BOOL)application:(UIApplication *)application handleOpenURL:(NSURL *)url { return [WXApi handleOpenURL:url delegate:self]; } - (void)onResp:(BaseResp *)resp { if([resp isKindOfClass:[PayResp class]]) { [[NSNotificationCenter defaultCenter] postNotificationName:@"doWeChatPayResult" object:resp]; } }
第十一步: 回調的時分需求觸發一個代理, 簽代理<WXApiDelegate>
第十二步: 在ViewController.m的viewDidLoad辦法中注冊告訴
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(zh_handleWeChatPayResult:) name:@"doWeChatPayResult" object:nil];
- (void)zh_handleWeChatPayResult:(NSNotification *)notification { BaseResp *resp = notification.object; switch (resp.errCode) { case WXSuccess: NSLog(@"領取成功"); break; default: NSLog(@"領取失敗"); break; } }
【iOS 微信領取 SDK版本1.7.5(2016年12月27日)】的相關資料介紹到這裡,希望對您有所幫助! 提示:不會對讀者因本文所帶來的任何損失負責。如果您支持就請把本站添加至收藏夾哦!