2.2.2
IOS
RNIAP APIを使用して、自動更新サブスクリプションがまだアクティブであるかどうかを確認できます
これをチェックするためにAndroidのIMでこれを行っています:
export const isUserSubscriptionActive = async (subscriptionId) =>{
// Get all the items that the user has
const availablePurchases = await getAvailablePurchases();
if(availablePurchases !== null && availablePurchases.length > 0){
const subscription = availablePurchases.find((element)=>{
return subscriptionId === element.productId;
});
if(subscription){
// check for the autoRenewingAndroid flag. If it is false the sub period is over
return subscription["autoRenewingAndroid"] == true;
}
}else{
return false;
}
}
}
iOSでは、それをチェックするフラグはありません。getAvailablePurchasesメソッドは、現在アクティブでないサブスクリプションも含め、行われたすべての購入を返します。
これを確認する方法はありますか?
よろしく、
マルコス
私もこれを理解するために取り組んでいます。 私はまだテストしていませんが、私が読んでいることから、iTunes Connectで「共有シークレット」を作成し、これをキー「password」でvalidateReceiptIosに渡すことで可能であることがわかりました。 これにより、サブスクリプションの検証ステータスを示すコードと、サブスクリプションのステータスを判断するために使用できるキーlatest_receipt、latest_receipt_info、latest_expired_receiptinfoなどを含むJSONオブジェクトが返されると思います。 私は文字通りこれを理解しているだけなので、まだテストしていません。 それは私が問題とAppleのドキュメントからまとめているものです。 これが機能する場合は、問題に埋もれているのではなく、ドキュメントで非常に明確にする必要があります。
次のリンクが関連していると思います。
https://developer.apple.com/library/archive/releasenotes/General/ValidateAppStoreReceipt/Chapters/ValidateRemotely.html
編集:私は上記のプロセスが機能することを確認できます。 ドキュメントでこれを完全に説明するために作業する必要があると思います。 アプリの起動時に次のようなものを実装して、サブスクリプションの有効期限が切れているかどうかを判断します。
RNIap.getPurchaseHistory()
.then(purchases => {
RNIap.validateReceiptIos({
//Get receipt for the latest purchase
'receipt-data': purchases[purchases.length - 1].transactionReceipt,
'password': 'whateveryourpasswordis'
}, __DEV__)
.then(receipt => {
//latest_receipt_info returns an array of objects each representing a renewal of the most
//recently purchased item. Kinda confusing terminology
const renewalHistory = receipt.latest_receipt_info
//This returns the expiration date of the latest renewal of the latest purchase
const expiration = renewalHistory[renewalHistory.length - 1].expires_date_ms
//Boolean for whether it has expired. Can use in your app to enable/disable subscription
console.log(expiration > Date.now())
})
.catch(error => console.log(`Error`))
})
@kevinEsherick
素晴らしい!
あなたのコードについてとても些細なことではないいくつかのこと。
const Expiration =
代わりに(おそらく単なるタイプミス)
const Expiration =
2)「パスワード」が何であるかを知らない人のために:「何でもあなたのパスワードは」:
アプリ内ページの共有秘密鍵を作成して、アプリで使用できます
手順は次のとおりです: https :
+1してドキュメントを更新します。また、 @ dooboolabを使用すると、IOSとAndroidのユースケースを分けることができます。いくつかの違いがあるようです。 あなたが望むなら私はあなたを助けることができます。
よろしく
@kevinEsherick
自動更新サブスクリプションはどうなりますか?
Expires_date_msが最初の有効期限であるようですが、更新されていません
私はこれをテストしました:
何か案は?
残念ながら、賞味期限が更新されているようです。少し時間がかかります。
誰かが同じシナリオにいる場合に備えて、このコメントをここに残しておきます。
よろしく
- そのはず
const Expiration =
代わりに(おそらく単なるタイプミス)
const Expiration =
おっと、あなたは正しいです、それはタイプミスでした。 意味をわかりやすくするために名前を変更しましたが、すべての出現箇所を変更するのを忘れていました。 編集しました、ありがとう。
そして、有効期限のある正確なシナリオはありませんでしたが、自動更新されないものがいくつかありましたが、それはどういうわけかそれ自体で解決しました(心配ですが、他に何をすべきかを再現することはできません)。 あなたが抱えていた問題はかなり一般的なものです。 これはApple側で予想される動作であるため、ユーザーのサブスクリプションを解除する前に、サブスクリプションを更新するためのバッファー期間を残す必要があります。 SOに関するこの問題は、より詳細に説明しています: https :
ありがとう! 素晴らしい情報、理由かもしれません
この問題については、 @ kevinEsherickコードをドキュメントに含める必要があると思います👍登録者を確認するのに最適な方法です!
はい。 PR
をリクエストされた方がいらっしゃいましたら、 readme
きちんとしたドキュメントをいただければ幸いです。 ありがとう。
こんにちは、みんな。 readmeにQ&Aセクションを追加しました。 誰かがこの問題のために私たちにPR
を与えることができることを願っています。
今後数日でPRを行うことを検討します:)
また、このライブラリをサブスクリプション専用に使用したいと考えています。 iOSとAndroidの両方。 ユーザーが有効なサブスクリプションを持っているかどうかを判断する適切な方法を文書化していただければ幸いです。 😄
@curiousdustinこれに関するAppleの実装は、 mediumを参照すると本当にひどいものです。 バックエンドでこの種の処理を行う必要があるため、モジュールでこれを完全にサポートすることはできませんでした。 ただし、iOSサブスクリプション製品では機能しないメソッドgetAvailablePurchases
を使用して、AndroidでavailablePurchases
を取得できます。
それで、 @ marcosmartinez7と@kevinEsherickがこのスレッドで取り組んでいる解決策は解決策ではなく、iOSサブスクリプションのステータスを確認するためにApple以外のバックエンドサーバーが必要だと言っていますか?
Appleのドキュメントと一緒に投稿したMediumの記事を読むと、サーバーを使用することが望ましいようですが、デバイスのみでサブスクリプションのステータスを判断することは不可能ではありません。
文章の一部の情報を見逃してしまい申し訳ありません。 これを管理します。
Apple
は、中間者攻撃を防ぐために、 receipt
を自分のサーバーに保存することを提案します。 したがって、後でそのレシートをチェックして、レシートが有効であるか、サブスクリプションがまだ利用可能であるかを確認できます。
ただし、 @ marcosmartinez7と@kevinEsherickがうまくいった所有のAppleサーバー(サンドボックスと本番)に検証レシートの直接フェッチを提供しているため、 react-native-iap
試してみるのは不可能ではありません。
私は現在、これがios
サブスクリプションをチェックするための解決策だと思います。
こんにちは、数日以上経ちました。仕事に追われましたが、READMEを更新するためにそのPRを送信します。 @curiousdustin上記で書いた方法は間違いなく機能し、ドキュメントに追加します。 今夜または明日PRを提出します:)
アップデートに感謝します。
あなたの例からもう1つ気づきました。
'receipt-data':purchases [purchases.length-1] .transactionReceipt、
..。
const Expiration = renewalHistory [renewalHistory.length-1] .expires_date_ms
私のテストでは、購入と更新履歴は必ずしも特定の順序である必要はありません。 意図したものを使用していることを確認するために、それらを並べ替える必要はありませんか?
こっちも一緒。 PurchasesとrenewalHistoryは間違いなく注文されていないため、最初に並べ替える必要があります。 開発では、それは多くの反復になることになります。
これが私が使用しているAndroidとiOSの両方で機能する関数であり、iOSで適切に並べ替えて、最新のレシートデータを確実に取得できるようにします。
import * as RNIap from 'react-native-iap';
import {ITUNES_CONNECT_SHARED_SECRET} from 'react-native-dotenv';
const SUBSCRIPTIONS = {
// This is an example, we actually have this forked by iOS / Android environments
ALL: ['monthlySubscriptionId', 'yearlySubscriptionId'],
}
async function isSubscriptionActive() {
if (Platform.OS === 'ios') {
const availablePurchases = await RNIap.getAvailablePurchases();
const sortedAvailablePurchases = availablePurchases.sort(
(a, b) => b.transactionDate - a.transactionDate
);
const latestAvailableReceipt = sortedAvailablePurchases[0].transactionReceipt;
const isTestEnvironment = __DEV__;
const decodedReceipt = await RNIap.validateReceiptIos(
{
'receipt-data': latestAvailableReceipt,
password: ITUNES_CONNECT_SHARED_SECRET,
},
isTestEnvironment
);
const {latest_receipt_info: latestReceiptInfo} = decodedReceipt;
const isSubValid = !!latestReceiptInfo.find(receipt => {
const expirationInMilliseconds = Number(receipt.expires_date_ms);
const nowInMilliseconds = Date.now();
return expirationInMilliseconds > nowInMilliseconds;
});
return isSubValid;
}
if (Platform.OS === 'android') {
// When an active subscription expires, it does not show up in
// available purchases anymore, therefore we can use the length
// of the availablePurchases array to determine whether or not
// they have an active subscription.
const availablePurchases = await RNIap.getAvailablePurchases();
for (let i = 0; i < availablePurchases.length; i++) {
if (SUBSCRIPTIONS.ALL.includes(availablePurchases[i].productId)) {
return true;
}
}
return false;
}
}
@andrewze
Androidシナリオでは、サブスクリプションが自動更新可能である場合、availablePurchasesで返されます
@curiousdustin @andrewzeyそうです、購入は注文されていません。 ただし、renewalHistory / latest_receipt_infoは常に注文されます。 購入が注文されていないことに気付いたのを覚えていますが、これが実際には問題ではないという何らかの理由を見つけたと思いました。 家に帰ってから数時間でこれを調べます。 これがわかるまで、PRを提出したくありません。
編集:購入を並べ替える必要がないと思う理由は、クエリした購入に関係なく、expires_date_msが同じ値を返すためです。 これはあなたたちにとって同じではありませんか? または、並べ替えが必要な情報が少しありますか? あなたの考えを聞かせてください。 私は、購入が時系列で注文されていないことをドキュメントが明確にする必要があることに同意しますが、私が知る限り、有効期限を取得するために並べ替えは必要ありません。
@kevinEsherickありがとう! 私の場合、購入も更新履歴も注文されていません。
@kevinEsherick @andrewzey皆さんはこのソリューションにPR
を与えることができますか? 苦しんでいる他の人たちと分かち合いたいと思います。
確かに、公開アプリの起動が完了したらすぐに準備します=)。
私は私の最後のコメントに関するさらなる会話を待っていました。 私は未解決のままであるいくつかの問題を提起しました。 上記を参照してください。 それが整理されたら、私たちの1人がPRを行うことができます。
@kevinEsherickああ、すみません、私はそれを逃しました。
expires_date_ms
は、更新の領収書ごとに私にとって間違いなくユニークです。 おそらく私は誤解しましたか? デコードされた各レシートに添付されている更新レシート配列は、選択されているレシートに関係なく同じであることに気付きました。そのため、次の(私の例から)必要がないことがわかります。
const sortedAvailablePurchases = availablePurchases.sort(
(a, b) => b.transactionDate - a.transactionDate
);
しかし、私はとにかく正確にしようとし、Appleが文書化したものからの実際のAPI応答で起こりうる矛盾を補うためにそれをしました。 自動更新サブスクリプションで発生する可能性のあるレシートの総数を考えると、ソート操作にそれほど費用がかかるとは思いません。
PRにETAはありますか? このケースをまったく処理しないため、このパッケージからの移行を検討しています。
@schumannd PRはドキュメントの更新のみであるため、ここでreact-native-iap
移動できます。
最近リリースされたアプリで、コードスニペットが実際に問題なく動作することを確認しました: https :
編集私は間違いなくPRを作成します(Trelloの「Giveback to OSS」リストにあります)が、ブラックフライデーの週末の狂気の後😄
@ schumannd @ andrewzeyが言ったことを2番目に。 PRが言うことはすべてこの投稿に含まれています。 私はそれを回避するつもりでしたが、何をする必要があるかを正確に整理するのに時間がかかりました。それは旅行と多忙なスタートアップ時間と混ざり合って、私はまだそれをPRする時間がなかったことを意味します。 私はまだすぐに計画していますが、他の誰もが望むならその間にステップアップすることができます。 そして@andrewzeyは男を祝福します! よさそうだ、ダウンロードしてあげよう!
このスレッドがiOSで自動更新サブスクリプションを管理する正しい方法を正確に文書化しているとは確信していませんが、代わりに、このライブラリによって公開されているAPIごとの「回避策」ワークフローについて説明しています。 しかし、これは完全に私の側の推測であり、私は間違っている可能性があることを十分に認識しているので、以下に概説する観察についてフィードバックをお願いします。
私はReactNativeで自動更新サブスクリプションを管理する正しい方法を何週間も無駄に研究してきたので、ギアを切り替えて、Objective-C / Swiftでネイティブに管理する方法を研究し始めました。 これにより、ネイティブのStoreKit APIと文書化された使用法を、このライブラリに実装されているものと比較するための参照ポイントが得られました。
この記事は、サブスクリプションの購入、検証、および復元をネイティブiOSアプリで処理する方法についてこれまでに見つけた最良の説明です: https : react-native-iap
で使用されている間、それらは異なるワークフローを実装しています。
私が見る主な違いは、 appStoreReceiptUrl
です。
StoreKitはappStoreReceiptUrl
を提供します。これは、私の理解では、iOSアプリの現在の購入/レシート情報をロードする正しい方法です。 これはreact-native-iap
コードで使用および参照されていますが、参照されている記事に記載されているワークフローとは異なるコンテキストにあるようです。
この実装の違いが問題になるかどうか/どのように問題があるかはわかりませんが、 react-native-iap
APIは、StoreKitのrestoreCompletedTransactions
に不必要な依存関係を作成しているようです。これは、最終的にgetPurchaseHistory
と呼ばれます。
react-native-iap
APIは、iOSの次のワークフローをサポートする必要があるようです。
appStoreReceiptUrl
介して)現在のアプリの領収書を読み込もうとしますappStoreReceiptUrl
がnullの場合、現在のデバイスで「復元」を開始すると、 appStoreReceiptUrl
の値が設定され、検証ロジックを再試行できます。考え?
繰り返しになりますが、このライブラリの実装または参照されているネイティブ実装を誤解している可能性があります。
@sellmeadog
あなたがリンクした記事でも言及されている重要なポイントはこれだと思います:
注:プロジェクトアプリはSelfieServiceを実行します。これは、領収書を受け取り、Appleの領収書検証サービスに直接アップロードします。 これは、サブスクリプションの設定に焦点を当てたチュートリアルを維持するための「チート」です。 実際のアプリでは、アプリではなく、リモートサーバーを使用する必要があります。
自動更新可能なサブスクリプション全体を理解するのに少し時間がかかりましたが、それを処理するための最良の方法は、信頼できる唯一の情報源として独自のバックエンドを使用することです。
これは、サブスクリプションを処理するための唯一の正しい方法のように思えました。 また、しばらくの間、自動更新可能なサブスクリプションを商業的に使用している他の開発者とこのプロセスを検証しました。
したがって、OPの質問に対する私の答えは、フロントエンドではなくバックエンドで定期的にサブスクリプションを確認することです。
@schumannd
同じ問題を理解しているのか、話しているのかわかりません。
領収書の検証はサーバーで実行する必要があります。 Apple自身のドキュメントによると:
アプリからAppStoreサーバーの
/verifyReceipt
エンドポイントを呼び出さないでください。
参照記事の「チート」は、バックエンドサーバーに委任するのではなく、簡潔にするために、サンプルアプリがアプリから直接/verifyReceipt
直接呼び出すものとして具体的に解釈しました。
Apple / App Storeは、信頼できる唯一の情報源であり、そうあるべきだと私には思えます。 Appleは最終的に購入、更新、キャンセルなどを処理し、それに応じて領収書を生成し、そのデータをStoreKit
APIを介して利用できるようにします。
react-native-iap
は問題なく購入と購入の復元を処理しますが、ローカルでappStoreReceiptUrl
で利用できるApp Storeのレシートデータへのアクセスにはまだギャップがあると思います。これも、 Appleが文書化したレシートへのアクセス方法です。データ:
領収書データを取得するには、
NSBundle
のappStoreReceiptURL
メソッドを使用して、アプリの領収書を見つけます...
Appleのドキュメントを読み、ネイティブのObject-C / Swift実装を参照することで理解できるワークフローは、次のとおりです。
appStoreReceiptUrl
によってStoreKit
ローカルに保存されます/verifyReceipt
直接送信しない)に送信する必要がありますappStoreReceiptUrl
は、キャンセルや更新が発生するたびにStoreKit
によって更新されます(適切なStoreKit
デリゲートが正しく登録されていると仮定)appStoreReceiptUrl
がnullの場合、ユーザーが新しいデバイスを使用しているなどの理由で、Apple / AppStoreから現在のレシートデータを取得する購入復元ワークフローを使用すると、 StoreKit
はこれをappStoreReceiptUrl
ローカルに保持します繰り返しになりますが、 react-native-iap
は、 appStoreReceiptUrl
からの領収書データの読み込みを除いて、これらすべてを処理します。 ローカルレシートを照会するgetReceipt
メソッドを使用すると、サブスクリプションやその他の購入を管理する負担が軽減されると思います。
Appleは、これを本来あるべきよりもはるかに推論するのを難しくしている。
appStoreReceiptUrl
は、キャンセルや更新が発生するたびにStoreKit
によって更新されます(適切なStoreKitデリゲートが正しく登録されていることを前提としています)
これは、私がこのアプローチで抱えている問題を説明しています。ユーザーがインターネット接続が機能している状態でアプリを後で開かない場合、更新/キャンセル/有効期限などの通知は届きません。
それ以外は、私が説明したアプローチの良い代替案のようです。 プロダクションアプリで最もよく使われているのはどれだろうか。
@sellmeadogそれは私がここに投稿したのと同じ考えだと思います:#356
レシートをローカルで検証することは1つの方法であり、アップルが推奨しています。 これは、サーバー/ネットワークの要求から完全に独立しています。
うん。 「ネットワーク接続がない-検証がない」という欠点があります。
しかし、そのユースケースがあります。
アプリを起動するたびにレシートをすばやく検証したいのですが、 UserDefaults
またはKeychain
介して自分でアプリ内購入を追跡したくありません。 StoreKit
すでに保存メカニズムを提供しています。
getAvailablePurchasesなどを介してitunesアカウントにログインするように求めることなく、IOSユーザーがサブスクリプションを更新またはキャンセルしたかどうかをどのように確認する必要がありますか?
例えば:
サブスクリプションを最初に購入すると、レシートを検証し、有効期限をFirebaseプロファイルに保存します。 そのFirebaseノードを使用して、アクティブなサブスクリプションがあるかどうかを起動を確認します。 この問題は、その有効期限が過ぎて新しい請求期間が開始されたときに発生します。 自動更新またはキャンセルされたかどうかを確認するにはどうすればよいですか? 前述のように、getAvailablePurchasesを使用していましたが、復元ボタンのようにitunesのログインを促します。これはひどいUIです。
私も同じことだろうか。
私たちのアプリでは、ステータスを確認するためにAppleと直接通信するサーバー側APIがあるため、これは必要ありません。 最初の購入後、レシートデータはサーバーに保存され、後で更新されたステータスを要求するために使用されます。
ただし、これはデバイス側でも可能であると思います。 私はこれに関する専門家ではありませんが、私が理解しているように、アプリは更新が発生するたびにOSから更新されたトランザクション/レシートを受け取ります。 このプラグインは、アプリの起動時にこれらのレシートを処理していると思われます。 (Xcodeから実行すると、複数のトランザクションを処理しているように見える大量のログが表示されます)しかし、私が知る限り、JSコードでこれらのイベントを利用する方法はありません。
これについてもう少し情報を得ることができますか?
@csumrell @curiousdustin実稼働環境でこの動作を確認しましたか? サンドボックスが原因で発生している可能性があるのではないかと思います。デバイスにはおそらく別の非サンドボックスアカウントがあるため、サンドボックスアカウントにサインインする必要がありますが、本番環境では、ユーザーはおそらく通常のアカウントにサインインします。モジュールは、ログインを要求せずにgetPurchasesを取得できる場合があります。
申し訳ありませんが、 getAvailablePurchases()
が本番環境でパスワードプロンプトを表示することを確認していません。
私の経験では、少なくともiOSでは認証が含まれる、購入の復元と一般に呼ばれる機能に使用されているこの方法についてドキュメントが説明しているためだと思いました。
@hyochan @JJMoonこれについてももっと情報を
@curiousdustin yeaなので、通常のiTunesアカウントからサインアウトしてサンドボックスアカウントにサインアウトしても、このメソッドが呼び出されたときにログインを求めるプロンプトが表示されなくなりました。 したがって、私の推測/希望は、ユーザーが使用中のサンドボックスアカウントを持っていない本番環境では、問題が発生することはないはずです。 ベータテストは、ユーザーがデバイスにサンドボックスアカウントを設定していない本番環境と同じように機能するはずです。これは、開発デバイスの問題にすぎません。 だから私は明日ベータユーザーでこれをテストし、私が見つけたものをあなたに知らせます。
編集:これがサンドボックス以外のデバイスで発生することを確認できます。 これはひどいUXであり、非常に問題があります。 誰か、何かアイデアはありますか?
そのため、アプリからAppStoreサーバー/ verifyReceiptエンドポイントを呼び出して自分のサーバーで検証すると、元の最初の購入レシートだけで、そのユーザーの最新の更新日情報が常に返されます。
ローカルのvalidateメソッドを使用しても常に最新の情報が返されるかどうかを誰かが知っていますか? それとも、ローカルで検証するのはその領収書のためだけですか?
また、Appleで検証するために独自のサーバーを設定するためのアドバイスはありますか? 私はそれについての経験がありません
@csumrell getPurchaseHistoryを呼び出して並べ替えることで、最新の購入の領収書を取得できます。 上記のコメントは、これを行う方法を詳しく説明しています。 これには最新の情報が含まれているはずです。
そして、お互いに助け合うことができるように、サーバーで検証するオプションを検討しようとしています。 しかし、他の誰かがそれについてどのように行ったかを聞きたいです。
@kevinEsherickはい。ただし、getPurchaseHistoryはItunesログインポップアップをトリガーします。 ユーザーが最初に購入したときに、元のレシートをローカルストレージに保存することについて話しています。 次に、getPurchaseHistoryを呼び出して次の請求を確認する代わりに、ローカルで検証されたvalidateReceiptIos(originalReceipt)を呼び出します。 ただし、validateReceiptIosがアップルサーバー/ verifyReceiptのように最新のトランザクションを返すかどうかはわかりません
@csumrellガッチャ。 それはすばやく簡単にテストできます。 やってみませんか? そうでない場合は、今日後でチェックアウトします。
編集: @csumrell validateReceiptIosは実際、その購入の最新の自動更新を追跡するため、これは有効な方法です。 これは、iTunesのログインプロンプトを回避するため、サブスクリプションをチェックするための上記の提案された方法よりも優れていると思います(誰かがその修正を思い付くことができない限り)。 欠点は、領収書をローカルに保存する必要があることです。 これはそれほど面倒なことではありません。 また、セキュリティ上の理由や、大量の(〜60k文字)という事実のために、これらの領収書をバックエンドに送信したくない場合もあります。そのため、サブスクライブしたユーザーがサインアウトするか、新しいデバイスの使用を開始した場合は、次のことを行う必要があります。最新の購入レシートを取得するためにログインするように促します。 サブスクリプションステータスを内部に保存して、最後にチェックしたときにサブスクライブしたユーザーのみにプロンプトを表示することができます。
@hyochanはこの問題に$ 20.00の資金を提供しました。 IssueHuntでご覧ください
@hyochanあなたはどのような具体的な解決策に資金を提供していますか? このスレッドでいくつか提供しましたが、私の最新のコメントは、これまでで最も強力な解決策であり、問題が最も少ないと思います。 これらのソリューションをREADMEの1つの簡潔なPRにまとめるために、誰かに資金を提供していますか? それとも、これはまだ解決したい実際のコードの問題がありますか?
@kevinEsherick
これらのソリューションをREADMEの1つの簡潔なPRにまとめるために、誰かに資金を提供していますか?
はい。 これは絶対に正しいです。 また、 issue hunt
が箱から出してどのように機能するかをテストしたかっただけです。 私の次の計画は、テストケースの作成に資金を提供することです。
@kevinEsherick正解です
この方法を使用して、独自のサーバーをセットアップする必要をなくし、サブスクリプションがアクティブかどうかを確認する際のitunesログインポップアップを回避します。
@csumrellと私がレイアウトしたこの検証フローの使用を検討している人への注意:開発中、最初の起動時にiTunesログインプロンプトがまだポップアップしていることがわかりました。 これは本番環境では発生しません。 あなたが私たちがレイアウトしたステップに従っている限り、すべてがうまくいくはずです。 これを行う理由については、iOSがIAPが使用されていることを確認した場合、または開発中のモジュールマップの一部である場合、自動的にサインインを促します。よくわかりませんが、サンドボックステストの機能にすぎないようです。
ねえ、最近この問題に関する活動はなかったようです。 問題は修正されましたか、それともコミュニティの注意が必要ですか? それ以上のアクティビティが発生しない場合、この問題は解決される可能性があります。 この問題に「ディスカッション用」または「良い最初の問題」というラベルを付けることもできます。開いたままにしておきます。 貢献していただきありがとうございます。
長期間使用されなかった後、この問題を解決します。 この問題が最新リリースでも引き続き発生する場合は、最新の情報を使用して新しい問題を作成してください。
おそらく、このフロー全体をドキュメントで明確にする必要がありますか?
特に自動更新サブスクリプションに関しては? サブスクリプションがまだアクティブであるかどうかについてexpires_date_ms
を確認できるかどうかは、初心者には非常に不明確ですか?
これに最適な場所は、より完全な実例にあると思いますか?
人々はこれに興味がありますか? 時間があれば、これに取り組むことができますか?
@alexpchinはい、それは間違いなくクリーンになります
同意! 誰かが#856に興味がありますか?
こんにちは、
@andrewzeyのメソッドは、サブスクリプションのレシートを突然検証できなくなった昨日まで、うまく機能していました
RN 0.61.4、RNIap:4.4.2、およびiOS13.3.1を実行しています
私たちは試しました:
サンドボックスを購入したときにfinishTransactionIOSを正しく使用していなかったかどうか疑問に思っていますか?
本当に奇妙なのは、このオンラインツールを使用してレシートを検証すると、すべてが正常に見え、すべてのレシートメタデータを確認できることです。
isSubscriptionActive = async () => {
const availablePurchases = await RNIap.getAvailablePurchases();
const sortedAvailablePurchases = availablePurchases.sort(
(a, b) => b.transactionDate - a.transactionDate
);
const latestAvailableReceipt = sortedAvailablePurchases[0].transactionReceipt;
const isTestEnvironment = __DEV__;
try {
const decodedReceipt = await RNIap.validateReceiptIos(
{
'receipt-data': latestAvailableReceipt,
password: Config.IN_APP_PURCHASE_SECRET,
},
isTestEnvironment
);
console.log('response!', decodedReceipt)
} catch (error) {
console.warn('Error validating receipt', error) // JSON PARSE ERROR HERE
}
...
@andrewzeyが配置したコードに関する質問。 Date.now()
が現在のデバイス時間ではなく、ユーザーがこれを変更して無限のサブスクリプションを持つ可能性がありますか? 🤔
また、アプリ自体からの領収書を確認することはお勧めできませんか?
@doteric彼らが落胆していると言っているところを教えて
Appleや他のSolidReactNativeソースから適切なドキュメントを見つけるのに苦労しています。
@doteric yes Date.now()はデバイス時間であるため、回避できます。 それでも、ユーザーがこれを行う可能性はごくわずかであり、他の方法でさえ、無限のサブスクリプションを回避することができます。 たとえば、単純なサーバー側の検証を使用する場合、アプリを開く前に機内モードに入り、アプリがサブスクリプションの有効期限が切れていることを認識しないようにすることができます。 もちろん、他にも保護策を講じることができますが、私のポイントは、Date.now()を使用するクライアント側は確かに機能しているということです。 @captaincole私は手元にドキュメントを持っていませんが、クライアント側の検証が推奨されていないことを私も読んだことを確認できます。 私はそれを私が信じるAppleドキュメントで読んだ。 そうは言っても、クライアント側が仕事を成し遂げると思います。
@kevinEsherick @captaincole
iOSでのクライアント側のレシート検証について:
こんにちは、
私は、validateReceiptIosとlatest_receipt_data(expires_date_msと実際の日付を比較)を使用して、このスレッドで説明されているアプローチの1つを試していました。 Xcodeでの開発中にはうまく機能しました。 ただし、Testflightでテストしたところ、機能しなくなりました。 デバッグが難しいため、正確な問題を特定できません。レシートデータを取得していないようです。 誰かがtestflightで同様の問題を抱えていましたか?
前もって感謝します!
こんにちは、
私は、validateReceiptIosとlatest_receipt_data(expires_date_msと実際の日付を比較)を使用して、このスレッドで説明されているアプローチの1つを試していました。 Xcodeでの開発中にはうまく機能しました。 ただし、Testflightでテストしたところ、機能しなくなりました。 デバッグが難しいため、正確な問題を特定できません。レシートデータを取得していないようです。 誰かがtestflightで同様の問題を抱えていましたか?
前もって感謝します!
+1
@asobralr @ Somnus007私は間違っているかもしれませんが、ユーザーはtestflightで購入できないため、testflightでIAPをテストできるとは思いません。 Appleは、本番環境のような環境で購入をテストするための素晴らしい機会を提供していません
@asobralr @ Somnus007私は間違っているかもしれませんが、ユーザーはtestflightで購入できないため、testflightでIAPをテストできるとは思いません。 Appleは、本番環境のような環境で購入をテストするための素晴らしい機会を提供していません
正しい。 残念なことに、サンドボックスで障害シナリオをシミュレートすることさえできません。 😞
こんにちは@kevinEsherick 、お返事ありがとうgetPurchaseHistoryは
requestSubscription()を呼び出す前にgetAvailablePurchases()を呼び出すと問題が発生するため、iOS14はこのソリューションを破っているようです。
最も参考になるコメント
これが私が使用しているAndroidとiOSの両方で機能する関数であり、iOSで適切に並べ替えて、最新のレシートデータを確実に取得できるようにします。