注意必讀
做了很多電商的項(xiàng)目了瞧剖,都在用各大第三方支付剩檀,蘋果已經(jīng)在強(qiáng)制推行內(nèi)購了吠式,簡(jiǎn)單說明一下,如果你購買的商品嘶摊,是在本app中使用和消耗的虛擬貨幣,就一定要用內(nèi)購舟陆,否則會(huì)被拒絕上線矾屯,例如:游戲幣,在線書籍呀袱,app中使用的道具等贸毕。如果購買的就是普通的商品,例如淘寶買東西等夜赵,就不需要用內(nèi)購
現(xiàn)在蘋果有一個(gè) bug 就是你填寫了銀行卡信息之后修改不了只能發(fā)郵件給蘋果等那邊重置,發(fā)郵件給他們處理有多慢你懂得....
一.向appStore提交資料
第一步
1749914-225b1c250f5c5382.png
第二步
1749914-f446608344ff5775.png
第三步
1749914-36a3a9752f7f5f09.png
操作完第三步然后記得保存
1749914-880a5bfbd6dbcfd9.png
第四步
1749914-6f05cc110112bc39.png
第五步
先點(diǎn)擊Contact Info 的Set Up
1749914-f154d3324adb13b8.png
第六步
1749914-2602d087074b8edc.png
第七步
都填寫完記得保存明棍,然后回到上一個(gè)頁面
1749914-016ab4e0306b73ff.png
第八步
1749914-6187ffdd8a9be141.png
第九步
1749914-3b216495c5385c19.png
第十步
1749914-f4cd66f1a9ed0174.png
第十一步
1749914-3ade39e8d4e7829e.png
第十二步
填寫銀行卡信息
第十三步
1749914-3773f5c84faae624.png
第十四步
1749914-1defa02638af70b7.png
第十五步
1749914-e8dc793dacabe69c.png
第十六步
1749914-0f12a7caa8d83cae.png
第十七步
1749914-8bdcf11af6a38bd7.png
第十八步
1749914-523d414a44dc9293.png
第十九步
1749914-8345169d6d89b17a.png
第二十步
1749914-5a77feb067f7db7f.png
第二十一步
1749914-bc89f24567bc0b01.png
恭喜你現(xiàn)在你完成了添加的信息,下面創(chuàng)建內(nèi)購項(xiàng)目
二.創(chuàng)建內(nèi)購項(xiàng)目
1749914-7c4f22c9a13ac343.png
第一步
1749914-99a1f3573a5c1d9a.png
第二步
根據(jù)自己app的需要選擇類型
第三步
1749914-e7b6de6a4931ea3c.png
第四步
一直下一步到結(jié)尾
三、添加項(xiàng)目?jī)?nèi)購測(cè)試帳號(hào)
1749914-84662a6fd31a7e7c.png
第一步
1749914-bdb0ef4137eb404f.png
四寇僧、上代碼
第一步導(dǎo)入StoreKit.framework庫
然后先看.h文件
#import <StoreKit/StoreKit.h>
typedef NS_ENUM(NSInteger, MyJellyShowType)
{
MyJellyShowType_Push = 0,
MyJellyShowType_Present = 1,
};
@interface MyJellyCurrencyViewController : BaseReuqestTableViewController<SKPaymentTransactionObserver,SKProductsRequestDelegate>
{
int buyType;
}
@property (nonatomic) MyJellyShowType showType;
- (void)RequestProductData;
- (void)buy:(int)type;
- (void)paymentQueue:(SKPaymentQueue *)queue updatedTransactions:(NSArray *)transactions;
- (void)completeTransaction: (SKPaymentTransaction *)transaction;
- (void)failedTransaction: (SKPaymentTransaction *)transaction;
- (void)restoreTransaction: (SKPaymentTransaction *)transaction;
@end
然后看.m文件
//在內(nèi)購項(xiàng)目中創(chuàng)的商品單號(hào)
#define ProductID_IAP0p600 @"guodong600"http://60
#define ProductID_IAP1p1200 @"guodong1200" //1200
#define ProductID_IAP2p5000 @"guodong5000" //5000
enum{
IAP0p600 = 0,
IAP1p1200,
IAP4p5000,
} buyCoinsT
#pragma mark - 點(diǎn)擊購買按鈕
-(void)buttonClickIndex:(NSInteger)index
{
[[SKPaymentQueue defaultQueue] addTransactionObserver:self];
if (index == 0)
{
buyCoinsTag = IAP0p600;
}
else if (index == 1)
{
buyCoinsTag = IAP1p1200;
}else if (index == 2)
{
buyCoinsTag = IAP4p5000;
}
coinNum = [jellyMutAry objectAtIndex:index];
[LoadingTool showLoadingTo:self.view isAfterDelay:NO];
mainTableView.userInteractionEnabled = NO;
[self buy:buyCoinsTag];
}
-(void)buy:(int)type{
buyType = type;
if ([SKPaymentQueue canMakePayments])
{
//允許程序內(nèi)付費(fèi)購買
[self RequestProductData];
}
else
{
//不允許程序內(nèi)付費(fèi)購買
mainTableView.userInteractionEnabled = YES;
[LoadingTool hideProgressHud:self];
UIAlertView *alerView = [[UIAlertView alloc] initWithTitle:@"提示" message:@"您的手機(jī)沒有打開程序內(nèi)付費(fèi)購買"
delegate:nil cancelButtonTitle:NSLocalizedString(@"關(guān)閉",nil) otherButtonTitles:nil];
[alerView show];
}
}
#pragma mark - 請(qǐng)求對(duì)應(yīng)的產(chǎn)品信息
-(void)RequestProductData
{
NSArray *product = nil;
switch (buyType)
{
case IAP0p600:
product=[[NSArray alloc] initWithObjects:ProductID_IAP0p600,nil];
break;
case IAP1p1200:
product=[[NSArray alloc] initWithObjects:ProductID_IAP1p1200,nil];
break;
case IAP4p5000:
product=[[NSArray alloc] initWithObjects:ProductID_IAP2p5000,nil];
break;
default:
break;
}
NSSet *nsset = [NSSet setWithArray:product];
SKProductsRequest *request=[[SKProductsRequest alloc] initWithProductIdentifiers: nsset];
request.delegate=self;
[request start];
}
#pragma mark - 收到產(chǎn)品反饋信息
- (void)productsRequest:(SKProductsRequest *)request didReceiveResponse:(SKProductsResponse *)response{
SKProduct * selectedProduct = nil;
selectedProduct = [response.products objectAtIndex:0];
SKPayment *payment = [SKPayment paymentWithProduct:selectedProduct];
[[SKPaymentQueue defaultQueue] addPayment:payment];
}
#pragma mark - 先商品添加進(jìn)列表 再交易
- (void)paymentQueue:(SKPaymentQueue *)queue updatedTransactions:(NSArray *)transactions//交易結(jié)果
{
for (SKPaymentTransaction *transaction in transactions) {
switch (transaction.transactionState) {
case SKPaymentTransactionStatePurchased://交易完成
{
[self completeTransaction:transaction];
}
break;
case SKPaymentTransactionStateFailed://交易失敗
{
//交易失敗
[self failedTransaction:transaction];
[WarningTool showToastHintWithText:@"購買失敗,請(qǐng)重試摊腋!"];
}
break;
case SKPaymentTransactionStateRestored://已經(jīng)購買過該商品
[self restoreTransaction:transaction];
break;
case SKPaymentTransactionStatePurchasing://商品添加進(jìn)列表
break;
default:
break;
}
}
[LoadingTool hideProgressHud:self];
mainTableView.userInteractionEnabled = YES;
}
#pragma mark - 交易完成調(diào)用
- (void) completeTransaction: (SKPaymentTransaction *)transaction{
NSString *product = transaction.payment.productIdentifier;
if ([product length] > 0)
{
NSArray *tt = [product componentsSeparatedByString:@"."];
NSString *bookid = [tt lastObject];
if ([bookid length] > 0)
{
[self recordTransaction:transaction];
}
}
// Remove the transaction from the payment queue.結(jié)束交易
[[SKPaymentQueue defaultQueue] finishTransaction: transaction];
}
#pragma mark - 記錄交易
-(void)recordTransaction:(SKPaymentTransaction *)transaction
{
transactionIdentifier = transaction.transactionIdentifier;
[self verifyPruchase];
// NSString *product = transaction.payment.productIdentifier;
// NSString *applicationUsername = transaction.payment.applicationUsername;
// NSString *transactionIdentifier = transaction.transactionIdentifier;
// // 驗(yàn)證憑據(jù),獲取到蘋果返回的交易憑據(jù)
// // appStoreReceiptURL iOS7.0增加的嘁傀,購買交易完成后兴蒸,會(huì)將憑據(jù)存放在該地址
// NSURL *receiptURL = [[NSBundle mainBundle] appStoreReceiptURL];
// // 從沙盒中獲取到購買憑據(jù)
// NSData *receiptData = [NSData dataWithContentsOfURL:receiptURL];
// NSString *encodeStr = [receiptData base64EncodedStringWithOptions:NSDataBase64EncodingEndLineWithLineFeed];
// NSString *result =[[ NSString alloc] initWithData:transaction.transactionReceipt encoding:NSUTF8StringEncoding];
// NSString *base64Str = [transaction.transactionReceipt base64EncodedStringWithOptions:NSDataBase64EncodingEndLineWithLineFeed];
}
- (void)verifyPruchase
{
[LoadingTool showLoadingTo:self.view isAfterDelay:NO];
// 驗(yàn)證憑據(jù),獲取到蘋果返回的交易憑據(jù)
// appStoreReceiptURL iOS7.0增加的细办,購買交易完成后橙凳,會(huì)將憑據(jù)存放在該地址
NSURL *receiptURL = [[NSBundle mainBundle] appStoreReceiptURL];
// 從沙盒中獲取到購買憑據(jù)
NSData *receiptData = [NSData dataWithContentsOfURL:receiptURL];
// 發(fā)送網(wǎng)絡(luò)POST請(qǐng)求,對(duì)購買憑據(jù)進(jìn)行驗(yàn)證
NSURL *url = [NSURL URLWithString:XTY_IAP_VerifyReceipt];
// 國(guó)內(nèi)訪問蘋果服務(wù)器比較慢笑撞,timeoutInterval需要長(zhǎng)一點(diǎn)
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:10.0f];
request.HTTPMethod = @"POST";
NSString *encodeStr = [receiptData base64EncodedStringWithOptions:NSDataBase64EncodingEndLineWithLineFeed];
NSString *payload = [NSString stringWithFormat:@"{\"receipt-data\" : \"%@\"}", encodeStr];
NSData *payloadData = [payload dataUsingEncoding:NSUTF8StringEncoding];
request.HTTPBody = payloadData;
// 提交驗(yàn)證請(qǐng)求岛啸,并獲得官方的驗(yàn)證JSON結(jié)果
NSData *result = [NSURLConnection sendSynchronousRequest:request returningResponse:nil error:nil];
// 官方驗(yàn)證結(jié)果為空驗(yàn)證失敗
if (result == nil)
{
[LoadingTool hideProgressHud:self];
[WarningTool showToastHintWithText:@"驗(yàn)證失敗"];
return;
}
NSDictionary *dict = [NSJSONSerialization JSONObjectWithData:result options:NSJSONReadingAllowFragments error:nil];
//驗(yàn)證成功
if ([[dict objectForKey:@"status"] integerValue] == 0) {
// 比對(duì)字典中以下信息基本上可以保證數(shù)據(jù)安全
// bundle_id&application_version&product_id&transaction_id
[self addJelly];
}else if ([[dict objectForKey:@"status"] integerValue] == 21007){
// 驗(yàn)證憑據(jù),獲取到蘋果返回的交易憑據(jù)
// appStoreReceiptURL iOS7.0增加的茴肥,購買交易完成后坚踩,會(huì)將憑據(jù)存放在該地址
NSURL *receiptURL = [[NSBundle mainBundle] appStoreReceiptURL];
// 從沙盒中獲取到購買憑據(jù)
NSData *receiptData = [NSData dataWithContentsOfURL:receiptURL];
// 發(fā)送網(wǎng)絡(luò)POST請(qǐng)求,對(duì)購買憑據(jù)進(jìn)行驗(yàn)證
NSURL *url = [NSURL URLWithString:@"https://sandbox.itunes.apple.com/verifyReceipt"];
// 國(guó)內(nèi)訪問蘋果服務(wù)器比較慢瓤狐,timeoutInterval需要長(zhǎng)一點(diǎn)
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:10.0f];
request.HTTPMethod = @"POST";
NSString *encodeStr = [receiptData base64EncodedStringWithOptions:NSDataBase64EncodingEndLineWithLineFeed];
NSString *payload = [NSString stringWithFormat:@"{\"receipt-data\" : \"%@\"}", encodeStr];
NSData *payloadData = [payload dataUsingEncoding:NSUTF8StringEncoding];
request.HTTPBody = payloadData;
// 提交驗(yàn)證請(qǐng)求瞬铸,并獲得官方的驗(yàn)證JSON結(jié)果
NSData *result = [NSURLConnection sendSynchronousRequest:request returningResponse:nil error:nil];
// 官方驗(yàn)證結(jié)果為空驗(yàn)證失敗
if (result == nil)
{
[LoadingTool hideProgressHud:self];
[WarningTool showToastHintWithText:@"驗(yàn)證失敗"];
return;
}
NSDictionary *dict = [NSJSONSerialization JSONObjectWithData:result options:NSJSONReadingAllowFragments error:nil];
if ([[dict objectForKey:@"status"] integerValue] == 0) {
[self addJelly];
}else{
[LoadingTool hideProgressHud:self];
[WarningTool showToastHintWithText:@"驗(yàn)證失敗"];
}
}
else{
[LoadingTool hideProgressHud:self];
[WarningTool showToastHintWithText:@"驗(yàn)證失敗"];
}
}
//失敗
- (void) failedTransaction: (SKPaymentTransaction *)transaction{
if (transaction.error.code != SKErrorPaymentCancelled){}
[[SKPaymentQueue defaultQueue] finishTransaction: transaction];
}
//交易恢復(fù)處理
- (void) restoreTransaction: (SKPaymentTransaction *)transaction{
// [self PurchasedTransaction:transaction];
[[SKPaymentQueue defaultQueue] finishTransaction: transaction];
// [[SKPaymentQueue defaultQueue] restoreCompletedTransactions];
}
- (void)paymentQueueRestoreCompletedTransactionsFinished:(SKPaymentQueue *)queue
{
}
-(void) paymentQueue:(SKPaymentQueue *) paymentQueue restoreCompletedTransactionsFailedWithError:(NSError *)error{
}
-(void) PurchasedTransaction: (SKPaymentTransaction *)transaction{
NSArray *transactions =[[NSArray alloc] initWithObjects:transaction, nil];
[ self paymentQueue:[SKPaymentQueue defaultQueue] updatedTransactions:transactions];
}
-(void)dealloc{
[[SKPaymentQueue defaultQueue] removeTransactionObserver:self];
//解除監(jiān)聽
}
- (void)addJelly
{
NSMutableDictionary *mutDic = [[NSMutableDictionary alloc]init];
[mutDic setObject:transactionIdentifier forKey:@"flowNO"];
[mutDic setObject:coinNum forKey:@"coinNum"];
[[NetworkRequests sharedClient]requestWithName:XTY_CoinCharge withParameters:mutDic successCallBack:^(MyJellyModel *myJellyModel) {
[LoadingTool hideProgressHud:self];
if ([myJellyModel.status integerValue] == 1)
{
[self beginRefreshing];
}
else
{
[WarningTool showToastHintWithText:myJellyModel.error];
}
} failCallback:^(NSString *error) {
[LoadingTool hideProgressHud:self];
[WarningTool showToastNetError];
}];
}