iOS StoreKit2新特性

1. 客戶端相關(guān):

?1. 使用iOS15以上可用的Swift異步并發(fā)API進(jìn)行開發(fā),代碼可以做到最簡(jiǎn)潔。

?2. 使用JWS來校驗(yàn)訂單,不需要服務(wù)器進(jìn)行驗(yàn)票,客戶端直接就能拿到支付成功后的訂單。

?關(guān)鍵代碼如下:

//根據(jù)productId獲取product
products = try await Product.products(for: Set(productIds))

//product.type可獲取訂閱類型
product.type == .autoRenewable

//獲取autoRenewable是否是第一次購(gòu)買優(yōu)惠
product.subscription?.isEligibleForIntroOffer

//支付,可以傳入orderid的uuid用來關(guān)聯(lián)指定用戶的訂單。orderid與userid的對(duì)應(yīng)關(guān)系由云端維護(hù)
let uuid = Product.PurchaseOption.appAccountToken(UUID.init(uuidString: "orderid")!)
let result = try await product.purchase(options: [uuid])

//處理支付結(jié)果,此時(shí)蘋果內(nèi)部已經(jīng)進(jìn)行了JWS校驗(yàn)
switch result {
    case .success(let verificationResult):
        //處理成功
        if case .verified(let transaction) = verificationResult {
            //transaction.appAccountToken可以拿到支付時(shí)傳入的uuid
            
            //在這里給服務(wù)器上傳transaction.id、transaction.originalID服務(wù)器就可以去蘋果服務(wù)器請(qǐng)求訂單信息了。
            
            await transaction.finish()
        } else {
            throw verifyFailure
        }
    case .userCancelled:
        //處理取消
    case .pending:
        //交易可能會(huì)在未來成功,通過Transaction.updates進(jìn)行通知。
}

//獲取當(dāng)前所有訂閱記錄
for await result in Transaction.currentEntitlements {
    if case .verified(let transaction) = result {
        
    }
}

//可以在應(yīng)用內(nèi)部彈出管理訂閱的窗口了
try await AppStore.showManageSubscriptions(in: scene)

//應(yīng)用內(nèi)可以請(qǐng)求退款了,沙盒也可以測(cè)試退款。
try await transaction.beginRefundRequest(in: scene)

//Transaction.updates, 當(dāng)網(wǎng)絡(luò)不好支付結(jié)果返回.pending或者用戶購(gòu)買時(shí)退出了app或卸載重裝,在這里會(huì)獲得回調(diào)。
Task.detached {
    for await verificationResult in Transaction.updates {
        if case .verified(let transaction) = verificationResult {
            //在這里給服務(wù)器上傳transaction.id、transaction.originalID服務(wù)器就可以去蘋果服務(wù)器請(qǐng)求訂單信息了。
            
            await transaction.finish()
        }
    }
}

//獲取全部交易訂單
Transaction.all

//獲取某個(gè)產(chǎn)品最新交易訂單
Transaction.latest(for: productId)

//獲取所有當(dāng)前訂閱的交易
Transaction.currentEntitlements

//獲取某個(gè)產(chǎn)品當(dāng)前訂閱的交易
Transaction.currentEntitlement(for: productId)

//同步不同設(shè)備之間的應(yīng)用內(nèi)購(gòu)買(恢復(fù)購(gòu)買)
try await AppStore.sync()

//內(nèi)購(gòu)對(duì)兌碼 當(dāng)服務(wù)器出問題了,為了挽留用戶或吸引更多用戶,
//可以給用戶郵箱發(fā)送內(nèi)購(gòu)對(duì)兌碼,讓用戶在app內(nèi)進(jìn)行兌換。非新功能。
SKPaymentQueue.default().presentCodeRedemptionSheet()

2. 服務(wù)器相關(guān):

?1. 服務(wù)器API接口匯總:https://developer.apple.com/documentation/appstoreserverapi

?2. 服務(wù)器可以主動(dòng)去蘋果服務(wù)器查詢訂閱狀態(tài)及交易歷史記錄。

??1. get_all_subscription_statuses: /inApps/v1/subscriptions 根據(jù)originalTransactionId獲取購(gòu)買交易信息及所有續(xù)訂信息。

??2. get_transaction_history: inApps/v1/history/ 根據(jù)originalTransactionId分頁(yè)獲取購(gòu)買交易信息

??(不包含續(xù)訂信息,如果需要續(xù)訂信息,當(dāng)從交易信息中拿到是訂閱類型的,再調(diào)用get_all_subscription_statuses接口去拿續(xù)訂信息。如果能開始時(shí)就確定是訂閱類型的,可以不調(diào)用此接口,直接調(diào)用get_all_subscription_statuses去獲取所有數(shù)據(jù))

?3. 可以根據(jù)訂單ID去蘋果服務(wù)器查詢交易信息。https://developer.apple.com/documentation/appstoreserverapi/look_up_order_id?language=_9

??用戶扣款后沒有收到商品,會(huì)找到咱們的客服進(jìn)行反饋,附帶蘋果郵箱里的扣款截圖,咱們服務(wù)器就可以根據(jù)截圖里的orderID去調(diào)用/inApps/v1/lookup/{customer_order_id}接口查找對(duì)應(yīng)的Transaction信息,根據(jù)信息確定是否要補(bǔ)發(fā)商品。

StoreKit2_image1.png

?4. 接收內(nèi)購(gòu)狀態(tài)改變通知,通知有刪除有新增:

StoreKit2_image2.png

?5. 購(gòu)買流程有變化:

??訂閱類型:

???蘋果服務(wù)器會(huì)通知我們的服務(wù)器

???我們也可以根據(jù)客戶端上報(bào)的originalTransactionId調(diào)用/inApps/v1/subscriptions 接口去驗(yàn)證。

StoreKit2_image3.png

?6. 總體購(gòu)買流程:

StoreKit2_image4.png

?7. 服務(wù)器可以主動(dòng)查詢退款訂單詳情。

??如果服務(wù)器宕機(jī)了或者沒有收到退款通知,服務(wù)器可以調(diào)用API主動(dòng)查詢用戶所有退款記錄訂單,只需要任意一個(gè)original_transaction_id。

??Apple Developer Documentation inApps/v2/refund/lookup/{originalTransactionId}

?8. 給用戶補(bǔ)償訂閱時(shí)長(zhǎng)。

??如果某個(gè)原因設(shè)計(jì)的活動(dòng)中斷了或取消了,可以給用戶一些福利去安撫用戶。

??Apple提供了一個(gè)API,允許一年有2次機(jī)會(huì)給訂閱用戶每次加90天免費(fèi)補(bǔ)償。

??Apple Developer Documentation inApps/v1/subscription/extend/{original_transaction_id

3. StoreKit2 丟單處理:

?還是有可能出現(xiàn)丟單的情況,例如購(gòu)買成功了,Apple 返回結(jié)果時(shí)由于網(wǎng)絡(luò)的原因?qū)е率×?,但是此時(shí)會(huì)更容易解決。

?解決辦法:

??冷啟動(dòng)時(shí),可監(jiān)聽 Transaction 變化,收到成功的 Transaction 后重新上傳,與 StoreKit 1 類似。

??在購(gòu)買時(shí)向 product 內(nèi) appAccountToken 字段里塞入業(yè)務(wù)方 orderID 相關(guān)的信息,當(dāng)用戶反饋扣款了但是沒發(fā)貨時(shí),可以讓用戶提供 Apple 的 orderID,通過它可以直接去蘋果服務(wù)器獲取對(duì)應(yīng)的 Transaction 信息,找到 Transaction.appAccountToken ,再給用戶發(fā)貨。(這里可以做成一個(gè)自動(dòng)化處理工具,只需要用戶提供蘋果的 orderID,就可以去查找對(duì)應(yīng)的業(yè)務(wù)方 orderID 進(jìn)行發(fā)貨。)

4. 參考文章:

?StoreKit2 有這么香?嗯,我試過了,真香 - 掘金

?iOS StoreKit 2 新特性解析-51CTO.COM

5. 有任何問題歡迎評(píng)論區(qū)留言進(jìn)行探討。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容