This commit is contained in:
liyuhua
2023-11-22 18:48:21 +08:00
parent 0b57eb3b68
commit f5c4958baa
11 changed files with 472 additions and 10 deletions

View File

@@ -9,6 +9,7 @@
/* Begin PBXBuildFile section */ /* Begin PBXBuildFile section */
23270C292B0E037300B9303B /* MessageConentAudioView.m in Sources */ = {isa = PBXBuildFile; fileRef = 23270C272B0E037300B9303B /* MessageConentAudioView.m */; }; 23270C292B0E037300B9303B /* MessageConentAudioView.m in Sources */ = {isa = PBXBuildFile; fileRef = 23270C272B0E037300B9303B /* MessageConentAudioView.m */; };
23270C2C2B0E041300B9303B /* MessageAudioCenter.m in Sources */ = {isa = PBXBuildFile; fileRef = 23270C2B2B0E041300B9303B /* MessageAudioCenter.m */; }; 23270C2C2B0E041300B9303B /* MessageAudioCenter.m in Sources */ = {isa = PBXBuildFile; fileRef = 23270C2B2B0E041300B9303B /* MessageAudioCenter.m */; };
23270C302B0E071B00B9303B /* MewPaymentAction.swift in Sources */ = {isa = PBXBuildFile; fileRef = 23270C2F2B0E071B00B9303B /* MewPaymentAction.swift */; };
233757562B0CB577001D0B7F /* MessagePresenter.m in Sources */ = {isa = PBXBuildFile; fileRef = 233757262B0CB577001D0B7F /* MessagePresenter.m */; }; 233757562B0CB577001D0B7F /* MessagePresenter.m in Sources */ = {isa = PBXBuildFile; fileRef = 233757262B0CB577001D0B7F /* MessagePresenter.m */; };
233757572B0CB577001D0B7F /* MessageMenuModel.m in Sources */ = {isa = PBXBuildFile; fileRef = 2337572C2B0CB577001D0B7F /* MessageMenuModel.m */; }; 233757572B0CB577001D0B7F /* MessageMenuModel.m in Sources */ = {isa = PBXBuildFile; fileRef = 2337572C2B0CB577001D0B7F /* MessageMenuModel.m */; };
233757582B0CB577001D0B7F /* ChatLimitModel.m in Sources */ = {isa = PBXBuildFile; fileRef = 2337572D2B0CB577001D0B7F /* ChatLimitModel.m */; }; 233757582B0CB577001D0B7F /* ChatLimitModel.m in Sources */ = {isa = PBXBuildFile; fileRef = 2337572D2B0CB577001D0B7F /* ChatLimitModel.m */; };
@@ -197,6 +198,8 @@
23270C282B0E037300B9303B /* MessageConentAudioView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MessageConentAudioView.h; sourceTree = "<group>"; }; 23270C282B0E037300B9303B /* MessageConentAudioView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MessageConentAudioView.h; sourceTree = "<group>"; };
23270C2A2B0E041300B9303B /* MessageAudioCenter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MessageAudioCenter.h; sourceTree = "<group>"; }; 23270C2A2B0E041300B9303B /* MessageAudioCenter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MessageAudioCenter.h; sourceTree = "<group>"; };
23270C2B2B0E041300B9303B /* MessageAudioCenter.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MessageAudioCenter.m; sourceTree = "<group>"; }; 23270C2B2B0E041300B9303B /* MessageAudioCenter.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MessageAudioCenter.m; sourceTree = "<group>"; };
23270C2E2B0E071B00B9303B /* yinmeng-ios-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "yinmeng-ios-Bridging-Header.h"; sourceTree = "<group>"; };
23270C2F2B0E071B00B9303B /* MewPaymentAction.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MewPaymentAction.swift; sourceTree = "<group>"; };
233757262B0CB577001D0B7F /* MessagePresenter.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MessagePresenter.m; sourceTree = "<group>"; }; 233757262B0CB577001D0B7F /* MessagePresenter.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MessagePresenter.m; sourceTree = "<group>"; };
233757272B0CB577001D0B7F /* MessagePresenter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MessagePresenter.h; sourceTree = "<group>"; }; 233757272B0CB577001D0B7F /* MessagePresenter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MessagePresenter.h; sourceTree = "<group>"; };
233757292B0CB577001D0B7F /* MessageProtocol.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MessageProtocol.h; sourceTree = "<group>"; }; 233757292B0CB577001D0B7F /* MessageProtocol.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MessageProtocol.h; sourceTree = "<group>"; };
@@ -599,6 +602,16 @@
/* End PBXFrameworksBuildPhase section */ /* End PBXFrameworksBuildPhase section */
/* Begin PBXGroup section */ /* Begin PBXGroup section */
23270C2D2B0E06F700B9303B /* MewIAP */ = {
isa = PBXGroup;
children = (
23270C2F2B0E071B00B9303B /* MewPaymentAction.swift */,
23270C2E2B0E071B00B9303B /* yinmeng-ios-Bridging-Header.h */,
);
name = MewIAP;
path = "yinmeng-ios/Base/MewIAP";
sourceTree = SOURCE_ROOT;
};
233757242B0CB577001D0B7F /* Message */ = { 233757242B0CB577001D0B7F /* Message */ = {
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
@@ -1749,6 +1762,7 @@
8C9C83C12B0C697A00A601BC /* Mew */ = { 8C9C83C12B0C697A00A601BC /* Mew */ = {
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
23270C2D2B0E06F700B9303B /* MewIAP */,
8C9C83C22B0C697A00A601BC /* Home */, 8C9C83C22B0C697A00A601BC /* Home */,
8C9C83E62B0C697A00A601BC /* Room */, 8C9C83E62B0C697A00A601BC /* Room */,
8C9C83FA2B0C697A00A601BC /* Party */, 8C9C83FA2B0C697A00A601BC /* Party */,
@@ -2157,6 +2171,7 @@
TargetAttributes = { TargetAttributes = {
8C4D534B2AFD4CF600238AE6 = { 8C4D534B2AFD4CF600238AE6 = {
CreatedOnToolsVersion = 14.0; CreatedOnToolsVersion = 14.0;
LastSwiftMigration = 1500;
}; };
}; };
}; };
@@ -2357,6 +2372,7 @@
8C9C845D2B0C697A00A601BC /* MewHomePresenter.m in Sources */, 8C9C845D2B0C697A00A601BC /* MewHomePresenter.m in Sources */,
2337575A2B0CB577001D0B7F /* UITableView+NIMScrollToBottom.m in Sources */, 2337575A2B0CB577001D0B7F /* UITableView+NIMScrollToBottom.m in Sources */,
8C9C84252B0C697A00A601BC /* YMMessageInfoModel.m in Sources */, 8C9C84252B0C697A00A601BC /* YMMessageInfoModel.m in Sources */,
23270C302B0E071B00B9303B /* MewPaymentAction.swift in Sources */,
8C9C82D12B0C695600A601BC /* RechargeStorage.m in Sources */, 8C9C82D12B0C695600A601BC /* RechargeStorage.m in Sources */,
8C9C84792B0C697A00A601BC /* MewLoginNumberViewController.m in Sources */, 8C9C84792B0C697A00A601BC /* MewLoginNumberViewController.m in Sources */,
8C9C841D2B0C697A00A601BC /* ThemeColor+Room.m in Sources */, 8C9C841D2B0C697A00A601BC /* ThemeColor+Room.m in Sources */,
@@ -2571,6 +2587,7 @@
buildSettings = { buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
CLANG_ENABLE_MODULES = YES;
CODE_SIGN_ENTITLEMENTS = "yinmeng-ios/yinmeng-ios.entitlements"; CODE_SIGN_ENTITLEMENTS = "yinmeng-ios/yinmeng-ios.entitlements";
CODE_SIGN_STYLE = Automatic; CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 1; CURRENT_PROJECT_VERSION = 1;
@@ -2597,6 +2614,9 @@
SUPPORTS_MACCATALYST = NO; SUPPORTS_MACCATALYST = NO;
SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = NO; SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = NO;
SWIFT_EMIT_LOC_STRINGS = YES; SWIFT_EMIT_LOC_STRINGS = YES;
SWIFT_OBJC_BRIDGING_HEADER = "yinmeng-ios/Base/MewIAP/yinmeng-ios-Bridging-Header.h";
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
SWIFT_VERSION = 5.0;
TARGETED_DEVICE_FAMILY = 1; TARGETED_DEVICE_FAMILY = 1;
}; };
name = Debug; name = Debug;
@@ -2607,6 +2627,7 @@
buildSettings = { buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
CLANG_ENABLE_MODULES = YES;
CODE_SIGN_ENTITLEMENTS = "yinmeng-ios/yinmeng-ios.entitlements"; CODE_SIGN_ENTITLEMENTS = "yinmeng-ios/yinmeng-ios.entitlements";
CODE_SIGN_STYLE = Automatic; CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 1; CURRENT_PROJECT_VERSION = 1;
@@ -2633,6 +2654,8 @@
SUPPORTS_MACCATALYST = NO; SUPPORTS_MACCATALYST = NO;
SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = NO; SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = NO;
SWIFT_EMIT_LOC_STRINGS = YES; SWIFT_EMIT_LOC_STRINGS = YES;
SWIFT_OBJC_BRIDGING_HEADER = "yinmeng-ios/Base/MewIAP/yinmeng-ios-Bridging-Header.h";
SWIFT_VERSION = 5.0;
TARGETED_DEVICE_FAMILY = 1; TARGETED_DEVICE_FAMILY = 1;
}; };
name = Release; name = Release;

View File

@@ -0,0 +1,264 @@
//
// MewPaymentAction.swift
// yinmeng-ios
//
// Created by duoban on 2023/11/22.
//
import UIKit
import StoreKit
@available(iOS 15.0, *)
typealias MewTransaction = StoreKit.Transaction
@available(iOS 15.0, *)
typealias MewRenewalInfo = StoreKit.Product.SubscriptionInfo.RenewalInfo
@available(iOS 15.0, *)
typealias MewRenewalState = StoreKit.Product.SubscriptionInfo.RenewalState
enum MewStoreError: Error {
//
case MewFailedVerification
case MewNoProduct
}
@objc public enum MewStoreConditionResult: Int64 { //
case MewStart //
case MewPay //
case MewVerifiedServer //
case MewUserCancelled //
case MewPending //
case MewUnowned
case MewNoProduct //
case MewFailedVerification //
}
@available(iOS 15.0, *)
public class MewPaymentAction: NSObject {
public typealias Mew_KConditionBlock = (_ state :MewStoreConditionResult,_ param:Dictionary<String,Any>?) ->()
@objc public var Mew_ConditionBlock: Mew_KConditionBlock! //
var Mew_updateListenerTask: Task<Void, Error>? = nil //
var Mew_transactionMap :[String:Transaction] // Idmap
var Mew_name: String = "Mew_iosStore" //
@objc public static let shared = {
let instance = MewPaymentAction()
return instance
}()
private override init() { // private
Mew_transactionMap = [:] //
super.init()
Task {
Mew_updateListenerTask = Mew_listenForTransactions()
}
}
// 退
@objc public func Mew_refunRequest(view: UIView,transactionId:UInt64) async{
do {
if let scene = await view.window?.windowScene{
try await Transaction.beginRefundRequest(for:transactionId , in: scene)
}
}catch{
print("iap error")
}
}
//
@objc public func Mew_demandCommodityThing(productId:String, uuid: String) async throws {
if(Mew_ConditionBlock != nil ){
Mew_ConditionBlock(MewStoreConditionResult.MewStart,nil)
}
do {
let list:[String] = [productId]
let storeProducts = try await Product.products(for: Set.init(list))
if storeProducts.count > 0 {
try await Mew_purchase(storeProducts[0],uuid)
}else {
print("iap: no found product")
if(Mew_ConditionBlock != nil ){
Mew_ConditionBlock(MewStoreConditionResult.MewNoProduct,nil)
}
throw MewStoreError.MewNoProduct //
}
} catch {
print("Failed product request from the App Store server: \(error)")
if(Mew_ConditionBlock != nil ){
Mew_ConditionBlock(MewStoreConditionResult.MewNoProduct,nil)
}
throw MewStoreError.MewNoProduct //
}
}
//
private func Mew_purchase(_ product: Product, _ uuid: String) async throws -> Transaction? {
if(Mew_ConditionBlock != nil ){
Mew_ConditionBlock(MewStoreConditionResult.MewPay,nil)
}
guard let curUUID = UUID.init(uuidString: uuid) else{
if(Mew_ConditionBlock != nil ){
Mew_ConditionBlock(MewStoreConditionResult.MewFailedVerification,nil)
}
return nil
}
let getUUID = Product.PurchaseOption.appAccountToken(curUUID)
let result = try await product.purchase(options: [getUUID])
switch result {
case .success(let verification): //
let transaction = try await Mew_verifiedAndAccomplish(verification)
return transaction
case .userCancelled: //
if(Mew_ConditionBlock != nil ){
Mew_ConditionBlock(MewStoreConditionResult.MewUserCancelled,nil)
}
return nil
case .pending: //
if(Mew_ConditionBlock != nil ){
Mew_ConditionBlock(MewStoreConditionResult.MewPending,nil)
}
return nil
default:
if(Mew_ConditionBlock != nil ){
Mew_ConditionBlock(MewStoreConditionResult.MewUnowned,nil)
}
return nil
}
}
//
func Mew_checkVerified<T>(_ result: VerificationResult<T>) throws -> T {
//Check whether the JWS passes StoreKit verification.
switch result {
case .unverified:
//StoreKit parses the JWS, but it fails verification.
if(Mew_ConditionBlock != nil ){
Mew_ConditionBlock(MewStoreConditionResult.MewFailedVerification,nil)
}
throw MewStoreError.MewFailedVerification
case .verified(let safe):
//The result is verified. Return the unwrapped value.
print("iap: verified success")
return safe
}
}
// &
func Mew_verifiedAndAccomplish(_ verification:VerificationResult<Transaction>) async throws -> Transaction?{
//Check whether the transaction is verified. If it isn't,
//this function rethrows the verification error.
let transaction = try Mew_checkVerified(verification)
// ~~~
let transactionId = try verification.payloadValue.id
// map
let key = String(transactionId)
Mew_transactionMap[key] = transaction
await Mew_uploadServer(for: transactionId)
//
await transaction.finish()
print("iap: finish")
return transaction
}
/*All transactions
Latest transactions
Current entitlements
*/
func Mew_getAllBusiness(transactionId:String) async {
let transactionIntId = UInt64(transactionId)
for await result in Transaction.all {
do {
let tran = try Mew_checkVerified(result)
let resultId = try result.payloadValue.id
if transactionIntId == resultId {
await tran.finish()
break
}
} catch let error {
print("error:----\(error)")
}
}
//Transaction.latest(for: "pid")
}
//
@objc public func Mew_verifyBusinessAccomplish(transaction:String) async{
if(Mew_transactionMap[transaction] != nil){
await Mew_transactionMap[transaction]!.finish()
Mew_transactionMap.removeValue(forKey: transaction)
print("verifyBusinessFinish end")
}else {
await Mew_getAllBusiness(transactionId: transaction)
}
}
@MainActor
func Mew_uploadServer(for transactionId:UInt64) async {
let dic :Dictionary<String,Any> = ["transactionId":transactionId]
if(Mew_ConditionBlock != nil ){
Mew_ConditionBlock(MewStoreConditionResult.MewVerifiedServer,dic)
}
}
//
func Mew_listenForTransactions() -> Task<Void, Error> {
return Task.detached {
//Iterate through any transactions that don't come from a direct call to `purchase()`.
// update unfinished?
for await result in Transaction.updates { //
do {
print("iap: updates")
print("result:\(result)")
try await self.Mew_verifiedAndAccomplish(result)
} catch {
//StoreKit has a transaction that fails verification. Don't deliver content to the user.
print("Transaction failed verification")
}
}
}
}
//广
func Mew_Promotion() async -> [SKProduct]?{
let promotion = SKProductStorePromotionController()
let prodicts = try? await promotion.promotionOrder()
return prodicts
}
//
deinit {
Mew_updateListenerTask?.cancel()
}
}

View File

@@ -0,0 +1,4 @@
//
// Use this file to import your target's public headers that you would like to expose to Swift.
//

View File

@@ -17,7 +17,7 @@ typedef NS_ENUM(NSInteger ,PaymentStatus) {
}; };
@protocol YMIAPHelperDelegate <NSObject> @protocol YMIAPHelperDelegate <NSObject>
@optional
///当前充值的状态 ///当前充值的状态
- (void)rechargeProcessStatus:(PaymentStatus)status; - (void)rechargeProcessStatus:(PaymentStatus)status;

View File

@@ -18,7 +18,8 @@
#import "YMMineSettingViewController.h" #import "YMMineSettingViewController.h"
#import "MewMineCollectionViewController.h" #import "MewMineCollectionViewController.h"
#import "MewRechargeViewController.h" #import "MewRechargeViewController.h"
#import "SessionViewController.h"
#import <NIMSDK/NIMSDK.h>
/// Tool /// Tool
#import "YMMacro.h" #import "YMMacro.h"
#import "ThemeColor.h" #import "ThemeColor.h"
@@ -238,7 +239,9 @@
/// optionType: 0 - 1 - 2- /// optionType: 0 - 1 - 2-
- (void)userIntrodctionViewWithUserOption:(NSInteger)optionType { - (void)userIntrodctionViewWithUserOption:(NSInteger)optionType {
if (optionType == 2) { // if (optionType == 2) { //
NIMSession *session = [NIMSession session:self.targetUid type:NIMSessionTypeP2P];
SessionViewController *vc = [[SessionViewController alloc] initWithSession:session];
[self.navigationController pushViewController:vc animated:YES];
} else { } else {
[self.presenter attentionUser:self.targetUid state:optionType == 1]; [self.presenter attentionUser:self.targetUid state:optionType == 1];
} }

View File

@@ -12,10 +12,13 @@
#import <Masonry/Masonry.h> #import <Masonry/Masonry.h>
#import "YMMacro.h" #import "YMMacro.h"
#import "YMIAPHelper.h" #import "YMIAPHelper.h"
#import "AccountInfoStorage.h"
/// P /// P
#import "MineRechargeProtocol.h" #import "MineRechargeProtocol.h"
#import "MineRechargePresenter.h" #import "MineRechargePresenter.h"
#import "YMHUDTool.h"
#import "yinmeng_ios-Swift.h"
#import "RechargeStorage.h"
@interface MewRechargeViewController ()<MineRechargeProtocol, MewRechargeSubViewDelegate, YMIAPHelperDelegate> @interface MewRechargeViewController ()<MineRechargeProtocol, MewRechargeSubViewDelegate, YMIAPHelperDelegate>
@property (nonatomic, strong) UIImageView *rechargeBgImageView; @property (nonatomic, strong) UIImageView *rechargeBgImageView;
@property (nonatomic, strong) UIButton *backButton; @property (nonatomic, strong) UIButton *backButton;
@@ -65,16 +68,141 @@
self.rechageView.rechargeModels = list; self.rechageView.rechargeModels = list;
} }
- (void)requestIAPRechargeOrderSuccess:(NSString *)orderId chargeProdId:(NSString *)chargeProdId { - (void)requestIAPRechargeOrderSuccess:(NSString *)orderId chargeProdId:(NSString *)chargeProdId uuid:(nonnull NSString *)uuid{
if (orderId.length > 0) { if (orderId.length > 0) {
self.orderId = orderId;
self.orderId = orderId;
if (@available(iOS 15.0, *)) {
MewPaymentAction *iap = [MewPaymentAction shared];
[iap Mew_demandCommodityThingWithProductId:chargeProdId uuid:uuid completionHandler:^(NSError * _Nullable error) {
}];
@kWeakify(self);
iap.Mew_ConditionBlock = ^(enum MewStoreConditionResult state, NSDictionary<NSString *,id> * _Nullable result) {
@kStrongify(self);
[self rechargeNewProcessStatus:state];
switch (state) {
case MewStoreConditionResultMewVerifiedServer:
{
NSString *transactionId = result[@"transactionId"];
[self rechargeSuccess:transactionId];
}
break;
default:
{
}
break;
}
};
//
} else {
[YMHUDTool hideHUDInView:kWindow];
[self showErrorToast:@"充值失败。当前仅支持运行iOS15及以上系统的手机进行充值请升级系统版本后重试。"];
}
}else{
[YMHUDTool hideHUDInView:kWindow];
} }
} }
///
- (void)rechargeNewProcessStatus:(MewStoreConditionResult)status {
if (status == MewStoreConditionResultMewPay || status == MewStoreConditionResultMewStart || status == MewStoreConditionResultMewVerifiedServer) {
}else if (status == MewStoreConditionResultMewUnowned) {
[YMHUDTool hideHUDInView:kWindow];
[self showErrorToast:@"出现未知错误,请重新尝试"];
}else{
[YMHUDTool hideHUDInView:kWindow];
[self showErrorToast:@"购买失败"];
}
}
///id
- (void)rechargeSuccess:(NSString *)transactionIdentifier {
///
[self saveRechageReciptWithTransactionIdentifier:transactionIdentifier];
///
[self.presenter checkReceiptWithOrderId:self.orderId transcationId:transactionIdentifier errorToast:YES];
}
///
- (void)checkReceiptSuccess:(NSString *)transcationId {
[YMHUDTool hideHUDInView:kWindow];
if (@available(iOS 15.0, *)) {
MewPaymentAction *iap = [MewPaymentAction shared];
[iap Mew_verifyBusinessAccomplishWithTransaction:[NSString stringWithFormat:@"%@",transcationId] completionHandler:^{
}];
}
[self deleteRechageReciptWithTransactionIdentifier:transcationId];
self.orderId = nil;
//5
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(5.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
///
[self.presenter getUserWalletInfo];
});
}
///
- (void)checkReceiptFailWithCode:(NSInteger)code transcationId:(NSString *)transcationId{
[YMHUDTool hideHUDInView:kWindow];
if(code == 1444){
if (@available(iOS 15.0, *)) {
MewPaymentAction *iap = [MewPaymentAction shared];
[iap Mew_verifyBusinessAccomplishWithTransaction:[NSString stringWithFormat:@"%@",transcationId] completionHandler:^{
}];
}
[self deleteRechageReciptWithTransactionIdentifier:transcationId];
}
}
///
- (void)deleteRechageReciptWithTransactionIdentifier:(NSString *)transactionIdentifier {
NSString * uid = [AccountInfoStorage instance].getUid;
BOOL deleteSuccess = [RechargeStorage delegateTranscationId:transactionIdentifier uid:uid];
if (deleteSuccess) {
#warning to do
}
}
///
- (void)saveRechageReciptWithTransactionIdentifier:(NSString *)transactionIdentifier {
NSData *receipt = [NSData dataWithContentsOfURL:[[NSBundle mainBundle] appStoreReceiptURL]];
NSString *encodeStr = [receipt base64EncodedStringWithOptions:NSDataBase64EncodingEndLineWithLineFeed];
NSMutableDictionary *dictionary = [NSMutableDictionary dictionary];
if(transactionIdentifier != nil){
[dictionary setObject:transactionIdentifier forKey:@"transcationId"];
}
if(encodeStr != nil){
[dictionary setObject:encodeStr forKey:@"recipt"];
}
if(self.orderId != nil){
[dictionary setObject:self.orderId forKey:@"orderId"];
}
if(dictionary.allKeys.count == 0)return;
NSString *reciptJson = [dictionary toJSONString];
NSString * uid = [AccountInfoStorage instance].getUid;
BOOL saveSuccess = [RechargeStorage saveTranscationId:transactionIdentifier recipt:reciptJson uid:uid];
if (!saveSuccess) {
#warning to do
}
}
#pragma mark - MewRechargeSubViewDelegate #pragma mark - MewRechargeSubViewDelegate
- (void)didSelectMewRechargeChargeProdId:(NSString *)chargeProdId { - (void)didSelectMewRechargeChargeProdId:(NSString *)chargeProdId {
[YMHUDTool showLoadingInView:kWindow];
[self.presenter requestIAPRechargeOrderWithChargeProdId:chargeProdId]; [self.presenter requestIAPRechargeOrderWithChargeProdId:chargeProdId];
} }

View File

@@ -88,6 +88,14 @@ NS_ASSUME_NONNULL_BEGIN
transcationId:(NSString *)transcationId transcationId:(NSString *)transcationId
uid:(NSString *)uid uid:(NSString *)uid
ticket:(NSString *)ticket; ticket:(NSString *)ticket;
/// 验证凭据
/// @param completion 完成
/// @param chooseEnv @"true"
/// @param chargeRecordId 服务端生成的订单编号
/// @param transcationId 内购的唯一标识符
/// @param uid 用户uid
/// @param ticket ticket
+ (void)checkReceipt:(HttpRequestHelperCompletion)completion chooseEnv:(NSString *)chooseEnv chargeRecordId:(NSString *)chargeRecordId transcationId:(NSString *)transcationId uid:(NSString *)uid ticket:(NSString *)ticket;
@end @end
NS_ASSUME_NONNULL_END NS_ASSUME_NONNULL_END

View File

@@ -81,7 +81,7 @@
/// @param deviceInfo uuid /// @param deviceInfo uuid
/// @param clientIp ip /// @param clientIp ip
+ (void)requestIAPRecharge:(HttpRequestHelperCompletion)completion chargeProdId:(NSString *)chargeProdId uid:(NSString *)uid ticket:(NSString *)ticket deviceInfo:(NSString *)deviceInfo clientIp:(NSString *)clientIp { + (void)requestIAPRecharge:(HttpRequestHelperCompletion)completion chargeProdId:(NSString *)chargeProdId uid:(NSString *)uid ticket:(NSString *)ticket deviceInfo:(NSString *)deviceInfo clientIp:(NSString *)clientIp {
[self makeRequest:@"order/placeV2" method:HttpRequestHelperMethodPOST completion:completion, __FUNCTION__,chargeProdId, uid, ticket, deviceInfo, clientIp, nil]; [self makeRequest:[NSString stringWithFormat:@"%@/%@",@"storeKitV2",@"placeOrder"] method:HttpRequestHelperMethodPOST completion:completion, __FUNCTION__,chargeProdId, uid, ticket, deviceInfo, clientIp, nil];
} }
@@ -96,5 +96,15 @@
+ (void)checkReceipt:(HttpRequestHelperCompletion)completion receipt:(NSString *)receipt chooseEnv:(NSString *)chooseEnv chargeRecordId:(NSString *)chargeRecordId transcationId:(NSString *)transcationId uid:(NSString *)uid ticket:(NSString *)ticket { + (void)checkReceipt:(HttpRequestHelperCompletion)completion receipt:(NSString *)receipt chooseEnv:(NSString *)chooseEnv chargeRecordId:(NSString *)chargeRecordId transcationId:(NSString *)transcationId uid:(NSString *)uid ticket:(NSString *)ticket {
[self makeRequest:@"verify/setiap" method:HttpRequestHelperMethodPOST completion:completion, __FUNCTION__,receipt, chooseEnv, chargeRecordId, transcationId, uid, ticket, nil]; [self makeRequest:@"verify/setiap" method:HttpRequestHelperMethodPOST completion:completion, __FUNCTION__,receipt, chooseEnv, chargeRecordId, transcationId, uid, ticket, nil];
} }
///
/// @param completion
/// @param chooseEnv @"true"
/// @param chargeRecordId
/// @param transcationId
/// @param uid uid
/// @param ticket ticket
+ (void)checkReceipt:(HttpRequestHelperCompletion)completion chooseEnv:(NSString *)chooseEnv chargeRecordId:(NSString *)chargeRecordId transcationId:(NSString *)transcationId uid:(NSString *)uid ticket:(NSString *)ticket {
[self makeRequest:[NSString stringWithFormat:@"%@/%@",@"storeKitV2",@"verifyOrder"] method:HttpRequestHelperMethodPOST completion:completion, __FUNCTION__, chooseEnv, chargeRecordId, transcationId, uid, ticket, nil];
}
@end @end

View File

@@ -30,7 +30,10 @@ NS_ASSUME_NONNULL_BEGIN
/// 批量验证内购掉单 /// 批量验证内购掉单
/// @param transcations 凭据的数组 /// @param transcations 凭据的数组
- (void)checkTranscationIds:(NSArray *)transcations; - (void)checkTranscationIds:(NSArray *)transcations;
/// 充值成功二次验证
/// @param orderId 订单编号
/// @param transcationId 商品id
- (void)checkReceiptWithOrderId:(NSString *)orderId transcationId:(NSString *)transcationId errorToast:(BOOL)errorToast;
@end @end
NS_ASSUME_NONNULL_END NS_ASSUME_NONNULL_END

View File

@@ -48,12 +48,28 @@
NSString * clientIp= [YYUtility ipAddress]; NSString * clientIp= [YYUtility ipAddress];
[Api requestIAPRecharge:[self createHttpCompletion:^(BaseModel * _Nonnull data) { [Api requestIAPRecharge:[self createHttpCompletion:^(BaseModel * _Nonnull data) {
NSString *orderId = (NSString *)data.data[@"recordId"]; NSString *orderId = (NSString *)data.data[@"recordId"];
[[self getView] requestIAPRechargeOrderSuccess:orderId chargeProdId:chargeProdId]; NSString *mew_uuid = (NSString *)data.data[@"appAccountToken"];
[[self getView] requestIAPRechargeOrderSuccess:orderId chargeProdId:chargeProdId uuid:mew_uuid];
} fail:^(NSInteger code, NSString * _Nullable msg) { } fail:^(NSInteger code, NSString * _Nullable msg) {
if(code != 50000){
[[self getView]showErrorToast:msg];
}
[[self getView] requestIAPRechargeOrderFail]; [[self getView] requestIAPRechargeOrderFail];
}] chargeProdId:chargeProdId uid:uid ticket:ticket deviceInfo:deviceInfo clientIp:clientIp]; }] chargeProdId:chargeProdId uid:uid ticket:ticket deviceInfo:deviceInfo clientIp:clientIp];
} }
///
/// @param orderId
/// @param transcationId id
- (void)checkReceiptWithOrderId:(NSString *)orderId transcationId:(NSString *)transcationId errorToast:(BOOL)errorToast{
NSString * uid = [AccountInfoStorage instance].getUid;
NSString * ticket = [AccountInfoStorage instance].getTicket;
[Api checkReceipt:[self createHttpCompletion:^(BaseModel * _Nonnull data) {
[[self getView] checkReceiptSuccess:transcationId];
}fail:^(NSInteger code, NSString * _Nullable msg) {
[[self getView]checkReceiptFailWithCode:code transcationId:transcationId];
} showLoading:NO errorToast:errorToast] chooseEnv:@"true" chargeRecordId:orderId transcationId:transcationId uid:uid ticket:ticket];
}
/// ///
/// @param receipt /// @param receipt

View File

@@ -10,18 +10,21 @@
NS_ASSUME_NONNULL_BEGIN NS_ASSUME_NONNULL_BEGIN
@protocol MineRechargeProtocol <NSObject> @protocol MineRechargeProtocol <NSObject>
@optional
///请求钱包余额信息 ///请求钱包余额信息
- (void)getUserWalletInfo:(WalletInfoModel *)balanceInfo; - (void)getUserWalletInfo:(WalletInfoModel *)balanceInfo;
///请求充值列表成功 ///请求充值列表成功
- (void)requestRechargeListSucccess:(NSArray *)list; - (void)requestRechargeListSucccess:(NSArray *)list;
///请求充值id的状态成功 ///请求充值id的状态成功
- (void)requestIAPRechargeOrderSuccess:(NSString *)orderId chargeProdId:(NSString *)chargeProdId; - (void)requestIAPRechargeOrderSuccess:(NSString *)orderId chargeProdId:(NSString *)chargeProdId uuid:(NSString *)uuid;
///请求充值账单失败 ///请求充值账单失败
- (void)requestIAPRechargeOrderFail; - (void)requestIAPRechargeOrderFail;
///二次校验成功 ///二次校验成功
- (void)checkReceiptSuccess:(NSString *)transcationId; - (void)checkReceiptSuccess:(NSString *)transcationId;
///批量验证凭据成功 ///批量验证凭据成功
- (void)checkTranscationIdsSuccess; - (void)checkTranscationIdsSuccess;
///二次校验失败
- (void)checkReceiptFailWithCode:(NSInteger)code transcationId:(NSString *)transcationId;
@end @end
NS_ASSUME_NONNULL_END NS_ASSUME_NONNULL_END