iOS 內(nèi)購(消耗型)

一漂问、前言

公司最近有個(gè)新需求赖瞒,充值金幣(消耗型),通過內(nèi)購的方式購買蚤假。今天就把我在內(nèi)購的時(shí)候的過程分享一下栏饮。這里我只說開發(fā)時(shí)候的過程,之前一些配置一筆帶過磷仰。我這里還有個(gè)需求袍嬉,因?yàn)槭嵌嗟貐^(qū)上線,所以在內(nèi)購的時(shí)候要根據(jù)不同App Store國家展示不同的貨幣灶平。(這個(gè)會(huì)重點(diǎn)說)

  1. 登錄開發(fā)者賬號(hào)伺通,配置相關(guān)協(xié)議,銀行信息等逢享,后臺(tái)添加商品罐监,配置沙盒測試賬號(hào)。(這部分我省略掉瞒爬,原因是網(wǎng)上很多詳細(xì)資料弓柱,不想拷貝)
  2. 開發(fā)的具體步驟(前提是第一步已經(jīng)完成沒有問題了)
  3. 需要注意和遇到的問題

1.1 遇到的問題

先把遇到的問題說出來,帶著問題開發(fā)侧但。

  • 沙盒環(huán)境支付成功后吆你,再次支付,告訴無需支付再次支付(提示信息:您已購買此APP內(nèi)購買項(xiàng)目俊犯,此項(xiàng)目將免費(fèi)恢復(fù))妇多,明明是消耗型產(chǎn)品,可以多次購買燕侠,為什么會(huì)提示這個(gè)信息者祖?
  • 沙盒測試賬號(hào)購買成功了怎么換其他的沙盒賬號(hào)?
  • 支付成功后绢彤,如何和自己公司進(jìn)行服務(wù)器憑證的驗(yàn)證七问?
  • 如何根據(jù)不同國家/地區(qū)的AppleID 判斷是屬于哪個(gè)國家的?
  • 提交審核時(shí)注意事項(xiàng)

接下來茫舶,我們帶著這些問題來開實(shí)現(xiàn)械巡。

二、開發(fā)具體實(shí)現(xiàn)

2.1 Xcode 配置

image.png

2.2 代碼實(shí)現(xiàn)

  1. 創(chuàng)建一個(gè)管理類,IAPManager,以單例的形式讥耗。
  2. 創(chuàng)建幾個(gè)方法有勾,如下

判斷用戶是否有權(quán)限購買,這個(gè)是個(gè)前提古程,因?yàn)檫@個(gè)關(guān)于家長控制的蔼卡,只有手機(jī)設(shè)置允許內(nèi)購,才可以進(jìn)行支付等操作,用到的方法如下挣磨,邏輯根據(jù)自己需求寫

/**
 *  判斷用戶是否具有內(nèi)購權(quán)限
 */
- (BOOL)determineUserHasPaymentAuthority;
- (BOOL)determineUserHasPaymentAuthority {
    // 判斷用戶是否具備支付權(quán)限
    if ([SKPaymentQueue canMakePayments]) {
        NSLog(@"允許應(yīng)用內(nèi)付費(fèi)購買");
        return YES;
    } else {
        NSLog(@"用戶禁止應(yīng)用內(nèi)付費(fèi)購買");
        return NO;
    }
}

根據(jù)productID雇逞,去調(diào)用支付的方法,這個(gè)請求是像蘋果服務(wù)器發(fā)送請求,其中 productID 是之前在后臺(tái)配置好的茁裙。發(fā)送請求塘砸,遵守協(xié)議,在回調(diào)中處理相關(guān)邏輯晤锥。

/**
 *  根據(jù)productID 去支付
 */
- (void)goToPayWithProductID:(NSArray *)productID orderID:(NSString *)orderID completion:(void (^)(IAPStatus status))completion;
- (void)requestInAppProductWithProductID:(NSArray *)productID isPay:(BOOL)isPay {
    // 拿到productID 發(fā)送請求 給蘋果
    NSSet *set = [NSSet setWithArray:productID];
    SKProductsRequest *request = [[SKProductsRequest alloc] initWithProductIdentifiers:set];
    request.delegate = self;
    _isPay = isPay;
    [request start];
}

這里遵守兩個(gè)協(xié)議 SKPaymentTransactionObserver SKProductsRequestDelegate谣蠢,第一個(gè)是支付整個(gè)過程的監(jiān)聽,第二個(gè)就是發(fā)送給蘋果服務(wù)器的回調(diào)查近。根據(jù)回調(diào),我們可以拿到 SKProduct挤忙。根據(jù)下面的方法去支付

// 去支付
SKPayment *payment = [SKPayment paymentWithProduct:product];
[[SKPaymentQueue defaultQueue] addPayment:payment];

接下來霜威,監(jiān)聽整個(gè)支付的過程。在合適的位置添加觀察者代碼册烈,在合適的位置移除觀察者戈泼。

- (instancetype)init {
    if (self = [super init]) {
        
        [[SKPaymentQueue defaultQueue] addTransactionObserver:self];
    }
    return self;
}
- (void)dealloc {
    [[SKPaymentQueue defaultQueue] removeTransactionObserver:self];
}

這里需要注意,在監(jiān)聽每個(gè)狀態(tài)結(jié)束后赏僧,都要調(diào)用一下這個(gè)方法大猛,必須調(diào)用 ,無論是成功還是失敗。如果不調(diào)用次方法淀零,在購買消耗類型成功后挽绩,會(huì)出現(xiàn),你已經(jīng)購買過該產(chǎn)品這樣的錯(cuò)誤驾中。(消耗類型是不存在已經(jīng)購買過的)唉堪。

[[SKPaymentQueue defaultQueue] finishTransaction:tran];

其實(shí)支付這部分不想說太多,因?yàn)橛刑鄬懙膬?yōu)秀的了肩民,我就是說說我的情況唠亚。下面才是我最想說的。

3.根據(jù)不同地區(qū)AppleID / AppStore 位置展示不同的貨幣

這個(gè)部分有個(gè)前提持痰,就是你必須支持內(nèi)購灶搜,并且后臺(tái)都配好了相關(guān)產(chǎn)品,使用StoreKit 才能實(shí)現(xiàn)。

3.1 向蘋果后臺(tái)發(fā)送請求割卖,獲取SKProuct

 // 拿到productID 發(fā)送請求 給蘋果
    NSSet *set = [NSSet setWithArray:productID];
    SKProductsRequest *request = [[SKProductsRequest alloc] initWithProductIdentifiers:set];
    request.delegate = self;
    _isPay = isPay;
    [request start];

3.2 根據(jù)SKProduct 獲取地區(qū)相關(guān)信息

- (void)judgeWhichCountryWithProduct:(SKProduct *)product {
    
    NSString *localID = product.priceLocale.localeIdentifier;
    NSArray *strings = [localID componentsSeparatedByString:@"@"];
    localID = [strings firstObject];
    NSArray *language = [localID componentsSeparatedByString:@"_"];
    localID = [language lastObject];
//    NSLog(@"localID --- %@",localID);

    if ([localID isEqualToString:@"VN"]) {
        NSLog(@"越南App Store");
        if (_countryCodeBlock) {
            _countryCodeBlock(CountryCodeVN);
        }
    } else if ([localID isEqualToString:@"ID"]) {
        NSLog(@"印度尼西亞 App Store");
        if (_countryCodeBlock) {
            _countryCodeBlock(CountryCodeID);
        }
    } else if ([localID isEqualToString:@"US"]) {
        NSLog(@"美國 App Store");
        if (_countryCodeBlock) {
            _countryCodeBlock(CountryCodeUS);
        }
    } else if ([localID isEqualToString:@"SG"]) {
        NSLog(@"新加坡 App Store");
        if (_countryCodeBlock) {
            _countryCodeBlock(CountryCodeSG);
        }
    } else if ([localID isEqualToString:@"IN"]) {
        NSLog(@"印度 App Store");
        if (_countryCodeBlock) {
            _countryCodeBlock(CountryCodeIN);
        }
    } else if ([localID isEqualToString:@"PH"]) {
        NSLog(@"菲律賓 App Store");
        if (_countryCodeBlock) {
            _countryCodeBlock(CountryCodePH);
        }
    } else if ([localID isEqualToString:@"MY"]) {
        NSLog(@"菲律賓 App Store");
        if (_countryCodeBlock) {
            _countryCodeBlock(CountryCodeMY);
        }
    } else {
        NSLog(@"其他地區(qū) App Store");
        if (_countryCodeBlock) {
            _countryCodeBlock(CountryCodeUS);
        }
    }
    
}

這樣你就知道前酿,你的AppleID 是哪個(gè)國家的了【可海可以根據(jù)各個(gè)國家展示相應(yīng)貨幣了薪者。

4. 遺留問題

  • 沙盒環(huán)境支付成功后,再次支付剿涮,告訴無需支付再次支付(提示信息:您已購買此APP內(nèi)購買項(xiàng)目言津,此項(xiàng)目將免費(fèi)恢復(fù)),明明是消耗型產(chǎn)品取试,可以多次購買悬槽,為什么會(huì)提示這個(gè)信息?

前面已經(jīng)提到了

  • 沙盒測試賬號(hào)購買成功了怎么換其他的沙盒賬號(hào)瞬浓?

你可能添加了各個(gè)國家/地區(qū)不同的沙盒測試賬號(hào)初婆,來測試貨幣問題,你發(fā)現(xiàn)猿棉,在支付界面無法更換磅叛。更換位置在手機(jī)設(shè)置 -> iTunes Store 與 App Store -> 滑到最底下,有個(gè)沙盒賬戶

  • 支付成功后萨赁,如何和自己公司進(jìn)行服務(wù)器憑證的驗(yàn)證弊琴?

成功后,你需要拿到一個(gè)支付憑證杖爽,拿到支付憑證敲董,發(fā)給自己服務(wù)器與蘋果后臺(tái)進(jìn)行校驗(yàn),檢驗(yàn)成功慰安,才充值成功

NSURL *receiptURL = [[NSBundle mainBundle] appStoreReceiptURL];
NSData *receipt = [NSData dataWithContentsOfURL:receiptURL];
NSString *receiptStr = [receipt base64EncodedStringWithOptions:NSDataBase64EncodingEndLineWithLineFeed];

注意 服務(wù)器那邊腋寨,要根據(jù)是沙盒環(huán)境還是正式環(huán)境給不同的URL發(fā)送請求,當(dāng)提交審核的時(shí)候化焕,蘋果審核時(shí)沙盒環(huán)境萄窜,所以要根據(jù)環(huán)境來判斷往哪里發(fā)送請求

服務(wù)器與蘋果服務(wù)器交互

  • 如何根據(jù)不同國家/地區(qū)的AppleID 判斷是屬于哪個(gè)國家的?
  • 提交審核時(shí)注意事項(xiàng)

以上兩個(gè)問題都涉及了撒桨,不懂的留言交流吧脂倦。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市元莫,隨后出現(xiàn)的幾起案子赖阻,更是在濱河造成了極大的恐慌,老刑警劉巖踱蠢,帶你破解...
    沈念sama閱讀 221,820評論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件火欧,死亡現(xiàn)場離奇詭異棋电,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)苇侵,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,648評論 3 399
  • 文/潘曉璐 我一進(jìn)店門赶盔,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人榆浓,你說我怎么就攤上這事于未。” “怎么了陡鹃?”我有些...
    開封第一講書人閱讀 168,324評論 0 360
  • 文/不壞的土叔 我叫張陵烘浦,是天一觀的道長。 經(jīng)常有香客問我萍鲸,道長闷叉,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 59,714評論 1 297
  • 正文 為了忘掉前任脊阴,我火速辦了婚禮握侧,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘嘿期。我一直安慰自己品擎,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,724評論 6 397
  • 文/花漫 我一把揭開白布备徐。 她就那樣靜靜地躺著萄传,像睡著了一般。 火紅的嫁衣襯著肌膚如雪坦喘。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 52,328評論 1 310
  • 那天西设,我揣著相機(jī)與錄音瓣铣,去河邊找鬼。 笑死贷揽,一個(gè)胖子當(dāng)著我的面吹牛棠笑,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播禽绪,決...
    沈念sama閱讀 40,897評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼蓖救,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了印屁?” 一聲冷哼從身側(cè)響起循捺,我...
    開封第一講書人閱讀 39,804評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎雄人,沒想到半個(gè)月后从橘,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體念赶,經(jīng)...
    沈念sama閱讀 46,345評論 1 318
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,431評論 3 340
  • 正文 我和宋清朗相戀三年恰力,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了叉谜。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,561評論 1 352
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡踩萎,死狀恐怖停局,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情香府,我是刑警寧澤董栽,帶...
    沈念sama閱讀 36,238評論 5 350
  • 正文 年R本政府宣布,位于F島的核電站回还,受9級特大地震影響裆泳,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜柠硕,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,928評論 3 334
  • 文/蒙蒙 一工禾、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧蝗柔,春花似錦闻葵、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,417評論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至胁编,卻和暖如春厢钧,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背嬉橙。 一陣腳步聲響...
    開封第一講書人閱讀 33,528評論 1 272
  • 我被黑心中介騙來泰國打工早直, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人市框。 一個(gè)月前我還...
    沈念sama閱讀 48,983評論 3 376
  • 正文 我出身青樓霞扬,卻偏偏與公主長得像,于是被迫代替她去往敵國和親枫振。 傳聞我的和親對象是個(gè)殘疾皇子喻圃,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,573評論 2 359

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