微信支付哪些事

1.根据官方文档,先将所用的库加入工程里去如sdk1.6.2中需要的库如下(具体请参照官方呆萌(demo)):

libxml2.tbd libc++.tbd libsqlite3.0.tbd CoreTelephony.framework libstdc++.6.0.9.tbd libz.tbd

2.将微信加入白名单中 TARGETS -> Info ->LSApplicationQueriesSchemes ->weixin ,weichat.

3.加入微信回调地址(在微信公共平台下创建应用得到的appid),TAGETS->Info ->URL Types

4.在AppDelegate导入头文件,这里我创建了一个微信管理类 

#import "WXApiManager.h" //这类里面包含了官门呆萌中提供的类 #import "WXApi.h"   #import "WXApiObject.h"

/**注册微信appid*/
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    // Override point for customization after application launch.

    //向微信注册 wxc43f9b2120a05409
    [WXApi registerApp:APP_ID withDescription:@"weixin"];
    
    return YES;
}
//打开微信
//微信
- (BOOL)application:(UIApplication *)application handleOpenURL:(NSURL *)url {
    return  [WXApi handleOpenURL:url delegate:[WXApiManager sharedManager]];
}

- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation { NSLog(@"%@",url); return [WXApi handleOpenURL:url delegate:[WXApiManager sharedManager]]; }

5.发送第一次签名(支付页面)

 if ([WXApi isWXAppInstalled]) {
            //  随机生机字符串
            NSString *noncestr = [self generateTradeNO];
            NSLog(@"%@",noncestr);
            
            
            //随机生成的商品订单号
            NSString *out_trade_no = [self getOrderNumber];
            
            //--------modey,1分钱
            NSString *total_fee = @"1"; 
            //--------create_ip,请看下面的,getIPhoneIp类
            NSString *creteIp = [getIPhoneIP getIPAddress]; NSString *tradeType = @"APP"; //获取sign签名,关于签名参数,请看官门文档中要拼接的参数,请参照下面的MD5类 DataMD5 *data = [[DataMD5 alloc] initWithAppid:APP_ID mch_id:MCH_ID nonce_str:noncestr partner_id:PARTNER_ID body:@"hotel" out_trade_no:out_trade_no total_fee:total_fee spbill_create_ip:creteIp notify_url:@"http://www.weixin.qq.com/wxpay/pay.php" trade_type:tradeType]; NSString *sign = [data getSignForMD5]; NSMutableDictionary *dic = [NSMutableDictionary dictionary]; [dic setValue:@"appid" forKey:@"appid"];//公众账号ID,创建商户自己获取的 [dic setValue:@"商户号" forKey:@"mch_id"];//商户号 [dic setValue:noncestr forKey:@"nonce_str"];//随机字符串 [dic setValue:sign forKey:@"sign"];//签名 [dic setValue:@"hotel" forKey:@"body"];//商品描述 [dic setValue:out_trade_no forKey:@"out_trade_no"];//订单号 [dic setValue:total_fee forKey:@"total_fee"];//金额 [dic setValue:creteIp forKey:@"spbill_create_ip"];//终端IP [dic setValue:@"http://www.weixin.qq.com/wxpay/pay.php" forKey:@"notify_url"];//通知地址 [dic setValue:tradeType forKey:@"trade_type"];//交易类型 // 转换成xml字符串 NSString *string = [dic XMLString]; //转换成xml [self http:string]; }else{ [MBProgressHUD showError:@"未安装微信"]; }

6.发送二次签名,(支付页面)

- (void)http:(NSString *)xml{

 

    [MBProgressHUD showMessage:@"正在获取支付订单..."];

    AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];

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

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

    [manager.requestSerializer setValue:@"text/xml; charset=utf-8" forHTTPHeaderField:@"Content-Type"]; [manager.requestSerializer setValue:@"https://api.mch.weixin.qq.com/pay/unifiedorder" forHTTPHeaderField:@"SOAPAction"]; [manager.requestSerializer setQueryStringSerializationWithBlock:^NSString *(NSURLRequest *request, NSDictionary *parameters, NSError *__autoreleasing *error) { return xml; //真正的xml }]; //发起请求  [manager POST:@"https://api.mch.weixin.qq.com/pay/unifiedorder" parameters:xml success:^(AFHTTPRequestOperation *operation, id responseObject) { NSString *responseString = [[NSString alloc] initWithData:responseObject encoding:NSUTF8StringEncoding] ; KGNSLog(@"%@",xml); //将微信返回的xml数据解析转义成字典,注意这里需要改XMLDictionary 第三方库  NSDictionary *dic = [NSDictionary dictionaryWithXMLString:responseString]; //判断返回的许可 if ([[dic objectForKey:@"result_code"] isEqualToString:@"SUCCESS"] &&[[dic objectForKey:@"return_code"] isEqualToString:@"SUCCESS"] ) { //发起微信支付,设置参数  PayReq *request = [[PayReq alloc] init]; request.openID = [dic objectForKey:@"appid"]; request.partnerId = [dic objectForKey:@"mch_id"]; request.prepayId= [dic objectForKey:@"prepay_id"]; request.package = @"Sign=WXPay"; request.nonceStr = [dic objectForKey:@"nonce_str"]; // request.nonceStr= noncestr;  KGNSLog(@"%@",request.nonceStr); //将当前事件转化成时间戳  NSDate *datenow = [NSDate date]; NSString *timeSp = [NSString stringWithFormat:@"%ld", (long)[datenow timeIntervalSince1970]]; UInt32 timeStamp =[timeSp intValue]; request.timeStamp= timeStamp; // 签名加密,二次签名  DataMD5 *md5 = [[DataMD5 alloc] init]; request.sign=[md5 createMD5SingForPay:request.openID partnerid:request.partnerId prepayid:request.prepayId package:request.package noncestr:request.nonceStr timestamp:request.timeStamp]; // 调用微信  [WXApi sendReq:request]; [MBProgressHUD hideHUD]; }else{ KGNSLog(@"参数不正确,请检查参数"); [MBProgressHUD hideHUD]; [MBProgressHUD showError:@"支付错误!"]; } } failure:^(AFHTTPRequestOperation *operation, NSError *error) { KGNSLog(@"error is %@",error); [MBProgressHUD hideHUD]; [MBProgressHUD showError:@"未完成支付"]; }]; }

7.微信管理单例类继承<WXApiDelegate>用来实现回调的方法

- (void)onResp:(BaseResp *)resp {
    
    //支付返回结果,实际支付结果需要去微信服务器端查询
    NSString *strMsg = [NSString stringWithFormat:@"errcode:%d",resp.errCode];
    NSString *strTitle;
    
    if ([resp isKindOfClass:[SendMessageToWXResp class]]) {
        strTitle = [NSString stringWithFormat:@"发送媒体消息结果"];
    }
    
  if([resp isKindOfClass:[PayResp class]]){ //支付返回结果,实际支付结果需要去微信服务站查询 strTitle = [NSString stringWithFormat:@"支付结果"]; switch (resp.errCode) { case WXSuccess:{ strMsg = @"支付结果:成功!"; NSLog(@"支付成功-PaySuccess,retcode = %d", resp.errCode); //这里应用发送通知,来清楚支付的结果 NSNotification *notification = [NSNotification notificationWithName:ORDER_PAY_NOTIFICATION object:@"success"]; [[NSNotificationCenter defaultCenter] postNotification:notification]; break; } default:{ strMsg = [NSString stringWithFormat:@"支付结果:失败!retcode = %d, retstr = %@", resp.errCode,resp.errStr]; NSLog(@"错误,retcode = %d, retstr = %@", resp.errCode,resp.errStr); NSNotification *notification = [NSNotification notificationWithName:ORDER_PAY_NOTIFICATION object:@"fail"]; [[NSNotificationCenter defaultCenter] postNotification:notification]; break; } } // UIAlertView *alert = [[UIAlertView alloc] initWithTitle:strTitle message:strMsg delegate:self cancelButtonTitle:@"OK" otherButtonTitles:nil, nil]; // [alert show];  } }

8.在(支付页面监听通知,并实现通知方法,告诉用户支付的结果)

- (void)viewWillAppear:(BOOL)animated{
    [super viewWillAppear:animated];
    if ([WXApi isWXAppInstalled]) {
        
        [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(getOrderPayResult:) name:ORDER_PAY_NOTIFICATION object:nil];
        
    }
}
//微信 pay Result
- (void)getOrderPayResult:(NSNotification *)noti{

    if ([noti.object isEqualToString:@"success"])
    {
        [self alert:@"恭喜" msg:@"您已成功支付啦!"]; } else { [self alert:@"提示" msg:@"支付失败"]; } }

9.支付页面的一些方法

1.随机生机字符串

- (NSString *)generateTradeNO
{
    static int kNumber = 15;
    
    NSString *sourceStr = @"0123456789ABCDEFGHIJKLMNOPQRST";
    NSMutableString *resultStr = [[NSMutableString alloc] init];
    srand(time(0)); for (int i = 0; i < kNumber; i++) { unsigned index = rand() % [sourceStr length]; NSString *oneStr = [sourceStr substringWithRange:NSMakeRange(index, 1)]; [resultStr appendString:oneStr]; } return resultStr; } 2.//随机生成的商品订单号 - (NSString *)getOrderNumber{ int random = arc4random()%10000; return [KCommon md5:[NSString stringWithFormat:@"%d",random]]; } 3.获取当前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; }

4.MD5类,注意下面代码添加商户密钥key字段[contentString appendFormat:@"key=%@",PARTNER_ID],这里需要填商户密钥

-(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=%@",PARTNER_ID]; // 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] ]; }

10.微信支付那些坑

1.如果你微信支付代码全写上了,跳转页面只出现了一个确定按钮,不要怀疑人生,请看看是不是密钥没有填,md5签名出现了问题.

2.时间戳必须符合微信官方的规范,10位数,一定记得最后要转换成int或integer型.

暂时只发现这两个.

 

转载于:https://www.cnblogs.com/TheYouth/p/5625759.html

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值