一漂问、前言
公司最近有個(gè)新需求赖瞒,充值金幣(消耗型),通過內(nèi)購的方式購買蚤假。今天就把我在內(nèi)購的時(shí)候的過程分享一下栏饮。這里我只說開發(fā)時(shí)候的過程,之前一些配置一筆帶過磷仰。我這里還有個(gè)需求袍嬉,因?yàn)槭嵌嗟貐^(qū)上線,所以在內(nèi)購的時(shí)候要根據(jù)不同App Store國家展示不同的貨幣灶平。(這個(gè)會(huì)重點(diǎn)說)
- 登錄開發(fā)者賬號(hào)伺通,配置相關(guān)協(xié)議,銀行信息等逢享,后臺(tái)添加商品罐监,配置沙盒測試賬號(hào)。(這部分我省略掉瞒爬,原因是網(wǎng)上很多詳細(xì)資料弓柱,不想拷貝)
- 開發(fā)的具體步驟(前提是第一步已經(jīng)完成沒有問題了)
- 需要注意和遇到的問題
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 配置
2.2 代碼實(shí)現(xiàn)
- 創(chuàng)建一個(gè)管理類,
IAPManager
,以單例的形式讥耗。 - 創(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ā)送請求
- 如何根據(jù)不同國家/地區(qū)的AppleID 判斷是屬于哪個(gè)國家的?
- 提交審核時(shí)注意事項(xiàng)
以上兩個(gè)問題都涉及了撒桨,不懂的留言交流吧脂倦。