React-native-iap: Fehler beim Kauf der iOS-In-App, wenn die Zahlungsmethode live hinzugefügt wird, wenn noch keine Zahlungsmethode vorhanden ist

Erstellt am 31. Okt. 2018  ·  27Kommentare  ·  Quelle: dooboolab/react-native-iap

Version von react-native-iap

react-native-iap": "^2.3.17

Plattformen, auf denen Sie den Fehler hatten (IOS oder Android oder beides?)

iOS

Erwartetes Verhalten

Die Zahlung sollte nur erfolgen, wenn finishTransaction aufgerufen wird

Tatsächliches Verhalten

Der Betrag wird erkannt, nachdem eine Zahlungsmethode wie eine Kreditkarte hinzugefügt wurde.
Aber die RNIap.buyProductWithoutFinishTransaction(sku) Methode wurde erreicht.

Getestete Umgebung (Emulator? Reales Gerät?)

Echtes Gerät - iPhone 6s

Schritte zum Reproduzieren des Verhaltens

  • Stellen Sie sicher, dass das Apple-Konto auf dem Gerät, auf das die Zahlungsmethode eingestellt ist, auf keine oder einige ungültige Zahlungsdetails eingestellt ist
  • Kaufen Sie die In-App über die App
  • Der Benutzer wird zur Seite Kontoeinstellungen weitergeleitet, um eine gültige Zahlungsmethode hinzuzufügen
  • Die Zahlungsmethode wird in Rechnung gestellt, aber der Transaktionsbeleg wird nicht im unten angegebenen Code empfangen
ComponentDidMount(){
     await RNIap.initConnection();
     await RNIap.consumeAllItems();
     const prod = await RNIap.getProducts(product);

} 

  async componentWillUnmount() {
       RNIap.endConnection()
}

buyProduct(sku){
await RNIap.clearTransaction();

RNIap.buyProductWithoutFinishTransaction(sku)
.then(purchase => {
  // not reached
 if(calltoserverisSuccess){
    RNIap.finishTransaction();
 }
})
.catch(error => {
 // code enters catch case if ever
}}
📱 iOS 🙏 help wanted

Hilfreichster Kommentar

Ich denke, wir müssen apple dafür kontaktieren und das sieht wirklich schrecklich aus, dass es einen anderen Testfall gibt, der in einer sandbox -Umgebung nicht reproduzierbar ist. Für diejenigen, die das Problem verstehen wollen, habe ich den Bildschirm aufgenommen und Sie können den Clip hier sehen . @anandwahed Könnten Sie Apple auch kontaktieren? Weil ich weiß, dass sie nicht so unterstützend sind, ist es besser, wenn mehr Menschen Kontakt zu ihnen haben. Lassen Sie uns zusammenkommen, um dieses Problem zu lösen.

Alle 27 Kommentare

Tut mir leid, das zu sagen, aber Ihr Code scheint viele Syntaxfehler zu haben. Bitte beziehen Sie sich auf unser Beispielprojekt in unserem Repo und vergleichen Sie es zuerst mit Ihrem Code.

@dooboolab
Vielen Dank für die Antwort. Der Code, der hier veröffentlicht wird, ist nur ein Beispiel. Dies ist nicht genau der Code, der in der realen Anwendung verwendet wird.
Ich werde versuchen zu erklären, was das Problem ist

  1. componentDidMount

    • Die Verbindung wird durch Aufrufen von RNIap.initConnection(); initiiert

    • Dann werden Produkte abgerufen und im Status gespeichert, indem RNIap.getProducts(product)

  1. Wenn der Benutzer auf die Schaltfläche "Kaufen" klickt

    • RNIap.clearTransaction(); wird aufgerufen, um sicherzustellen, dass keine ausstehenden Transaktionen mehr vorhanden sind.
    • RNIap.buyProductWithoutFinishTransaction(sku) wird im Erfolgsfall aufgerufen, wenn ein Aufruf des Anwendungsservers ausgelöst wird. Wenn der Server den Erfolgsfall true angibt, wird RNIap.finishTransaction(); aufgerufen, um die Zahlung abzuschließen.
  2. componentWillUnmount ()

    • RNIap.endConnection() zum Beenden der Verbindung.

Dieser Vorgang funktioniert einwandfrei, wenn der Benutzer bereits eine Zahlungsmethode hinzugefügt hat. Wenn dem Benutzer keine Zahlungsmethode hinzugefügt wurde, muss die Seite mit den Zahlungsmethoden hinzugefügt werden, und der Betrag wird berechnet, bevor die RNIap.finishTransaction();

Danke für das Detail. Ihr Problem sieht jetzt klar aus. cc @JJMoon

@JJMoon

@ zohaibahmed-22 Ist das Sandbox-Testfall?

@JJMoon Nein, es ist ein realer Umgebungsfall.

Ich verstehe, dass dieser Fehler auftritt, wenn sich der Benutzer im abgemeldeten Zustand befindet oder keine Kreditkarteninformationen vorliegen.
Wenn die Methoden einwandfrei funktionieren, liegt die Ursache für diesen Fehler an einer anderen Stelle.
Wir müssen diese Aktion vorbereiten, die die App, viewDidDisappear usw. verlässt.
Im Sandbox-Modus tritt dieses Symptom etwas anders auf.
Wenn ich ein neues Sandbox-Konto erstelle und der erste Kauf nicht funktioniert.
Beim zweiten Mal ist das Gerät angemeldet und funktioniert einwandfrei.
Ich habe keine Ahnung für diesen Fehler.

@dooboolab und @JJMoon Ich glaube auch, dass ich das Problem beim aktualisierten Transaktionsmethode eine Fehlermeldung in SKPaymentTransactionStateDeferred oder SKPaymentTransactionStateFailed , wird nicht angenommen, dass finishTransaction .

Da in vielen Fällen auf das Ergebnis von SKPaymentTransactionStateFailed ein SKPaymentTransactionStatePurchased folgt, wie im obigen Thread 6431 erwähnt . Ich bin mir über den Objective-C-Code nicht sicher. Überprüfen und bestätigen Sie daher, ob wir die Transaktion bei einem Fehler löschen.

@anandwahed Ich stimme dir zu. Es ist meine Schuld. Das tut mir leid.
Ich werde den Thread von Apple durchsehen und mich um das Problem kümmern.

@anandwahed Ich denke, es ist der richtige Weg zu finish transaction wenn es fehlgeschlagen ist. Bitte schauen Sie in diesem Thread nach. https://stackoverflow.com/questions/11008636/inapp-purchase-skpaymentqueue-finish-transaction-doesnt-work
Wenn dies fehlschlägt, wird keine Quittung ausgestellt, sodass Sie das Kaufprodukt nicht anwenden. Und die Abschluss-Transaktion bedeutet nicht immer "Einkauf".
In der Zwischenzeit werde ich Thread 6431 untersuchen.

Ich habe gerade den Thread 6431 gelesen (https://forums.developer.apple.com/thread/6431#14562)
Das Endergebnis. Problem seit 2015 nicht gelöst. Wow ..
Es gibt zwei verschiedene Möglichkeiten, um diesen "Store Kit Flow" -Effekt zu handhaben.

  1. Zeigen Sie keine Benutzerwarnung an.
  2. Zeigen Sie das Ergebnis.

Und ich habe zwei Dinge gelernt.
A. Wir müssen finishTransaction wenn es fehlgeschlagen ist. (Ich denke mit oder ohne Option, immer)
B. Der Storekit-Fluss schlägt fehl und der Erfolg mit dem Empfang ist beides. (es ist schlecht)

Ich empfehle Ihnen allen, diesen Thread zu lesen und zu diesem Thema zurückzukehren.

Ich denke, welchen Weg Sie wählen (1 oder 2), ist allein.
Möglicherweise benötigen wir einen Rückruf, um auf Fehler zu reagieren.

@JJMoon bedeutet das, dass wir buyProductWithoutFinishTransaction nicht verwenden sollten?

@ maxs15 Das habe ich nicht so gemeint. Entschuldigung für die Verwirrung.
Der StoreKit-Ablauf kann bei jedem Einkauf erfolgen. Es ist ein iOS-Problem, nicht dieses Modul.
Im Moment habe ich auch keine Ahnung. Dies passiert in allen nativen iOS-Apps. Richtig?
In unserer Freizeit werden wir mehr graben.

Heute habe ich versucht, dieses Problem zu debuggen, weil ich dieses Problem generiert habe. Die Zahlung finishTransanction und ist abgeschlossen, erhält jedoch nicht die callback wenn payMethod geändert wurde. Ich habe versucht, das Schreiben von console.log zu debuggen, aber ich konnte die echte Abrechnung in einer dev -Umgebung nicht testen. Könnte mir jemand vorschlagen, wie ich diesen Prozess debuggen kann, damit ich debug dies für real purchase ? Sollte ich dies im sandbox -Modus verwenden müssen? Es funktioniert perfekt in Sandbox, daher habe ich keine Ahnung, wie ich das debuggen soll. Das ist sehr zurückhaltend.

Lassen Sie uns einige Ideen sammeln, da ich denke, dass dies sehr wichtig ist, um behoben zu werden.

Ich erhalte immer diese Fehlermeldung, wenn ich den Kauf mit einem Benutzer ohne Sandbox versuche.

@hyochan Wenn Sie den realen Server (Ihren) verbinden, spielt es keine Rolle, ob Sie sich im Debug- oder Release-Modus befinden. Ich denke du hast 2 Möglichkeiten.

  1. Sie laufen auf dem realen Gerät im Debug-Modus in Xcode. Verwenden Sie das JS-Konsolenprotokoll.
  2. Sie laufen auf dem realen Gerät im Release-Modus in Xcode. Verwenden Sie NSLog im Objective-C-Code.
    Beide Methoden sollten funktionieren.

@JJMoon Ja, das habe ich schon herausgefunden, aber ich konnte immer noch keine Live- Stapelüberlauf wahr? Wie kann ich dann dieses Problem lösen? Wir müssen den Live-Kauf testen.

Ich bin sicher, jeder, der mit diesem Problem konfrontiert ist, gibt uns bitte eine Vorstellung davon, wie wir diesem Problem begegnen können. in-app purchase fail when payment method added live wie im Titel der Ausgabe beschrieben. Wie könnte ich das debuggen? @anandwahed Hast du Apple jemals wegen dieses Problems kontaktiert?

@hyochan Nein, wir haben den Apple-Support nicht kontaktiert.

Ich denke, wir müssen apple dafür kontaktieren und das sieht wirklich schrecklich aus, dass es einen anderen Testfall gibt, der in einer sandbox -Umgebung nicht reproduzierbar ist. Für diejenigen, die das Problem verstehen wollen, habe ich den Bildschirm aufgenommen und Sie können den Clip hier sehen . @anandwahed Könnten Sie Apple auch kontaktieren? Weil ich weiß, dass sie nicht so unterstützend sind, ist es besser, wenn mehr Menschen Kontakt zu ihnen haben. Lassen Sie uns zusammenkommen, um dieses Problem zu lösen.

Heute haben wir eine Antwort von Apple erhalten. Möglicherweise wird nach failure Rückruf zurückgegeben. Wir arbeiten an einer Problemumgehungslösung in # 348, aber ich befürchte, dass dies sehr böse sein könnte.

Ich habe auf 2.4.0-beta1 freigegeben und versucht, eine Problemumgehung für dieses Problem zu finden. Das PR # 348 wurde zu dieser Version hinzugefügt, und Sie können auch die Readme-Datei dieser Funktion anzeigen. Beachten Sie, dass dies derzeit getestet wird.

Ich habe dies in einem Live-Kauf getestet und scheint zu funktionieren. Beachten Sie jedoch, dass Sie den Listener nur hinzufügen sollten, wenn ein Fehler aufgetreten ist oder er möglicherweise mit einem erfolgreichen Ergebnis dupliziert wird.

Leute, danke, dass ihr Zeit in dieses Problem investiert habt! 🙏

Ich denke, die aktuelle Dokumentation muss klarer in Bezug auf die Verwendung von addAdditionalSuccessPurchaseListenerIOS . Das habe ich versucht, auf # 414 anzusprechen.

Ich denke aber auch, dass dies Raum für Verbesserungen der API lässt. Würdet ihr offen sein, eine Änderung in der API zu diskutieren, die den sogenannten "Store Kit Flow" besser berücksichtigen kann? Etwas, das vielleicht RxJS verwendet, zum Beispiel:

const observable = RNIap.buyProduct('com.example.coins100')
                        .subscribe(
                            purchase => console.log(purchase), // successful payment
                            err => console.log(err) // err.code and err.message are available
                        )

Oder etwas anderes, das das zusätzliche Abonnement für iOS besser verbirgt?

@Edgpaez Das ist großartig, aber das ändert das Verhalten des Kaufs in android . Ich hoffe, ich kann version 3 dieses Moduls in 2019 .

hi @hyochan , AFAICT, wir müssen das interne Verhalten des Pakets nicht ändern, nur die öffentlich zugängliche Oberfläche. Wir können die buyItemByType- Methode aufzulösen , und einfach ein bisschen Rx zusätzlich zu index.js hinzufügen .

Zum Beispiel hätten wir dies in index.js:

export const buyProduct = (sku) => Platform.select({
  android: () => Observable.of(RNIapModule.buyItemByType(ANDROID_ITEM_TYPE_IAP, sku, null, 0)), // returns an observable that emits when the RNIapModule.buyItemByType promise resolves
  ios: ... // ios would do the same but taking into account the usage of addAdditionalSuccessPurchaseListenerIOS
})();

Mein Ziel ist nicht diese spezifische Implementierung, sondern das Ausblenden von Details, die für den "Store Kit Flow" spezifisch sind.
Halten Sie das für eine gute Idee?
Würden Sie sich für eine PR interessieren?

@ Edgpaez Ok. Ich verstehe das Detail jetzt. Ich bin jedoch der Meinung, dass das Hinzufügen von RxJS etwas zu viel für die Implementierung von feature da ich denke, dass dies ohne es abgedeckt werden kann.

Ich denke auch, dass das Folgende etwas anderes wäre.

RNIap.buyProduct('com.example.coins100')
                        .subscribe(
                            purchase => console.log(purchase), // successful payment
                            err => console.log(err) // err.code and err.message are available
                        )

Wenn Sie buyProduct für zwei Artikel wie unten anrufen,

RNIap.buyProduct('com.example.coins100');
RNIap.buyProduct('com.example.coins200');

Wir können nicht garantieren, welches zuerst fertig wird, daher denke ich, dass wir dies in nativem Zustand von sendEvent bis JS .

Ich denke, die Implementierung sollte so aussehen

RNIap.buyProduct('com.example.coins100');
RNIap.buyProduct('com.example.coins200');

// receiving events
const subs =  RNIap.purchaseUpdateListener(purchase => {
  ...
});

Bitte sagen Sie mir, ob ich etwas verpasst habe.

Lassen Sie uns in # 423 weiter mit Disccustin umgehen

War diese Seite hilfreich?
0 / 5 - 0 Bewertungen