#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