React-native-iap: Kesalahan saat mengupgrade / downgrade langganan di Android dengan mode DEFERRED

Dibuat pada 28 Des 2019  ·  31Komentar  ·  Sumber: dooboolab/react-native-iap

Versi react-native-IAP

4.3.3

Versi react-native

0.59.10

Platform yang Anda hadapi kesalahan (IOS atau Android atau keduanya?)

Android

Perilaku yang diharapkan

Saat meningkatkan / menurunkan versi langganan dengan mode DEFERRED, pendengar pembaruan pembelian harus dipanggil dengan tanda terima transaksi baru.

Perilaku sebenarnya

pendengar kesalahan pembelian dipanggil dengan kesalahan berikut:

{message: 'pembelian adalah null.',
kode: 'OK',
debugMessage: '',
responseCode: 0}

Lingkungan yang diuji (Emulator? Perangkat Nyata?)

Perangkat Nyata - kotak pasir

Langkah-langkah untuk mereproduksi perilaku

1. Beli langganan dengan RNIap.requestSubscription (sku), ini berfungsi dengan benar.

2. Tingkatkan atau turunkan langganan dengan RNIap.requestSubscription (newSku, false, sku, 4). (4 adalah Mode Prorasi TERTENTU) Dialog penagihan Google Play akan menunjukkan rencana berlangganan berhasil diubah, dan Anda akan menerima email pemberitahuan dari Google Play tentang itu. Namun, pendengar kesalahan dipanggil dengan kesalahan yang disebutkan di atas.

3. Jika Anda memanggil RNIap.requestSubscription (newSku, false, sku, 4) lagi, dialog penagihan Google Play akan mengatakan bahwa mereka tidak dapat mengubah paket langganan, dan pendengar kesalahan dipanggil dengan kesalahan berikut:

{message: 'Google menunjukkan bahwa kami mengalami masalah saat menghubungkan ke pembayaran.',
kode: 'E_DEVELOPER_ERROR',
debugMessage: '',
responseCode: 5}

Namun terkadang dialog penagihan Google Play akan mengatakan bahwa pesanan Anda sedang dalam proses dan produk Anda akan segera dikirim, dan pemroses kesalahan dipanggil dengan kesalahan berikut:

{message: 'Anda sudah memiliki item ini.',
kode: 'E_ALREADY_OWNED',
debugMessage: '',
responseCode: 7}

Saya kira ini karena transaksi pada langkah 2 sedang menunggu untuk diakui. Namun, karena langkah 2 tidak mengembalikan tanda terima, kami tidak dapat mengakuinya.

🕵️‍♂️ need more investigation 🙏 help wanted 🤖 android

Komentar yang paling membantu

Ada rencana untuk mengatasi masalah ini?

Semua 31 komentar

Cobalah menelepon getAvailablePurchases setelah Anda meningkatkan / menurunkan versi langganan.
Lihat dokumen , The list of Purchase objects in onPurchasesUpdated() does not contain paused subscriptions. .

Saya tidak begitu yakin harapan kuat itu membantu. Jangan ragu untuk meninggalkan percobaan dan diskusi lainnya.

Saya mencoba getAvailablePurchases () setelah memutakhirkan / menurunkan versi langganan, tetapi sayangnya, hanya tanda terima transaksi dari pembelian asli yang ada dalam larik yang dikembalikan.

RNIap v2.3.19 & v2.5.5 berfungsi dengan benar, buySubscription () akan mengembalikan tanda terima baru saat meningkatkan / menurunkan versi langganan. Tetapi saya ingin meningkatkan ke v3 atau v4 yang memiliki model berbasis peristiwa yang lebih baik jika memungkinkan.

Berikut adalah dokumen referensi yang menjelaskan cara kerja peningkatan / penurunan versi langganan Android dan mengapa kami memerlukan tanda terima baru setelah peningkatan / penurunan versi.

@ howg0924 Terima kasih telah mengkonfirmasikan hal ini. Saya ingin membandingkan perbedaannya dengan v2 dan versi kami saat ini dan melihat bagaimana saya dapat memperbaiki masalah ini.

Saya telah mencari kode pada akhir pekan untuk Anda di # 893
Pembaruan baru akan datang dalam 4.4.0 .

Bisakah Anda menguji versi [email protected] ?

@hyochan Saya baru mencoba 4.4.0-rc.1, tetapi situasinya masih sama.

Setelah memanggil RNIap.requestSubscription (oldSku, false, newSku 4) dan menyelesaikan upgrade / downgrade, error listener akan dipanggil dengan error berikut:

{message: 'pembelian adalah null.',
kode: 'OK',
debugMessage: '',
responseCode: 0}

Dan getAvailablePurchases () hanya berisi tanda terima lama.

@ howg0924 Jika Anda tahu cara men-debug android , saya harap Anda menguji menempatkan Log.d dan melihat apakah itu melewati if kondisi di buyItemByType . Apakah itu mungkin untuk Anda? Saya ingin melihat bagaimana mereka dieksekusi.

@ howg0924 Oh tunggu ~! Saya rasa saya menemukan masalah, biarkan saya menghubungi Anda segera!

@ howg0924 Bisakah Anda mencoba 4.4.0-rc.2 ? Saya pikir ini akan berhasil kali ini.

@hyochan 4.4.0-rc.2 build gagal pada:

RNIapModule.java:436: error: incompatible types: SkuDetails cannot be converted to String:
   builder.setOldSku(selectedOldSku);
                     ^

@hyochan Saya memantau buyItemByType () dari 4.4.0-rc.1. Saat meningkatkan / menurunkan versi, itu dijalankan:

builder.setReplaceSkusProrationMode(BillingFlowParams.ProrationMode.DEFERRED);

dan juga dieksekusi:

BillingResult billingResult = billingClient.launchBillingFlow(activity, flowParams);

Apakah Anda ingin saya memantau / membuang aliran / data apa pun?

(dihapus karena beberapa kesalahpahaman)

@ howg0924 Maaf saya telah membuat kesalahan karena saya tidak memiliki debugging yang baik env . Saya telah mengembalikan ini di 4.4.0-rc.3 . Sepertinya kode Anda tidak menjalankan builder.setOldSku(oldSku) yang paling penting.

Setelah membandingkan dengan 2.5.5, saya menemukan 2.5.5 tidak menelepon

builder.setReplaceSkusProrationMode (BillingFlowParams.ProrationMode.DEFERRED);

saat menggunakan mode DEFERRED.

Jadi saya mencoba untuk menghapus baris ini di 4.4.0-rc.1, dan berhasil! Tapi, saya tidak tahu:

1. mode prorasi apa yang sedang dikerjakannya sekarang.
2. mengapa tidak berfungsi saat disetel ke mode DEFERRED oleh setReplaceSkusProrationMode ()

        if (prorationMode != null && prorationMode != -1) {
          if (prorationMode == BillingFlowParams.ProrationMode.IMMEDIATE_AND_CHARGE_PRORATED_PRICE) {
            builder.setReplaceSkusProrationMode(BillingFlowParams.ProrationMode.IMMEDIATE_AND_CHARGE_PRORATED_PRICE);
            if (type.equals(BillingClient.SkuType.SUBS) == false) {
              String debugMessage = "IMMEDIATE_AND_CHARGE_PRORATED_PRICE for proration mode only works in subscription purchase.";
              WritableMap error = Arguments.createMap();
              error.putString("debugMessage", debugMessage);
              error.putString("code", PROMISE_BUY_ITEM);
              error.putString("message", debugMessage);
              sendEvent(reactContext, "purchase-error", error);
              promise.reject(PROMISE_BUY_ITEM, debugMessage);
              return;
            }
          } else if (prorationMode == BillingFlowParams.ProrationMode.IMMEDIATE_WITHOUT_PRORATION) {
            builder.setReplaceSkusProrationMode(BillingFlowParams.ProrationMode.IMMEDIATE_WITHOUT_PRORATION);
          } else if (prorationMode == BillingFlowParams.ProrationMode.DEFERRED) {
            builder.setReplaceSkusProrationMode(BillingFlowParams.ProrationMode.DEFERRED);
          } else if (prorationMode == BillingFlowParams.ProrationMode.IMMEDIATE_WITH_TIME_PRORATION) {
            builder.setReplaceSkusProrationMode(BillingFlowParams.ProrationMode.IMMEDIATE_WITH_TIME_PRORATION);
          } else {
            builder.setReplaceSkusProrationMode(BillingFlowParams.ProrationMode.UNKNOWN_SUBSCRIPTION_UPGRADE_DOWNGRADE_POLICY);
          }
        }

Saat ini kami memberikan ProrationMode seperti di atas. Jadi apakah itu berarti Anda dapat auto renew subscription bila Anda telah menghapus DEFERRED ?

Maksud saya jika saya mengubah kode menjadi:

        if (prorationMode != null && prorationMode != -1) {
          if (prorationMode == BillingFlowParams.ProrationMode.IMMEDIATE_AND_CHARGE_PRORATED_PRICE) {
            builder.setReplaceSkusProrationMode(BillingFlowParams.ProrationMode.IMMEDIATE_AND_CHARGE_PRORATED_PRICE);
            if (type.equals(BillingClient.SkuType.SUBS) == false) {
              String debugMessage = "IMMEDIATE_AND_CHARGE_PRORATED_PRICE for proration mode only works in subscription purchase.";
              WritableMap error = Arguments.createMap();
              error.putString("debugMessage", debugMessage);
              error.putString("code", PROMISE_BUY_ITEM);
              error.putString("message", debugMessage);
              sendEvent(reactContext, "purchase-error", error);
              promise.reject(PROMISE_BUY_ITEM, debugMessage);
              return;
            }
          } else if (prorationMode == BillingFlowParams.ProrationMode.IMMEDIATE_WITHOUT_PRORATION) {
            builder.setReplaceSkusProrationMode(BillingFlowParams.ProrationMode.IMMEDIATE_WITHOUT_PRORATION);
          } else if (prorationMode == BillingFlowParams.ProrationMode.DEFERRED) {
            // comment following line
            // builder.setReplaceSkusProrationMode(BillingFlowParams.ProrationMode.DEFERRED);
          } else if (prorationMode == BillingFlowParams.ProrationMode.IMMEDIATE_WITH_TIME_PRORATION) {
            builder.setReplaceSkusProrationMode(BillingFlowParams.ProrationMode.IMMEDIATE_WITH_TIME_PRORATION);
          } else {
            builder.setReplaceSkusProrationMode(BillingFlowParams.ProrationMode.UNKNOWN_SUBSCRIPTION_UPGRADE_DOWNGRADE_POLICY);
          }
        }

maka saya dapat menggunakan RNIap.requestSubscription (newSku, false, sku, mode 4 / * DEFERRED * /) untuk mengupgrade / downgrade langganan. Meskipun saya tidak yakin mode prorasi apa yang sebenarnya berfungsi karena builder.setReplaceSkusProrationMode () tidak dijalankan, seperti yang dilakukan v2.5.5.

Kode berikut berasal dari v2.5.5:

        if (type.equals(BillingClient.SkuType.SUBS) && oldSku != null && !oldSku.isEmpty()) {
          // Subscription upgrade/downgrade
          if (prorationMode != null && prorationMode != 0) {
            builder.setOldSku(oldSku);
            if (prorationMode == BillingFlowParams.ProrationMode.IMMEDIATE_AND_CHARGE_PRORATED_PRICE) {
              builder.setReplaceSkusProrationMode(BillingFlowParams.ProrationMode.IMMEDIATE_AND_CHARGE_PRORATED_PRICE);
            } else if (prorationMode == BillingFlowParams.ProrationMode.IMMEDIATE_WITHOUT_PRORATION) {
              builder.setReplaceSkusProrationMode(BillingFlowParams.ProrationMode.IMMEDIATE_WITHOUT_PRORATION);
            } else {
              builder.addOldSku(oldSku);
            }
          } else {
            builder.addOldSku(oldSku);
          }
        }

@ howg0924 Ini sangat aneh karena kami bahkan tidak menetapkan DEFFERED di cabang utama kami 4.3.4 . Saya telah menambahkan kode ini di 4.4.0+ .

Saya pikir alasannya mungkin sesuatu yang berbeda. Saya harap Anda bisa kembali lagi jika ada berita lain.

Terkait # 391 # 555

Oke, saya akan mencoba lebih banyak dan melaporkan kembali.

Terkait # 707

@hyochan Setelah pengujian lebih lanjut pada 4.4.0-rc.1:

IMMEDIATE_WITH_TIME_PRORATION => berfungsi
IMMEDIATE_AND_CHARGE_PRORATED_PRICE => berfungsi
IMMEDIATE_WITEMENTS_PRORATION => berfungsi
DEFERRED => NOT WORK (tidak tahu kenapa)

Ini sangat aneh karena kami bahkan tidak menyetel DEFFERED di cabang master kami saat ini yaitu 4.3.4. Saya telah menambahkan kode ini di 4.4.0+.

Saya yakin ini karena kode berikut di 4.3.0 masih disetel ke mode DEFERRED:

  if (prorationMode != 0 && prorationMode != -1) {
    builder.setReplaceSkusProrationMode(prorationMode);
  }

Namun, kode di atas tidak ada di 2.3.19 & 2.5.5. Oleh karena itu, ketika saya memanggil RNIap.requestSubscription (newSku, false, sku, 4 / * DEFERRED * /) pada 2.3.19 & 2.5.5, saya pikir ini berfungsi sebelumnya, tetapi sekarang saya menyadari itu benar-benar bekerja pada mode IMMEDIATE_WITH_TIME_PRORATION default .

Ok jadi kita harus tahu mengapa Deffered tidak berfungsi. Saya tidak dapat menemukan alasannya untuk saat ini.

Saya punya masalah yang sama tetapi perilakunya berbeda.

Ketika saya memanggil requestSubscription(newSku, false, oldSku, 4) , itu membuat kesalahan dengan kode kesalahan OK dan pesan kesalahan kosong. Pembayaran di sisi Google Play seperti yang diharapkan (ditangguhkan). Saat biaya langganan berikutnya terjadi, saya mendapatkan acara purchaseUpdatedListener saat aplikasi dimulai tetapi tidak dapat mengakui pembelian (dengan menelepon finishTransaction() ). finishTransaction() memberikan kesalahan DEVELOPER_ERROR .

Terjadi pada kedua versi 4.4.0 dan 4.3.4 .

Halo @hyochan , saya melihat bahwa di https://github.com/dooboolab/react-native-iap/pull/893 Anda menandai ini sebagai terselesaikan tetapi saya memperbarui react-native-iap ke versi terbaru tetapi yang ini masih belum tetap. Saya masih mendapat kesalahan di pendengar error {"code": "OK", "debugMessage": "", "message": "purchases are null.", "responseCode": 0} dan menerima email You updated your subscription purchase normal. Jadi pertanyaan saya adalah apa solusi yang tepat untuk mode DEFERRED?

Terakhir kali saya menemukan masalah ini juga. Anehnya tidak hanya bekerja dalam mode deferred . Kami perlu menyelidiki ini.

Hai @ howg0924 , apakah Anda sudah mendapatkan solusi untuk masalah ini?

@ nenjamin2405 Tidak, saya masih menggunakan mode IMMEDIATE_WITH_TIME_PRORATION default, dan saya sangat berharap ini bisa diperbaiki.

Hai @hyochan , ada pembaruan tentang ini? Fitur baru aplikasi saya terhambat oleh masalah ini. Terima kasih atas upaya Anda menyelidiki hal ini

Belum. Saya tidak punya waktu untuk membahas masalah ini.
Saya berharap seseorang juga memberikan informasi yang berguna untuk menangani masalah ini.
Meminta Google atau StackOverflow dan membagikannya di utas ini mungkin sangat membantu.

Halo, sepertinya tidak ada aktivitas terkait masalah ini akhir-akhir ini. Apakah masalah sudah diperbaiki, atau masih membutuhkan perhatian masyarakat? Masalah ini mungkin ditutup jika tidak ada aktivitas lebih lanjut yang terjadi. Anda juga dapat memberi label masalah ini sebagai "Untuk Diskusi" atau "Edisi pertama yang baik" dan saya akan membiarkannya terbuka. Terima kasih atas kontribusi Anda.

Kami telah melihat masalah ini dan ingin berbagi dengan komunitas, ini dapat membantu beberapa orang di luar sana.

Masalahnya karena pendengar yang diperbarui pembelian dipanggil dengan daftar pembelian kosong pada penggantian langganan yang ditangguhkan, yang merupakan cara kerja Android (Lihat di sini "Untuk mode penggantian yang ditangguhkan ...")

Kami menambahkan dukungan android deferred subscription replace pada react-native-iaphub dengan melakukan perbaikan saat purchases are null pada penggantian langganan. ( Lihat komit )

Tentu saja Anda harus melakukan beberapa modifikasi di sisi server Anda yang memvalidasi tanda terima Anda juga, menyegarkan tanda terima tidak cukup saat berurusan dengan langganan yang ditangguhkan.
Anda harus mengimplementasikan notifikasi realtime Android untuk mendeteksi kapan penggantian langganan terjadi dan memproses token baru.

Atau Anda bisa menggunakan IAPHUB yang melakukan semua itu untuk Anda 🙂

Ada rencana untuk mengatasi masalah ini?

Seperti yang disebutkan @iaphub , masalahnya adalah bahwa onPurchasesUpdated dipanggil dengan argumen purchases sebagai null saat mode DEFERRED digunakan.

Dari google dokumen :

Untuk mode penggantian yang ditangguhkan, aplikasi Anda menerima panggilan ke PurchasesUpdatedListener dengan daftar pembelian kosong dan status berhasil atau tidaknya upgrade atau downgrade.

Jadi ini hanya masalah menangani kasus itu di dalam pendengar itu.

Tetapi saya tidak yakin tentang apa yang seharusnya menjadi cara yang tepat untuk menangani situasi itu:

  • Mengatasi janji dengan info langganan sebelumnya
  • Menyelesaikan janji dengan undefined
  • Menolak janji dengan kode PURCHASE_DEFERRED

Bagaimana menurut anda?

Apakah halaman ini membantu?
0 / 5 - 0 peringkat