一. 支付准备工作
1. 微信相关准备工作
(1) 向微信官方开通支付功能. 这个不是前端的工作.
(2) 导入官方下载的微信支付SDK包. 我用的是微信开放平台下载的最新SDK
(3) 导入必要的库文件
SystemConfiguration.framework,
libz.dylib,
libsqlite3.0.dylib,
libc++.dylib,
CoreTelephoy.framework (坑一: 这个库是必要的,但是微信官方文档中没有说到要导入)
(4) 该项目中的Bundle Identifier 应该填向微信注册的Bundle Identifier
(5) 注册微信 (回调的时候用到,告诉微信,从微信返回到哪个APP)
Target --> info --> URL Types --> +按钮 -->
填写identifier 和 URL Schemes. 前一个是标识符,一般填@"weixin".后一个是注册的微信appId.
比如"wx19a984b788a8a0b1".(注释: 假的appid)
(6) 添加微信白名单
info.plist --> 右击 --> open as --> source Code --> 添加白名单
我是在CFBundleVersion这一行上面添加的. 注意保持正确的键值对.别插错了
(7) 如果支付成功,回调方法不执行,或者回调不成功.请再次确认(4)(5)(6),是否填写正确.
(8) 运行一下,不报错.报错,再次确认(1)--(7)步骤.
二.代码相关
1. 在AppDelegate.h中
(1) 导入微信类 #import @"WXApi.h".
(2) 遵守微信代理方法
2. 在APPDelegate.m中
(1) 注册微信
#pragma mark 注册微信
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
//注册 微信
/**
参数1 : 微信Appid
参数2 : 对项目的描述信息(用项目名称)
*/
[WXApi registerApp:@"微信Appid" withDescription:@"云宴"];
return YES;
}
(2) 跳转方法,并设置代理
#pragma mark 跳转处理//被废弃的方法. 但是在低版本中会用到.建议写上- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation{ return [WXApi handleOpenURL:url delegate:self];}//被废弃的方法. 但是在低版本中会用到.建议写上- (BOOL)application:(UIApplication *)application handleOpenURL:(NSURL *)url{ return [WXApi handleOpenURL:url delegate:self];}//新的方法- (BOOL)application:(UIApplication *)app openURL:(NSURL *)url options:(NSDictionary*)options
{
return [WXApi handleOpenURL:url delegate:self];
}
(3) 微信回调方法 (注意: 不要写成Req方法了)
#pragma mark 微信回调方法
- (void)onResp:(BaseResp *)resp
{
NSString * strMsg = [NSString stringWithFormat:@"errorCode: %d",resp.errCode];
NSLog(@"strMsg: %@",strMsg);
NSString * errStr = [NSString stringWithFormat:@"errStr: %@",resp.errStr];
NSLog(@"errStr: %@",errStr);
NSString * strTitle;
//判断是微信消息的回调 --> 是支付回调回来的还是消息回调回来的.
if ([resp isKindOfClass:[SendMessageToWXResp class]])
{
strTitle = [NSString stringWithFormat:@"发送媒体消息的结果"];
}
NSString * wxPayResult;
//判断是否是微信支付回调 (注意是PayResp 而不是PayReq)
if ([resp isKindOfClass:[PayResp class]])
{
//支付返回的结果, 实际支付结果需要去微信服务器端查询
strTitle = [NSString stringWithFormat:@"支付结果"];
switch (resp.errCode)
{
case WXSuccess:
{
strMsg = @"支付结果:";
NSLog(@"支付成功: %d",resp.errCode);
wxPayResult = @"success";
break;
}
case WXErrCodeUserCancel:
{
strMsg = @"用户取消了支付";
NSLog(@"用户取消支付: %d",resp.errCode);
wxPayResult = @"cancel";
break;
}
default:
{
strMsg = [NSString stringWithFormat:@"支付失败! code: %d errorStr: %@",resp.errCode,resp.errStr];
NSLog(@":支付失败: code: %d str: %@",resp.errCode,resp.errStr);
wxPayResult = @"faile";
break;
}
}
//发出通知 从微信回调回来之后,发一个通知,让请求支付的页面接收消息,并且展示出来,或者进行一些自定义的展示或者跳转
NSNotification * notification = [NSNotification notificationWithName:@"WXPay" object:wxPayResult];
[[NSNotificationCenter defaultCenter] postNotification:notification];
}
}
3. 在ViewController.h (进行支付请求的类)
暂时没有任何操作
4. 在ViewController.m中(进行支付的请求的类)
(1) 导入微信库 #import @"WXApi.h"
(2) 监听APPDelegate.m中发送的通知
#pragma mark 监听通知
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:YES];
//检测是否装了微信软件
if ([WXApi isWXAppInstalled])
{
//监听通知
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(getOrderPayResult:) name:@"WXPay" object:nil];
}
}
#pragma mark - 事件
- (void)getOrderPayResult:(NSNotification *)notification
{
NSLog(@"userInfo: %@",notification.userInfo);
if ([notification.object isEqualToString:@"success"])
{
UIAlertView * alertView = [[UIAlertView alloc] initWithTitle:@"提示信息" message:@"支付成功" delegate:self cancelButtonTitle:@"确定" otherButtonTitles:nil, nil];
[alertView show];
}
else
{
[self alert:@"提示" msg:@"支付失败"];
}
}
//客户端提示信息
- (void)alert:(NSString *)title msg:(NSString *)msg
{
UIAlertView *alter = [[UIAlertView alloc] initWithTitle:title message:msg delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil];
[alter show];
}
(3) 移除通知
#pragmamark 移除通知- (void)dealloc
{//移除通知[[NSNotificationCenter defaultCenter] removeObserver:self];
}
(4) 调起微信去支付
- (void)viewDidLoad
{
[super viewDidLoad];
[self pay_button];
}
#pragma mark - 实现方法
#pragma mark 创建支付按钮
- (void)pay_button
{
self.payButton = [UIButton buttonWithType:UIButtonTypeCustom];
self.payButton.frame = CGRectMake(10, 100, 300, 40);
self.payButton.backgroundColor = [UIColor orangeColor];
[self.payButton setTitle:@"去支付" forState:UIControlStateNormal];
[self.payButton addTarget:self action:@selector(payButtonClicked) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:self.payButton];
}
#pragma mark - 点击事件
- (void)payButtonClicked
{
[self sendNetWorking_WXPay];
}
- (void)sendNetWorking_WXPay
{
NSString * urlStr = [NSString stringWithFormat:@"%@%@",YYIP,@"wx/pay"];
NSDictionary * parameter = @{
@"pay_type" : @"1",
@"total_price" : @"10",
@"appointment_id" : @"208"
};
[self sendNetWorkingWith:urlStr andParameter:parameter];
}
#pragma mark 网络请求 -->> post
- (void)sendNetWorkingWith:(NSString *)url andParameter:(NSDictionary *)parameter
{
AFHTTPSessionManager * manager = [AFHTTPSessionManager manager];
[manager POST:url parameters:parameter progress:^(NSProgress * _Nonnull uploadProgress) {
} success:^(NSURLSessionDataTask * _Nonnull task, id _Nullable responseObject) {
NSLog(@"%@",responseObject);
//网络请求回来的8个参数.详见微信开发平台
NSDictionary * result = responseObject[@"result"];
NSString * appid = result[@"appid"];
NSString * noncestr = result[@"noncestr"];
NSString * package1 = result[@"package1"];
NSString * partnerid = result[@"partnerid"];
NSString * paySign = result[@"paySign"];
NSString * prepayid = result[@"prepayid"];
NSString * timestamp = result[@"timestamp"];
// NSString * err_code = result[@"err_code"];
// NSString * timeStamp = result[@"timeStamp"];
// NSString * tradeid = result[@"tradeid"];
[self WXPayRequest:appid nonceStr:noncestr package:package1 partnerId:partnerid prepayId:prepayid timeStamp:timestamp sign:paySign];
} failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
NSLog(@"%@",error);
}];
}
#pragma mark - 调起微信支付
- (void)WXPayRequest:(NSString *)appId nonceStr:(NSString *)nonceStr package:(NSString *)package partnerId:(NSString *)partnerId prepayId:(NSString *)prepayId timeStamp:(NSString *)timeStamp sign:(NSString *)sign{
//调起微信支付
PayReq* wxreq = [[PayReq alloc] init];
wxreq.openID = appId; // 微信的appid
wxreq.partnerId = partnerId;
wxreq.prepayId = prepayId;
wxreq.nonceStr = nonceStr;
wxreq.timeStamp = [timeStamp intValue];
wxreq.package = package;
wxreq.sign = sign;
[WXApi sendReq:wxreq];
}
三.上代码
1. AppDelegate.h
#import#import "WXApi.h"@interface AppDelegate : UIResponder@property (strong, nonatomic) UIWindow *window;
@end
2. AppDelegate.m
#import "AppDelegate.h"@interface AppDelegate ()@end@implementation AppDelegate#pragma mark 注册微信- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions{ //注册 微信 /** 参数1 : 微信Appid 参数2 : 对项目的描述信息(用项目名称) */ [WXApi registerApp:@"wx09a984b788a8a0b0" withDescription:@"云宴"]; return YES;}#pragma mark 跳转处理//被废弃的方法. 但是在低版本中会用到.建议写上- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation{ return [WXApi handleOpenURL:url delegate:self];}//被废弃的方法. 但是在低版本中会用到.建议写上- (BOOL)application:(UIApplication *)application handleOpenURL:(NSURL *)url{ return [WXApi handleOpenURL:url delegate:self];}//新的方法- (BOOL)application:(UIApplication *)app openURL:(NSURL *)url options:(NSDictionary*)options
{
return [WXApi handleOpenURL:url delegate:self];
}
#warning 这一步中 不要错误的把req 当成了 resp
#pragma mark 微信回调方法
- (void)onResp:(BaseResp *)resp
{
NSString * strMsg = [NSString stringWithFormat:@"errorCode: %d",resp.errCode];
NSLog(@"strMsg: %@",strMsg);
NSString * errStr = [NSString stringWithFormat:@"errStr: %@",resp.errStr];
NSLog(@"errStr: %@",errStr);
NSString * strTitle;
//判断是微信消息的回调
if ([resp isKindOfClass:[SendMessageToWXResp class]])
{
strTitle = [NSString stringWithFormat:@"发送媒体消息的结果"];
}
NSString * wxPayResult;
//判断是否是微信支付回调 (注意是PayResp 而不是PayReq)
if ([resp isKindOfClass:[PayResp class]])
{
//支付返回的结果, 实际支付结果需要去微信服务器端查询
strTitle = [NSString stringWithFormat:@"支付结果"];
switch (resp.errCode)
{
case WXSuccess:
{
strMsg = @"支付结果:";
NSLog(@"支付成功: %d",resp.errCode);
wxPayResult = @"success";
break;
}
case WXErrCodeUserCancel:
{
strMsg = @"用户取消了支付";
NSLog(@"用户取消支付: %d",resp.errCode);
wxPayResult = @"cancel";
break;
}
default:
{
strMsg = [NSString stringWithFormat:@"支付失败! code: %d errorStr: %@",resp.errCode,resp.errStr];
NSLog(@":支付失败: code: %d str: %@",resp.errCode,resp.errStr);
wxPayResult = @"faile";
break;
}
}
//发出通知
NSNotification * notification = [NSNotification notificationWithName:@"WXPay" object:wxPayResult];
[[NSNotificationCenter defaultCenter] postNotification:notification];
}
}
@end
4. ViewController.m
#import "ViewController.h"
#import "AFHTTPSessionManager.h"
#import "WXApi.h"
#define YYIP @"http:公司IP地址"
@interface ViewController ()
@property (nonatomic, strong) UIButton * payButton;
@end
@implementation ViewController
#pragma mark 监听通知
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:YES];
//检测是否装了微信软件
if ([WXApi isWXAppInstalled])
{
//监听通知
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(getOrderPayResult:) name:@"WXPay" object:nil];
}
}
#pragma mark 移除通知
- (void)viewWillDisappear:(BOOL)animated
{
[super viewWillDisappear:YES];
//移除通知
[[NSNotificationCenter defaultCenter] removeObserver:self];
}
- (void)viewDidLoad
{
[super viewDidLoad];
[self pay_button];
}
#pragma mark - 实现方法
#pragma mark 创建支付按钮
- (void)pay_button
{
self.payButton = [UIButton buttonWithType:UIButtonTypeCustom];
self.payButton.frame = CGRectMake(10, 100, 300, 40);
self.payButton.backgroundColor = [UIColor orangeColor];
[self.payButton setTitle:@"去支付" forState:UIControlStateNormal];
[self.payButton addTarget:self action:@selector(payButtonClicked) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:self.payButton];
}
#pragma mark - 点击事件
- (void)payButtonClicked
{
if ([WXApi isWXAppInstalled])
{
[self sendNetWorking_WXPay];
}
else
{
[self alert:@"提示" msg:@"未安装微信"];
}
}
- (void)sendNetWorking_WXPay
{
NSString * urlStr = [NSString stringWithFormat:@"%@%@",YYIP,@"wx/pay"];
NSDictionary * parameter = @{
@"pay_type" : @"1",
@"total_price" : @"10",
@"appointment_id" : @"208"
};
[self sendNetWorkingWith:urlStr andParameter:parameter];
}
#pragma mark 网络请求 -->> post
- (void)sendNetWorkingWith:(NSString *)url andParameter:(NSDictionary *)parameter
{
AFHTTPSessionManager * manager = [AFHTTPSessionManager manager];
[manager POST:url parameters:parameter progress:^(NSProgress * _Nonnull uploadProgress) {
} success:^(NSURLSessionDataTask * _Nonnull task, id _Nullable responseObject) {
NSLog(@"%@",responseObject);
//网络请求回来的8个参数.详见微信开发平台
NSDictionary * result = responseObject[@"result"];
NSString * appid = result[@"appid"];
NSString * noncestr = result[@"noncestr"];
NSString * package1 = result[@"package1"];
NSString * partnerid = result[@"partnerid"];
NSString * paySign = result[@"paySign"];
NSString * prepayid = result[@"prepayid"];
NSString * timestamp = result[@"timestamp"];
// NSString * err_code = result[@"err_code"];
// NSString * timeStamp = result[@"timeStamp"];
// NSString * tradeid = result[@"tradeid"];
[self WXPayRequest:appid nonceStr:noncestr package:package1 partnerId:partnerid prepayId:prepayid timeStamp:timestamp sign:paySign];
} failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
NSLog(@"%@",error);
}];
}
#pragma mark - 调起微信支付
- (void)WXPayRequest:(NSString *)appId nonceStr:(NSString *)nonceStr package:(NSString *)package partnerId:(NSString *)partnerId prepayId:(NSString *)prepayId timeStamp:(NSString *)timeStamp sign:(NSString *)sign{
//调起微信支付
PayReq* wxreq = [[PayReq alloc] init];
wxreq.openID = appId; // 微信的appid
wxreq.partnerId = partnerId;
wxreq.prepayId = prepayId;
wxreq.nonceStr = nonceStr;
wxreq.timeStamp = [timeStamp intValue];
wxreq.package = package;
wxreq.sign = sign;
[WXApi sendReq:wxreq];
}
#pragma mark - 事件
- (void)getOrderPayResult:(NSNotification *)notification
{
NSLog(@"userInfo: %@",notification.userInfo);
if ([notification.object isEqualToString:@"success"])
{
UIAlertView * alertView = [[UIAlertView alloc] initWithTitle:@"提示信息" message:@"支付成功" delegate:self cancelButtonTitle:@"确定" otherButtonTitles:nil, nil];
[alertView show];
}
else if([notification.object isEqualToString:@"cancel"])
{
[self alert:@"提示" msg:@"用户取消了支付"];
}
else
{
[self alert:@"提示" msg:@"支付失败"];
}
}
//客户端提示信息
- (void)alert:(NSString *)title msg:(NSString *)msg
{
UIAlertView *alter = [[UIAlertView alloc] initWithTitle:title message:msg delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil];
[alter show];
}
@end