react-native-iap": "^2.3.17
iOS
Le paiement ne doit être effectué que lorsque finishTransaction
est appelé
Le montant est détecté après l'ajout d'un mode de paiement tel qu'une carte de crédit.
Mais la méthode RNIap.buyProductWithoutFinishTransaction(sku)
arrivée.
Appareil réel - iPhone 6s
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
}}
Désolé de le dire, mais votre code semble comporter de nombreuses erreurs de syntaxe. Veuillez vous référer à notre exemple de projet dans notre repo et comparer d'abord avec votre code.
@dooboolab
Merci pour la réponse, le code affiché ici n'est qu'un exemple, ce n'est pas l'exact qui est utilisé dans l'application réelle.
je vais essayer d'expliquer quel est le problème
RNIap.initConnection();
RNIap.getProducts(product)
lorsque l'utilisateur clique sur le bouton d'achat
RNIap.clearTransaction();
est appelé juste pour s'assurer qu'aucune transaction en attente ne reste.RNIap.buyProductWithoutFinishTransaction(sku)
est appelé en cas de succès, un appel au serveur d'applications est déclenché si le serveur donne le cas de succès true, puis RNIap.finishTransaction();
est appelé pour effectuer le paiement.composantWillUnmount ()
RNIap.endConnection()
pour mettre fin à la connexion.Ce processus fonctionne bien si l'utilisateur a déjà ajouté un mode de paiement. Lorsque l'utilisateur n'a pas ajouté de mode de paiement, il faut ajouter la page du mode de paiement et le montant est facturé avant d'atteindre le RNIap.finishTransaction();
Merci pour le détail. Votre problème semble clair maintenant. cc @JJMoon
@JJMoon
@ zohaibahmed-22 Est-ce un cas de test sandbox?
@JJMoon Non, c'est un vrai cas d'environnement.
Je comprends que cette erreur se produit lorsque l'utilisateur est déconnecté ou qu'il n'y a aucune information de carte de crédit.
Si les méthodes fonctionnent correctement, la cause de cette erreur se trouve ailleurs.
Nous devons préparer cette action, qui quitte l'application, viewDidDisappear etc.
En mode sandbox, ce symptôme se produit de manière quelque peu différente.
Lorsque je crée un nouveau compte sandbox et que le premier achat ne fonctionne pas.
À la deuxième fois, l'appareil est connecté et fonctionne correctement.
Je n'ai aucune idée de cette erreur.
@dooboolab @JJMoon jetez un œil à celui-ci
https://forums.developer.apple.com/thread/6431
https://forums.developer.apple.com/thread/64489
@dooboolab et @JJMoon aussi je pense avoir trouvé le problème en parcourant notre code iOS. Dans la méthode updatedTransactions , lorsque nous recevons un message d'échec dans le SKPaymentTransactionStateDeferred
ou SKPaymentTransactionStateFailed
nous ne sommes pas supposés finishTransaction
.
Puisque dans de nombreux cas, le résultat SKPaymentTransactionStateFailed
est suivi d'un SKPaymentTransactionStatePurchased
comme mentionné dans le thread 6431 ci-dessus. Je ne suis pas sûr du code Objective-C, veuillez donc vérifier et confirmer si nous effaçons la transaction en cas d'échec.
@anandwahed Je suis d'accord avec vous. C'est de ma faute. Désolé.
Je vais examiner le fil d'Apple et m'occuper du problème.
@anandwahed Je suppose que c'est la bonne façon de finish transaction
cas d'échec. Veuillez rechercher ce fil. https://stackoverflow.com/questions/11008636/inapp-purchase-skpaymentqueue-finish-transaction-doesnt-work
En cas d'échec, il n'y aura pas de reçu, vous n'appliquez donc pas le produit acheté. Et la transaction finale ne signifie pas toujours «acheter».
En attendant, j'étudierai le fil 6431.
Je viens de lire le fil 6431 (https://forums.developer.apple.com/thread/6431#14562)
La ligne du bas. Problème non résolu depuis 2015. Wow ..
Il existe deux manières différentes de gérer cet effet de «flux de kit de magasin».
Et j'ai appris deux choses.
A. Nous devons finishTransaction
cas d'échec. (Je suppose avec ou sans option, toujours)
B. Le flux de Storekit échoue et réussit à la fois. (c'est mauvais)
Je vous suggère à tous de lire ce fil et de revenir sur ce numéro.
Je suppose que, de quelle manière vous choisissez (1 ou 2), c'est tout seul.
Nous pourrions avoir besoin d'un rappel pour une réponse en cas de panne.
@JJMoon cela signifie-t-il que nous ne devrions pas utiliser buyProductWithoutFinishTransaction?
@ maxs15 Je ne voulais pas dire ça. Désolé pour la confusion.
Le flux StoreKit peut se produire à n'importe quel achat. C'est un problème iOS, pas ce module.
Pour l'instant, je n'en ai aucune idée non plus. Cette chose se produit dans toutes les applications iOS natives. Droit?
Nous creuserons davantage pendant notre temps libre.
Aujourd'hui, j'ai essayé de déboguer ce problème car j'ai généré ce problème. Le paiement finishTransanction
est terminé mais n'obtient pas le callback
lorsque payMethod a changé. J'ai essayé de déboguer l'écriture de console.log
mais je n'ai pas pu tester la facturation réelle dans l'environnement dev
. Quelqu'un pourrait-il me suggérer comment déboguer ce processus afin que je puisse debug
ceci pour real purchase
? Dois-je utiliser ceci en mode sandbox
? Cela fonctionne parfaitement dans le bac à sable, donc je n'ai aucune idée de comment le déboguer. C'est très réticent.
Rassemblons quelques idées car je pense qu'il est très important de le corriger.
J'obtiens toujours cette erreur lorsque je tente d'acheter avec un utilisateur non sandbox.
@hyochan Si vous connectez le vrai serveur (le vôtre), que vous soyez en mode débogage ou en mode version n'a pas d'importance. Je suppose que vous avez 2 options.
@JJMoon Ouais, je l'ai déjà compris mais je ne pouvais toujours pas faire de test d'achat en direct sur iOS. Ce stackoverflow est-il vrai? Alors, comment puis-je résoudre ce problème? Nous devons tester l'achat en direct.
Quiconque est confronté à ce problème, je suis sûr que tous le font, veuillez nous donner une idée de la façon de le résoudre. in-app purchase fail when payment method added live
comme décrit dans le titre du numéro. Comment pourrais-je déboguer cela? @anandwahed Avez-vous déjà contacté apple à propos de ce problème?
@hyochan Non, nous n'avons pas contacté l'assistance Apple.
Je pense que nous devons contacter apple
pour cela et cela semble vraiment terrible qu'il y ait un cas de test différent qui n'est pas reproductible dans l'environnement sandbox
. Pour ceux qui veulent comprendre le problème, j'ai enregistré l'écran et vous pouvez voir le clip ici . @anandwahed Pourriez-vous également contacter Apple à ce sujet? Parce que je sais qu'ils ne les soutiennent pas, il est donc préférable que plus de gens aient des contacts avec eux. Rassemblons-nous pour résoudre ce problème.
Aujourd'hui, nous avons reçu une réponse d'Apple. Un rappel peut être renvoyé après failure
. Nous travaillons sur une solution de contournement dans # 348, mais je crains que cela puisse être très désagréable.
J'ai publié dans 2.4.0-beta1
, en essayant de résoudre ce problème. Le PR
# 348 a été ajouté à cette version et vous pouvez également voir le readme de cette fonctionnalité . Notez que ceci est en cours de test.
J'ai testé cela dans un achat en direct et semble fonctionner. Cependant, gardez à l'esprit que vous ne devez ajouter un écouteur qu'en cas d'échec ou il peut être dupliqué avec un résultat réussi.
Les gars, merci d'avoir investi du temps dans ce problème! 🙏
Je pense que la documentation actuelle doit être plus claire sur l'utilisation de addAdditionalSuccessPurchaseListenerIOS
. C'est quelque chose que j'ai essayé d'aborder au # 414.
Mais je pense aussi que cela laisse place à l'amélioration de l'API. Seriez-vous disposé à discuter d'un changement dans l'API qui peut mieux s'adapter au soi-disant «flux de kit de magasin»? Quelque chose utilise peut-être RxJS, par exemple:
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
)
Ou quelque chose de différent qui cache mieux l'abonnement supplémentaire pour iOS?
@Edgpaez C'est super mais ça va changer le comportement de l'achat en android
. J'espère pouvoir étudier version 3
de ce module dans 2019
.
salut @hyochan , AFAICT, nous n'avons pas besoin de changer le comportement interne du paquet, seulement l'interface publique. Nous pouvons conserver la méthode buyItemByType pour résoudre les promesses et simplement ajouter un peu de Rx en plus de cela sur index.js .
par exemple, nous aurions ceci dans 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
})();
Mon objectif n'est pas cette implémentation spécifique mais de cacher des détails spécifiques au «flux du kit de magasin».
Pensez-vous que ce soit une bonne idée?
Seriez-vous intéressé par un PR?
@Edgpaez Ok. Je comprends le détail maintenant. Cependant, je pense que l'ajout de RxJS
est un peu trop pour implémenter le feature
car je pense que cela peut être couvert sans cela.
De plus, je pense que ce qui suit serait quelque chose de différent.
RNIap.buyProduct('com.example.coins100')
.subscribe(
purchase => console.log(purchase), // successful payment
err => console.log(err) // err.code and err.message are available
)
Si vous appelez buyProduct
pour deux articles comme ci-dessous,
RNIap.buyProduct('com.example.coins100');
RNIap.buyProduct('com.example.coins200');
Nous ne pouvons pas garantir lequel finirait en premier, donc je pense que nous devrions gérer cela en natif de sendEvent
à JS
.
J'ai l'impression que la mise en œuvre devrait ressembler à
RNIap.buyProduct('com.example.coins100');
RNIap.buyProduct('com.example.coins200');
// receiving events
const subs = RNIap.purchaseUpdateListener(purchase => {
...
});
Dites-moi s'il y a quelque chose que j'ai manqué.
Permet de gérer plus en détail dans # 423
Commentaire le plus utile
Je pense que nous devons contacter
apple
pour cela et cela semble vraiment terrible qu'il y ait un cas de test différent qui n'est pas reproductible dans l'environnementsandbox
. Pour ceux qui veulent comprendre le problème, j'ai enregistré l'écran et vous pouvez voir le clip ici . @anandwahed Pourriez-vous également contacter Apple à ce sujet? Parce que je sais qu'ils ne les soutiennent pas, il est donc préférable que plus de gens aient des contacts avec eux. Rassemblons-nous pour résoudre ce problème.