iOS內(nèi)購圖文流程(2017)

什么是內(nèi)購玛歌?

只要在iPhone App上購買的不是實物產(chǎn)品(也就是虛擬產(chǎn)品如qq幣.虎牙幣.電子書......) 都需要走內(nèi)購流程,蘋果在里面抽走三成。

使用內(nèi)購需要走的流程。

1,填寫協(xié)議,稅務(wù)和銀行業(yè)務(wù);
2,填寫用戶和職能; 創(chuàng)建內(nèi)購的項目
3,寫代碼,和后臺配合
4,添加項目內(nèi)購測試賬號;檢驗成果

具體步驟:

接下來的步驟特別繁瑣鲸阔,請做好準備澎剥。

一.填寫協(xié)議,稅務(wù)和銀行業(yè)務(wù)配置 https://itunesconnect.apple.com

1.請求合同

填寫地址信息

閱讀同意協(xié)議

2.填寫聯(lián)系方式

添加新的聯(lián)系人

選中聯(lián)系人

3.填寫銀行信息

添加銀行卡

選擇銀行卡所在國家

填寫銀行CNAPS Code
貨幣類型 CN###銀行賬號如果是對公的賬號叭首,需要填寫公司的英文名稱,如果沒有的話拼音

4.填寫稅務(wù)信息

U.S Tax Forms: 美國稅務(wù)
Australia Tax Forms:澳大利亞稅務(wù)
Canada Tax Forms: 加拿大稅務(wù)



第一個問題如下:詢問你是否是美國居民互广,有沒有美國伙伴關(guān)系或者美國公司敛腌,如果沒有直接選擇No。



第二個問題如下:詢問你有沒有在美國的商業(yè)性活動惫皱,沒有也直接選No

然后填寫你的稅務(wù)信息像樊,包括以下幾點:

Individual or Organization Name:個人或者組織名稱
Country of incorporation: 所在國家
Type of Beneficial Owner:受益方式,獨立開發(fā)者選個人
Permanent Residence:居住地址
Mailing address:郵寄地址
Name of Person Making this Declaration:聲明人
Title:頭銜

填寫完這些信息后就可以提交了



5.等待審核,時間24小時左右旅敷。

二.創(chuàng)建內(nèi)購項目

選中你要添加內(nèi)購項目的APP然后點擊功能,點擊+創(chuàng)建內(nèi)購項目生棍。

根據(jù)自己APP的需求選擇類型

填寫項目名稱id (ps:應(yīng)用在首次添加內(nèi)購買項目時需要與新的應(yīng)用版本一起提交審核。)

添加沙盒技術(shù)測試員

用戶職能>沙箱技術(shù)測試員


注意事項:

郵箱隨便寫但是格式要正確(test@163.com)媳谁,但是不能用已經(jīng)是AppleID的郵箱

App Store 地區(qū)不要亂選涂滴。雖然隨便哪個地區(qū)都可以用來測試(還沒上線之前app并沒有地區(qū)之分)友酱,但是在沙盒測試的時候,彈出的購買提示框會根據(jù)當前AppleID(沙盒賬號)的地區(qū)顯示語言的柔纵。

使用沙盒測試一定要用真機 (越獄的不行)

沙盒賬號不能直接登錄AppleStore登錄時會提示"不允許創(chuàng)建iTunes賬戶”

進行沙盒測試時需要退出AppleStore的賬號

三.代碼

#import <Foundation/Foundation.h>
#import "WXApi.h"

typedef NS_ENUM(NSInteger , Payment) {
    IAP6 = 6,
    IAP25 = 25,
    IAP60 = 60
};

@interface PayCenter : NSObject

singleton_interface(PayCenter);

- (void)startInit;

- (void)payWithMoney:(NSInteger)money andType:(PayType)type dataDic:(NSDictionary *)dataDic;

@property (nonatomic, strong) MBProgressHUD * hud;

@property (nonatomic, copy) NSString * rechargeNumber;

@end
#define kProductID_IAP6 @"org.qqhl.nursning.6"http://6

#import "PayCenter.h"
#import "PayHttpRequest.h"
//#import "Order.h"
//#import "DataSigner.h"
//#import <AlipaySDK/AlipaySDK.h>
#import <StoreKit/StoreKit.h>

@interface PayCenter()<SKPaymentTransactionObserver,SKProductsRequestDelegate>
{
    int buyType;
    NSInteger _money;
}
@property (nonatomic, strong) NSMutableDictionary * dataDic;

@end
@implementation PayCenter

singleton_implementation(PayCenter);

- (void)startInit
{
    [WXApi registerApp:kWeChatShareAppKey withDescription:appDefaultTilte];
}

- (void)payWithMoney:(NSInteger)money andType:(PayType)type dataDic:(NSDictionary *)dataDic
{
    _money = money;
    self.dataDic = [NSMutableDictionary dictionaryWithDictionary:dataDic];
    switch (type) {
        case PayTypeWX:
            [self payTypeWXPay];
            break;
        case ApplePay:
//            [self payTypeAliPay];
            [[SKPaymentQueue defaultQueue]addTransactionObserver:self];
           
            if ([SKPaymentQueue canMakePayments]) {
                HULog(@"允許程序內(nèi)付費購買");

                [self payTypeApplePay];
            }else {
                HULog(@"不允許程序內(nèi)付費購買");
                UIAlertView *alerView =  [[UIAlertView alloc] initWithTitle:@"提示"
                                                                    message:@"您的手機沒有打開程序內(nèi)付費購買"
                                                                   delegate:nil cancelButtonTitle:NSLocalizedString(@"關(guān)閉",nil) otherButtonTitles:nil];
               
                [alerView show];
               
            }

            break;
        default:
            break;
    }
}

- (void)payTypeApplePay{
    NSLog(@"---------請求對應(yīng)的產(chǎn)品信息------------");
    NSArray *product = nil;
    switch (_money) {
        case IAP6:
        {
            product=[[NSArray alloc] initWithObjects:kProductID_IAP6,nil];
            NSLog(@"---------IAP6------------");

        }
            break;
        case IAP25:
        {
            NSLog(@"---------IAP25------------");

        }
            break;
        case IAP60:
        {
            NSLog(@"---------IAP60------------");
        }

            break;
    
        default:
            break;
    }
   
    NSSet *nsSet = [NSSet setWithArray:product];
    SKProductsRequest *request = [[SKProductsRequest alloc]initWithProductIdentifiers:nsSet];
    request.delegate = self;
    [request start];
}
#pragma mark -  SKProductsRequestDelegate代理
//返回的在蘋果服務(wù)器請求的產(chǎn)品信息
- (void)productsRequest:(SKProductsRequest *)request didReceiveResponse:(SKProductsResponse *)response{
    HULog(@"收到產(chǎn)品信息");
    NSArray *myProduct = response.products;
    HULog(@"產(chǎn)品id %@",response.invalidProductIdentifiers);
    NSLog(@"產(chǎn)品付費數(shù)量%d",(int)[myProduct count]);
//populate UI
    for (SKProduct *product in myProduct) {
      NSLog(@"product info");
      NSLog(@"SKProduct 描述信息%@", [product description]);
      NSLog(@"產(chǎn)品標題 %@" , product.localizedTitle);
      NSLog(@"產(chǎn)品描述信息: %@" , product.localizedDescription);
      NSLog(@"價格: %@" , product.price);
      NSLog(@"Product id: %@" , product.productIdentifier);
    }
    SKPayment *payment = nil;
    switch (_money) {
        case IAP6:
        {
            payment = [SKPayment paymentWithProductIdentifier:kProductID_IAP6];
        }
            break;
        case IAP25:{
           
        }
        default:
            break;
    }
   
    NSLog(@"發(fā)起購買請求");
    [[SKPaymentQueue defaultQueue]addPayment:payment];
   
   
}
//實現(xiàn)監(jiān)聽方法
- (void)paymentQueue:(SKPaymentQueue *)queue updatedTransactions:(NSArray<SKPaymentTransaction *> *)transactions{
    NSLog(@"調(diào)用了幾次這個方法缔杉?");
    SKPaymentTransaction *transaction = transactions.lastObject;
    switch (transaction.transactionState) {
        case SKPaymentTransactionStatePurchased: {
            NSLog(@"購買完成,向自己的服務(wù)器驗證 ---- %@", transaction.payment.applicationUsername);
            NSData *data = [NSData dataWithContentsOfFile:[[[NSBundle mainBundle] appStoreReceiptURL] path]];
            NSString *receipt = [data base64EncodedStringWithOptions:0];
//            [self buySuccessWithReceipt:receipt transaction:transaction];
        }
            break;
        case SKPaymentTransactionStateFailed: {
            NSLog(@"交易失敗");
            [[SKPaymentQueue defaultQueue] finishTransaction:transaction];
        }
            break;
        case SKPaymentTransactionStateRestored: {
            NSLog(@"已經(jīng)購買過該商品");
            [[SKPaymentQueue defaultQueue] finishTransaction:transaction];
        }
            break;
        case SKPaymentTransactionStatePurchasing: {
            NSLog(@"商品添加進列表");
        }
            break;
        default: {
            NSLog(@"這是什么情況啊搁料?");
        }
            break;
    }
}

@end```
####購買成功后需要跟服務(wù)器交互驗證交易是否成功

// 驗證憑據(jù)或详,獲取到蘋果返回的交易憑據(jù)
// appStoreReceiptURL iOS7.0增加的,購買交易完成后郭计,會將憑據(jù)存放在該地址
NSURL receiptURL = [[NSBundle mainBundle] appStoreReceiptURL];
// 從沙盒中獲取到購買憑據(jù)
NSData receipt = [NSData dataWithContentsOfURL:receiptURL];
// 傳輸?shù)氖荁ASE64編碼的字符串
/

BASE64 常用的編碼方案霸琴,通常用于數(shù)據(jù)傳輸,以及加密算法的基礎(chǔ)算法昭伸,傳輸過程中能夠保證數(shù)據(jù)傳輸?shù)姆€(wěn)定性
BASE64是可以編碼和解碼的
*/
NSDictionary *requestContents = @{
@"receipt-data": [receipt base64EncodedStringWithOptions:0]
};
NSError *error;
// 轉(zhuǎn)換為 JSON 格式
NSData requestData = [NSJSONSerialization dataWithJSONObject:requestContents
options:0
error:&error];
// 不存在
if (!requestData) { /
... Handle error ... */ }

// 發(fā)送網(wǎng)絡(luò)POST請求沈贝,對購買憑據(jù)進行驗證  
NSString *verifyUrlString;  

測試環(huán)境 verifyUrlString = @"https://sandbox.itunes.apple.com/verifyReceipt";
生產(chǎn)環(huán)境 verifyUrlString = @"https://buy.itunes.apple.com/verifyReceipt";
// 國內(nèi)訪問蘋果服務(wù)器比較慢,timeoutInterval 需要長一點
NSMutableURLRequest *storeRequest = [NSMutableURLRequest requestWithURL:[[NSURL alloc] initWithString:verifyUrlString] cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:10.0f];

[storeRequest setHTTPMethod:@"POST"];  
[storeRequest setHTTPBody:requestData];  
  
// 在后臺對列中提交驗證請求勋乾,并獲得官方的驗證JSON結(jié)果  
NSOperationQueue *queue = [[NSOperationQueue alloc] init];  
[NSURLConnection sendAsynchronousRequest:storeRequest queue:queue  
                       completionHandler:^(NSURLResponse *response, NSData *data, NSError *connectionError) {  
                           if (connectionError) {  
                               NSLog(@"鏈接失敗");  
                           } else {  
                               NSError *error;  
                               NSDictionary *jsonResponse = [NSJSONSerialization JSONObjectWithData:data options:0 error:&error];  
                               if (!jsonResponse) {  
                                   NSLog(@"驗證失敗");  
                               }  
                                 
                               // 比對 jsonResponse 中以下信息基本上可以保證數(shù)據(jù)安全  
                               /* 
                                bundle_id 
                                application_version 
                                product_id 
                                transaction_id 
                                */  
                                 
                               NSLog(@"驗證成功");  
                           }  
                       }];  

}

[蘋果官方文檔](https://developer.apple.com/library/content/releasenotes/General/ValidateAppStoreReceipt/Chapters/ValidateRemotely.html#//apple_ref/doc/uid/TP40010573-CH104-SW4)
```剛接觸內(nèi)購如有不足之處請指教 ```
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末宋下,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子辑莫,更是在濱河造成了極大的恐慌学歧,老刑警劉巖,帶你破解...
    沈念sama閱讀 206,482評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件各吨,死亡現(xiàn)場離奇詭異枝笨,居然都是意外死亡,警方通過查閱死者的電腦和手機揭蜒,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,377評論 2 382
  • 文/潘曉璐 我一進店門横浑,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人屉更,你說我怎么就攤上這事徙融。” “怎么了瑰谜?”我有些...
    開封第一講書人閱讀 152,762評論 0 342
  • 文/不壞的土叔 我叫張陵欺冀,是天一觀的道長。 經(jīng)常有香客問我萨脑,道長隐轩,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 55,273評論 1 279
  • 正文 為了忘掉前任渤早,我火速辦了婚禮职车,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己悴灵,他們只是感情好扛芽,可當我...
    茶點故事閱讀 64,289評論 5 373
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著称勋,像睡著了一般胸哥。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上赡鲜,一...
    開封第一講書人閱讀 49,046評論 1 285
  • 那天空厌,我揣著相機與錄音,去河邊找鬼银酬。 笑死嘲更,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的揩瞪。 我是一名探鬼主播赋朦,決...
    沈念sama閱讀 38,351評論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼李破!你這毒婦竟也來了宠哄?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 36,988評論 0 259
  • 序言:老撾萬榮一對情侶失蹤嗤攻,失蹤者是張志新(化名)和其女友劉穎毛嫉,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體妇菱,經(jīng)...
    沈念sama閱讀 43,476評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡承粤,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 35,948評論 2 324
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了闯团。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片辛臊。...
    茶點故事閱讀 38,064評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖房交,靈堂內(nèi)的尸體忽然破棺而出彻舰,到底是詐尸還是另有隱情,我是刑警寧澤涌萤,帶...
    沈念sama閱讀 33,712評論 4 323
  • 正文 年R本政府宣布淹遵,位于F島的核電站,受9級特大地震影響负溪,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜济炎,卻給世界環(huán)境...
    茶點故事閱讀 39,261評論 3 307
  • 文/蒙蒙 一川抡、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦崖堤、人聲如沸侍咱。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,264評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽楔脯。三九已至,卻和暖如春胯甩,著一層夾襖步出監(jiān)牢的瞬間昧廷,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,486評論 1 262
  • 我被黑心中介騙來泰國打工偎箫, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留木柬,地道東北人。 一個月前我還...
    沈念sama閱讀 45,511評論 2 354
  • 正文 我出身青樓淹办,卻偏偏與公主長得像眉枕,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子怜森,可洞房花燭夜當晚...
    茶點故事閱讀 42,802評論 2 345

推薦閱讀更多精彩內(nèi)容

  • 轉(zhuǎn)載自[iOS內(nèi)購圖文流程(2017)] 什么是內(nèi)購速挑? 只要在iPhone App上購買的不是實物產(chǎn)品(也就是虛擬...
    咸魚而已閱讀 982評論 0 0
  • 參考鏈接iOS開發(fā)之內(nèi)購-AppStore iOS App提交指南(二)-協(xié)議、稅務(wù)和銀行業(yè)務(wù)iOS應(yīng)用內(nèi)付費(I...
    sjzuo閱讀 2,986評論 4 4
  • 轉(zhuǎn)載 公司項目中有虛擬產(chǎn)品,所以要使用蘋果內(nèi)購.自此記錄一下蘋果內(nèi)購的流程.前提是已有開發(fā)者賬號 協(xié)議,稅務(wù)和銀行...
    George2016閱讀 1,293評論 9 6
  • 公司項目中有虛擬產(chǎn)品,所以要使用蘋果內(nèi)購.自此記錄一下蘋果內(nèi)購的流程.前提是已有開發(fā)者賬號 協(xié)議,稅務(wù)和銀行業(yè)務(wù) ...
    看我的大白眼閱讀 15,004評論 62 70
  • 這幾天來了好多波拜訪的上家副硅,涉及方方面面:服務(wù)器姥宝,存儲,網(wǎng)絡(luò)設(shè)備想许,一體機等等伶授。聊到政企IT市場的現(xiàn)狀,大家都感慨單...
    申國斌青藍信息閱讀 594評論 0 0