phizclip-ios-demo/demo/Common/FINExtensionHelper.m

230 lines
9.5 KiB
Objective-C
Raw Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

//
// FINExtensionHelper.m
// finclip_custom_demo
//
// Created by Haley on 2020/12/3.
//
#import "FINExtensionHelper.h"
#import <FinApplet/FinApplet.h>
#import <WechatOpenSDK/WXApi.h>
#import <CommonCrypto/CommonDigest.h>
#import <CommonCrypto/CommonHMAC.h>
@interface FINExtensionHelper () <WXApiDelegate>
// 支付时,支付的回调是异步的,故这里将小程序的回调持有,在适当的时机调用(用户可根据自己的场景自行实现自己调用的逻辑)
@property (nonatomic, copy) FATExtensionApiCallback callback;
@end
static FINExtensionHelper *instance = nil;
@implementation FINExtensionHelper
+ (instancetype)sharedHelper {
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
instance = [[FINExtensionHelper alloc] init];
});
return instance;
}
+ (instancetype)allocWithZone:(struct _NSZone *)zone {
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
instance = [super allocWithZone:zone];
});
return instance;
}
- (id)copy {
return instance;
}
// 注入自定义api
- (void)registerCustomApis {
[[FATClient sharedClient] registerExtensionApi:@"onNative" handler:^(FATAppletInfo *appletInfo, id param, FATExtensionApiCallback callback) {
NSString *inputText = @"床前明月光,疑是地上霜。举头望明月,低头思故乡。";
callback(FATExtensionCodeSuccess, @{@"text":inputText});
}];
[[FATClient sharedClient] fat_registerWebApi:@"user_define_native" handler:^(FATAppletInfo *appletInfo, id param, FATExtensionApiCallback callback) {
NSString *inputText = @"鹅鹅鹅,曲项向天歌,白毛浮绿水,红掌拨清波。";
callback(FATExtensionCodeSuccess, @{@"text":inputText});
}];
// 注入获取用户信息
[[FATClient sharedClient] registerExtensionApi:@"getUserProfile" handler:^(FATAppletInfo *appletInfo, id param, FATExtensionApiCallback callback) {
NSDictionary *userInfo = @{@"nickName":@"张三",@"avatarUrl":@"",@"gender":@1,@"country":@"中国",@"province":@"广东省",@"city":@"深圳",@"language":@"zh_CN"};
NSDictionary *resDic = @{@"userInfo":userInfo};
callback(FATExtensionCodeSuccess,resDic);
}];
// 注入登录方法
[[FATClient sharedClient] registerExtensionApi:@"login" handler:^(FATAppletInfo *appletInfo, id param, FATExtensionApiCallback callback) {
// 处理小程序登录逻辑后,调用小程序回调
// 登录成功回调示例
NSString *wxid = appletInfo.wechatLoginInfo[@"wechatOriginId"];
NSString *path = appletInfo.wechatLoginInfo[@"profileUrl"];
BOOL canWXLogin = [WXApi isWXAppInstalled] && [wxid length] > 0 && [path length] > 0;
if (canWXLogin) {
self.callback = callback;
WXLaunchMiniProgramReq *req = [WXLaunchMiniProgramReq object];
req.userName = wxid;
req.path = path;
req.miniProgramType = WXMiniProgramTypeRelease;
[WXApi sendReq:req completion:^(BOOL success) {
NSLog(@"打开微信:%d", success);
}];
}
else {
callback(FATExtensionCodeSuccess,@{@"desc":@"登录成功"});
}
}];
// 注入微信支付方法
__weak typeof(self) weakSelf = self;
[[FATClient sharedClient] registerExtensionApi:@"requestPayment" handler:^(FATAppletInfo *appletInfo, id param, FATExtensionApiCallback callback) {
// 支付有两种方式实现:
// 1.利用app实现支付结果通过回调通告小程序
[weakSelf getTestPayment:callback];
// 2.使用微信小程序实现支付
// [weakSelf wechatMiniProgramPayment:appletInfo param:param callback:callback];
}];
}
#pragma mark - WXPay
// 模拟向服务请求支付订单
- (void)getTestPayment:(FATExtensionApiCallback)callback {
// 以下只是示例代码,演示自行实现的过程
// 1.请求自己业务后台的订单信息
// 2.调用app的微信支付功能支付
// 3.返回支付结果给小程序
NSString *urlString = @"https://finclip-testing.finogeeks.club/mop/wechat-auth/api/order";
NSURL *url = [NSURL URLWithString:urlString];
NSMutableURLRequest *requset = [NSMutableURLRequest requestWithURL:url];
requset.HTTPMethod = @"POST";
__weak typeof(self) weakSelf = self;
NSURLSessionTask *task = [[NSURLSession sharedSession] dataTaskWithRequest:requset completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse *)response;
if (httpResponse.statusCode == 200) {
NSString *appId = @"wx85663af68a0cbbc8";
NSString *partnerId = @"1600932850";
NSDictionary *dict = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableLeaves error:nil];
NSString *prepayId = dict[@"data"][@"prepay_id"];
NSString *nonceStr = @"5K8264ILTKCH16CQ2502SI8ZNMTM67VS"; // 随机字符串,这里就不模拟了
UInt32 timeStamp = [[NSDate date] timeIntervalSince1970];
NSString *text = [NSString stringWithFormat:@"%@\n%ld\n%@\n%@\n", appId, (long)timeStamp, nonceStr, prepayId];
NSString *sign = [weakSelf sha256:text];
PayReq *request = [[PayReq alloc] init];
request.partnerId = partnerId;
request.prepayId = prepayId;
request.package = @"Sign=WXPay";
request.nonceStr = nonceStr;
request.timeStamp = timeStamp;
request.sign= sign;
dispatch_async(dispatch_get_main_queue(), ^{
[WXApi sendReq:request completion:^(BOOL success) {
if (success) {
weakSelf.callback = callback;
} else {
callback(FATExtensionCodeFailure, nil);
}
}];
});
return;
}
callback(FATExtensionCodeFailure, nil);
}];
[task resume];
}
- (void)wechatMiniProgramPayment:(FATAppletInfo *)appletInfo
param:(NSDictionary *)param
callback:(FATExtensionApiCallback)callback
{
NSDictionary *info = appletInfo.wechatLoginInfo;
NSString *wxid = appletInfo.wechatLoginInfo[@"wechatOriginId"];
NSString *path = appletInfo.wechatLoginInfo[@"paymentUrl"];
if (wxid.length == 0 || path.length == 0) {
callback(FATExtensionCodeFailure, @{@"desc":@"微信小程序关联信息异常"});
return;
}
NSDictionary *dataDic = param;
NSString *payString = [NSString stringWithFormat:@"?appId=%@&nonceStr=%@&package=%@&paySign=%@&signType=%@&timeStamp=%@&type=%@", dataDic[@"appId"], dataDic[@"nonceStr"], dataDic[@"package"], dataDic[@"paySign"], dataDic[@"signType"], dataDic[@"timeStamp"], dataDic[@"type"]];
// 需要appDelegate 里注册微信开放SDK。
WXLaunchMiniProgramReq *launchMiniProgramReq = [WXLaunchMiniProgramReq object];
launchMiniProgramReq.userName = wxid;
launchMiniProgramReq.path = [NSString stringWithFormat:@"%@%@", wxid, payString];
if (appletInfo.appletVersionType == FATAppletVersionTypeRelease) {
launchMiniProgramReq.miniProgramType = WXMiniProgramTypeRelease; //正式版
} else if (appletInfo.appletVersionType == FATAppletVersionTypeTrial) {
launchMiniProgramReq.miniProgramType = WXMiniProgramTypePreview; //体验版
} else {
launchMiniProgramReq.miniProgramType = WXMiniProgramTypeTest; //开发版
}
[WXApi sendReq:launchMiniProgramReq completion:^(BOOL success) {
NSLog(@"打开微信:%d", success);
if (success) {
callback(FATExtensionCodeSuccess, @{@"desc":@"支付成功"});
return;
}
callback(FATExtensionCodeFailure, @{@"desc":@"支付失败"});
}];
}
// 签名加密(正常是放在后台处理,由上面的请求接口返回
- (NSString *)sha256:(NSString *)shaStr {
NSData *data = [shaStr dataUsingEncoding:NSUTF8StringEncoding];
uint8_t digest[CC_SHA256_DIGEST_LENGTH];
CC_SHA256(data.bytes, (CC_LONG)data.length, digest);
NSData *adata = [[NSData alloc] initWithBytes:digest length:CC_SHA256_DIGEST_LENGTH];
adata = [adata base64EncodedDataWithOptions:0];
NSString *ret = [[NSString alloc] initWithData:adata encoding:NSUTF8StringEncoding];
return ret;
}
#pragma mark - WXApiDelegate
//发起支付请求回调
- (void)onReq:(BaseReq *)req {
}
//微信结果回调
- (void)onResp:(BaseResp *)resp {
FATExtensionCode code = FATExtensionCodeSuccess;
if (resp.errCode != WXSuccess) {
code = FATExtensionCodeFailure;
}
if ([resp isKindOfClass:[PayResp class]]) {//支付
self.callback(code, nil);
}
else if ([resp isKindOfClass:[WXLaunchMiniProgramResp class]]) {//打开小程序
NSString *extMsg = ((WXLaunchMiniProgramResp *)resp).extMsg;
if (extMsg.length <= 0) {
self.callback(FATExtensionCodeFailure, nil);
}
else {
self.callback(code, [self dictionaryWithJsonString:extMsg]);
}
}
}
- (NSDictionary *)dictionaryWithJsonString:(NSString *)jsonString {
if (jsonString == nil) return nil;
NSData *jsonData = [jsonString dataUsingEncoding:NSUTF8StringEncoding];
NSError *err;
NSDictionary *dic = [NSJSONSerialization JSONObjectWithData:jsonData options:NSJSONReadingMutableContainers error:&err];
if(err) {
NSLog(@"json解析失败%@",err);
return nil;
}
return dic;
}
@end