iOS In-App Purchase(IAP) 流程与实现
source link: https://zackzheng.info/2016/05/31/ios-in-app-purchase-iap/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
- 程序内购买流程
- iTunes Connect商品配置
- 添加沙箱技术测试员
- App内获取购买商品
- 验证receipt
最近做了iOS程序内购买,封装了一下给上层调用,现在介绍下流程和简单的实现。具体可以看我上传到Github的代码ZInAppPurchase,或者直接在CocoaPods拉取ZInAppPurchase。(第一次试试上传到CocoaPods,还没加demo)
程序内购买要做的话要考虑很多,像漏单处理、重新购买处理等等,对于游戏App来说更需要考虑。下面只介绍最简单的流程和处理。
程序内购买流程
iOS程序内购买流程主要分几步:
- iTunes Connect商品配置
- 添加沙箱技术测试员
- App内获取购买商品
- 验证receipt
iTunes Connect商品配置
主要是填写完整信息和添加商品。
填写完整信息
登录iTunes Connect,进入”协议、税务和银行业务“。
如果Contracts In Process下有All(See Contract)和Contact Info、Bank Info、Tax Info三列,则表示已填写;否则点击Request按照提示进行操作。之后就会出现Contact Info、Bank Info、Tax Info三列,分别Set Up(需要同公司财务人员一起填写)。
(如果没有填写完整只能添加免费订阅商品)
登录iTunes Connect,进入我的App——功能——App内购买项目,点击+号。可以添加的类型有:消耗型项目、非消耗型项目、自动续订订阅、免费订阅、非续订订阅。商品添加完屏幕快照就会变成准备提交状态。
注意:产品 ID不可重复,如果删除某个商品,以后这个产品的ID也不可用,即使它已经被删除了;另外类型也不能改,选错了只能重新增加一个商品。
添加沙箱技术测试员
登录iTunes Connect,进入用户和职能——沙箱技术测试员,点击+号。(必须是未注册的Apple账号,用于测试购买)
App内获取购买商品
- 导入系统库StoreKit
1
import StoreKit
- 获取商品信息
根据productId获取商品信息(可以获取多个):
1
2
3
let productRequest = SKProductsRequest(productIdentifiers: Set<String>(arrayLiteral: productId))
productRequest.delegate = self
productRequest.start()
实现SKProductsRequestDelegate:
1
2
3
4
func productsRequest(request: SKProductsRequest, didReceiveResponse response: SKProductsResponse) {
if let product = response.products.first {// 获取返回的商品
}
}
购买获取的商品product:
1
2
3
4
5
if SKPaymentQueue.canMakePayments() {// 是否能且允许支付
let payment = SKPayment(product: product)
SKPaymentQueue.defaultQueue().addTransactionObserver(self)
SKPaymentQueue.defaultQueue().addPayment(payment)
}
实现SKPaymentTransactionObserver:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
func paymentQueue(queue: SKPaymentQueue, updatedTransactions transactions: [SKPaymentTransaction]) {
for transaction in transactions {
switch transaction.transactionState {
case .Purchased: // Transaction is in queue, user has been charged. Client should complete the transaction.
if let receiptUrl = NSBundle.mainBundle().appStoreReceiptURL, let receiptData = NSData(contentsOfURL: receiptUrl) {
let receiptString = receiptData.base64EncodedStringWithOptions(NSDataBase64EncodingOptions(rawValue: 0))
// 将receiptString发给服务器
}
SKPaymentQueue.defaultQueue().finishTransaction(transaction)
case .Failed: // Transaction was cancelled or failed before being added to the server queue.
if let errorCode = transaction.error?.code {
}
SKPaymentQueue.defaultQueue().finishTransaction(transaction)
default:
break
}
}
}
验证receipt
receipt验证可以本地验证,也可以提交给App Store验证。
参考链接:Validating Receipts With the App Store
我们是将receipt进行base64编码后,传给服务器,服务器判断凭证是否已经存在或验证过,再去POST给Apple服务器验证。
- 沙箱环境POST的URL
https://sandbox.itunes.apple.com/verifyReceipt
- 正式环境POST的URL
https://buy.itunes.apple.com/verifyReceipt
验证后Apple会返回数据,从中可以获取product_id、quantity等,下面是正确时的返回数据:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
{
"status": 0,
"environment": "Sandbox",
"receipt": {
"receipt_type": "ProductionSandbox",
"adam_id": 0,
"app_item_id": 0,
"bundle_id": "com.xxx.xxxxxx",
"application_version": "999",
"download_id": 0,
"version_external_identifier": 0,
"receipt_creation_date": "2016-05-26 04:35:08 Etc/GMT",
"receipt_creation_date_ms": "1464237308000",
"receipt_creation_date_pst": "2016-05-25 21:35:08 America/Los_Angeles",
"request_date": "2016-05-26 06:40:32 Etc/GMT",
"request_date_ms": "1464244832729",
"request_date_pst": "2016-05-25 23:40:32 America/Los_Angeles",
"original_purchase_date": "2013-08-01 07:00:00 Etc/GMT",
"original_purchase_date_ms": "1375340400000",
"original_purchase_date_pst": "2013-08-01 00:00:00 America/Los_Angeles",
"original_application_version": "1.0",
"in_app": [
{
"quantity": "1",
"product_id": "000000",
"transaction_id": "1000000213676495",
"original_transaction_id": "1000000213676495",
"purchase_date": "2016-05-26 04:35:08 Etc/GMT",
"purchase_date_ms": "1464237308000",
"purchase_date_pst": "2016-05-25 21:35:08 America/Los_Angeles",
"original_purchase_date": "2016-05-26 04:35:08 Etc/GMT",
"original_purchase_date_ms": "1464237308000",
"original_purchase_date_pst": "2016-05-25 21:35:08 America/Los_Angeles",
"is_trial_period": "false"
}
]
}
}
下面是在沙箱环境下的真机测试截图(“测试”是所填写的产品名称,未登录Apple ID时会提示登录,已登录时会提示输入密码/Touch ID):
在iTunes Connect添加完App版本后,在App 内购买项目处添加该版本新增的App内购买项目。
####找不到入口
Information Needed
We have begun the review of your app but aren’t able to continue because we can’t locate the In-App Purchase(s) within your app.
At your earliest opportunity, please reply to this message providing the steps for locating the In-App Purchase(s) in your app.
####使用In-App Purchase之前要求登录/注册
Hello,
Thank you for providing the information. Upon further review of your application, we have found the following issue(s):
Legal - 5.1.1
We noticed that your app requires users to register with personal information to access non account-based features(including In-App Purchase feature), which is not allowed on the App Store.
We’ve attached screenshot(s) for your reference.
Apps cannot require user registration prior to allowing access to app content and features that are not associated specifically to the user.
Next Steps
User registration that requires the sharing of personal information must be optional or tied to account-specific functionality.
Please make it clear to the user that registering will enable them to access the content from any of their iOS devices, and to provide them a way to register at any time, if they wish to later extend access to additional iOS devices.
Please note that although guideline 3.1.2 of the App Store Review Guidelines requires an application to make subscription content available to all the iOS devices owned by a single user, it is not appropriate to force user registration to meet this requirement; such user registration must be made optional.
-END-
欢迎到我的博客交流:https://zackzheng.info
Recommend
-
60
IAP,即in-App Purchase ,是一种智能移动终端应用程序付费的模式. 最近笔者的项目中增加了付费内容,要使用IAP,就用这篇文章记录下IAP的开发过程和过程中遇到的一些问题。
-
15
Announcement React Native IAP hook is out. You can see medium post on how to use it. The react-native-iap module hasn't bee...
-
0
China is contemptuous of Apple's IAP concession- PingWestChina is contemptuous of Apple's IAP concession Zijing Fu posted on September 6, 2021 4:33 pmEditor :
-
9
Aruba IAP-514 for APoS August 29, 2021 By Rowell Leave a Comment My trusty Aruba IAP-514 ha...
-
4
Convert Aruba CAP to IAP Convert Aruba CAP to IAP 2021-03-22 03:10:28 # 网络
-
4
V2EX › 程序员 教育类 app 上架 App Store 绕过 iap
-
8
Global IAP/Subscription Pricing Sucks
-
5
苹果手机用户可能对IAP支付这一方式并不陌生,因为它是苹果为App内购买虚拟商品或服务提供的一套支付系统,用户在交易场景中大多使用过。那么,苹果为什么要搭建这样一套交易系统?IAP支付的系统流程又是如何进行交互的呢?本文作者便做了总结与分析,一...
-
3
硅谷的社交媒体做IAP,捆在一起干不过TikTok 白鲸出海 2023-03-22 0 评论...
-
5
苹果测试 iap 是必须要先提交 app 过审后才能测试吗 V2EX › 问与答
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK