iOS微信支付_第四节_集成技术(见证时刻的时候到了)(更新完毕~)

    一、在AppDelegate里面做的事情

    1.设置appid

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    
#pragma mark (可以忽略此步)设置window的rootView界面
    self.window = [[UIWindow alloc]initWithFrame:[[UIScreen mainScreen] bounds]];
    XYTabBarViewController *tabBar = [[XYTabBarViewController alloc]init];
    //[naVC addChildViewController:login];
    self.window.rootViewController = tabBar;
    [self.window addSubview:tabBar.view];
    self.window.backgroundColor = [UIColor whiteColor];
    //self.window.rootViewController = nv;
    [self.window makeKeyAndVisible];
    
#pragma mark - 微信支付
    [WXApi registerApp:@"你的微信支付appID"];

    return YES;
}

   2.微信支付完毕之后回调的方法 

#pragma mark - 微信支付回调

-(void)onResp:(BaseResp *)resp{
    NSString *strTitle;
    if ([resp isKindOfClass:[SendMessageToWXResp class]]) {
        strTitle = [NSString stringWithFormat:@"发送媒体消息结果"];
    }
    if ([resp isKindOfClass:[PayResp class]]) {
        strTitle = [NSString stringWithFormat:@"支付结果"];
        switch (resp.errCode) {
            case WXSuccess:
            {
                YHLog(@"支付结果: 成功!");
                
                // 跳转到主界面
                XYTabBarViewController *tabBar = [[XYTabBarViewController alloc]init];
                self.window.rootViewController = tabBar;
                [tabBar CreateAlertActionWithTitle:@"提示" AndMessage:@"支付成功"];
                [self.window addSubview:tabBar.view];

            }
                break;
            case WXErrCodeCommon:
            { //签名错误、未注册APPID、项目设置APPID不正确、注册的APPID与设置的不匹配、其他异常等
                
                YHLog(@"支付结果: 失败!");
            }
                break;
            case WXErrCodeUserCancel:
            { //用户点击取消并返回
                
            }
                break;
            case WXErrCodeSentFail:
            { //发送失败
                YHLog(@"发送失败");
            }
                break;
            case WXErrCodeUnsupport:
            { //微信不支持
                YHLog(@"微信不支持");
            }
                break;
            case WXErrCodeAuthDeny:
            { //授权失败
                YHLog(@"授权失败");
            }
                break;
            default:
                break;
        }
        //------------------------
    }
}

 3.设置、支付完毕之后 回到当前应用

#pragma mark other

- (BOOL)application:(UIApplication *)application handleOpenURL:(NSURL *)url
{
    return [WXApi handleOpenURL:url delegate:self];
}
/**当用户通过其它应用启动本应用时,会回调这个方法,url参数是其它应用调用openURL:方法时传过来的。*/
- (BOOL)application:(UIApplication *)application
            openURL:(NSURL *)url
  sourceApplication:(NSString *)sourceApplication
         annotation:(id)annotation
{
    // 此处是支付宝(可以忽略)
    if ([url.host isEqualToString:@"safepay"]) {
        //跳转支付宝钱包进行支付,处理支付结果
        [[AlipaySDK defaultService] processOrderWithPaymentResult:url standbyCallback:^(NSDictionary *resultDic) {
            YHLog(@"result = %@",resultDic);
        }];
    }

    // 微信 
    return
    [WXApi handleOpenURL:url delegate:self];
}

 二、支付界面 要处理的事情

    1.点击微信支付时候做的处理

  // 判断当前用户有没有安装了微信客户端
        if ([WXApi isWXAppInstalled])
        {
            // 已经安装过的、、可以进行授权
            
            NSString *identifierForVendor = [[UIDevice currentDevice].identifierForVendor UUIDString];
            NSString *phoneIP = [getIPhoneIP getIPAddress:1];
            YHLog(@"%@",identifierForVendor);
            
            YHLog(@"phoneIP %@",phoneIP);
            
            // 这里请求网络
            [self loadWXNetWork_WithOpenid:nil withIdentifierForVendor:identifierForVendor AndPhoneIP:phoneIP];
            
        }
        else
        {
            [self CreateAlertActionWithTitle:@"提示" AndMessage:@"请先安装微信客户端"];
            YHLog(@"请安装微信客户端");
        }

 2.网络请求

#pragma mark - 1.微信支付网络
-(void)loadWXNetWork_WithOpenid:(NSString *)openid withIdentifierForVendor:(NSString *)identifierForVendor AndPhoneIP:(NSString *)phoneIP
{
    YHLog(@"微信支付");
    //有网络的情况下,隐藏重新加载视图
    NSMutableDictionary *param =  [[NSMutableDictionary  alloc]init];
    YHLog(@"%@",self.goods_name);
    NSString *path = [[NSString alloc]initWithFormat:kCommon_applyWay_URL_WeXinPay];
    
    MKNetworkEngine *engine = [[MKNetworkEngine alloc]initWithHostName:kBaseHostName customHeaderFields:nil];
    
    [param setObject:identifierForVendor forKey:@"device_info"];
    //    [param setObject:openid forKey:@"openid"];
    [param setObject:phoneIP forKey:@"spbill_create_ip"];
    [param setObject:self.order_sn forKey:@"out_trade_no"];
    [param setObject:self.goods_money forKey:@"total_fee"];
    [param setObject:self.goods_name forKey:@"body"];
    
    YHLog(@"\n设备号:%@\n手机ip:%@\n订单号:%@\n价格:%@\n订单名:%@\n",identifierForVendor,phoneIP,self.order_sn,self.goods_money,self.goods_name);
    
    MKNetworkOperation *op = [engine operationWithPath:path params:param httpMethod:@"POST"];
    
    //    [self.view.window showHUDWithText:@"加载中" Type:ShowLoading Enabled:YES];
    
    [op addCompletionHandler:^(MKNetworkOperation *completedOperation) {
        
        NSString * msgData = [completedOperation responseStringWithEncoding:NSUTF8StringEncoding];
        YHLog(@"微信支付授权登录返回的数据 is %@",msgData);
        id json = [completedOperation responseJSON];
        NSDictionary *jd = (NSDictionary *)json;
        
        NSDictionary *data = [jd objectForKey:@"data"];
        NSDictionary *status = [jd objectForKey:@"status"];
        NSNumber *succeed = [status objectForKey:@"succeed"];
        
        if (succeed.intValue == 1) {
#pragma mark 微信支付核心代码
            //发起微信支付,设置参数
            PayReq *request = [[PayReq alloc] init];
            //            request.openID = kWX_AppID;
            request.partnerId = [data objectForKey:@"partnerId"];
            request.prepayId= [data objectForKey:@"prepayid"];
            request.package = [data objectForKey:@"packageValue"];
            request.nonceStr= [data objectForKey:@"nonceStr"];
            UInt32 timeStamp =[[data objectForKey:@"timeStamp"] intValue];
            request.timeStamp= timeStamp;
            request.sign = [data objectForKey:@"sign"];
            
            // 客户端生成sign签名 // 可以使用服务器生成的
            //            DataMD5 *md5 = [[DataMD5 alloc] init];
            //            request.sign=[md5 createMD5SingForPay:kWX_AppID partnerid:request.partnerId prepayid:request.prepayId package:request.package noncestr:request.nonceStr timestamp:request.timeStamp];
            //            //            调用微信
            
            YHLog(@"sign %@",request.sign);
            [WXApi sendReq:request];
        }
        
        //        [self.view.window showHUDWithText:nil Type:ShowDismiss Enabled:YES];
        
        
    } errorHandler:^(MKNetworkOperation *completedOperation, NSError *error) {
        YHLog(@"请求错误");
        //        [self.view.window showHUDWithText:nil Type:ShowDismiss Enabled:YES];
    }];
    [engine enqueueOperation:op];
}

3.客户端生成sign(如果服务器返回,可以忽略此步)

appid、noncestr、package、partnerid、prepayid、timestamp 的字段必须要小写

(商户密钥可以在————商户平台里面获取)(第三节讲到)

DataMD5.h

#import <Foundation/Foundation.h>

@interface DataMD5 : NSObject
-(instancetype)initWithAppid:(NSString *)appid_key
                      mch_id:(NSString *)mch_id_key
                   nonce_str:(NSString *)noce_str_key
                  partner_id:(NSString *)partner_id
                        body:(NSString *)body_key
               out_trade_no :(NSString *)out_trade_no_key
                   total_fee:(NSString *)total_fee_key
            spbill_create_ip:(NSString *)spbill_create_ip_key
                  notify_url:(NSString *)notify_url_key
                  trade_type:(NSString *)trade_type_key;
///获取MD5签名
- (NSString *)getSignForMD5;
///创建发起支付时的sige签名
-(NSString *)createMD5SingForPay:(NSString *)appid_key partnerid:(NSString *)partnerid_key prepayid:(NSString *)prepayid_key package:(NSString *)package_key noncestr:(NSString *)noncestr_key timestamp:(UInt32)timestamp_key;
@end

DataMD5.h

#import "DataMD5.h"
#import <CommonCrypto/CommonDigest.h>
@interface DataMD5()
@property (nonatomic,strong) NSString *appid;
@property (nonatomic,strong) NSString *mch_id;
@property (nonatomic,strong) NSString *nonce_str;
@property (nonatomic,strong) NSString *partnerkey;
@property (nonatomic,strong) NSString *body;
@property (nonatomic,strong) NSString *out_trade_no;
@property (nonatomic,strong) NSString *total_fee;
@property (nonatomic,strong) NSString *spbill_create_ip;
@property (nonatomic,strong) NSString *notify_url;
@property (nonatomic,strong) NSString *trade_type;
@end

@implementation DataMD5
-(instancetype)initWithAppid:(NSString *)appid_key
                      mch_id:(NSString *)mch_id_key
                   nonce_str:(NSString *)noce_str_key
                  partner_id:(NSString *)partner_id
                        body:(NSString *)body_key
               out_trade_no :(NSString *)out_trade_no_key
                   total_fee:(NSString *)total_fee_key
            spbill_create_ip:(NSString *)spbill_create_ip_key
                  notify_url:(NSString *)notify_url_key
                  trade_type:(NSString *)trade_type_key{
    self = [super init];
    if (self) {
        _appid = appid_key;
        _mch_id = mch_id_key;
        _nonce_str = noce_str_key;
        _partnerkey = partner_id;
        _body = body_key;
        _out_trade_no = out_trade_no_key;
        _total_fee = total_fee_key;
        _spbill_create_ip = spbill_create_ip_key;
        _notify_url = notify_url_key;
        _trade_type = trade_type_key;
        
    }
    return self;
}
///获取sign签名
- (NSString *)getSignForMD5{
    NSMutableDictionary *dic = [NSMutableDictionary dictionary];
    [dic setValue:_appid forKey:@"appid"];
    [dic setValue:_mch_id forKey:@"mch_id"];
    [dic setValue:_nonce_str forKey:@"nonce_str"];
    [dic setValue:_body forKey:@"body"];
    [dic setValue:_out_trade_no forKey:@"out_trade_no"];
    [dic setValue:_total_fee forKey:@"total_fee"];
    [dic setValue:_spbill_create_ip forKey:@"spbill_create_ip"];
    [dic setValue:_notify_url forKey:@"notify_url"];
    [dic setValue:_trade_type forKey:@"trade_type"];
    return [self createMd5Sign:dic];
}

//创建签名
-(NSString*) createMd5Sign:(NSMutableDictionary*)dict
{
    NSMutableString *contentString  =[NSMutableString string];
    NSArray *keys = [dict allKeys];
    //按字母顺序排序
    NSArray *sortedArray = [keys sortedArrayUsingComparator:^NSComparisonResult(id obj1, id obj2) {
        return [obj1 compare:obj2 options:NSNumericSearch];
    }];
    //拼接字符串
    for (NSString *categoryId in sortedArray) {
        if (   ![[dict objectForKey:categoryId] isEqualToString:@""]
            && ![[dict objectForKey:categoryId] isEqualToString:@"sign"]
            && ![[dict objectForKey:categoryId] isEqualToString:@"key"]
            )
        {
            [contentString appendFormat:@"%@=%@&", categoryId, [dict objectForKey:categoryId]];
        }
    }
    //添加商户密钥key字段
    [contentString appendFormat:@"key=%@", _partnerkey];
    //得到MD5 sign签名
    NSString *md5Sign =[self md5:contentString];
    
    return md5Sign;
}

//创建发起支付时的sige签名
-(NSString *)createMD5SingForPay:(NSString *)appid_key partnerid:(NSString *)partnerid_key prepayid:(NSString *)prepayid_key package:(NSString *)package_key noncestr:(NSString *)noncestr_key timestamp:(UInt32)timestamp_key{
    NSMutableDictionary *signParams = [NSMutableDictionary dictionary];
    [signParams setObject:appid_key forKey:@"appid"];
    [signParams setObject:noncestr_key forKey:@"noncestr"];
    [signParams setObject:package_key forKey:@"package"];
    [signParams setObject:partnerid_key forKey:@"partnerid"];
    [signParams setObject:prepayid_key forKey:@"prepayid"];
    [signParams setObject:[NSString stringWithFormat:@"%u",timestamp_key] forKey:@"timestamp"];
    
    NSMutableString *contentString  =[NSMutableString string];
    NSArray *keys = [signParams allKeys];
    //按字母顺序排序
    NSArray *sortedArray = [keys sortedArrayUsingComparator:^NSComparisonResult(id obj1, id obj2) {
        return [obj1 compare:obj2 options:NSNumericSearch];
    }];
    //拼接字符串
    for (NSString *categoryId in sortedArray) {
        if (   ![[signParams objectForKey:categoryId] isEqualToString:@""]
            && ![[signParams objectForKey:categoryId] isEqualToString:@"sign"]
            && ![[signParams objectForKey:categoryId] isEqualToString:@"key"]
            )
        {
            [contentString appendFormat:@"%@=%@&", categoryId, [signParams objectForKey:categoryId]];
        }
    }
    //添加商户密钥key字段
    [contentString appendFormat:@"key=%@", @"此处填入商家密钥"];
    //    NSString *signString =[self md5:contentString];
    NSString *result = [self md5:contentString];
    return result;
}

-(NSString *) md5:(NSString *)str
{
    const char *cStr = [str UTF8String];
    //加密规则,因为逗比微信没有出微信支付demo,这里加密规则是参照安卓demo来得
    unsigned char result[16]= "0123456789abcdef";
    CC_MD5(cStr, (CC_LONG)strlen(cStr), result);
    //这里的x是小写则产生的md5也是小写,x是大写则md5是大写,这里只能用大写,逗比微信的大小写验证很逗
    return [NSString stringWithFormat:
            @"%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X",
            result[0], result[1], result[2], result[3],
            result[4], result[5], result[6], result[7],
            result[8], result[9], result[10], result[11],
            result[12], result[13], result[14], result[15]
            ];
}

4.到了此处,您的微信支付基本上是可以进行调用了。但是有些小伙伴调起微信支付的时候。仅仅出现一个确定按钮。

一般情况下是sign签名错误。或者有可能服务器没有返回prepayid.

验证sign:

https://pay.weixin.qq.com/wiki/tools/signverify/

5.赋上链接去查看吧

http://www.cocoachina.com/bbs/read.php?tid-321546.html



转载于:https://my.oschina.net/u/2619573/blog/611117

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值