iOS內(nèi)購開發(fā)前信息注冊逗柴、代碼開發(fā)過程蛹头、以及最后收款

前言:什么時候用內(nèi)購?---平臺有虛擬貨幣交易而非真實(shí)貨品交易且有充值的時候戏溺,打比方題主項目是在平臺充值優(yōu)幣(相當(dāng)于金幣)渣蜗,然后用該貨幣去購買資源等作用,并非一種真實(shí)的物品交易旷祸。在Appstore市場不選擇內(nèi)購則有可能面臨下架風(fēng)險耕拷。


一、簽訂內(nèi)購協(xié)議:

1托享、簽訂前的準(zhǔn)備

(1)聯(lián)系人信息(可以只填一人骚烧,這人有一定代表性即可,我全部填寫的我們總監(jiān)闰围,省事):職稱和郵箱止潘、電話;

(2)公司賬戶信息:公司結(jié)算賬戶賬號辫诅、開戶行行號(實(shí)在不知道的問清楚開戶行地址也行凭戴,后面具體介紹根據(jù)地址找到行號)、持卡人姓名(名在前姓在后炕矮,我們是公司賬號名么夫,就得要公司的英文賬戶名)。

2肤视、開始簽訂:登錄ITunes Connect點(diǎn)擊左上角進(jìn)入:


簽訂協(xié)議稅務(wù)銀行業(yè)務(wù).png

點(diǎn)擊協(xié)議進(jìn)入:


進(jìn)入?yún)f(xié)議.png

3档痪、填寫聯(lián)系人信息:

沒簽訂之前contact Info 下按鈕顯示的是setup,點(diǎn)擊進(jìn)入:

我這里為了省事高管邢滑、財務(wù)腐螟、技術(shù)人員、法人、市場全部都可以填寫一個具有代表性的人乐纸;

選擇聯(lián)系人png
添加聯(lián)系人.png

4衬廷、添加銀行業(yè)務(wù):

銀行國家我們填寫中國:


銀行所在國家.png

填寫code銀行開戶行行號,不知道行號的可以根據(jù)銀行名字汽绢、城市和郵編搜索出一系列的支行行號吗跋,再根據(jù)開戶銀行地址選擇所對應(yīng)的行號;

CNAPS Code:就是開戶行行號宁昭;


查找開戶行行號.png
填寫銀行賬戶信息.png

5跌宛、填寫稅務(wù)信息:

點(diǎn)擊第一個就行;

選擇稅務(wù)信息.png

進(jìn)入U.S Tax后积仗,會有兩個選項疆拘,是否是美國人或者親屬是美國人,根據(jù)實(shí)際情況填寫Yes/No寂曹,還有一個是否參與美國活動哎迄,也是一樣的填寫Yes/No,一般都是NO稀颁,根據(jù)實(shí)際情況來吧芬失;

類型.png

中間一截都不用管楣黍,最后勾選同意就行的匾灶,當(dāng)然謹(jǐn)慎者有研究精神者多去看看是很好的;

勾選同意稅務(wù)png

協(xié)議簽訂完了租漂,可是完成了一件大事阶女!


二、創(chuàng)建內(nèi)購項目并提交:

進(jìn)入內(nèi)購項目哩治,點(diǎn)擊?即添加內(nèi)購項目秃踩;

內(nèi)購項目.png

我們是購買金幣類型,所以是消耗型項目业筏;


消耗型項目.png

創(chuàng)建產(chǎn)品的時候憔杨,產(chǎn)品ID是唯一的,最好定義bundleId+產(chǎn)品標(biāo)識蒜胖;

創(chuàng)建內(nèi)購產(chǎn)品-名稱定價png

創(chuàng)建內(nèi)購產(chǎn)品審核備注那里填寫創(chuàng)建的沙盒測試賬號以供上線審核:

創(chuàng)建內(nèi)購產(chǎn)品-審核備注.png

沙盒測試賬號密碼不可修改消别,忘記了可以重新創(chuàng)建一個即可,點(diǎn)擊編輯可刪除該賬號:


沙盒測試賬號.png

三台谢、代碼:
去蘋果服務(wù)器請求:

#pragma mark - Appstore Request
- (void)requestProductData:(NSString *)type {/**<去蘋果服務(wù)器請求商品*/
    NSLog(@"-------------請求對應(yīng)的產(chǎn)品信息----------------");
    [[WBProgressHUDView sharedInstance] showInView:self.view withTitleLabelText:@"請稍后..." withUserInterfaceEnable:YES];
    NSArray *product = [[NSArray alloc] initWithObjects:type,nil];
    NSSet *set = [NSSet setWithArray:product];
    SKProductsRequest *request = [[SKProductsRequest alloc] initWithProductIdentifiers:set];
    request.delegate = self;
    [request start];
}

- (void)productsRequest:(SKProductsRequest *)request didReceiveResponse:(SKProductsResponse *)response {/**<收到產(chǎn)品返回信息*/
    
    NSLog(@"--------------收到產(chǎn)品反饋消息---------------------");
    NSArray *product = response.products;
    if([product count] == 0){
        [[WBProgressHUDView sharedInstance] dismissFromSuperView];
        NSLog(@"--------------沒有商品------------------");
        return;
    }
    
    NSLog(@"productID:%@", response.invalidProductIdentifiers);
    NSLog(@"產(chǎn)品付費(fèi)數(shù)量:%lu",(unsigned long)[product count]);
    
    SKProduct *p = nil;
    for (SKProduct *pro in product) {
        NSLog(@"%@", [pro description]);
        NSLog(@"%@", [pro localizedTitle]);
        NSLog(@"%@", [pro localizedDescription]);
        NSLog(@"%@", [pro price]);
        NSLog(@"%@", [pro productIdentifier]);
        
        if([pro.productIdentifier isEqualToString:self.productId]){
            p = pro;
        }
    }
    SKPayment *payment = [SKPayment paymentWithProduct:p];
    NSLog(@"發(fā)送購買請求");
    [[SKPaymentQueue defaultQueue] addPayment:payment];
}

- (void)request:(SKRequest *)request didFailWithError:(NSError *)error {/**<請求失敗*/
    UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:@"溫馨提示" message:@"支付失斞翱瘛!" delegate:nil cancelButtonTitle:@"確定" otherButtonTitles:nil, nil];
    [alertView show];
    NSLog(@"------------------錯誤-----------------:%@", error);
}

- (void)requestDidFinish:(SKRequest *)request {/**<請求結(jié)束*/
    [[WBProgressHUDView sharedInstance] dismissFromSuperView];
    NSLog(@"------------反饋信息結(jié)束-----------------");
}

從蘋果沙盒環(huán)境驗(yàn)證購買:(適用于本地測試朋沮,真實(shí)環(huán)境請切換至服務(wù)器驗(yàn)證蛇券,** 測試的時候一定要記得是沙盒環(huán)境!K崖狻轻腺! **)

#pragma mark - Verify in Environment
/**<沙盒測試環(huán)境驗(yàn)證*/
#define SANDBOX @"https://sandbox.itunes.apple.com/verifyReceipt"
/**<正式環(huán)境驗(yàn)證*/
#define AppStore @"https://buy.itunes.apple.com/verifyReceipt"
/**
 *  驗(yàn)證購買,避免越獄軟件模擬蘋果請求達(dá)到非法購買問題
 *  (用于本地測試戒傻,實(shí)際需轉(zhuǎn)至服務(wù)器驗(yàn)證防止刷單漏單)
 */
- (void)verifyPurchaseWithPaymentTransaction {
    
    /**<從沙盒中獲取交易憑證并且拼接成請求體數(shù)據(jù)*/
    NSURL *receiptUrl = [[NSBundle mainBundle] appStoreReceiptURL];
    NSData *receiptData = [NSData dataWithContentsOfURL:receiptUrl];
    NSString *receiptString=[receiptData base64EncodedStringWithOptions:NSDataBase64EncodingEndLineWithLineFeed];/**<轉(zhuǎn)化為base64字符串*/
    NSString *bodyString = [NSString stringWithFormat:@"{\"receipt-data\" : \"%@\"}", receiptString];/**<拼接請求數(shù)據(jù)*/
    NSData *bodyData = [bodyString dataUsingEncoding:NSUTF8StringEncoding];

    /**<創(chuàng)建請求到蘋果官方進(jìn)行購買驗(yàn)證*/
    NSURL *url = [NSURL URLWithString:SANDBOX];
    NSMutableURLRequest *requestM=[NSMutableURLRequest requestWithURL:url];
    requestM.HTTPBody=bodyData;
    requestM.HTTPMethod=@"POST";
    
    /**<創(chuàng)建連接并發(fā)送同步請求*/
    NSError *error=nil;
    NSData *responseData=[NSURLConnection sendSynchronousRequest:requestM returningResponse:nil error:&error];
    if (error) {
        NSLog(@"驗(yàn)證購買過程中發(fā)生錯誤菜枷,錯誤信息:%@",error.localizedDescription);
        return;
    }
    NSDictionary *dic=[NSJSONSerialization JSONObjectWithData:responseData options:NSJSONReadingAllowFragments error:nil];
    NSLog(@"%@",dic);
    if([dic[@"status"] intValue] == 0){
        NSLog(@"購買成功苍糠!");
        NSDictionary *dicReceipt = dic[@"receipt"];
        NSDictionary *dicInApp = [dicReceipt[@"in_app"] firstObject];
        NSString *productIdentifier = dicInApp[@"product_id"];/**<讀取產(chǎn)品標(biāo)識*/
        /**<如果是消耗品則記錄購買數(shù)量,非消耗品則記錄是否購買過*/
        NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
        if ([productIdentifier isEqualToString:@"com.k12chn.UCoin6"] || [productIdentifier isEqualToString:@"com.k12chn.UCoin80"] || [productIdentifier isEqualToString:@"com.k12chn.UCoin120"]) {
            NSInteger purchasedCount = [defaults integerForKey:productIdentifier];/**<已購買數(shù)量*/
            [[NSUserDefaults standardUserDefaults] setInteger:(purchasedCount+1) forKey:productIdentifier];
        } else {
            [defaults setBool:YES forKey:productIdentifier];
        }
        /**<在此處對購買記錄進(jìn)行存儲啤誊,可以存儲到開發(fā)商的服務(wù)器端*/
    } else {
        NSLog(@"購買失敗岳瞭,未通過驗(yàn)證!");
    }
}

題主公司項目服務(wù)器驗(yàn)證購買請求參數(shù):

NSURL *receiptUrl = [[NSBundle mainBundle] appStoreReceiptURL];
    NSData *receiptData = [NSData dataWithContentsOfURL:receiptUrl];
    NSString *receiptString = [receiptData base64EncodedStringWithOptions:NSDataBase64EncodingEndLineWithLineFeed];//轉(zhuǎn)化為base64字符串

    NSString *url = @"/index.php?app=account_epay&act=UcoinExcharge";
    NSDictionary *dic = @{
                          @"userId":userInfoModel.UserId,
                          @"receiptdata":receiptString,
                          @"ucoin":ucoin,
                          @"money":price
                          };

購買結(jié)果監(jiān)聽:

#pragma mark - Observe Result
- (void)paymentQueue:(SKPaymentQueue *)queue updatedTransactions:(NSArray *)transaction{
    for(SKPaymentTransaction *tran in transaction) {/**<監(jiān)聽購買結(jié)果*/
        switch (tran.transactionState) {
            case SKPaymentTransactionStatePurchased: {
                NSLog(@"交易完成");
                /**<發(fā)送到蘋果服務(wù)器驗(yàn)證憑證*/
                [self requstVerifyPurchase];
                [[SKPaymentQueue defaultQueue] finishTransaction:tran];
            }
                break;
            case SKPaymentTransactionStatePurchasing:
                NSLog(@"商品添加進(jìn)列表");
                
                break;
            case SKPaymentTransactionStateRestored: {
                NSLog(@"已經(jīng)購買過商品");
                
                [[SKPaymentQueue defaultQueue] finishTransaction:tran];
            }
                break;
            case SKPaymentTransactionStateFailed: {
                NSLog(@"交易失敗");
                [[SKPaymentQueue defaultQueue] finishTransaction:tran];
                UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:@"溫馨提示" message:@"購買失斘们隆瞳筏!" delegate:nil cancelButtonTitle:@"確定" otherButtonTitles:nil, nil];
                [alertView show];
            }
                break;
            default:
                break;
        }
    }
}

- (void)completeTransaction:(SKPaymentTransaction *)transaction {/**<交易結(jié)束*/
    NSLog(@"交易結(jié)束");
    [[SKPaymentQueue defaultQueue] finishTransaction:transaction];
}

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

OK啦,成功告一段落了牡昆,但是最后要注意的是:
測試的時候需要先進(jìn)設(shè)置->iTunes Store 與 App Store 里面退出原來真實(shí)的Apple ID(退出就好姚炕,無需急著登錄測試賬號),然后在app中測試購買的時候回跳出請輸入Appstore賬號丢烘,這時輸入我們的沙盒測試賬號即可柱宦。


最后來處理掉單問題了:
兩種情況:1、付款了Appstore服務(wù)器出問題回調(diào)不成功播瞳;
2掸刊、AppStore返會成功但自己服務(wù)器驗(yàn)證未通過未發(fā)放對應(yīng)貨幣。
針對情況1:我在AppDelegate里重新監(jiān)聽向AppStore購買請求結(jié)果赢乓,如果存在訂單但又回執(zhí)失敗的話忧侧,是會重新發(fā)送請求的;
針對情況2:我在購買監(jiān)聽回調(diào)中做了個3次循環(huán)驗(yàn)證牌芋,如果超過3次還失敗蚓炬,那也無需繼續(xù)請求,說明服務(wù)器出問題了躺屁。
(ps:總覺得這些處理內(nèi)心不是很踏實(shí)不是很滿意肯夏,求有其它好處理方式的共享,感謝~)

內(nèi)購除了開發(fā)過程坑犀暑,還有收賬過程也是有點(diǎn)意思驯击,因?yàn)槭呛M馊胭~,銀行會打電話給公司母怜,需提供形式發(fā)票等一系列資料才能完整到公司銀行賬戶余耽。財務(wù)一開始沒有及時收賬,導(dǎo)致銀行又原路退回到蘋果公司苹熏。后面天天逼著我一個小小開發(fā)者做發(fā)票碟贾,也是趕鴨子上架币喧,各種百度,嘗試性地問財務(wù)要一個平時的發(fā)票格式袱耽,我依葫蘆畫瓢把一些內(nèi)購買數(shù)據(jù)和賬單里一些數(shù)據(jù)填上去杀餐,結(jié)果神奇般地后面的款項都收到了,于是又回頭去聯(lián)系蘋果財務(wù)朱巨,請求將先前的退款重新發(fā)起史翘,我們及時提供形式發(fā)票等資料就可以入賬。那真的是一波三折~知道這個過程的冀续,還是很easy琼讽。不知道的,度娘上資料都微乎其微洪唐!


形式發(fā)票參考.jpg
貨描詳情參考.jpg
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末钻蹬,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子凭需,更是在濱河造成了極大的恐慌问欠,老刑警劉巖,帶你破解...
    沈念sama閱讀 221,635評論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件粒蜈,死亡現(xiàn)場離奇詭異顺献,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)枯怖,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,543評論 3 399
  • 文/潘曉璐 我一進(jìn)店門注整,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人嫁怀,你說我怎么就攤上這事设捐〗枳牵” “怎么了塘淑?”我有些...
    開封第一講書人閱讀 168,083評論 0 360
  • 文/不壞的土叔 我叫張陵,是天一觀的道長蚂斤。 經(jīng)常有香客問我存捺,道長,這世上最難降的妖魔是什么曙蒸? 我笑而不...
    開封第一講書人閱讀 59,640評論 1 296
  • 正文 為了忘掉前任捌治,我火速辦了婚禮,結(jié)果婚禮上纽窟,老公的妹妹穿的比我還像新娘肖油。我一直安慰自己,他們只是感情好臂港,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,640評論 6 397
  • 文/花漫 我一把揭開白布森枪。 她就那樣靜靜地躺著视搏,像睡著了一般。 火紅的嫁衣襯著肌膚如雪县袱。 梳的紋絲不亂的頭發(fā)上浑娜,一...
    開封第一講書人閱讀 52,262評論 1 308
  • 那天,我揣著相機(jī)與錄音式散,去河邊找鬼筋遭。 笑死,一個胖子當(dāng)著我的面吹牛暴拄,可吹牛的內(nèi)容都是我干的漓滔。 我是一名探鬼主播,決...
    沈念sama閱讀 40,833評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼乖篷,長吁一口氣:“原來是場噩夢啊……” “哼次和!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起那伐,我...
    開封第一講書人閱讀 39,736評論 0 276
  • 序言:老撾萬榮一對情侶失蹤踏施,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后罕邀,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體畅形,經(jīng)...
    沈念sama閱讀 46,280評論 1 319
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,369評論 3 340
  • 正文 我和宋清朗相戀三年诉探,在試婚紗的時候發(fā)現(xiàn)自己被綠了日熬。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,503評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡肾胯,死狀恐怖竖席,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情敬肚,我是刑警寧澤毕荐,帶...
    沈念sama閱讀 36,185評論 5 350
  • 正文 年R本政府宣布,位于F島的核電站艳馒,受9級特大地震影響憎亚,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜弄慰,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,870評論 3 333
  • 文/蒙蒙 一第美、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧陆爽,春花似錦什往、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,340評論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽第献。三九已至,卻和暖如春兔港,著一層夾襖步出監(jiān)牢的瞬間庸毫,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,460評論 1 272
  • 我被黑心中介騙來泰國打工衫樊, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留飒赃,地道東北人。 一個月前我還...
    沈念sama閱讀 48,909評論 3 376
  • 正文 我出身青樓科侈,卻偏偏與公主長得像载佳,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子臀栈,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,512評論 2 359

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