iOS內(nèi)購(gòu)看我就夠了(含代碼)

內(nèi)購(gòu)是啥

App 內(nèi)購(gòu)買項(xiàng)目允許顧客通過訪問 App Store 購(gòu)買您 App 中的內(nèi)容、功能或服務(wù),并安全處理來自用戶的付款。

詳情傳送門https://help.apple.com/itunes-connect/developer/#/devb57be10e7

下面來說內(nèi)購(gòu)集成流程

1.協(xié)議

登錄蘋果開發(fā)者中心,進(jìn)入iTunes Connect,再進(jìn)入“協(xié)議病线、稅務(wù)和銀行業(yè)務(wù)”頁(yè)面,如圖


圖1.協(xié)議入口

點(diǎn)擊進(jìn)入可以看到,目前共有兩個(gè)分組,三種合同送挑。(此處有坑绑莺,比如我們當(dāng)前賬號(hào)不能申請(qǐng)合同!如下圖)

Request Contracts 可以申請(qǐng)的合同惕耕;

Contracts In Effect 已經(jīng)生效的合同纺裁。

三種合同分別是

Free Applications 免費(fèi)應(yīng)用(默認(rèn)已經(jīng)生效);

Paid Applications 付費(fèi)應(yīng)用司澎,需要申請(qǐng)欺缘;

iAd App Network 廣告應(yīng)用,需要申請(qǐng)挤安。


圖2.未申請(qǐng)樣式

內(nèi)購(gòu)對(duì)應(yīng)的是Paid Applications 付費(fèi)應(yīng)用谚殊,需要申請(qǐng),如圖2.(如果Request按鈕不顯示,則說明當(dāng)前賬號(hào)權(quán)限有問題)

點(diǎn)擊Request完善信息,提交就行.

2.內(nèi)購(gòu)集成

內(nèi)購(gòu)實(shí)現(xiàn)流程:

1.客戶端向Appstore請(qǐng)求購(gòu)買產(chǎn)品(假設(shè)產(chǎn)品信息已經(jīng)取得),Appstore驗(yàn)證產(chǎn)品成功后蛤铜,從用戶的Apple賬戶余額中扣費(fèi)嫩絮。

2.Appstore向客戶端返回一段receipt-data,里面記錄了本次交易的證書和簽名信息围肥。

3.客戶端向我們可以信任的服務(wù)器提供receipt-data

4.服務(wù)器對(duì)receipt-data進(jìn)行一次base64編碼

5.把編碼后的receipt-data發(fā)往itunes.appstore進(jìn)行驗(yàn)證

6.itunes.appstore返回驗(yàn)證結(jié)果給服務(wù)器

7.服務(wù)器對(duì)商品購(gòu)買狀態(tài)以及商品類型絮记,向客戶端發(fā)放相應(yīng)的道具與推送數(shù)據(jù)更新通知

注,下圖3步驟和上面流程不是一一對(duì)應(yīng)

圖3.內(nèi)購(gòu)流程

我項(xiàng)目里面的購(gòu)買流程,加入了一點(diǎn)業(yè)務(wù)邏輯和后臺(tái)驗(yàn)證流程,有什么問題歡迎大家指出.


圖4.完整內(nèi)購(gòu)流程

3.去蘋果開發(fā)者中心創(chuàng)建內(nèi)購(gòu)商品

如下圖5,點(diǎn)擊+號(hào)去創(chuàng)建內(nèi)購(gòu)商品,產(chǎn)品id最好是當(dāng)前應(yīng)用+數(shù)字,價(jià)格區(qū)間蘋果提供了一張表,商品價(jià)格只能是表上的價(jià)格,蘋果會(huì)抽取30%,商家能收到的錢是用戶充值的70%.這就造成了部分平臺(tái)區(qū)分安卓和蘋果.兩端賬號(hào)不互通,也造就了代充行業(yè),再次就不展開說了.

商品價(jià)格大于100$,提交審核的時(shí)候要說明這個(gè)金額是確認(rèn)過的,不然可能會(huì)被拒


圖5.添加內(nèi)購(gòu)商品

4.代碼集成

建議單獨(dú)建一個(gè)類來處理內(nèi)購(gòu)業(yè)務(wù)


導(dǎo)入頭文件#import <StoreKit/StoreKit.h>

遵循協(xié)議<SKPaymentTransactionObserver,SKProductsRequestDelegate>

?[[SKPaymentQueue defaultQueue] addTransactionObserver:self];// 4.設(shè)置支付服務(wù)

-(void)starBuyToAppStore:(NSString *)goodsID{? ? if ([SKPaymentQueue canMakePayments]) {//5.判斷app是否允許apple支付?? ? ?? ? ? ? [self getRequestAppleProduct:goodsID];// 6.請(qǐng)求蘋果后臺(tái)商品?? ? ? ?? ? } else {//? ? ? ? NSLog(@"not");? ? }}

#pragma mark ------ 請(qǐng)求蘋果商品- (void)getRequestAppleProduct:(NSString *)goodsID{? ? self.goodsId = goodsID;//把前面?zhèn)鬟^來的商品id記錄一下,下面要用? ? // 7.這里的com.czchat.CZChat01就對(duì)應(yīng)著蘋果后臺(tái)的商品ID,他們是通過這個(gè)ID進(jìn)行聯(lián)系的虐先。? ? NSArray *product = [[NSArray alloc] initWithObjects:goodsID,nil];? ? NSSet *nsset = [NSSet setWithArray:product];?? ?? ? //SKProductsRequest參考鏈接:https://developer.apple.com/documentation/storekit/skproductsrequest? ? //SKProductsRequest 一個(gè)對(duì)象,可以從App Store檢索有關(guān)指定產(chǎn)品列表的本地化信息派敷。? ? SKProductsRequest *request = [[SKProductsRequest alloc] initWithProductIdentifiers:nsset];// 8.初始化請(qǐng)求? ? request.delegate = self;? ? [request start];// 9.開始請(qǐng)求}

// 10.接收到產(chǎn)品的返回信息,然后用返回的商品信息進(jìn)行發(fā)起購(gòu)買請(qǐng)求- (void) productsRequest:(SKProductsRequest *)request didReceiveResponse:(SKProductsResponse *)response{? ? NSArray *product = response.products;?? ?? ? if([product count] == 0){//如果服務(wù)器沒有產(chǎn)品? ? ? ? return;? ? }?? ?? ? SKProduct *requestProduct = nil;? ? for (SKProduct *pro in product) {//? ? ? ? NSLog(@"%@", [pro description]);//? ? ? ? NSLog(@"%@", [pro localizedTitle]);//? ? ? ? NSLog(@"%@", [pro localizedDescription]);//? ? ? ? NSLog(@"%@", [pro price]);//? ? ? ? NSLog(@"%@", [pro productIdentifier]);? ? ? ? // 11.如果后臺(tái)消費(fèi)條目的ID與我這里需要請(qǐng)求的一樣(用于確保訂單的正確性)? ? ? ? if([pro.productIdentifier isEqualToString:self.goodsId]){? ? ? ? ? ? requestProduct = pro;? ? ? ? }? ? }? ? // 12.發(fā)送購(gòu)買請(qǐng)求蛹批,創(chuàng)建票據(jù)? 這個(gè)時(shí)候就會(huì)有彈框了? ? SKPayment *payment = [SKPayment paymentWithProduct:requestProduct];? ? [[SKPaymentQueue defaultQueue] addPayment:payment];//將票據(jù)加入到交易隊(duì)列?? ?}

// 13.監(jiān)聽購(gòu)買結(jié)果- (void)paymentQueue:(SKPaymentQueue *)queue updatedTransactions:(NSArray *)transaction{? ? if (self.delegate && [self.delegate respondsToSelector:@selector(EMAppStorePay:responseAppStorePayStatusshow:error:)]) {? ? ? ? [self.delegate EMAppStorePay:self responseAppStorePayStatusshow:@{@"value":transaction} error:nil];? ? }? ? for(SKPaymentTransaction *tran in transaction){//? ? ? ? NSLog(@"%@",tran.payment.applicationUsername);? ? ? ? switch (tran.transactionState) {? ? ? ? ? ? case SKPaymentTransactionStatePurchased:{//? ? ? ? ? ? ? ? NSLog(@"交易完成");? ? ? ? ? ? ? ? // 購(gòu)買后告訴交易隊(duì)列,把這個(gè)成功的交易移除掉篮愉。? ? ? ? ? ? ? ? //走到這就說明這單交易走完了腐芍,無論成功失敗,所以要給它移出试躏。finishTransaction? ? ? ? ? ? ? ? [self completeTransaction:tran];//這兒出了問題拋異常猪勇,導(dǎo)致下面一句代碼沒執(zhí)行? ? ? ? ? ? ? ? [[SKPaymentQueue defaultQueue] finishTransaction:tran];?? ? ? ? ? ? ? ?? ? ? ? ? ? }? ? ? ? ? ? ? ? break;?? ? ? ? ? ? ? ?? ? ? ? ? ? case SKPaymentTransactionStatePurchasing://? ? ? ? ? ? ? ? NSLog(@"商品添加進(jìn)列表");? ? ? ? ? ? ? ? break;?? ? ? ? ? ? ? ?? ? ? ? ? ? case SKPaymentTransactionStateRestored://? ? ? ? ? ? ? ? NSLog(@"已經(jīng)購(gòu)買過商品");? ? ? ? ? ? ? ? [[SKPaymentQueue defaultQueue] finishTransaction:tran];? ? ? ? ? ? ? ? break;?? ? ? ? ? ? ? ?? ? ? ? ? ? case SKPaymentTransactionStateFailed://? ? ? ? ? ? ? ? NSLog(@"交易失敗");? ? ? ? ? ? ? ? [[SKPaymentQueue defaultQueue] finishTransaction:tran];? ? ? ? ? ? ? ? break;?? ? ? ? ? ? ? ?? ? ? ? ? ? case SKPaymentTransactionStateDeferred://? ? ? ? ? ? ? ? NSLog(@"交易還在隊(duì)列里面,但最終狀態(tài)還沒有決定");? ? ? ? ? ? ? ? break;?? ? ? ? ? ? ? ?? ? ? ? ? ? default:? ? ? ? ? ? ? ? break;? ? ? ? }?? ? ? ?? ? }?? ?}

#pragma mark ------ 支付完成,得到交易憑證- (void)completeTransaction:(SKPaymentTransaction *)transaction{?? ?? ? //此時(shí)告訴后臺(tái)交易成功颠蕴,并把receipt傳給后臺(tái)驗(yàn)證? ? NSString *transactionReceiptString= nil;? ? //系統(tǒng)IOS7.0以上獲取支付驗(yàn)證憑證的方式應(yīng)該改變泣刹,切驗(yàn)證返回的數(shù)據(jù)結(jié)構(gòu)也不一樣了。? ? // 驗(yàn)證憑據(jù)犀被,獲取到蘋果返回的交易憑據(jù)? ? // appStoreReceiptURL iOS7.0增加的椅您,購(gòu)買交易完成后,會(huì)將憑據(jù)存放在該地址? ? NSURLRequest *appstoreRequest = [NSURLRequest requestWithURL:[[NSBundle mainBundle] appStoreReceiptURL]];? ? NSError *error = nil;? ? // 從沙盒中獲取到購(gòu)買憑據(jù)?? ?? ? NSData * receiptData = [NSURLConnection sendSynchronousRequest:appstoreRequest returningResponse:nil error:&error];? ? // 20 BASE64 常用的編碼方案寡键,通常用于數(shù)據(jù)傳輸掀泳,以及加密算法的基礎(chǔ)算法,傳輸過程中能夠保證數(shù)據(jù)傳輸?shù)姆€(wěn)定性 21 BASE64是可以編碼和解碼的 22? ? transactionReceiptString = [receiptData base64EncodedStringWithOptions:0];//[receiptData base64EncodedStringWithOptions:0];? ? //? ? NSLog(@"requestContentstr:%@",[receiptData base64EncodedStringWithOptions:0]);?? ?? ? //? ? NSDictionary *dic = @{@"orderCode":self.dataOrder.orderCode,? ? //? ? ? ? ? ? ? ? ? ? ? ? ? @"receipt":transactionReceiptString,? ? //? ? ? ? ? ? ? ? ? ? ? ? ? @"category":@"1"? ? //? ? ? ? ? ? ? ? ? ? ? ? ? };? ? //? ? NSLog(@"diczhi:%@",dic);? ? //? ? //? ? self.tran = transaction;? ? //? ? [self.bizEBeanBuy requestAppStorePaySuccessCallBack:dic];//蘋果支付成功,傳receipt-data給后臺(tái)驗(yàn)證?? ???? ?? ? [[SKPaymentQueue defaultQueue] finishTransaction:transaction];?? ?}


5.沙盒測(cè)試

如下圖6,點(diǎn)添加創(chuàng)建沙盒測(cè)試賬號(hào),賬號(hào)未未注冊(cè)成AppleID的賬號(hào),測(cè)試前先到設(shè)置里退出當(dāng)前AppleID,登錄沙盒測(cè)試賬號(hào),沙盒測(cè)試賬號(hào)只能用來測(cè)試沙盒支付,不具備正常AppleID的功能.


圖6.創(chuàng)建沙盒測(cè)試賬號(hào)

需要了解雙重驗(yàn)證,交易憑證判重機(jī)制,漏單處理,提交審核坑,集成坑,交易流水對(duì)賬的朋友下方留言我抽時(shí)間補(bǔ)充.

補(bǔ)充內(nèi)容和代碼請(qǐng)看我的另一篇文章:iOS內(nèi)購(gòu)全面實(shí)戰(zhàn)

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末员舵,一起剝皮案震驚了整個(gè)濱河市脑沿,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌马僻,老刑警劉巖庄拇,帶你破解...
    沈念sama閱讀 217,084評(píng)論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異巫玻,居然都是意外死亡丛忆,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,623評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門仍秤,熙熙樓的掌柜王于貴愁眉苦臉地迎上來熄诡,“玉大人,你說我怎么就攤上這事诗力』烁。” “怎么了?”我有些...
    開封第一講書人閱讀 163,450評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵苇本,是天一觀的道長(zhǎng)袜茧。 經(jīng)常有香客問我,道長(zhǎng)瓣窄,這世上最難降的妖魔是什么笛厦? 我笑而不...
    開封第一講書人閱讀 58,322評(píng)論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮俺夕,結(jié)果婚禮上裳凸,老公的妹妹穿的比我還像新娘。我一直安慰自己劝贸,他們只是感情好姨谷,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,370評(píng)論 6 390
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著映九,像睡著了一般梦湘。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上件甥,一...
    開封第一講書人閱讀 51,274評(píng)論 1 300
  • 那天捌议,我揣著相機(jī)與錄音,去河邊找鬼嚼蚀。 笑死禁灼,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的轿曙。 我是一名探鬼主播弄捕,決...
    沈念sama閱讀 40,126評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼僻孝,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來了守谓?” 一聲冷哼從身側(cè)響起穿铆,我...
    開封第一講書人閱讀 38,980評(píng)論 0 275
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎斋荞,沒想到半個(gè)月后荞雏,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,414評(píng)論 1 313
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡平酿,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,599評(píng)論 3 334
  • 正文 我和宋清朗相戀三年凤优,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片蜈彼。...
    茶點(diǎn)故事閱讀 39,773評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡筑辨,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出幸逆,到底是詐尸還是另有隱情棍辕,我是刑警寧澤,帶...
    沈念sama閱讀 35,470評(píng)論 5 344
  • 正文 年R本政府宣布还绘,位于F島的核電站楚昭,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏拍顷。R本人自食惡果不足惜抚太,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,080評(píng)論 3 327
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望昔案。 院中可真熱鬧凭舶,春花似錦、人聲如沸爱沟。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,713評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)呼伸。三九已至,卻和暖如春钝尸,著一層夾襖步出監(jiān)牢的瞬間括享,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,852評(píng)論 1 269
  • 我被黑心中介騙來泰國(guó)打工珍促, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留铃辖,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 47,865評(píng)論 2 370
  • 正文 我出身青樓猪叙,卻偏偏與公主長(zhǎng)得像娇斩,于是被迫代替她去往敵國(guó)和親仁卷。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,689評(píng)論 2 354

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

  • 自己開發(fā)的視頻直播項(xiàng)目犬第,牽涉到充值金幣锦积,用到了蘋果公司的內(nèi)購(gòu),趴坑了兩天丰介,這里總結(jié)下實(shí)現(xiàn)蘋果內(nèi)購(gòu)。 一. 創(chuàng)建測(cè)試...
    Leo丶Dicaprio閱讀 3,378評(píng)論 8 7
  • - 消耗型項(xiàng)目 就像你玩游戲需要買金幣鉴分,買鉆石等哮幢,只要花錢就可以無限次的購(gòu)買 - 非消耗型項(xiàng)目 就像你在App S...
    tiger2016閱讀 654評(píng)論 0 1
  • 主要做一些轉(zhuǎn)載 備注在自己的簡(jiǎn)書里面。 每篇文章都注明轉(zhuǎn)載 本文章轉(zhuǎn)載http://www.reibang.com...
    aEva柳絮閱讀 2,170評(píng)論 0 1
  • 內(nèi)購(gòu)的前提: 有個(gè)人開發(fā)者賬號(hào);開通了銀行業(yè)務(wù);在開發(fā)者后臺(tái)添加了內(nèi)購(gòu)產(chǎn)品;創(chuàng)建了相應(yīng)的Bundle id 和證書...
    無wu閱讀 798評(píng)論 0 0
  • 姓名:刁偉聰 公司:寧波貞觀電器有限公司 寧波盛和塾《六項(xiàng)精進(jìn)》235期謙虛二組學(xué)員 【知~學(xué)習(xí)】 背誦六項(xiàng)精進(jìn)志珍,...
    真誠(chéng)無敵閱讀 112評(píng)論 0 0