iOS微信支付
移动支付盛行,app接入逐渐成为标配
今天和大家分享一下微信支付的接入
调起微信支付的整个流程是:
一、在appDelegate中配置,并写好方法接受微信返回信息,
二、调用后台接口(自定义)与微信交互,微信返回必要参数,其中最主要一个参数是prepay_id
三、使用appid、noncestr(下面有详细生成方法)package(目前为固定值,直接给@"Sign=WXPay")、partnerid(就是mchId)timestamp(时间戳)、prepayid生成签名sign
四、将必要参数传给PayReq对象
五、最后,使用WXApi的sendReq方法吊起微信。
下面开始贴方法:
准备工作:
到微信开放平台,申请开通支付功能(唯一注意,bundleId需与工程一致),在财付通回馈的邮箱中获取以下信息(注:以下信息已修改,不可直接复制使用)
APP_ID @"wxf120b5260432545" //APPID
APP_SECRET @"998d17563f0d6d0181b90ff543656ygrs" //appsecret
MCH_ID @"1269999401" //商户号
PARTNER_ID @"xbM5MBCVOj2sEAs8KrMfwla4djpcQKuvG9" //商户API密钥
2.下载微信支付SDK
3.AppDelegate 可直接复制使用
1 #import "WXApi.h" 2 #import "WXApiObject.h" 3 - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { 4 5 // 1.注册微信 6 [WXApi registerApp:WECHAT_APPID withDescription:@"weichatpayblog"]; 7 8 return YES; 9 } 10 11 - (BOOL)application:(UIApplication *)application 12 openURL:(NSURL *)url 13 sourceApplication:(NSString *)sourceApplication 14 annotation:(id)annotation 15 { 16 return [WXApi handleOpenURL:url delegate:self]; 17 } 18 19 - (void)onResp:(BaseResp *)resp 20 { 21 NSString *strMsg = [NSString stringWithFormat:@"errcode:%d",resp.errCode]; 22 NSString *strTitle; 23 NSString *strNote; 24 if ([resp isKindOfClass:[PayResp class]]) { 25 // 支付返回结果,实际支付结果需要去微信服务器端查询 26 strTitle = @"支付结果"; 27 } 28 29 switch (resp.errCode) { 30 case WXSuccess:{ 31 strMsg = @"支付成功,可以进行洗车"; 32 strNote = @"success"; 33 break; 34 } 35 case WXErrCodeUserCancel: 36 strMsg = @"支付已取消"; 37 strNote = @"cancel"; 38 break; 39 case WXErrCodeSentFail: 40 strMsg = @"支付失败,请重新支付"; 41 strNote = @"fail"; 42 break; 43 default:{ 44 strMsg = @"支付失败"; 45 strNote = @"fail"; 46 break; 47 } 48 } 49 50 // NSNotification *notification = [NSNotification notificationWithName:ORDER_PAY_NOTIFICATION object:strNote]; 51 // [[NSNotificationCenter defaultCenter] postNotification:notification]; 52 [[NSNotificationCenter defaultCenter] postNotificationName:ORDER_PAY_NOTIFICATION object:strNote]; 53 [Alert showWithTitle:strMsg]; 54 } 55 56 - (BOOL)application:(UIApplication *)application handleOpenURL:(NSURL *)url 57 { 58 return [WXApi handleOpenURL:url delegate:self]; 59 }
4.调起支付
1 #import "WXApi.h" 2 #import "WXApiObject" 3 #import "WXUtil.h" 4 - (void)clickPayWithWechat 5 { 6 7 // 判断客户端是否安装微信/版本是否支持 8 if ([self isWXAppInstalled]) { 9 10 [self updateOrderInfo]; 11 } 12 13 } 14 15 - (BOOL)isWXAppInstalled 16 { 17 // 1.判断是否安装微信 18 if (![WXApi isWXAppInstalled]) { 19 [Alert showWithTitle:@"您尚未安装\"微信App\",请先安装后再返回支付"]; 20 return NO; 21 } 22 23 // 2.判断微信的版本是否支持最新Api 24 if (![WXApi isWXAppSupportApi]) { 25 [Alert showWithTitle:@"您微信当前版本不支持此功能,请先升级微信应用"]; 26 return NO; 27 } 28 return YES; 29 } 30 31 // 32 - (void)updateOrderInfo 33 { 34 // 调用自己后台接口 35 返回 prePay_id 36 } 37 38 - (void)updateOrderInfoToWechat 39 { 40 // wechatModel 为自定义模型 存储微信支付所需参数 41 if (wechatModel.prepay_id != nil) { 42 DLog(@" %@ ",wechatModel.prepay_id); 43 NSString *package, *time_stamp, *nonce_str; 44 time_t now; 45 time(&now); 46 time_stamp = [NSString stringWithFormat:@"%ld",now]; 47 // WXUtil类 可留言,我发邮箱 或加我qq 343381934 注明博客园 微信支付 48 nonce_str = [WXUtil md5:time_stamp]; 49 package = @"Sign=WXPay"; 50 NSMutableDictionary *signParams = [NSMutableDictionary dictionary]; 51 [signParams setObject:WECHAT_APPID forKey:@"appid"]; 52 [signParams setObject:nonce_str forKey:@"noncestr"]; 53 [signParams setObject:package forKey:@"package"]; 54 [signParams setObject:WECHAT_MCH_ID forKey:@"partnerid"]; 55 [signParams setObject:time_stamp forKey:@"timestamp"]; 56 [signParams setObject:wechatModel.prepay_id forKey:@"prepayid"]; 57 NSString *sign = [self createMd5Sign:signParams] 58 ; 59 [signParams setObject:sign forKey:@"sign"];
// 这里 调起微信 一个参数也不能少 重要的事 我不想说三遍了,调不起会来看三遍的 哈哈哈.... 60 PayReq *req = [[PayReq alloc] init]; 61 req.openID = WECHAT_APPID; 62 req.partnerId = WECHAT_MCH_ID; 63 req.prepayId = wechatModel.prepay_id; 64 req.nonceStr = nonce_str; 65 req.timeStamp = time_stamp.intValue; 66 req.package = package; 67 req.sign = sign; 68 [WXApi sendReq:req]; 69 } 70 } 71 72 -(NSString*) createMd5Sign:(NSMutableDictionary*)dict 73 { 74 NSMutableString *contentString =[NSMutableString string]; 75 NSArray *keys = [dict allKeys]; 76 //按字母顺序排序 77 NSArray *sortedArray = [keys sortedArrayUsingComparator:^NSComparisonResult(id obj1, id obj2) { 78 return [obj1 compare:obj2 options:NSNumericSearch]; 79 }]; 80 //拼接字符串 81 for (NSString *categoryId in sortedArray) { 82 if ( ![[dict objectForKey:categoryId] isEqualToString:@""] 83 && ![categoryId isEqualToString:@"sign"] 84 && ![categoryId isEqualToString:@"key"] 85 ) 86 { 87 [contentString appendFormat:@"%@=%@&", categoryId, [dict objectForKey:categoryId]]; 88 } 89 90 } 91 //添加key字段 92 [contentString appendFormat:@"key=%@", wechatModel.key]; 93 //得到MD5 sign签名 94 NSString *md5Sign =[WXUtil md5:contentString]; 95 96 // //输出Debug Info 97 // [debugInfo appendFormat:@"MD5签名字符串:\n%@\n\n",contentString]; 98 99 return md5Sign; 100 }
至此 应该已经成功调起微信支付了,在这个类当中,添加观察者,对跳转后的信息处理
将状态信息传给自己的后台 就结束了
过程中需要注意的是
1.传个PayReq对象的参数不能少
2.如果工程中使用了友盟,会出现冲突,因为友盟的包里包含了微信sdk,删掉友盟里重复即可,这里网上有相关资料,不再赘述
如仍有问题,欢迎留言 一起探讨