内购


#import <Foundation/Foundation.h>

NS_ASSUME_NONNULL_BEGIN

//typedef NS_ENUM(NSUInteger, APTYPE) {
//    AP_WECHAT,
//    AP_ALIPAY,
//};


//@protocol APDelegate <NSObject>
//-(void)APSuccess:(APTYPE)type;
//-(void)APFail:(APTYPE)type;
//@end


static NSString * const USERDEFAULT_KEY = @"transaction";

typedef enum : NSUInteger {
    VTPaymentTransactionStateNoPaymentPermission,//没有Payment权限
    VTPaymentTransactionStateAddPaymentFailed,//addPayment失败
    VTPaymentTransactionStatePurchasing,//正在购买
    VTPaymentTransactionStatePurchased,//购买完成(销毁交易)
    VTPaymentTransactionStateFailed,//购买失败(销毁交易)
    VTPaymentTransactionStateCancel,//用户取消
    VTPaymentTransactionStateRestored,//恢复购买(销毁交易)
    VTPaymentTransactionStateDeferred,//最终状态未确定
} VTPaymentTransactionState;

@class SKPaymentTransaction;

@protocol VTInAppPurchasingDelegate <NSObject>

@required
- (BOOL)isProductIdentifierAvailable:(NSString*)productIdentifier;
@optional
- (void)updatedTransactions:(VTPaymentTransactionState)state;
//购买成功
- (void)buySuccess;
//购买失败
- (void)buyFailed:(NSString*)errorInfo;

@end



@interface APManager : NSObject

+(instancetype) shared;

@property(nonatomic,weak) id<VTInAppPurchasingDelegate> delegate;
- (void)identifyCanMakePayments:(NSArray*)requestArray;
//-(void)handleOpenURL:(NSURL *)url;
//-(void)sendOrder:(APTYPE)type Order:(NSDictionary *)order;

@end

NS_ASSUME_NONNULL_END
#import "APManager.h"
#import <StoreKit/StoreKit.h>
//#import "WXApi.h"
//#import <AlipaySDK/AlipaySDK.h>

//#define WECHAT @"pay"
//#define WECHATSCHEME @""
//#define ALIPAY @"safepay"
//#define ALIPAYSCHEME @"alipay"
//#define WX_AppID @""


#define ITMS_VERIFY_RECEIPT_URL   @"https://sandbox.itunes.apple.com/verifyReceipt"
//@"https://buy.itunes.apple.com/verifyReceipt"

#define isServiceVerify 0

@interface APManager ()<SKPaymentTransactionObserver,SKProductsRequestDelegate/*WXApiDelegate*/>
@property (nonatomic, strong) SKProductsRequest *request;
@end

@implementation APManager


+(instancetype) shared{
    static APManager *_singleInstance;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        _singleInstance = [[APManager alloc]init];
    });
    
    return _singleInstance;
}


-(instancetype)init{
    if (self = [super init]) {
        
         [[SKPaymentQueue defaultQueue] addTransactionObserver:self];
    //微信支付
//        [WXApi registerApp:WX_AppID];
    }
    return self;
}


- (void)identifyCanMakePayments:(NSArray*)requestArray{
    if (requestArray.count == 0) {
        if (self.delegate && [self.delegate respondsToSelector:@selector(updatedTransactions:)]) {
            [self.delegate updatedTransactions:VTPaymentTransactionStateAddPaymentFailed];
        }
        return;
    }
    
    if ([SKPaymentQueue canMakePayments]) {
        [self releaseRequest];
        self.request = [[SKProductsRequest alloc]initWithProductIdentifiers:[NSSet setWithArray:requestArray]];
        self.request.delegate = self;
        [self.request start];
    }else{
        if (self.delegate && [self.delegate respondsToSelector:@selector(updatedTransactions:)]) {
            [self.delegate updatedTransactions:VTPaymentTransactionStateNoPaymentPermission];
        }
    }
    
}




- (void)releaseRequest{
    if(_request) {
        [_request cancel];
        _request.delegate=nil;
        _request=nil;
    }
}

-(void)dealloc{
    [self releaseRequest];
    [[SKPaymentQueue defaultQueue] removeTransactionObserver:self];
}


#pragma mark ------------ SKProductsRequestDelegate

- (void)productsRequest:(SKProductsRequest*)request didReceiveResponse:(SKProductsResponse*)response{
    NSArray * myProducts = response.products;
    for(SKProduct*product in myProducts){
        NSLog(@"SKProduct 描述信息%@", [product description]);
        NSLog(@"产品标题 %@", product.localizedTitle);
        NSLog(@"产品描述信息: %@" , product.localizedDescription);
        NSLog(@"价格: %@", product.price);
        NSLog(@"Product id: %@" , product.productIdentifier);
        
        
        
        if (self.delegate && [self.delegate respondsToSelector:@selector(isProductIdentifierAvailable:)]) {
            if ([self.delegate isProductIdentifierAvailable:product.productIdentifier]) {
                SKPayment *payment = [SKPayment paymentWithProduct:product];
                [[SKPaymentQueue defaultQueue] addPayment:payment];
                return;
            }
        }
    }
    
    if (self.delegate && [self.delegate respondsToSelector:@selector(updatedTransactions:)]) {
        [self.delegate updatedTransactions:VTPaymentTransactionStateAddPaymentFailed];
    }
   
}

- (void)request:(SKRequest *)request didFailWithError:(NSError *)error{
    NSLog(@"-------弹出错误信息----------");
    
}

#pragma mark -------- SKPaymentTransactionObserver


-(void)paymentQueue:(SKPaymentQueue *)queue updatedTransactions:(NSArray<SKPaymentTransaction *> *)transactions{
    
    for (SKPaymentTransaction *transaction in transactions) {
        VTPaymentTransactionState state;
        switch (transaction.transactionState) {
            case SKPaymentTransactionStatePurchasing:
                
                state = VTPaymentTransactionStatePurchasing;
                
                break;
            case SKPaymentTransactionStatePurchased:
                
                //防止漏单
//                [[NSUserDefaults standardUserDefaults] setObject:transaction forKey:USERDEFAULT_KEY];
//                [[NSUserDefaults standardUserDefaults] synchronize];
                
                state = VTPaymentTransactionStatePurchased;
                if (isServiceVerify) {
                    [self completeTransaction:transaction];
                }else{
                    [self verifyPurchase:transaction];
                }
                
                break;
            case SKPaymentTransactionStateFailed:
            {
                if (transaction.error.code!= SKErrorPaymentCancelled) {
                    state = VTPaymentTransactionStateFailed;
                }else{
                    state = VTPaymentTransactionStateCancel;
                }
                [self finshTransaction:transaction];
            }
                break;
            case SKPaymentTransactionStateRestored:
                state = VTPaymentTransactionStateRestored;
                [self finshTransaction:transaction];
                break;
            case SKPaymentTransactionStateDeferred:
                state = VTPaymentTransactionStateDeferred;
                break;
            default:
                break;
        }
        
        
        if (self.delegate && [self.delegate respondsToSelector:@selector(updatedTransactions:)]) {
            [self.delegate updatedTransactions:state];
        }
    }
}

// Sent when an error is encountered while adding transactions from the user's purchase history back to the queue.
- (void)paymentQueue:(SKPaymentQueue*)queue restoreCompletedTransactionsFailedWithError:(NSError*)error
{
    NSLog(@"restoreCompletedTransactionsFailedWithError");
}
// Sent when all transactions from the user's purchase history have successfully been added back to the queue.
- (void)paymentQueueRestoreCompletedTransactionsFinished:(SKPaymentQueue*)queue
{
    NSLog(@"paymentQueueRestoreCompletedTransactionsFinished");
}
// Sent when the download state has changed.
- (void)paymentQueue:(SKPaymentQueue*)queue updatedDownloads:(NSArray *)downloads
{
    NSLog(@"updatedDownloads");
}


- (void)paymentQueue:(SKPaymentQueue*)queue removedTransactions:(NSArray *)transactions
{
    NSLog(@"---removedTransactions");
}


#pragma mark ------ private methods

- (void)completeTransaction:(SKPaymentTransaction*)transaction{
    //服务器校验
    
}

- (void)verifyPurchase:(SKPaymentTransaction*)transaction{
    NSURL *receiptURL = [[NSBundle mainBundle] appStoreReceiptURL];
    NSData*receiptData = [NSData dataWithContentsOfURL:receiptURL];
    NSString *encodeStr = [receiptData base64EncodedStringWithOptions:NSDataBase64EncodingEndLineWithLineFeed];
    NSURL *url = [NSURL URLWithString:ITMS_VERIFY_RECEIPT_URL];
    NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:10.0f];
    
    NSString *payload = [NSString stringWithFormat:@"{\"receipt-data\" : \"%@\"}", encodeStr];
    NSData *payloadData = [payload dataUsingEncoding:NSUTF8StringEncoding];
    [request setHTTPBody:payloadData];
    [request setHTTPMethod:@"POST"];
    NSURLResponse*response = nil;
    // 此请求返回的是一个json结果  将数据反序列化为数据字典
    NSData *data = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:nil];
    if(data ==nil) {
        return;
    }
    NSDictionary *jsonResponse = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingAllowFragments error:nil];
    if(jsonResponse !=nil) {
        if([[jsonResponse objectForKey:@"status"]intValue] ==0)
            {
                //通常需要校验:bid,product_id,purchase_date,status
                if (self.delegate && [self.delegate respondsToSelector:@selector(buySuccess)]) {
                    [self.delegate buySuccess];
                }
            }
        else
            {
                if (self.delegate && [self.delegate respondsToSelector:@selector(buyFailed:)]) {
                    [self.delegate buyFailed:@""];
                }
                //验证失败,检查你的机器是否越狱
            }
        
        [[NSUserDefaults standardUserDefaults] removeObjectForKey:USERDEFAULT_KEY];
        
    }else{
        if (self.delegate && [self.delegate respondsToSelector:@selector(buyFailed:)]) {
            [self.delegate buyFailed:@""];
        }
    }
    
    
    
    //结束交易
    [self finshTransaction:transaction];
    
}

- (void)finshTransaction:(SKPaymentTransaction*)transaction
{
    //结束交易
    [[SKPaymentQueue defaultQueue] finishTransaction: transaction];
}


//-(void)handleOpenURL:(NSURL *)url{
//    if ([url.host isEqualToString:WECHAT]) {
//        [WXApi handleOpenURL:url delegate:self];
//    }else if ([url.host isEqualToString:ALIPAY]){
//        // 支付跳转支付宝钱包进行支付,处理支付结果
//        [[AlipaySDK defaultService] processOrderWithPaymentResult:url standbyCallback:^(NSDictionary *resultDic) {
//            NSLog(@"result = %@",resultDic);
//        }];
//
////        // 授权跳转支付宝钱包进行支付,处理支付结果
////        [[AlipaySDK defaultService] processAuth_V2Result:url standbyCallback:^(NSDictionary *resultDic) {
////            NSLog(@"result = %@",resultDic);
////            // 解析 auth code
////            NSString *result = resultDic[@"result"];
////            NSString *authCode = nil;
////            if (result.length>0) {
////                NSArray *resultArr = [result componentsSeparatedByString:@"&"];
////                for (NSString *subResult in resultArr) {
////                    if (subResult.length > 10 && [subResult hasPrefix:@"auth_code="]) {
////                        authCode = [subResult substringFromIndex:10];
////                        break;
////                    }
////                }
////            }
////            NSLog(@"授权结果 authCode = %@", authCode?:@"");
////        }];
//    }
//}
//
//-(void)sendOrder:(APTYPE)type Order:(NSDictionary *)order{
//    switch (type) {
//        case AP_ALIPAY:
//        {
//            NSString *orderString = [order objectForKey:@"orderString"];
//            [[AlipaySDK defaultService] payOrder:orderString fromScheme:ALIPAYSCHEME callback:^(NSDictionary *resultDic) {
//                NSLog(@"reslut = %@",resultDic);
//            }];
//        }
//            break;
//        case AP_WECHAT:
//        {
//            PayReq *request = [[PayReq alloc] init];
//            request.openID = [order objectForKey:@"appid"];
//            request.partnerId = [order objectForKey:@"partnerid"];
//            request.prepayId= [order objectForKey:@"prepayid"];
//            request.package = [order objectForKey:@"package"];
//            request.nonceStr= [order objectForKey:@"noncestr"];
//            request.timeStamp = [[order objectForKey:@"timestamp"] intValue];
//            request.sign = [order objectForKey:@"sign"];
//            [WXApi sendReq:request];
//        }
//            break;
//        default:
//            break;
//    }
//}


//#pragma mark ----WXApiDelegate-----

//- (void)onResp:(BaseResp *)resp{
//    if ([resp isKindOfClass:[PayResp class]]) {
//        PayResp*response=(PayResp*)resp;  // 微信终端返回给第三方的关于支付结果的结构体
//        switch (response.errCode) {
//            case WXSuccess:
//            {// 支付成功,向后台发送消息
//                NSLog(@"支付成功");
//            }
//                break;
//            case WXErrCodeCommon:
//            { //签名错误、未注册APPID、项目设置APPID不正确、注册的APPID与设置的不匹配、其他异常等
//                NSLog(@"支付失败");
//            }
//                break;
//            case WXErrCodeUserCancel:
//            { //用户点击取消并返回
//                NSLog(@"取消支付");
//            }
//                break;
//            case WXErrCodeSentFail:
//            { //发送失败
//                NSLog(@"发送失败");
//            }
//                break;
//            case WXErrCodeUnsupport:
//            { //微信不支持
//                NSLog(@"微信不支持");
//            }
//                break;
//            case WXErrCodeAuthDeny:
//            { //授权失败
//                NSLog(@"授权失败");
//            }
//                break;
//            default:
//                break;
//        }
//    }
//}

@end
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容