你好,歡迎來到IOS教程網

 Ios教程網 >> IOS編程開發 >> IOS開發綜合 >> iOS 微信領取 SDK版本1.7.5(2016年12月27日)

iOS 微信領取 SDK版本1.7.5(2016年12月27日)

編輯:IOS開發綜合

第一步: 導入微信SDK

IOS 微信支付 SDK版本1.7.5(2016年12月27日)

第三步: 設置URL TypesIOS 微信支付 SDK版本1.7.5(2016年12月27日)

注: 這步操作後運轉, 假如是新建的項目能夠會報這個錯誤

IOS 微信支付 SDK版本1.7.5(2016年12月27日)

第八步: 創立一個PCH文件 Common.pch

定義三個宏

#define WeChatAppID @"xxxxxxxxxxxxx"// APPID
#define PartnerID @"xxxxx"//商戶ID
#define APISignKey @"xxxxxxxx商戶平台 -> 賬戶中心 -> API平安 -> API密鑰, 設置密鑰"// API私鑰

第九步: ViewController.m中的代碼
//
//  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

第十步: 在AppDelegate.m中添加領取完成回調, 此處會在回調中觸發一個告訴.
// 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;
    }
}

最後附個demo地址:https://github.com/MrZhou1990/ZHWeChatPay.git


【iOS 微信領取 SDK版本1.7.5(2016年12月27日)】的相關資料介紹到這裡,希望對您有所幫助! 提示:不會對讀者因本文所帶來的任何損失負責。如果您支持就請把本站添加至收藏夾哦!

  1. 上一頁:
  2. 下一頁:
蘋果刷機越獄教程| IOS教程問題解答| IOS技巧綜合| IOS7技巧| IOS8教程
Copyright © Ios教程網 All Rights Reserved