IAP內(nèi)購(gòu)支付流程
- Client向Server發(fā)送請(qǐng)求侨赡,獲得一份產(chǎn)品列表。
- Server返回包含產(chǎn)品標(biāo)識(shí)符的列表锚烦。
- Client向App Store發(fā)送請(qǐng)求扩然,得到產(chǎn)品的信息。
- App Store返回產(chǎn)品信息聋伦。
- Client把返回的產(chǎn)品信息顯示給用戶(App的store界面)
- 用戶選擇某個(gè)產(chǎn)品
- Client向App Store發(fā)送支付請(qǐng)求
- App Store處理支付請(qǐng)求并返回交易完成信息
- Client從信息中獲得數(shù)據(jù)夫偶,并發(fā)送至Server
- Server紀(jì)錄數(shù)據(jù)界睁,并進(jìn)行審(我們的)查
- Server將數(shù)據(jù)發(fā)給App Store來(lái)驗(yàn)證該交易的有效性
- App Store對(duì)收到的數(shù)據(jù)進(jìn)行解析,返回該數(shù)據(jù)和說(shuō)明其是否有效的標(biāo)識(shí)
- Server讀取返回的數(shù)據(jù)兵拢,確定用戶購(gòu)買的內(nèi)容
- Server將購(gòu)買的內(nèi)容傳遞給Client
配置內(nèi)購(gòu)環(huán)境
- 按要求錄入該賬戶銀行卡信息和相關(guān)用戶信息
- 根據(jù)項(xiàng)目需求選擇適合的內(nèi)購(gòu)類型:消耗項(xiàng)目翻斟、非消耗項(xiàng)目、自動(dòng)續(xù)費(fèi)说铃、非自動(dòng) 續(xù)費(fèi)访惜;
- 錄入相應(yīng)的產(chǎn)品內(nèi)購(gòu)信息如:名稱、ID腻扇、價(jià)格债热;
- 創(chuàng)建 沙盒測(cè)試賬號(hào) ;
- Capabilities里面打開(kāi)Purchase功能幼苛;
* 錄入該賬戶銀行卡信息和相關(guān)用戶信息
點(diǎn)擊 “協(xié)議窒篱、稅務(wù)和銀行業(yè)務(wù)”
內(nèi)購(gòu)用的是付費(fèi)應(yīng)用程序,先簽署《付費(fèi)應(yīng)用程序協(xié)議》舶沿,同意后狀態(tài)變更為“用戶信息待處理”墙杯,等待審核。
狀態(tài)更改完畢后括荡,點(diǎn)擊“開(kāi)始設(shè)置稅務(wù)高镐、銀行業(yè)務(wù)和聯(lián)系信息”。
(1)添加銀行賬戶,按照要求填寫相關(guān)內(nèi)容即可畸冲。
(2)選擇報(bào)稅表嫉髓,并填寫。所有與 Apple 有商業(yè)合作者必選都是美國(guó)召夹,若有其他需求岩喷,可以多選。
繼續(xù)填寫监憎,首先認(rèn)證公司基本信息纱意,選擇所有人類型,確認(rèn)無(wú)誤后認(rèn)證條款處打?qū)?/p>
Part I 部分鲸阔,繼續(xù)核對(duì)公司相關(guān)信息逼纸,選填內(nèi)容可不填。
Part III 部分汰翠,簽署稅務(wù)條約十拣,設(shè)置利益限制條款的種類,選填內(nèi)容可不填渔扎。此部分如果需要可勾選上下圖勾選框硫狞,不需要可不勾選,我們這個(gè)項(xiàng)目沒(méi)有用到part III 部分,所以沒(méi)有勾選。
Part XXX 部分残吩,確認(rèn)之前填寫的信息财忽,勾選完畢后,提交
(3)填寫聯(lián)系信息泣侮,共5個(gè)即彪。高級(jí)管理、財(cái)務(wù)活尊、技術(shù)隶校、法務(wù)、營(yíng)銷蛹锰。只需要提供5個(gè)人的基本信息即可深胳。
添加內(nèi)購(gòu)商品信息
https://appstoreconnect.apple.com/apps/1604297713/appstore/addons?m=
消耗型項(xiàng)目
只可使用一次的產(chǎn)品,使用之后即失效宁仔,必須再次購(gòu)買稠屠。
示例:釣魚(yú) App 中的魚(yú)食。
非消耗型項(xiàng)目
只需購(gòu)買一次翎苫,不會(huì)過(guò)期或隨著使用而減少的產(chǎn)品权埠。
示例:游戲 App 的賽道。
自動(dòng)續(xù)期訂閱
允許用戶在固定時(shí)間段內(nèi)購(gòu)買動(dòng)態(tài)內(nèi)容的產(chǎn)品煎谍。除非用戶選擇取消攘蔽,否則此類訂閱會(huì)自動(dòng)續(xù)期。
示例:每月訂閱提供流媒體服務(wù)的 App呐粘。
非續(xù)期訂閱
允許用戶購(gòu)買有時(shí)限性服務(wù)的產(chǎn)品满俗。此 App 內(nèi)購(gòu)買項(xiàng)目的內(nèi)容可以是靜態(tài)的。此類訂閱不會(huì)自動(dòng)續(xù)期作岖。
示例:為期一年的已歸檔文章目錄訂閱唆垃。
用于 App 審核的商品截屏
App 內(nèi)購(gòu)買項(xiàng)目的截屏,即所售項(xiàng)目的示意圖痘儡。例如辕万,如果 App 內(nèi)購(gòu)買項(xiàng)目是一本圖書,您可以提交圖書的截屏沉删。您也可以提交購(gòu)買頁(yè)的截屏渐尿。該截屏僅用于 Apple 審核,不會(huì)在 App Store 中顯示矾瑰。
截屏要求如下:
iOS 至少需要 640 x 920 像素
Apple tvOS 需要 1920 x 1080 像素
macOS 需要 1280 x 800 像素
App 審核圖像上傳后砖茸,可以替換,但無(wú)法移除殴穴。當(dāng)您的 App 內(nèi)購(gòu)買項(xiàng)目處于審核中時(shí)凉夯,您無(wú)法更新截屏货葬。
- 在首頁(yè)上,點(diǎn)按“我的 App”劲够,然后選擇與該 App 內(nèi)購(gòu)買項(xiàng)目相關(guān)聯(lián)的 App宝惰。
- 在工具欄中,點(diǎn)按“功能”再沧,然后在左列中點(diǎn)按“App 內(nèi)購(gòu)買項(xiàng)目”。
- 若要添加 App 內(nèi)購(gòu)買項(xiàng)目尊残,請(qǐng)前往“App 內(nèi)購(gòu)買項(xiàng)目”炒瘸,并點(diǎn)按“添加”按鈕(+)。
- 選擇“消耗型項(xiàng)目”寝衫、“非消耗型項(xiàng)目”或“非續(xù)訂訂閱”顷扩,并點(diǎn)按“創(chuàng)建”。有關(guān)自動(dòng)續(xù)訂訂閱的信息慰毅,請(qǐng)參見(jiàn)創(chuàng)建自動(dòng)續(xù)期訂閱隘截。
- 添加參考名稱、產(chǎn)品 ID 和本地化顯示名稱汹胃。
- 點(diǎn)按“存儲(chǔ)”或“提交以供審核”婶芭。
提交審核前需要上傳購(gòu)買界面截圖,供蘋果審核
在項(xiàng)目中開(kāi)啟In-App Purchase
- 提交新的版本
我看的文章都是創(chuàng)建好內(nèi)購(gòu)項(xiàng)目之后就可能在項(xiàng)目中使用測(cè)試了着饥,當(dāng)時(shí)我的結(jié)果就是無(wú)效productID
犀农。綠色框中寫的很明白要重新提交二進(jìn)制文件(.ipa文件),新的版本中添加在步驟3中添加的內(nèi)購(gòu)項(xiàng)目宰掉。
- 注意:
最好選擇手動(dòng)發(fā)布呵哨,因?yàn)楸敬翁峤恢皇菫榱俗寗?chuàng)建的內(nèi)購(gòu)項(xiàng)目ID生效,項(xiàng)目中可以沒(méi)有關(guān)于內(nèi)購(gòu)的邏輯代碼
* 沙盒賬號(hào)創(chuàng)建及使用注意事項(xiàng)
① 沙盒賬號(hào)創(chuàng)建
https://appstoreconnect.apple.com/access/testers
- 登錄蘋果開(kāi)發(fā)者后臺(tái)--iTunes Connect--用戶和職能--沙箱測(cè)試技術(shù)員轨奄,在這個(gè)界面你可以看到當(dāng)前賬號(hào)已經(jīng)創(chuàng)建好的沙盒賬號(hào)孟害。
- 點(diǎn)擊“+”進(jìn)行創(chuàng)建
②注意事項(xiàng)
- 電子郵件不能是別人已經(jīng)注冊(cè)過(guò)AppleID的郵箱
- App Store 地區(qū)不要亂選。雖然隨便哪個(gè)地區(qū)都可以用來(lái)測(cè)試(還沒(méi)上線之前app并沒(méi)有地區(qū)之分)挪拟,但是在沙盒測(cè)試的時(shí)候挨务,彈出的購(gòu)買提示框會(huì)根據(jù)當(dāng)前AppleID(沙盒賬號(hào))的地區(qū)顯示語(yǔ)言的。
沙箱賬號(hào)怎么登錄不成功舞丛?
沙箱賬號(hào)是不能直接在App Store進(jìn)行登錄的耘子,只能在點(diǎn)擊了購(gòu)買商品之后,在彈出的登錄框進(jìn)行登錄
球切。
驗(yàn)證是否已登錄沙箱測(cè)試賬號(hào):
設(shè)置--iTunes Store與App Store谷誓,頁(yè)面拉到最底部,會(huì)看到沙箱賬戶項(xiàng)會(huì)列出你已登錄的沙箱測(cè)試賬號(hào)吨凑!
③沙盒賬號(hào)使用的前提
- bundleID別搞錯(cuò)了捍歪,開(kāi)發(fā)者賬號(hào)户辱、證書、bundleID要一致
- 內(nèi)購(gòu)的商品ID糙臼,價(jià)格等相關(guān)信息已經(jīng)錄入到開(kāi)發(fā)者后臺(tái)了(不然那你買什么)
- 開(kāi)發(fā)者后臺(tái)已經(jīng)創(chuàng)建好沙盒測(cè)試賬號(hào)了(下面我們會(huì)講如何創(chuàng)建)
- 你要有一部真機(jī)(iPhone或iPad都行庐镐,別用模擬器就好。而且不能是越獄機(jī))
- 如果你是第一次在這個(gè)開(kāi)發(fā)者賬號(hào)上集成內(nèi)購(gòu)功能变逃,請(qǐng)先將iTune Connect上的稅務(wù)協(xié)議都填寫好必逆,否則內(nèi)購(gòu)時(shí)會(huì)發(fā)現(xiàn)商品ID無(wú)效。
④沙盒賬號(hào)使用流程
- 1.在iPhone上安裝測(cè)試包(必須是adhoc簽名證書或者develop簽名證書打的包揽乱,不能是從App Store上下載的)
- 2.
退出iPhone的App Store賬號(hào)(因?yàn)槲覀冃枰褂蒙澈匈~號(hào)登錄)
名眉。
操作方法一:打開(kāi)App Store應(yīng)用首頁(yè)滑到最下方--選中AppleID--注銷
操作方法二:設(shè)置--iTunes Store與App Store--選中AppleID--注銷
- 3.在測(cè)試包里面購(gòu)買商品,系統(tǒng)會(huì)讓你進(jìn)行登錄凰棉,這里我們點(diǎn)擊“使用現(xiàn)有的AppleID”就可以輸入剛才創(chuàng)建好的沙盒測(cè)試賬號(hào)進(jìn)行登錄了
- 4.點(diǎn)擊購(gòu)買商品之后损拢,成功的話會(huì)出現(xiàn)相應(yīng)提示
- 5.我們?cè)趇Tunes Connect上創(chuàng)建商品了之后,除了需要填商品ID撒犀,商品名稱福压,商品描述,價(jià)格等之外或舞,還要上傳一張圖片荆姆,圖片就是下面這個(gè)界面。
flutter_inapp_purchase 支付插件使用
1.下載依賴
# iOS 內(nèi)購(gòu)
flutter_inapp_purchase: ^2.0.5
2.常見(jiàn)用法
2.1初始化配置(initState
)
checks if the client can make payments(檢測(cè)App是否能支付)
StreamSubscription _purchaseUpdatedSubscription;
StreamSubscription _purchaseErrorSubscription;
List<IAPItem> _items = [];
List<PurchasedItem> _purchases = [];
Future<void> initPlatformState() async {
// prepare
var result = await FlutterInappPurchase.instance.initConnection;
print('result: $result');
// 判斷容器是否加載
if (!mounted) return;
// 更新購(gòu)買訂閱消息
_purchaseUpdatedSubscription =
FlutterInappPurchase.purchaseUpdated.listen((productItem) {
print('purchase-updated: $productItem');
});
// 購(gòu)買報(bào)錯(cuò)訂閱消息
_purchaseErrorSubscription =
FlutterInappPurchase.purchaseError.listen((purchaseError) {
print('purchase-error: $purchaseError');
});
}
2.2結(jié)束支付
await FlutterInappPurchase.instance.endConnection;
_purchaseUpdatedSubscription.cancel();
_purchaseUpdatedSubscription = null;
_purchaseErrorSubscription.cancel();
_purchaseErrorSubscription = null;
setState(() {
this._items = [];
this._purchases = [];
});
2.3獲取商品(_getProduct
)
final List<String> _productLists = Platform.isAndroid
? [
'android.test.purchased',
'point_1000',
'5000_point',
'android.test.canceled',
]
: ['com.cooni.point1000', 'com.cooni.point5000'];
List<IAPItem> _items = [];
////////////////////////////////////
Future _getProduct() async {
List<IAPItem> items =
await FlutterInappPurchase.instance.getProducts(_productLists);
for (var item in items) {
print('item==============>${item.toString()}');
this._items.add(item);
}
setState(() {
this._items = items;
this._purchases = [];
});
}
2.4獲取已購(gòu)買商品(_getPurchases
)
getAvailablePurchases
Get all non-consumed purchases 獲取未消費(fèi)的商品
Future _getPurchases() async {
List<PurchasedItem> items =
await FlutterInappPurchase.instance.getAvailablePurchases();
print('_getPurchases${items}');
for (var item in items) {
print('getAvailablePurchases======>${item.toString()}');
this._purchases.add(item);
}
setState(() {
this._items = [];
this._purchases = items;
});
}
2.5.獲取購(gòu)買歷史(getPurchaseHistory)
Future _getPurchaseHistory() async {
List<PurchasedItem> items =
await FlutterInappPurchase.instance.getPurchaseHistory();
print('_getPurchaseHistory${items}');
for (var item in items) {
print('${item.toString()}');
this._purchases.add(item);
}
setState(() {
this._items = [];
this._purchases = items;
});
}
2.6購(gòu)買商品(requestPurchase
)
print("---------- Buy Item Button Pressed");
Map<String, dynamic> json = {
'price': '0.01',
'productId': 'com.games.ztyxs.product_point.1'
};
IAPItem item = IAPItem.fromJSON(json);
this._requestPurchase(item);
---------------------------
void _requestPurchase(IAPItem item) {
FlutterInappPurchase.instance
.requestPurchase(item.productId ?? 'com.games.ztyxs.product_point.1');
}
打印信息查詢映凳;
purchase-error: responseCode: null, debugMessage: Invalid product ID., code: E_DEVELOPER_ERROR, message: Invalid product ID.
原因:
沒(méi)有先執(zhí)行g(shù)etProducts胞枕,直接執(zhí)行requestPurchase方法,要先拉取商品列表,再執(zhí)行購(gòu)買操作.
2.7.補(bǔ)充
- 如果用戶退款魏宽,在recipt字段中會(huì)接收到
cancel_data
字段取消日期對(duì)于由Apple客戶支持取消的交易腐泻,取消的時(shí)間和日期
iOS 內(nèi)購(gòu)返回商品列表ID為空
問(wèn)題描述;
response.products商品返回列表為空
response.invalidProductIdentifiers無(wú)效產(chǎn)品id有數(shù)據(jù)
解決方法
- 1.創(chuàng)建的App ID是否啟用了IAP功能队询。
//允許內(nèi)購(gòu)允許iap
if([SKPaymentQueue canMakePayments]){
[self requestProductData:product];
}else{
NSLog(@"不允許程序內(nèi)付費(fèi)");
}
- 2.商品信息是否配置到iTurn Connect派桩,并到達(dá)“準(zhǔn)備提交”狀態(tài).
3.在iTurn Connect中創(chuàng)建沙盒測(cè)試員,并收取郵件激活蚌斩。之后登錄到測(cè)試用手機(jī)的設(shè)置頁(yè)面中(Store選項(xiàng))铆惑。
4.是否創(chuàng)建相應(yīng)的provisioning profile,并用此簽名App送膳。
5.iTurn Connect后臺(tái)配置完商品信息后员魏,是否等待若干小時(shí)生效。
6.SKProductsRequest請(qǐng)求的商品Id必須和iTurn Connect中配置的一致叠聋。(如:com.test.product.xxx)
7.iTunes Connect中配置的銀行撕阎、稅務(wù)信息是否正確。
8.是否先刪除舊App碌补,再重新編譯生成新的虏束。
漏單等情況預(yù)防與處理方案
1.漏單必須要處理棉饶,玩家花RMB購(gòu)買的東西卻丟失了,是絕對(duì)不能容忍的镇匀。所謂的漏單就是玩家已經(jīng)正常付費(fèi)照藻,卻沒(méi)有拿到該拿的道具。
解決:只要購(gòu)買成功汗侵,便將購(gòu)買記錄(receipt等賬單信息)保存下來(lái)幸缕,然后將賬單信息傳送給我們游戲服務(wù)器,游戲服務(wù)器獲得賬單后晰韵,和蘋果服務(wù)器驗(yàn)證冀值,賬單有效的話,回饋給游戲服務(wù)器處理宫屠,游戲服務(wù)器處理后,返回給游戲客戶端處理滑蚯,處理完畢浪蹂,將本地保存的購(gòu)買記錄刪除。
receipt-data 支付憑證校驗(yàn)
https://developer.apple.com/library/content/releasenotes/General/ValidateAppStoreReceipt/Chapters/ValidateRemotely.html 官方文檔:向蘋果校驗(yàn)支付憑證
蘋果反饋的狀態(tài)碼
21000 App Store無(wú)法讀取你提供的JSON數(shù)據(jù)
21002 收據(jù)數(shù)據(jù)不符合格式
21003 收據(jù)無(wú)法被驗(yàn)證
21004 你提供的共享密鑰和賬戶的共享密鑰不一致
21005 收據(jù)服務(wù)器當(dāng)前不可用
21006 收據(jù)是有效的告材,但訂閱服務(wù)已經(jīng)過(guò)期坤次。當(dāng)收到這個(gè)信息時(shí),解碼后的收據(jù)信息也包含在返回內(nèi)容中
21007 收據(jù)信息是測(cè)試用(sandbox)斥赋,但卻被發(fā)送到產(chǎn)品環(huán)境中驗(yàn)證 【請(qǐng)求sandbox校驗(yàn)支付憑證】
21008 收據(jù)信息是產(chǎn)品環(huán)境中使用缰猴,但卻被發(fā)送到測(cè)試環(huán)境中驗(yàn)證
被蘋果拒絕:內(nèi)購(gòu)類型問(wèn)題
消耗類型: 例如:金幣、道具等疤剑。
非續(xù)訂訂閱: non-renewable subscription 例如:VIP
注意
您的首個(gè) App 內(nèi)購(gòu)買項(xiàng)目必須以新的 App 版本提交滑绒。請(qǐng)創(chuàng)建您的 App 內(nèi)購(gòu)買項(xiàng)目,然后前往 App 的“App Store”頁(yè)隘膘,從“App 內(nèi)購(gòu)買項(xiàng)目”中進(jìn)行選擇疑故,點(diǎn)按“提交”。 了解更多
在上傳二進(jìn)制文件并提交首個(gè) App 內(nèi)購(gòu)買項(xiàng)目以供審核后弯菊,您可以使用下表提交其他 App 內(nèi)購(gòu)買項(xiàng)目纵势。
參考
唐巧-iOS應(yīng)用內(nèi)付費(fèi)(IAP)開(kāi)發(fā)步驟列表
未完~待續(xù)
iOS內(nèi)購(gòu)問(wèn)題總結(jié)
1.沙盒測(cè)試賬號(hào)在支付成功后,再次購(gòu)買相同的商品,會(huì)提示“您已購(gòu)買此App內(nèi)購(gòu)買項(xiàng)目。此項(xiàng)目將免費(fèi)恢復(fù)管钳∏仗”
問(wèn)題分析
當(dāng)使用內(nèi)購(gòu)購(gòu)買過(guò)商品之后沒(méi)有把這個(gè)交易關(guān)閉,所以再次去購(gòu)買商品后就會(huì)調(diào)用以前已經(jīng)購(gòu)買成功的交易去購(gòu)買因?yàn)橐呀?jīng)購(gòu)買過(guò)才漆,才會(huì)有這個(gè)提示
解決方法
- 使用
[[SKPaymentQueue defaultQueue] addPayment:payment];
這個(gè)方法進(jìn)行支付請(qǐng)求后牛曹,因?yàn)槲覀円呀?jīng)把支付所需要的信息都添加到蘋果的支付隊(duì)列,蘋果會(huì)自動(dòng)完成后續(xù)的購(gòu)買請(qǐng)求 - 用戶購(gòu)買成功或者點(diǎn)擊取消購(gòu)買的后會(huì)回調(diào)
// 該方法返回響應(yīng)的結(jié)果信息
- (void)paymentQueue:(SKPaymentQueue )queue updatedTransactions:(NSArray )transaction;
- 在該方法內(nèi)除了得到響應(yīng)的支付信息編寫自身的業(yè)務(wù)的代碼外還要記得調(diào)用
[[SKPaymentQueue defaultQueue] finishTransaction:transaction];
方法通知蘋果的支付隊(duì)列該交易已經(jīng)完成醇滥,否者就會(huì)調(diào)用已經(jīng)購(gòu)買成功的支付隊(duì)列躏仇,就會(huì)出現(xiàn)您以購(gòu)買過(guò)此APP內(nèi)購(gòu)項(xiàng)目恋脚,此項(xiàng)目將免費(fèi)恢復(fù)這句提示。
- (void)paymentQueue:(SKPaymentQueue *)queue updatedTransactions:(NSArray<SKPaymentTransaction *> *)transactions{
NSLog(@"調(diào)用了幾次這個(gè)方法焰手?");
SKPaymentTransaction *transaction = transactions.lastObject;
switch (transaction.transactionState) {
case SKPaymentTransactionStatePurchased: {
[[SKPaymentQueue defaultQueue] finishTransaction:transaction];//記得關(guān)閉交易事件
NSLog(@"購(gòu)買完成,向自己的服務(wù)器驗(yàn)證 ---- %@", transaction.payment.applicationUsername);
NSData *data = [NSData dataWithContentsOfFile:[[[NSBundle mainBundle] appStoreReceiptURL] path]];
NSString *receipt = [data base64EncodedStringWithOptions:0];
// [self buySuccessWithReceipt:receipt transaction:transaction];
}
break;
case SKPaymentTransactionStateFailed: {
NSLog(@"交易失敗");
[[SKPaymentQueue defaultQueue] finishTransaction:transaction];
}
break;
case SKPaymentTransactionStateRestored: {
NSLog(@"已經(jīng)購(gòu)買過(guò)該商品");
[[SKPaymentQueue defaultQueue] finishTransaction:transaction];
}
break;
case SKPaymentTransactionStatePurchasing: {
NSLog(@"商品添加進(jìn)列表");
}
break;
default: {
}
break;
}
}
- 在買次購(gòu)買之前檢測(cè)是否有未完成的交易如果有就關(guān)閉糟描。
NSArray* transactions = [SKPaymentQueue defaultQueue].transactions;
if (transactions.count > 0) {
//檢測(cè)是否有未完成的交易
SKPaymentTransaction* transaction = [transactions firstObject];
if (transaction.transactionState == SKPaymentTransactionStatePurchased) {
[[SKPaymentQueue defaultQueue] finishTransaction:transaction];
return;
}
}
2.iOS后臺(tái)添加內(nèi)購(gòu)項(xiàng)目,提交顯示元數(shù)據(jù)丟失
原因:添加內(nèi)購(gòu)項(xiàng)目時(shí)书妻,信息填寫不完整船响,app審核圖像未上傳
處理方法:上傳app審核圖片(合適的尺寸),點(diǎn)擊提交躲履,狀態(tài)改為正在準(zhǔn)備審核中见间。
3.您已經(jīng)購(gòu)買了此項(xiàng)目,您想免費(fèi)再獲取一次嗎
這個(gè)是內(nèi)購(gòu)選擇類型不匹配原因?qū)е隆?/p>
- 非消耗型就是消耗一次后在該appid下都能使用工猜。
- 消耗型比如一些直播平臺(tái)的貨幣 使用完以后可以在充值米诉。
4.Purchase二次驗(yàn)證
購(gòu)買成功之后,Apple會(huì)返回以下四個(gè)數(shù)據(jù)給應(yīng)用
- 產(chǎn)品標(biāo)識(shí)符:
- 交易狀態(tài): state
- Receipt:很長(zhǎng)的一段字符串篷帅,大概49行史侣,作為二次驗(yàn)證的重要依據(jù)
- 交易標(biāo)識(shí)符: transaction Identifier 我們需要把Receipt發(fā)送給蘋果的蘋果的服務(wù)器驗(yàn)證,用戶的購(gòu)買信息是否真實(shí)
交易狀態(tài)
- Purchased 購(gòu)買成功
- Restored 恢復(fù)購(gòu)買
- Failed 失敗
- Deferred 等待確認(rèn)魏身,兒童模式需要詢問(wèn)家長(zhǎng)同意
蘋果返回狀態(tài)碼
- 21000 App Store不能讀取你提供的JSON對(duì)象
- 21002 receipt-data域的數(shù)據(jù)有問(wèn)題
- 21003 receipt無(wú)法通過(guò)驗(yàn)證
- 21004 提供的shared secret不匹配你賬號(hào)中的shared secret
- 21005 receipt服務(wù)器當(dāng)前不可用
- 21006 receipt合法惊橱,但是訂閱已過(guò)期。服務(wù)器接收到這個(gè)狀態(tài)碼時(shí)箭昵,receipt數(shù)據(jù)仍然會(huì)解碼并一起發(fā)送
- 21007 receipt是Sandbox receipt税朴,但卻發(fā)送至生產(chǎn)系統(tǒng)的驗(yàn)證服務(wù)
- 21008 receipt是生產(chǎn)receipt,但卻發(fā)送至Sandbox環(huán)境的驗(yàn)證服務(wù)
5.蘋果后臺(tái)添加內(nèi)購(gòu)商品報(bào)問(wèn)題
Review the updated Paid Applications Schedule.
解決辦法
先打開(kāi) https://itunesconnect.apple.com 首頁(yè)
-
然后找到這個(gè)協(xié)議的位置
-
點(diǎn)進(jìn)去之后家制,如下所示
-
右上角有個(gè)Request按鈕正林,好了,點(diǎn)擊這個(gè)按鈕颤殴,然后點(diǎn)擊Submit提交
同意之后就OK了卓囚,然后到首頁(yè)重新添加商品可以看到提醒消息已經(jīng)消失了
5.iOS內(nèi)購(gòu)匿名購(gòu)買-內(nèi)購(gòu)游客模式解決方案
游客身份解決方案:即不登錄也要能購(gòu)買
1)服務(wù)器端做一個(gè)蘋果審核機(jī)制,審核期間游客身份可以進(jìn)行一切行為诅病,一旦審核通過(guò)哪亿,修改服務(wù)端即可達(dá)到強(qiáng)制用戶登錄進(jìn)行內(nèi)購(gòu)買的目的(這個(gè)有點(diǎn)。贤笆。蝇棉。)
2)游客可以進(jìn)行內(nèi)購(gòu)買,購(gòu)買時(shí)以設(shè)備UUID為準(zhǔn)芥永,生成一個(gè)游客賬號(hào)篡殷,將購(gòu)買信息保存在服務(wù)器和本地,當(dāng)用戶登錄正式賬戶后判斷此設(shè)備是否進(jìn)行過(guò)內(nèi)購(gòu)埋涧,有的話提示用戶將游客身份購(gòu)買的權(quán)益與現(xiàn)有賬號(hào)綁定板辽,如果綁定奇瘦,游客權(quán)益則遷移到正式賬戶,如果不遷移劲弦,則游客身份和正是賬戶是兩個(gè)獨(dú)立賬戶耳标,正式賬戶不享有游客身份的權(quán)益(我用的這個(gè))
內(nèi)購(gòu)游客模式解決方案
iOS內(nèi)購(gòu)規(guī)則
6.審核注意事項(xiàng)
- 1.沙盒/正式環(huán)境:后臺(tái)提供開(kāi)關(guān)控制
- 2.內(nèi)購(gòu)支付建議添加開(kāi)關(guān),因?yàn)榻刂辽暇€前審核模式只能通過(guò)沙盒測(cè)試邑跪,上線后才能看到正式功能的支付次坡。所以建議手動(dòng)發(fā)布,發(fā)布前先關(guān)閉開(kāi)關(guān)画畅,待測(cè)試完成后再打開(kāi)顯示支付開(kāi)關(guān)砸琅。
- 3.支付流程
- ①.先下單獲取訂單號(hào)
- ②.獲取支付參數(shù)(商品ID)
- ③.發(fā)起支付,到支付回調(diào)
- ④.通知上報(bào)
transactionReceipt
給Server
【此處Server驗(yàn)證較慢】 - ⑤調(diào)用訂單狀態(tài)查詢(輪詢)轴踱,添加友好提示
問(wèn)題描述:
- 4.
支付收據(jù)驗(yàn)證比較慢
- 先快速通知症脂,不做業(yè)務(wù)處理只上報(bào):之后調(diào)取查詢訂單狀態(tài)接口
- 添加重試機(jī)制(比如5次或者5秒)
- 5.
漏單處理
(斷網(wǎng),Server未收到支付憑證淫僻,Server無(wú)返回)
支付成功回調(diào)后诱篷,存儲(chǔ)訂單號(hào)和支付憑證,Server驗(yàn)證成功后remove嘁傀,其他情況(例如:Server5秒無(wú)返回)發(fā)送事件通知(上報(bào)給Server),然后直接走訂單查詢视粮,并且下次啟動(dòng)App時(shí)上報(bào)給Server细办。