iOS內(nèi)置付費開發(fā)筆記四(解鎖產(chǎn)品)

上一篇筆記

沃爾瑪賣一支牙膏的流程是: 1.把商家的牙膏放到貨柜上 2. 讓用戶自由選擇 3.用戶去收銀臺刷信用卡 4. 刷卡器交給用戶己肮,等待銀行確認(rèn)刷卡信息给猾,如果返回付款確認(rèn)信息占锯,讓用戶拿走牙膏。

內(nèi)置付費已經(jīng)走完了前面的三步透乾,用戶要一手交錢了侠仇,我們也要準(zhǔn)備一手交貨嘍。(只收錢不辦事兒在App Store是行不通的筑累,寫軟件易袱蜡,建國家難,且寫且珍惜慢宗。)

這一步的流程圖如下:


Delivering Products
Delivering Products

處理支付信息 (Processes payment)

再回到沃爾瑪購買牙膏的場景坪蚁,當(dāng)刷信用卡的時候,整個操作流程大體如下:

對于銀聯(lián)的直聯(lián)商戶镜沽,流程如下:
1敏晤、刷卡信息(包括磁道和密碼)由POS機(jī)具受理后通過收單機(jī)構(gòu)送往銀聯(lián)的收單系統(tǒng)。
2淘邻、銀聯(lián)收單系統(tǒng)將報文通過銀聯(lián)核心交換平臺送到信用卡的發(fā)卡銀行茵典,根據(jù)交易指令,在發(fā)卡銀行的對應(yīng)的卡片賬戶進(jìn)行扣款宾舅。
3统阿、銀聯(lián)核心交換系統(tǒng)收到扣款成功的返回后,將交易結(jié)果原路返回到POS終端上筹我。
4扶平、當(dāng)天晚上11點,清算信息開始批量處理蔬蕊。
5结澄、T+1日,各行在人行的頭寸賬戶根據(jù)銀聯(lián)的清算文件(指令)將資金進(jìn)行劃撥岸夯,即交易資金從信用卡的發(fā)卡銀行轉(zhuǎn)移到商戶的收單銀行麻献。
6、收單銀行將資金轉(zhuǎn)入商戶的具體清算賬戶(也可以由銀聯(lián)直接轉(zhuǎn)入)猜扮。
就扮演的角色而言勉吻,有持卡人、商戶旅赢、收單機(jī)構(gòu)(為商戶提供服務(wù)的銀行或機(jī)構(gòu))齿桃、轉(zhuǎn)接清算機(jī)構(gòu)(銀聯(lián)惑惶、VISA等卡組織)、發(fā)卡機(jī)構(gòu)(信用卡銀行)
(以上答案為知乎網(wǎng)友周宇的解答短纵,鏈接在此)

在內(nèi)置付費購買環(huán)節(jié)中带污,App Store在此處也扮演了銀聯(lián)收單系統(tǒng)的角色,App Store會把扣款成功的信息返回給“售貨員”, 這里的“售貨員”是我們的一段代碼香到,名字叫做transaction queue observer鱼冀。這個“售貨員”放在哪里有程序員自己來決定,大體上有兩個地方比較好:

  1. 對于非常小型的App, 可以放在 app delegate中
    2.對大部分的Apps, 單獨弄一個類养渴,和其它與Store有關(guān)的代碼放在一起就很不錯
    這個名叫observer的"售貨員"必須要"簽署"SKPaymentTransactionObserver協(xié)議才能完成工作雷绢。

    • (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary )launchOptions
      {
      /
      放一個“售貨員” */
      [[SKPaymentQueue defaultQueue] addTransactionObserver:observer];
      }

簽署了"SKPaymentTransactionObserver協(xié)議的“售貨員”必須遵從協(xié)議中的要求——執(zhí)行paymentQueue:updatedTransactions:這個函數(shù)泛烙。工作的職責(zé)是: 當(dāng)交易狀態(tài)(The Status of a Transaction)有任何的變化, 都要調(diào)用這個操作理卑。操作的具體細(xì)節(jié)需要我們來完成。

交易的四種主要狀態(tài)以及采取相應(yīng)的行動:

  1. SKPaymentTransactionStatePurchasing: 購買中蔽氨,此時可更新UI來展現(xiàn)購買的過程
  1. SKPaymentTransactionStateFailed: 購買錯誤藐唠,此時要根據(jù)錯誤的代碼給用戶相應(yīng)的提示

  2. SKPaymentTransactionStatePurchased: 購買成功,此時要提供給用戶相應(yīng)的內(nèi)容

  3. SKPaymentTransactionStateRestored: 恢復(fù)已購產(chǎn)品鹉究,此時需要將已經(jīng)購買的商品恢復(fù)給用戶

    • (void)paymentQueue:(SKPaymentQueue *)queue updatedTransactions:(NSArray *)transactions
      {
      for (SKPaymentTransaction *transaction in transactions) {
      switch (transaction.transactionState) {
      // Call the appropriate custom method.
      case SKPaymentTransactionStatePurchased: // 購買成功
      [self completeTransaction:transaction];
      break;
      case SKPaymentTransactionStateFailed: // 購買失敗
      [self failedTransaction:transaction];
      break;
      case SKPaymentTransactionStateRestored: // 恢復(fù)已購
      [self restoreTransaction:transaction];
      default:
      break;
      }
      }
      }

    • (void)completeTransaction:(SKPaymentTransaction *)transaction
      {
      NSString * productIdentifier = transaction.payment.productIdentifier;
      NSString * receipt = [transaction.transactionReceipt base64EncodedString];
      if ([productIdentifier length] > 0) {
      // 向自己的服務(wù)器驗證購買憑證
      }
      // Remove the transaction from the payment queue.
      [[SKPaymentQueue defaultQueue] finishTransaction: transaction];
      }

    • (void)failedTransaction:(SKPaymentTransaction *)transaction {
      if(transaction.error.code != SKErrorPaymentCancelled) {
      NSLog(@"購買失敗");
      } else {
      NSLog(@"用戶取消交易");
      }
      [[SKPaymentQueue defaultQueue] finishTransaction: transaction];
      }

    • (void)restoreTransaction:(SKPaymentTransaction *)transaction {
      // 恢復(fù)已經(jīng)購買的產(chǎn)品
      [[SKPaymentQueue defaultQueue] finishTransaction: transaction];
      }

保存好購物憑證(Persisting the Purchase)

現(xiàn)實中宇立,購物以后要給個發(fā)票或者購物小票。在這里自赔,也需要這么做妈嘹,永久存儲交易記錄。這樣做至少有兩個用處:

  • 程序啟動以后绍妨,檢查購買記錄润脸,讓已購的功能生效。
  • 當(dāng)用戶需要恢復(fù)已購功能的時候, 可以讀取這個記錄他去。
    保存購物憑證的方法有如下幾種:
  1. 對于非消耗(non-consumable) 品毙驯, 并且iOS 7以上,可以使用app receipt來記錄
  2. 對于非消耗(non-consumable)品灾测,但是是iOS7以下爆价,可以使用User Defaults system 或者 iCloud來記錄
  3. 對于消耗品(consumable), 因為不能在不同設(shè)備上同步,因此不需要做永久記錄(有種強(qiáng)拆的感覺啊!)

將Value/Key保存在User Defaults 或者 iCloud中

#if USE_ICLOUD_STORAGE
NSUbiquitousKeyValueStore *storage = [NSUbiquitousKeyValueStore defaultStore];
#else
NSUserDefaults *storage = [NSUserDefaults standardUserDefaults];
#endif

[storage setBool:YES forKey:@"enable_rocket_car"];
[storage setObject:@15 forKey:@"highest_unlocked_level"];
[storage synchronize];

將Receipt保存在User Defaults 或者 iCloud中

#if USE_ICLOUD_STORAGE
NSUbiquitousKeyValueStore *storage = [NSUbiquitousKeyValueStore defaultStore];
#else
NSUserDefaults *storage = [NSUserDefaults standardUserDefaults];
#endif

NSData *newReceipt = transaction.transactionReceipt;
NSArray *savedReceipts = [storage arrayForKey:@"receipts"];
if (!receipts) {
    // Storing the first receipt
    [storage setObject:@[newReceipt] forKey:@"receipts"];
} else {
    // Adding another receipt
    NSArray *updatedReceipts = [savedReceipts arrayByAddingObject:newReceipt];
    [storage setObject:updatedReceipts forKey:@"receipts"];
}
[storage synchronize];

解鎖功能 Unlocking App Functionality

當(dāng)用戶購買成功以后媳搪,就需要對相應(yīng)的產(chǎn)品功能進(jìn)行解鎖, 當(dāng)使用Receipt的時候铭段,代碼應(yīng)該類似于下面的樣子

NSURL *receiptURL = [[NSBundle mainBundle] appStoreReceiptURL];
NSData *receiptData = [NSData dataWithContentsOfURL:receiptURL];
// Custom method to work with receipts

BOOL rocketCarEnabled = [self receipt:receiptData includesProductID:@"com.example.rocketCar"];

當(dāng)使用Key:Value來存儲的時候, 代碼應(yīng)該類似于下面的樣子:

NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
BOOL rocketCarEnabled = [defaults boolForKey:@"enable_rocket_car"];

在程序中寫下如下相應(yīng)的代碼,判斷是否可以使用高級一點的功能 :)

if (rocketCarEnabled) {
    // Use the rocket car.
} else {
    // Use the regular car.
}

解鎖資源Delivering Associated Content

如果購買是有關(guān)資源的秦爆,比如更多的聲音序愚,更多的圖片,更多的素材等等鲜结,可以有三種方式來處理這種情況:

  1. (Local Content) 內(nèi)置一些熱門資源(預(yù)期會大賣的資源)展运,不要太大活逆,頂多幾M左右即可。
  2. (Apple-hosted Content) 使用Apple提供的Apple-hosted服務(wù)拗胜,這樣可以保證App的尺寸較為精簡蔗候。支持iOS 6以上。
  3. 使用自己的服務(wù)器埂软。

結(jié)束交易 Finishing the Transaction

這里沒什么好講的锈遥,就是結(jié)束交易了。

SKPaymentTransaction *transaction = <# The current payment #>;
[[SKPaymentQueue defaultQueue] finishTransaction:transaction];

需要注意的一點是勘畔,在交易結(jié)束之前所灸,不要調(diào)用這個函數(shù),會讓Apple-hosted Content沒法下載炫七,因為在下載Apple-hosted內(nèi)容之前爬立,返回的transaction有一個SKDownload屬性,如果貿(mào)然調(diào)用了此函數(shù)万哪,有可能會導(dǎo)致下載中斷侠驯,以及潛在的其它問題。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末奕巍,一起剝皮案震驚了整個濱河市吟策,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌的止,老刑警劉巖檩坚,帶你破解...
    沈念sama閱讀 219,188評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異诅福,居然都是意外死亡匾委,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,464評論 3 395
  • 文/潘曉璐 我一進(jìn)店門权谁,熙熙樓的掌柜王于貴愁眉苦臉地迎上來剩檀,“玉大人,你說我怎么就攤上這事旺芽』铮” “怎么了?”我有些...
    開封第一講書人閱讀 165,562評論 0 356
  • 文/不壞的土叔 我叫張陵采章,是天一觀的道長运嗜。 經(jīng)常有香客問我,道長悯舟,這世上最難降的妖魔是什么担租? 我笑而不...
    開封第一講書人閱讀 58,893評論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮抵怎,結(jié)果婚禮上奋救,老公的妹妹穿的比我還像新娘岭参。我一直安慰自己,他們只是感情好尝艘,可當(dāng)我...
    茶點故事閱讀 67,917評論 6 392
  • 文/花漫 我一把揭開白布演侯。 她就那樣靜靜地躺著,像睡著了一般背亥。 火紅的嫁衣襯著肌膚如雪秒际。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,708評論 1 305
  • 那天狡汉,我揣著相機(jī)與錄音娄徊,去河邊找鬼。 笑死盾戴,一個胖子當(dāng)著我的面吹牛寄锐,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播捻脖,決...
    沈念sama閱讀 40,430評論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼锐峭,長吁一口氣:“原來是場噩夢啊……” “哼中鼠!你這毒婦竟也來了可婶?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,342評論 0 276
  • 序言:老撾萬榮一對情侶失蹤援雇,失蹤者是張志新(化名)和其女友劉穎矛渴,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體惫搏,經(jīng)...
    沈念sama閱讀 45,801評論 1 317
  • 正文 獨居荒郊野嶺守林人離奇死亡具温,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,976評論 3 337
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了筐赔。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片铣猩。...
    茶點故事閱讀 40,115評論 1 351
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖茴丰,靈堂內(nèi)的尸體忽然破棺而出达皿,到底是詐尸還是另有隱情,我是刑警寧澤贿肩,帶...
    沈念sama閱讀 35,804評論 5 346
  • 正文 年R本政府宣布峦椰,位于F島的核電站,受9級特大地震影響汰规,放射性物質(zhì)發(fā)生泄漏汤功。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,458評論 3 331
  • 文/蒙蒙 一溜哮、第九天 我趴在偏房一處隱蔽的房頂上張望滔金。 院中可真熱鬧色解,春花似錦、人聲如沸餐茵。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,008評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽钟病。三九已至萧恕,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間肠阱,已是汗流浹背票唆。 一陣腳步聲響...
    開封第一講書人閱讀 33,135評論 1 272
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留屹徘,地道東北人走趋。 一個月前我還...
    沈念sama閱讀 48,365評論 3 373
  • 正文 我出身青樓,卻偏偏與公主長得像噪伊,于是被迫代替她去往敵國和親簿煌。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,055評論 2 355

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