iOS微信支付_第四节_集成技术(见证时刻的时候到了)(更新完毕~)
2016-01-28 00:00
621 查看
摘要: iOS微信支付
调用微信支付 需要给服务器 必须要传递参数
1、手机ip地址
2、手机设备号
3、订单号(商家自定格式)
4、价格
5、商品名
一、在AppDelegate里面做的事情
1.点击微信支付时候做的处理
(商户密钥可以在————商户平台里面获取)(第三节讲到)
DataMD5.h
DataMD5.h
https://pay.weixin.qq.com/wiki/tools/signverify/
调用微信支付 需要给服务器 必须要传递参数
1、手机ip地址
2、手机设备号
3、订单号(商家自定格式)
4、价格
5、商品名
一、在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相关文章推荐
- 浅谈使用PHP开发微信支付的流程
- 微信支付如何实现内置浏览器的H5页面支付
- php开发微信支付获取用户地址
- java实现微信支付(服务端)
- 浅析PHP微信支付通知的处理方式
- PHP开发微信支付的代码分享
- 微信公众号支付(二)实现统一下单接口
- 微信支付PHP SDK之微信公众号支付代码详解
- Java通过JsApi方式实现微信支付
- java开发微信公众号支付
- 分享微信扫码支付开发遇到问题及解决方案-附Ecshop微信支付插件
- 微信支付开发IOS图文教程案例
- PHP 微信支付类 demo
- Android微信支付开发问题
- IOS客户端接入微信支付
- 微信支付phpv3给我们留下的坑
- 分享微信扫码支付开发遇到问题及解决方案-附Ecshop微信支付插件
- 支付宝支付、微信支付,银联支付
- app集成微信支付服务器端开发(java)
- 微信支付 该支付域名未获授权,无法发起该笔交易问题解决方案