###### tags: `ELK-ROOM` 上面是訂閱頁面內容 下面是 API 跟狀態值 持續測試各狀態中 # 訂閱頁面 ### 會員狀態、帳戶狀態 一、我是會員 - 1. 已訂閱 - 1-1. 平常 - 1-2. 快到期 - 2. 寬限期 - 3. 付款已更新 二、我不是會員 - 4. 未訂閱 - 5. 帳戶保留 ### 流程 - 正常續訂 會員狀態 | 二 →    一    | 帳戶狀態 | 4. → 1-1. → 1-2. → 1. | - 取消訂閱 會員狀態 | 二 →  一  →      二     | 帳戶狀態 | 4. → 1.(都可) → 5.(如果沒過期) → 4. | - 寬限期或帳戶保留時,沒有更新付款方式,自動過期 會員狀態 | 二 →    一    →  二  | 帳戶狀態 | 4. → 1-1. → 1-2. → 2. → 5. → 4. | - 寬限期時,更新付款方式,恢復訂閱 會員狀態 | 二 →      一       | 帳戶狀態 | 4. → 1-1. → 1-2. → 2. → 3. → 1. | - 帳戶保留時,或取消訂閱後(尚未到期),再恢復訂閱 會員狀態 | 二 →    一    → 二 → 一 | 帳戶狀態 | 4. → 1-1. → 1-2. → 2. → 5. → 3. → 1.| ------- 詳細內容 👇🏻👇🏻👇🏻👇🏻 ## 一、我是會員 ![](https://i.imgur.com/FAACK7u.png =40%x) ```ts // isSubscription (expiryTime 未過) true ``` - ### 1. 已訂閱 使用者在未訂閱狀態下,透過 GP 頁面按下訂閱時: 付款方式錯誤:無法訂閱,不會成立訂單,也不會打後端 API 付款方式正確:打 `[post] /v1/subscription` ```ts // Payment received "paymentState": 1 // 收到 notification 後變 4 (使用者已購買新的訂閱項目) "notification": null // 如果後端向 GP API ack 沒成功會回 400,所以基本上不會看到 acknowledged: 0 "acknowledged": 1 ``` - 1-1. 平常 ![](https://i.imgur.com/mAN7Qae.png =40%x) ```ts // 收費日顯示 expiryTime,如果 expiryTime 在一個月之後,就顯示正常灰字 "expiryTime": "2022-10-05T06:40:52.695Z", ``` - 1-2. 快到期 ![](https://i.imgur.com/t943OS4.png =40%x) ```ts // 收費日顯示 expiryTime,如果 expiryTime 在一個月之內,就顯示快到期的紅字 "expiryTime": "2022-10-05T06:40:52.695Z", ``` - 以上可能的狀態 ```ts // (4) SUBSCRIPTION_PURCHASED - 使用者已購買新的訂閱項目。) // (2) SUBSCRIPTION_RENEWED - 目前的訂閱項目已續訂。 // (3) SUBSCRIPTION_CANCELED - 訂閱項目遭自願取消或非自願取消。如果是自願取消的情況,會在使用者取消時傳送此值。 // (12) SUBSCRIPTION_REVOKED - 使用者在訂閱到期前已取消訂閱項目。 // 3 跟 12 使用者雖然已經取消了,但在過期前依然是會員 "notificationType": 4 or 2 or 12 ``` - ### 2. 寬限期 ![](https://i.imgur.com/pQvzrbS.png =40%x) ```ts // SUBSCRIPTION_IN_GRACE_PERIOD - 訂閱項目已進入寬限期 (如果已啟用)。 "notificationType": 6 ``` - ### 3. 付款已更新 ![](https://i.imgur.com/Myak1Ju.png =40%x) ```ts // (1) SUBSCRIPTION_RECOVERED - 訂閱項目已從帳戶保留狀態恢復。 // (7) SUBSCRIPTION_RESTARTED - 使用者已從「Play」>「帳戶」>「訂閱」還原訂閱項目。訂閱項目已取消,但在使用者還原時尚未到期。詳情請參閱 [還原] (/google/play/billing/subscriptions#restore)。 "notificationType": 1 or 7 ``` ## 二、我不是會員 ![](https://i.imgur.com/boS40zr.png =40%x) ```ts // isSubscription (expiryTime 已過) false ``` - ### 4. 未訂閱 ![](https://i.imgur.com/qoeKBC8.png =40%x) ```ts // SUBSCRIPTION_EXPIRED - 訂閱項目已到期。 "notificationType": 13 ``` - ### 5. 帳戶保留 備註:圖片內,應該就不是會員了 ![](https://i.imgur.com/T6tgeGE.png =40%x) ```ts // SUBSCRIPTION_ON_HOLD - 訂閱項目已進入帳戶保留狀態 (如果已啟用)。 "notificationType": 5 ``` # API 1. `[GET] /v1/subscription` ```ts // 單純判斷 expiryTime 有沒有過 boolean ``` 3. `[GET] /v1/subscription/subscribed` 5. `[POST] /v1/subscription` 2 跟 3 回一樣 ```ts { "id": 39, "userId": "R72kvgB8HfUh1mdp8F0t4FHpnC63", "planId": "premium_plan", "offerId": "monthly", "orderId": "GPA.3366-9610-6536-85169", "token": "iminphknkcfgjimfjgcfeckj.AO-J1OwQu90owZqnTvZ3iR9Oh0BGn4kwEyJbYlrwKraD8sXOpi7GpD-fq6RM28p-x97fDqLmVKoba9DUQWaDeTZ58eKDSsy_I3ZGFUHqUbV9V0c1PgGriLI", "startTime": "2022-10-05T06:33:55.206Z", "expiryTime": "2022-10-05T06:40:52.695Z", "notificationType": null, "acknowledged": 1, "paymentState": 1, "autoRenewing": true, "renewId": null, "autoResumeTime": null, "cancelReason": null, "userCancelTime": null, "priceMicros": "63000000", "priceCurrency": "TWD", "countryCode": "TW", "priceChangeState": null, "newPriceMicros": null, "newPriceCurrency": null } ``` 7. `[POST] /v1/subscription/play-notification` - decode notification message ```ts { version: '1.0', packageName: 'com.elkroom.gamelauncher.dev', eventTimeMillis: '1664435732689', subscriptionNotification: { version: '1.0', notificationType: 4, purchaseToken: 'ohmhgdggemcomgnholmpmceb.AO-J1OxPy6x4QlQgzbaF6xoWjgHz_fiqgTpMAsLpeQr-POzjcirIrAN3IemAGpXJ-CRB0GlSi4ONom6uyydh1iESbsKfUN2v_ccC6u7kRf4-MGzf5MFV_Q0', subscriptionId: 'premium_plan' } } ``` - 拿 decode 的 `purchaseToken` 打 GP API 拿訂閱資料 ```ts { startTimeMillis: '1664329709436', expiryTimeMillis: '1664330127053', autoRenewing: true, priceCurrencyCode: 'TWD', priceAmountMicros: '63000000', countryCode: 'TW', developerPayload: 'premium_plan', paymentState: 1, orderId: 'GPA.3371-7672-2252-67848', purchaseType: 0, acknowledgementState: 0, kind: 'androidpublisher#subscriptionPurchase', obfuscatedExternalAccountId: 'R72kvgB8HfUh1mdp8F0t4FHpnC63' } ``` ## 狀態值 - notificationType: ```ts 更新 (1) SUBSCRIPTION_RECOVERED - 訂閱項目已從帳戶保留狀態恢復。 更新 (2) SUBSCRIPTION_RENEWED - 目前的訂閱項目已續訂。 更新 (3) SUBSCRIPTION_CANCELED - 訂閱項目遭自願取消或非自願取消。如果是自願取消的情況,會在使用者取消時傳送此值。 新增+驗證 (4) SUBSCRIPTION_PURCHASED - 使用者已購買新的訂閱項目。 更新 (5) SUBSCRIPTION_ON_HOLD - 訂閱項目已進入帳戶保留狀態 (如果已啟用)。 更新 (6) SUBSCRIPTION_IN_GRACE_PERIOD - 訂閱項目已進入寬限期 (如果已啟用)。 更新 (7) SUBSCRIPTION_RESTARTED - 使用者已從「Play」>「帳戶」>「訂閱」還原訂閱項目。訂閱項目已取消,但在使用者還原時尚未到期。詳情請參閱 [還原] (/google/play/billing/subscriptions#restore)。 測不出來 (8) SUBSCRIPTION_PRICE_CHANGE_CONFIRMED - 使用者已成功確認訂閱項目價格異動。 還沒測 (9) SUBSCRIPTION_DEFERRED - 訂閱項目的週期時間已延長。 更新 (10) SUBSCRIPTION_PAUSED - 訂閱項目已暫停。 更新 (11) SUBSCRIPTION_PAUSE_SCHEDULE_CHANGED - 訂閱暫停時間表已變更。 更新 (12) SUBSCRIPTION_REVOKED - 使用者在訂閱到期前已取消訂閱項目。 更新 (13) SUBSCRIPTION_EXPIRED - 訂閱項目已到期。 ``` 除了 (8)(9),在訂閱頁面中,還沒判斷到的狀態 ``` 更新 (10) SUBSCRIPTION_PAUSED - 訂閱項目已暫停。 更新 (11) SUBSCRIPTION_PAUSE_SCHEDULE_CHANGED - 訂閱暫停時間表已變更。 ``` - acknowledged: - 0. Yet to be acknowledged - 1. Acknowledged - paymentState: - 0. Payment pending - 1. Payment received - 2. Free trial - 3. Pending deferred upgrade/downgrade - cancelReason: - 0. User canceled the subscription - 1. Subscription was canceled by the system, for example because of a billing problem - 2. Subscription was replaced with a new subscription - 3. Subscription was canceled by the developer