一、微信支付,首先利用CocoaPods
,导入微信支付SDK
pod 'WechatOpenSDK'
二、 创建微信支付管理类 WechatManager
// WechatManager.h
#import <Foundation/Foundation.h>
#import <WXApi.h>
@interface WechatManager : NSObject
+ (id)shareInstance;
+ (BOOL)handleOpenUrl:(NSURL *)url;
+ (void)hangleWechatPayWith:(PayReq *)req;
@end
// WechatManager.m
#import "WechatManager.h"
@interface WechatManager()<WXApiDelegate>
@end
@implementation WechatManager
+ (id)shareInstance {
static WechatManager *weChatPayInstance = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
weChatPayInstance = [[WechatManager alloc] init];
});
return weChatPayInstance;
}
+ (BOOL)handleOpenUrl:(NSURL *)url {
return [WXApi handleOpenURL:url delegate:[WechatManager shareInstance]];
}
+ (void)hangleWechatPayWith:(PayReq *)req {
[WXApi sendReq:req completion:^(BOOL success) {
if (success) {
NSLog(@"微信支付成功");
} else {
NSLog(@"微信支付异常");
}
}];
}
#pragma mark - 微信支付回调
- (void)onResp:(BaseResp *)resp {
if ([resp isKindOfClass:[PayResp class]]) {
/*
enum WXErrCode {
WXSuccess = 0, < 成功
WXErrCodeCommon = -1, < 普通错误类型
WXErrCodeUserCancel = -2, < 用户点击取消并返回
WXErrCodeSentFail = -3, < 发送失败
WXErrCodeAuthDeny = -4, < 授权失败
WXErrCodeUnsupport = -5, < 微信不支持
};
*/
PayResp *response = (PayResp*)resp;
switch (response.errCode) {
case WXSuccess: {
NSLog(@"微信回调支付成功");
[[NSNotificationCenter defaultCenter] postNotificationName:UserNotificationAlipayOrWechatSuccess
object:nil
userInfo:nil];
break;
}
case WXErrCodeCommon: {
NSLog(@"微信回调支付异常");
break;
}
case WXErrCodeUserCancel: {
NSLog(@"微信回调用户取消支付");
break;
}
case WXErrCodeSentFail: {
NSLog(@"微信回调发送支付信息失败");
break;
}
case WXErrCodeAuthDeny: {
NSLog(@"微信回调授权失败");
break;
}
case WXErrCodeUnsupport: {
NSLog(@"微信回调微信版本暂不支持");
break;
}
default: {
break;
}
}
}
}
@end
三、在AppDelegate
里面注册APPKey
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
self.window.backgroundColor = [UIColor whiteColor];
LoginCodeViewController *mainViewController = [[LoginCodeViewController alloc] init];
self.window.rootViewController = [[UINavigationController alloc] initWithRootViewController:mainViewController];
[self.window makeKeyAndVisible];
// 微信支付注册
// WeiXinPayKey:APP在微信开发者网站上申请的Key。WeiXinLinks:微信开发者Universal Link(这个有点麻烦,后面会详细说明,先把集成过程讲完)。
BOOL isSuccess = [WXApi registerApp:WeiXinPayKey universalLink:WeiXinLinks];
if (isSuccess) {
NSLog(@"微信支付API注册成功");
} else {
NSLog(@"微信支付API注册失败");
} return YES;
}
四、补充说明:WeiXinPayKey:APP在微信开发者网站上申请的Key。WeiXinLinks:是微信开发者的Universal Link(通用链接),
- 该链接一般为以
https
开头的公司域名;
- 开发者中心配置,配置App ID支持Associated Domains:
配置开发者中心支持Associated Domains.png
- Xcode工程配置
- 在工程里 -
Capabilities
里面打开Associated Domains
开关,配置内容为以下格式:
applinks:www.baidu.com
- 在工程里 -
Info
里面新建 LSApplicationQueriesSchemes
数组,配置内容为以下格式:
LSApplicationQueriesSchemes.png
- 配置指定文件,这个文件名必须为
apple-app-site-association
,切记没有后缀名,文件内容如下:
{
"applinks": {
"apps": [],
"details": [
{
"appID": "9JA89QQLNQ.com.apple.wwdc",
"paths": [ "/wwdc/news/", "/videos/wwdc/2015/*"]
},
{
"appID": "Xcode项目的Bundle Identifier",
"paths": [ "*" ]
}
]
}
}
- 上传上一步新建的文件到域名根目录下:
- 上传该文件到你的域名所对应的根目录或者.well-known目录下,这是为了苹果能获取到你上传的文件。
五、APPDelegate
处理支付SDK
回调
#pragma mark - 微信支付配置返回 url处理方法
- (BOOL)application:(UIApplication *)app openURL:(NSURL *)url options:(NSDictionary<UIApplicationOpenURLOptionsKey,id> *)options {
if ([url.scheme containsString:WeiXinPayKey]) {
if ([url.absoluteString containsString:[NSString stringWithFormat:@"%@://pay", WeiXinPayKey]]) {
return [WechatManager handleOpenUrl:url];
} else if ([url.absoluteString containsString:[NSString stringWithFormat:@"%@://oauth?", WeiXinPayKey]]) {
return [WechatManager handleOpenUrl:url];
}
}
return YES;
}
- (BOOL)application:(UIApplication *)application continueUserActivity:(NSUserActivity *)userActivity restorationHandler:(void (^)(NSArray<id<UIUserActivityRestoring>> * _Nullable))restorationHandler {
NSURL *continueURL = userActivity.webpageURL;
NSString *relativePath = continueURL.relativePath;
if ([relativePath containsString:WeiXinPayKey] && [relativePath containsString:@"pay"]) {
return [WXApi handleOpenUniversalLink:userActivity delegate:[WechatManager shareInstance]];
} else if ([relativePath containsString:[NSString stringWithFormat:@"%@", WeiXinPayKey]]) {
return [WXApi handleOpenUniversalLink:userActivity delegate:[WechatShareManager shareInstance]];
}
return YES;
}
六、URL-Types
配置,这个schems
就是微信开发者平台注册的APPKey
七、调用支付接口,处理微信支付后处理通知
- 在支付界面控制器,添加通知
- (void)viewDidLoad {
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(ailyPayOrWechatSuccessAction)
name:UserNotificationAlipayOrWechatSuccess
object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(ailyPayOrWechatFailAction)
name:UserNotificationAlipayOrWechatFail
object:nil];
}
- 书写支付结果通知回调方法, 然后对通知的函数进行处理
#pragma mark - 利用通知处理支付结果
// 支付成功
- (void)ailyPayOrWechatSuccessAction {
// 处理支付结果
NSLog(@"处理支付成功结果");
}
// 支付失败
- (void)ailyPayOrWechatFailAction {
NSLog(@"处理支付失败结果");
}
- (void)dealloc {
[[NSNotificationCenter defaultCenter] removeObserver:self];
}
- 创建订单,创建成功后拿到后台返回的信息,然后调用微信支付
#pragma mark - 确认支付
- (void)userBuyGoodsAction {
// @param address_id 地址ID
// @param count 商品数量
// @param refer_id 商品ID
// @param refer_type 商品类型 0课程 1直播
// @param type 支付类型 0微信 1支付宝
// @param coupon_id 优惠券ID
// @param handle 返回签名
int type = self.isWeixinPay ? 0 : 1;
[HttpManager createOrderWithAddressId:self.locationModel.location_id count:@(1) refer_id:self.lessonModel.ID refer_type:@(0) type:@(type) coupon_id:nil andHandle:^(NSString *error, NSDictionary *result) {
if (error == nil) {
NSLog(@"微信支付创建订单回执-%@",result);
NSDictionary *dict = [self jsonToDictionary:result[@"data"][@"data"]];
PayReq *req = [[PayReq alloc] init];
req.nonceStr = [dict objectForKey:@"noncestr"];
req.timeStamp = [[dict objectForKey:@"timestamp"] intValue];
req.package = [dict objectForKey:@"package"];
req.partnerId = [dict objectForKey:@"partnerid"];
req.prepayId = [dict objectForKey:@"prepayid"];
req.sign = [dict objectForKey:@"sign"];
[WechatManager hangleWechatPayWith:req];
} else {
NSLog(@"订单创建失败,失败原因-%@",result);
}
}];
}