WWDC Quick Look 💓 By SwiftGGTeam
Support customers and handle refunds

Support customers and handle refunds

元の動画を見る

ハイライト

StoreKit 2 は showManageSubscriptions()beginRefundRequest() API を追加し、ユーザーが App 内でサブスクリプション管理と返金申請を行えるようにします。Consumption API により、開発者は Apple に消費データを提供し、返金判断に関与できます。

主要内容

ユーザーがサブスクリプションをキャンセルしたいのに入口が見つからない、返金を申請したいのに方法が分からない。こうした場面では、ユーザーが App に低評価を付けたり、Apple サポートへ連絡したりする可能性があります。App 内でこれらの問題を直接解決できれば、ユーザー体験は大きく向上します。

StoreKit 2 は今年、これらの課題を解決するために 3 つの API を追加しました。

詳細

App 内でサブスクリプションを管理する

11:42

以前、ユーザーがサブスクリプションを管理するには、App を離れて App Store へ移動する必要がありました。今は App 内から管理ページを直接開けます。

import StoreKit

// サブスクリプション管理ページを表示する
func showSubscriptionManagement() {
    if let windowScene = view.window?.windowScene {
        Task {
            try await AppStore.showManageSubscriptions(in: windowScene)
        }
    }
}

12:20

キーポイント:

  • AppStore.showManageSubscriptions(in:) はシステムの管理ページを表示します
  • ユーザーは現在のサブスクリプションと更新オプションを確認できます
  • アップグレード、ダウングレード、キャンセルができます
  • すべての操作は App Store と同期されます

管理ページの前にリテンションオファーを表示することもできます。

// ユーザーがキャンセルを選ぶ前にオファーを表示する
func showRetentionOffer() {
    // カスタムのリテンション画面を表示する
    // ユーザーがそれでもキャンセルしたい場合は showManageSubscriptions を呼び出す
}

App 内で返金を申請する

13:36

ユーザーは Apple サポートへ連絡せずに、App 内から直接返金を申請できます。

import StoreKit

// 返金を申請する
func requestRefund(for transaction: Transaction) async {
    do {
        let refundStatus = try await transaction.beginRefundRequest(
            in: view.window!.windowScene!
        )

        switch refundStatus {
        case .success:
            // 返金申請が送信された
            showRefundSubmittedMessage()
        case .userCancelled:
            // ユーザーが申請をキャンセルした
            break
        }
    } catch {
        // エラーを処理する
        print("Refund request failed: \(error)")
    }
}

14:14

キーポイント:

  • transaction.beginRefundRequest(in:) は返金申請を開始します
  • システムは返金理由の選択画面を表示します
  • 返金が承認されると、サーバーは REFUND 通知を受け取ります
  • 返金が却下されると、サーバーは REFUND_DECLINED 通知を受け取ります
  • サンドボックス環境は返金テストに対応します

Invoice Lookup API

03:44

ユーザーがカスタマーサポートに「購入したのに受け取っていない」と問い合わせたとします。サポート担当者はユーザーに注文番号(order ID)の提供を依頼し、Invoice Lookup API で照会できます。

GET https://api.storekit.itunes.apple.com/inApps/v1/lookup/{orderId}

戻り値:

{
  "status": 0,
  "signedTransactions": [
    {
      "transactionId": "1000000123456789",
      "originalTransactionId": "1000000098765432",
      "productId": "com.example.coins",
      "purchaseDate": 1620000000000,
      "quantity": 100
    }
  ]
}

04:20

キーポイント:

  • status 0 は有効、1 は注文番号が無効、2 は一致する取引がないことを示します
  • JWS 形式の署名済み取引データを返します
  • 取引状態と返金状態を検証できます
  • サポート担当者が問題をすばやく特定するのに役立ちます

Refund Lookup API

06:02

特定ユーザーのすべての返金記録を照会します。

GET https://api.storekit.itunes.apple.com/inApps/v1/refund/lookup/{originalTransactionId}

サーバー outage 後に返金データを後追い同期する用途に適しています。

06:44

キーポイント:

  • originalTransactionId で照会します
  • そのユーザーのすべての返金取引を返します
  • 後追い同期と監査に適しています
  • JWS 形式のデータを返します

Subscription Extension API

09:40

サービス障害(ライブ配信の中断など)が発生した場合、補償としてユーザーのサブスクリプション期間を無料で延長できます。

PUT https://api.storekit.itunes.apple.com/inApps/v1/subscriptions/extend

{
  "originalTransactionId": "1000000098765432",
  "extensionDuration": 7,
  "extensionReason": 1,
  "requestIdentifier": "unique-request-id"
}

10:23

キーポイント:

  • 各サブスクリプションは年に最大 2 回まで延長できます
  • 1 回につき最大 90 日まで延長できます
  • 理由コードの提供が必要です
  • ユーザーにはメール通知が届きます
  • 延長期間は 85% の収益配分に必要な 1 年の期間には含まれません

Consumption API

19:12

当用户申请退款时,Apple 会向你的服务器发送 CONSUMPTION_REQUEST 通知。你可以在 12 小时内回复消费数据,帮助 Apple 做退款决策。

PUT https://api.storekit.itunes.apple.com/inApps/v1/consumption/{originalTransactionId}

{
  "customerConsented": true,
  "consumptionStatus": 1,
  "consumptionPlatform": 1,
  "sampleContent": 1,
  "deliveryStatus": 0,
  "appAccountToken": "uuid-string",
  "accountTenure": 365,
  "playTime": 120,
  "lifetimeSpend": 99.99,
  "userStatus": 0
}

20:00

キーポイント:

  • customerConsented:用户是否同意分享数据
  • consumptionStatus:0=未消费,1=部分消费,2=完全消费,3=已转让
  • deliveryStatus:0=成功交付,1=交付失败
  • 必须在 12 小时内回复
  • 数据帮助 Apple 做更准确的退款决策

重要ポイント

  1. 在应用内提供订阅管理入口。用户不需要离开应用就能查看和修改订阅。入口 API:AppStore.showManageSubscriptions(in:)

  2. 在应用内提供退款申请入口。减少用户给差评或联系 Apple 支持的概率。入口 API:transaction.beginRefundRequest(in:)

  3. 用 Invoice Lookup API 辅助客服。用户报问题时,用订单号快速查询交易状态。入口 API:GET /inApps/v1/lookup/{orderId}

  4. 用 Subscription Extension API 补偿服务故障。直播中断或服务器故障时,免费延长用户订阅。入口 API:PUT /inApps/v1/subscriptions/extend

  5. 回复 Consumption Request 参与退款决策。提供消费数据,减少不合理的退款。入口 API:PUT /inApps/v1/consumption/{originalTransactionId}

関連セッション

コメント

GitHub Issues · utterances