脱力駆動開発記

ゲームアプリを作るエンジニアの技術メモ

MENU

【Unity/IAP】UnityIAPv4.9.3以降でAndroidのOnPurchaseFailedが呼ばれない問題の対応

背景

先日「2023/8/14頃からUnityIAPでのiOSローカルレシート検証で失敗するようになった場合の対策」という記事を上げました。
UnityIAPをv4.9.4にバージョンアップしないとiOSのローカルレシート検証に失敗してしまうので、アップデートをしましょう。という内容でした。

しかし今度はv4.9.4にアップデートをすると、AndroidでOnPurchaseFailedが呼ばれなくなるという問題が起きてしまうようです。
正確にはv4.9.3から起きてしまう問題なので、v4.9.3でiOS・Androidの両方で8/14以降公開する場合は、iOSではローカルレシート検証に失敗するしAndroidではOnPurchaseFailedが呼ばれないという最悪の状態になってしまいますね。
とりあえずv4.9.4に上げればiOSの方は解決するので、IAPのアップデート自体はしてしまっても良いかと思います。
OnPurchaseFailedが呼ばれない問題の対応について記載します。

起きる環境

この不具合が起きるのは、

  • 特定のUnityバージョン(2022.3.5f1 ~ 2022.3.30f1)
  • かつUnityIAPv4.9.3 ~ v4.9.4を使用している
  • かつAndroidプラットフォームで課金処理を実行して失敗したとき

というケースです。 Unity2020や2021の他のバージョンでも起きるかもしれませんが、フォーラムで報告に挙がっているのは2022.3.5f1以降のバージョンです。
もしこの記事を読まれている方で、上記のUnityバージョン以外でも起きたという方がいましたら、ぜひコメント欄かTwitterでリプライで教えていただけますと大変ありがたいです!

現象

購入失敗時に

UnityEngine.Purchasing.IStoreListener.OnPurchaseFailed(Product product, PurchaseFailureReason failureReason);

が呼ばれなくなる

対応

いくつか方法があります。

方法1. Unityをアップデートする

Unity2022を使用している場合はすでに修正されたバージョン2022.3.10がリリースされたので、アップデートすればOKです

Unity2021を使用している場合は、2023/10/4あたりにこの問題に対応した2021.3.31f1がリリースされる予定なので、それまで待つ必要があります。
待てない場合は以下の2つの方法のどれかを試すのが良いかと思います。

方法2. UnityIAP v4.9.4(v4.9.3)のローカルパッケージを修正する

フォーラムに他のユーザーさんが投稿していた内容ですが、Unityのバージョンを変えずに対応したい場合はこれが手っ取り早いかと思います。

//com.unity.purchasing@4.9.3/Runtime/Stores/Android/GooglePlay/AAR/Listeners/GooglePurchaseUpdatedListener.cs
 
[Preserve]
void onPurchasesUpdated(AndroidJavaObject billingResult, AndroidJavaObject javaPurchasesList)
{
    IGoogleBillingResult result = new GoogleBillingResult(billingResult);
    var purchases = m_PurchaseBuilder.BuildPurchases(javaPurchasesList.EnumerateAndWrap()).ToList();
    OnPurchasesUpdated(result, purchases);
}
 

onPurschasesUpdatedというメソッドをpublicにすることで、とりあえずGooglePlay側の課金状態の変更を正しく処理してくれるようになり、OnPuruchaseFailedも呼ばれるようになるようです。

//com.unity.purchasing@4.9.3/Runtime/Stores/Android/GooglePlay/AAR/Listeners/GooglePurchaseUpdatedListener.cs
 
[Preserve]
public void onPurchasesUpdated(AndroidJavaObject billingResult, AndroidJavaObject javaPurchasesList)
{
    IGoogleBillingResult result = new GoogleBillingResult(billingResult);
    var purchases = m_PurchaseBuilder.BuildPurchases(javaPurchasesList.EnumerateAndWrap()).ToList();
    OnPurchasesUpdated(result, purchases);
}
 

(自分の環境では未検証なので、これを試す場合は動作確認の上自己責任でお願い致します

パッケージを書き換える方法はいくつかありますが、シンプルなのは以下です。

  • com.unity.purchasingパッケージを任意の場所にコピーする
  • スクリプトを編集する
  • packages/manifeset.jsonを編集する

以下の行を削除

"com.unity.purchasing": "4.9.3",
  • プロジェクトルート/Packages以下に編集したcom.unity.purchasingフォルダを配置する

これでとりあえず自前のcom.unity.purchasingを使用してくれるはずです。

方法3. Unityを2022.3.41f以前にダウングレードする

上の2つの方法をどれも取れない場合は、バージョンを下げることでもこの現象は起きなくなります。 (あまりやりたくはないですが、、

おわり

iOSのローカルレシート検証の対応でUnityIAPをアップデートする必要が出たのに、アップデートしたら今度はAndroid側が正しく動かなくなるという困った状況なわけですが、遭遇した方のお役に立てれば幸いです。

最近はUnityのRuntimeFeeのことで界隈は盛り上がっていますし、自分も大いに盛り上がってしまいましたが、Unityの記事は今後も定期的に投稿するのでぜひ読者登録してもらえると嬉しいです!

参考

Unity Issue Tracker - [Android] AndroidJavaProxy cannot find a private proxy method when button is clicked

forum.unity.com