This commit is contained in:
2025-11-13 19:20:57 +08:00
parent 50163d02a7
commit ae79d1b1ba
17 changed files with 846 additions and 4 deletions

View File

@@ -0,0 +1,17 @@
//
// IAPVerifyTransactionObj.h
// 将 Swift 内购验签逻辑迁移到 Objective-C
//
#import <Foundation/Foundation.h>
#import <StoreKit/StoreKit.h>
#import "FGIAPVerifyTransaction.h"
NS_ASSUME_NONNULL_BEGIN
@interface IAPVerifyTransactionObj : NSObject <FGIAPVerifyTransaction>
@end
NS_ASSUME_NONNULL_END

View File

@@ -0,0 +1,71 @@
//
// IAPVerifyTransactionObj.m
//
#import "IAPVerifyTransactionObj.h"
#import "PayVM.h"
#import "KBAuthManager.h"
#import "KBHUD.h"
#import "KBLoginSheetViewController.h"
@interface IAPVerifyTransactionObj ()
@property (nonatomic, strong) PayVM *payVM;
@end
@implementation IAPVerifyTransactionObj
- (instancetype)init {
if (self = [super init]) {
_payVM = [PayVM new];
}
return self;
}
#pragma mark - FGIAPVerifyTransaction
- (void)pushSuccessTradeReultToServer:(NSString *)receipt
transaction:(SKPaymentTransaction *)transaction
complete:(FGIAPVerifyTransactionPushCallBack)handler {
if (![self checkLogin]) { return; }
NSLog(@"receipt = %@", receipt);
NSInteger type = 0;
#if DEBUG
type = 0;
#else
type = 1;
#endif
NSDictionary *params = @{ @"payment": @{ @"receipt": receipt ?: @"", @"type": @(type) } };
__weak typeof(self) weakSelf = self;
[self.payVM applePayReqWithParams:params needShow:NO completion:^(NSInteger sta, NSString * _Nullable msg) {
[KBHUD dismiss];
[KBHUD showInfo:(sta == KB_PAY_ERROR_CODE ? @"支付失败" : @"支付成功")];
if (sta == KB_PAY_SUCC_CODE) {
[[SKPaymentQueue defaultQueue] finishTransaction:transaction];
if (handler) handler(@"成功", nil);
} else {
if (handler) handler(@"失败", nil);
}
(void)weakSelf; // keep self during block life if needed
}];
}
#pragma mark - Helpers
- (BOOL)checkLogin {
BOOL loggedIn = [[KBAuthManager shared] isLoggedIn];
if (!loggedIn) {
dispatch_async(dispatch_get_main_queue(), ^{
UIViewController *top = [UIViewController kb_topMostViewController];
if (top) { [KBLoginSheetViewController presentIfNeededFrom:top]; }
});
return NO;
}
return YES;
}
@end

View File

@@ -0,0 +1,33 @@
//
// PayVM.h
// 支付相关 VM封装 Apple IAP 验签请求
//
#import <Foundation/Foundation.h>
NS_ASSUME_NONNULL_BEGIN
/// 统一的支付回调sta 为状态码0 成功,非 0 失败msg 为后端返回的消息
typedef void(^KBPayCompletion)(NSInteger sta, NSString * _Nullable msg);
/// 统一状态码(与原 Swift 代码的 succCode / errorCode 语义一致)
#ifndef KB_PAY_SUCC_CODE
#define KB_PAY_SUCC_CODE 0
#endif
#ifndef KB_PAY_ERROR_CODE
#define KB_PAY_ERROR_CODE 1
#endif
@interface PayVM : NSObject
/// Apple 内购验签
/// params 形如:@{ @"payment": @{ @"receipt": receipt, @"type": @(type) } }
/// needShow是否显示加载 HUD
- (void)applePayReqWithParams:(NSDictionary *)params
needShow:(BOOL)needShow
completion:(KBPayCompletion)completion;
@end
NS_ASSUME_NONNULL_END

View File

@@ -0,0 +1,65 @@
//
// PayVM.m
//
#import "PayVM.h"
#import "KBNetworkManager.h"
#import "KBAPI.h"
#import "KBHUD.h"
@implementation PayVM
- (void)applePayReqWithParams:(NSDictionary *)params
needShow:(BOOL)needShow
completion:(KBPayCompletion)completion {
if (needShow) { [KBHUD show]; }
[[KBNetworkManager shared] POST:KB_API_IAP_VERIFY jsonBody:params headers:nil completion:^(id _Nullable jsonOrData, NSURLResponse * _Nullable response, NSError * _Nullable error) {
if (needShow) { [KBHUD dismiss]; }
if (error) {
if (completion) completion(KB_PAY_ERROR_CODE, error.localizedDescription ?: @"网络错误");
return;
}
NSInteger sta = [self.class extractStatusFromResponseObject:jsonOrData response:response];
NSString *msg = [self.class extractMessageFromResponseObject:jsonOrData] ?: (sta == KB_PAY_SUCC_CODE ? @"OK" : @"失败");
if (completion) completion(sta, msg);
}];
}
#pragma mark - Helpers
+ (NSInteger)extractStatusFromResponseObject:(id)obj response:(NSURLResponse *)resp {
// JSON code/status/success
if ([obj isKindOfClass:NSDictionary.class]) {
NSDictionary *d = (NSDictionary *)obj;
id code = d[@"code"] ?: d[@"status"] ?: d[@"retcode"];
if ([code isKindOfClass:NSNumber.class]) {
return [((NSNumber *)code) integerValue] == 0 ? KB_PAY_SUCC_CODE : KB_PAY_ERROR_CODE;
}
if ([code isKindOfClass:NSString.class]) {
// "0"
return [((NSString *)code) integerValue] == 0 ? KB_PAY_SUCC_CODE : KB_PAY_ERROR_CODE;
}
id success = d[@"success"] ?: d[@"ok"];
if ([success respondsToSelector:@selector(boolValue)]) {
return [success boolValue] ? KB_PAY_SUCC_CODE : KB_PAY_ERROR_CODE;
}
}
// HTTP 2xx
NSInteger http = 0;
if ([resp isKindOfClass:NSHTTPURLResponse.class]) { http = ((NSHTTPURLResponse *)resp).statusCode; }
return (http >= 200 && http < 300) ? KB_PAY_SUCC_CODE : KB_PAY_ERROR_CODE;
}
+ (NSString *)extractMessageFromResponseObject:(id)obj {
if (![obj isKindOfClass:NSDictionary.class]) return nil;
NSDictionary *d = (NSDictionary *)obj;
NSString *msg = d[@"message"] ?: d[@"msg"] ?: d[@"error"];
if (![msg isKindOfClass:NSString.class]) msg = nil;
return msg;
}
@end