微信支付功能的简单集成,提倡使用Ping++,简单,粗暴。
所有信息的生成都在前端完成,包括对订单进行sign签名以及MD5签名加密(此方法相对来说有些复杂,没有官方给的方法简单)。
注:官方给的是v3&v4支付流程,签名和加密都是在服务器端进行,由于没有对接过,所以就暂时没有办法分享。
1. 准备工作
- 工程所需的微信支付SDK,如下图:

- 微信支付所需的相关用户信息(由用户申请)
1 2 3 4 5 6 7 8
| #define MCH_ID @"YOUR_MCH_ID"
#define WX_AppID @"YOUR_WX_AppID"
#define WX_PartnerKey @"YOUR_WX_PartnerKey"
#define WX_AppSecret @"YOUR_WX_AppSecret"
|
2. 集成开发流程
1 . iOS 9系统策略更新,限制了http协议的访问,此外应用需要在“Info.plist”中将要使用的URL Schemes(跳转程序)列为白名单,才可正常检查其他应用是否安装(引自微信支付SDK1.6.2,Readme.text)。如下图:

注:LSApplicationQueriesSchemes 下面其他的为友盟分享要添加的白名单,当然也包含微信。
2 . 在项目属性中的URL Types中添加URL Schemes,如图中标红位置所示。

3 . 在项目工程Appdelegate.m文件里面添加注册微信支付信息,注:如果项目中第三方分享用的是友盟,在注册的时候要把友盟注册放在微信注册的前面执行。如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
| #pragma mark - 设置第三方 注册信息 - (void)registerMethods {
[UMSocialData setAppKey:UMSocial_AppKey];
[UMSocialWechatHandler setWXAppId:WX_appID appSecret:WX_AppSecret url:@"http://www.umeng.com/social"];
[UMSocialQQHandler setQQWithAppId:QQ_AppID appKey:QQ_AppKey url:@"http://www.umeng.com/social"]; [UMSocialConfig hiddenNotInstallPlatforms:@[UMShareToQQ, UMShareToQzone, UMShareToWechatTimeline, UMShareToWechatTimeline]];
[UMSocialSinaSSOHandler openNewSinaSSOWithAppKey:Sina_AppKey RedirectURL:@"http://sns.whalecloud.com/sina2/callback"]; [UMSocialSinaHandler openSSOWithRedirectURL:@"http://sns.whalecloud.com/sina2/callback"];
[WXApi registerApp:WX_appID]; 两个任选一行,还不清楚这个appdesc有何作用 }
|
4.配置DataMD5.m文件,本地对签名进行二次加密,如果忽略这个步骤,就会造成调起微信支付,只出现一个确定按钮。注:之前出现这个问题,被卡壳了两天才发现,FK。

5 . 在要唤起微信支付的.m文件中,直接上代码方便ctrl+c, ctrl+v
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105
| #pragma mark - 微信支付相关方法 - (void)weixinChooseAct { NSString *appid,*mch_id,*nonce_str,*sign,*body,*out_trade_no,*total_fee,*spbill_create_ip,*notify_url,*trade_type,*partner; appid = WX_appID; mch_id = MCH_ID; nonce_str =[self generateTradeNO]; body =@"微信支付时候看到的支付信息"; out_trade_no = self.gold_sn; total_fee = self.payCount; spbill_create_ip =[getIPhoneIP getIPAddress]; notify_url =@"www.cccuu.com"; trade_type =@"APP"; partner = WX_partnerKey; DataMD5 *data = [[DataMD5 alloc] initWithAppid:appid mch_id:mch_id nonce_str:nonce_str partner_id:partner body:body out_trade_no:out_trade_no total_fee:total_fee spbill_create_ip:spbill_create_ip notify_url:notify_url trade_type:trade_type]; sign = [data 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:sign forKey:@"sign"]; [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"]; NSString *string = [dic XMLString]; [self http:string]; }
#pragma mark - 拿到转换好的xml发送请求 - (void)http:(NSString *)xml { [MBProgressHUD showMessage:@"正在获取支付订单..."]; AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager]; 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; }]; [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] ; 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"]; 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{ LXLog(@"参数不正确,请检查参数"); [MBProgressHUD hideHUD]; [MBProgressHUD showError:@"支付错误!"]; } } failure:^(AFHTTPRequestOperation *operation, NSError *error) { LXLog(@"error is %@",error); [MBProgressHUD hideHUD]; [MBProgressHUD showError:@"未完成支付"]; }]; }
#pragma mark - 产生随机订单号 - (NSString *)generateTradeNO { static int kNumber = 15;
NSString *sourceStr = @"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"; 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; }
|
注:上面 stand(time(0));报警告,如下图:

6 . 最后在Appdelegate.m文件中添加微信支付结果 onResp 回调方法,非常重要:给后台发送数据进行后台数据的更新(例如:充值浩方Vip会员,微信钱包钱已经扣了,而后台没有收到信息,钱不就白花了 - - 、),如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46
| #pragma mark - WXApiDelegate -(void)onResp:(BaseResp *)resp { if ([resp isKindOfClass:[PayResp class]]) { PayResp*response=(PayResp*)resp; switch (response.errCode) { case WXSuccess: { LXLog(@"支付成功"); [[NSNotificationCenter defaultCenter] postNotificationName:@"WX_PaySuccess" object:nil]; } break; case WXErrCodeCommon: { [MBProgressHUD showError:@"支付失败"]; LXLog(@"支付失败"); } break; case WXErrCodeUserCancel: { LXLog(@"取消支付"); [MBProgressHUD showError:@"取消支付"]; } break; case WXErrCodeSentFail: { LXLog(@"发送失败"); [MBProgressHUD showError:@"发送失败"]; } break; case WXErrCodeUnsupport: { LXLog(@"微信不支持"); [MBProgressHUD showError:@"微信不支持"]; } break; case WXErrCodeAuthDeny: { LXLog(@"授权失败"); [MBProgressHUD showError:@"授权失败"]; } break; default: break; } } }
|
到此结束,忘能正常唤起微信支付。
3. 总结
- 按照官方Demo来看,加密证书之类的操作也是在服务器端完成,这样商户的信息就不会暴露在前端,才能达到 “TA好,我也好”。* ps:此方法本人没有做过,以和后台司马同学商量过,后期整理出来 *。
- 第一次用MarkDown记录,感觉自己用着好笨,对于代码部分的应用非常不得手,多多练习。
- 银联支付集成,待续。