React-native-iap: finishTransactionIOS / finishTransaction no hace nada para iOS

Creado en 19 feb. 2020  ·  34Comentarios  ·  Fuente: dooboolab/react-native-iap

Versión de react-native-iap

4.4.1

Versión de react-native

0,60,4

Plataformas a las que se enfrentó el error (¿IOS o Android o ambos?)

iOS

Comportamiento esperado

Al llamar a finishTransactionIOS (purchaseId) o finishTransaction (compra) para una suscripción, la transacción debe finalizar y no volver a enviarse a la aplicación en el próximo lanzamiento. Si hubiera un problema con esto, esperaría que se devolviera algo al oyente de errores o en una promesa de una de las funciones de finishTransaction, no sucede nada.

Android parece funcionar bien.

Comportamiento real

La transacción se emite en cada lanzamiento a menos que se llame a clearTransactionIOS, que parece tener otros efectos secundarios.

Entorno probado (¿Emulador? ¿Dispositivo real?)

Dispositivo real

Pasos para reproducir el comportamiento

  • Cree un producto de suscripción.
  • Compra la suscripción
  • Simular la validación de backend
  • Llame a finishTransactionIOS o finishTransaction en esa suscripción. No tiene efecto.

He probado este montón de diferentes formas, y absolutamente nada parece funcionar, no importa lo que haga, aparte de borrar las transacciones, la compra se emite nuevamente a la aplicación cada lanzamiento. ¿Alguna idea de lo que está pasando o de lo que podría estar haciendo o entendiendo mal?

ℹ needs more info 📱 iOS 🙏 help wanted 🚶🏻 stale

Comentario más útil

@hyochan ¿ alguna actualización sobre este tema? Hemos estado estancados durante bastante tiempo y no pudimos publicar nuestra aplicación.

Todos 34 comentarios

Tengo el mismo problema.

¿Puedes compartir los ackResult ?

          try {
            const ackResult = await finishTransaction(purchase);
            console.log('ackResult', ackResult);
          } catch (ackErr) {
            console.warn('ackErr', ackErr);
          }

@hyochan
En mi caso:
ackResult undefined

@hyochan
En mi caso:
ackResult undefined

Aquí igual

También en mi caso, el valor devuelto no está definido (dispositivo real con un usuario de sandbox).

Parece relacionado con el número 366. También por ios finishTransaction no devolverá nada.
¿Pueden concentrarse en el n. ° 366 y volver para la actualización?

Parece relacionado con el número 366. También por ios finishTransaction no devolverá nada.
¿Pueden concentrarse en el n. ° 366 y volver para la actualización?

Solo para aclarar: dado que el número 366 se trata de pruebas, ¿está sugiriendo que esto debería funcionar bien en producción sin la necesidad de clearTransactionIOS?

@hyochan Cuando estoy probando la configuración de depuración con una cuenta de sandbox, básicamente recibo una notificación de Notificaciones de servidor a servidor (Apple) sobre una compra. El problema es que, después de un tiempo, el oyente de mi cliente recibe otra notificación sobre la compra, pero con un ID de transacción diferente, incluso cuando la acción de compra sucedió solo una vez, por lo que parece un problema para finalizar correctamente la transacción anterior. En Android, todo funciona bien y creo que eso no está relacionado con el # 366 porque no tengo ningún problema para probar el proceso de compra con una cuenta de sandbox.

`` tsx
useEffect (() => {
purchaseUpdateSubscription.current = purchaseUpdatedListener (
async (compra: InAppPurchase | SubscriptionPurchase) => {
recibo constante = purchase.transactionReceipt;
if (recibo) {
tratar {
aguardar myBackendHandler ({
usuario,
compra,
});
resultado constante = aguardar RNIap.finishTransaction (compra, falso);
console.log ('resultado', resultado);
} captura (e) {
// HACER
}
}
}
);
return () => {
if (purchaseUpdateSubscription.current) {
purchaseUpdateSubscription.current.remove ();
purchaseUpdateSubscription.current = null;
}
};
}, []);
`` ``

Hola equipo, gracias por todo el trabajo duro en esta biblioteca, realmente nos hace la vida más fácil. Estoy comentando porque este problema no se ha resuelto y no veo cómo las transacciones antiguas que no se compensan tienen algo que ver con el número 366.

Mi caso de uso es

  1. El usuario 1 realiza la compra y el beneficio premium se aplica a su cuenta.
  2. El usuario 1 cierra la sesión
  3. Usuario 2 inicia sesión

Resultado Esperado:

  • Las transacciones del Usuario 1 no se emiten a través del escucha de compras

Resultado actual

  • Las transacciones del Usuario 1 NO se borran y se emiten nuevamente. Aunque un nuevo usuario haya iniciado sesión y haya obtenido datos incorrectos.

Este es solo un ejemplo de por qué es importante priorizar este tema. Gracias por leer este largo comentario ...

aquí igual

exactamente el mismo problema que el anterior, parece que la pila no se borra en absoluto, incluso después de desconectar la cuenta de sandbox / itunes, reiniciar el dispositivo, reinstalar la aplicación ...: /

¿Podría verificar que finishTransaction realmente no hace nada en el archivo RNIapIos.m ?
Lo acabo de comprobar y finaliza correctamente su transacción.

Por favor, marque el método clearTransaction o finishTransactionWithIdentifier e intente poner cualquier registro dentro. Intente encontrar los siguientes códigos.

RCT_EXPORT_METHOD(clearTransaction) {
    NSArray *pendingTrans = [[SKPaymentQueue defaultQueue] transactions];
    NSLog(@"\n\n\n  ***  clear remaining Transactions. Call this before make a new transaction   \n\n.");
    for (int k = 0; k < pendingTrans.count; k++) {
        [[SKPaymentQueue defaultQueue] finishTransaction:pendingTrans[k]];
    }
-(void)finishTransactionWithIdentifier:(NSString *)transactionIdentifier {
    SKPaymentQueue *queue = [SKPaymentQueue defaultQueue];
    for(SKPaymentTransaction *transaction in queue.transactions) {
        if([transaction.transactionIdentifier isEqualToString:transactionIdentifier]) {
            [[SKPaymentQueue defaultQueue] finishTransaction:transaction];
        }
    }
}

No puedo hacer avanzar este problema porque no tengo idea de lo que está sucediendo. Espero que alguien pueda depurar cosas en su entorno y compartir 🙏

alguna actualización sobre este tema?

arriba, yo también estoy experimentando este problema.

lo mismo aquí finishTransactionIOS / finishTransaction esto no funciona en IOS

Me parece experimentar lo mismo.
La compra de IAP se completa con éxito, pero la llamada final a finishTransaction devuelve undefined .

// Finish transaction
const ackResult = await finishTransaction(purchase);
console.log("Ack result: ", ackResult); // Ack result: undefined

_Dispositivo real "iPhone 6s" que utiliza el entorno Sandbox de la App Store.

¿Cuál es el resultado esperado de finishTransaction? ¿Es undefined un buen resultado o debo esperar algo más?

También estoy experimentando este problema en iOS, donde ni finishTransactionIOS ni finishTransaction están eliminando esas transacciones, lo que me impide lanzar la aplicación. ¿Cualquier actualización?

@hyochan Aunque definitivamente no soy fluido en Objective-C, agregué algunos registros en finishTransaction y finishTransactionWithIdentifier y parece que se están ejecutando correctamente (la identificación se está pasando y haciendo coincidir). Lo único que se me ocurre es que [[SKPaymentQueue defaultQueue] finishTransaction:transaction]; no se está conectando realmente a StoreKit y finalizando la transacción. Realmente no sé a dónde ir desde aquí, pero espero que esto sea útil a medida que depura

¿También está manejando notificaciones de estado de suscripción desde la App Store? En mi caso, tuve este problema hasta que me aseguré de que mi servidor manejara todos los eventos de notificación correctamente y respondiera con un 200.

@espenjanson Interesante. No, no lo estaba. Pero en realidad, ayer me cambié al módulo InAppPurchases de expo y ahora todo funciona muy bien.

@lachlanglen No importa . Fue solo un golpe de suerte (?) O algo más. Construí otra versión de la aplicación y el problema está ahí nuevamente. Pensando en hacer lo mismo pero un poco preocupado de que el repositorio expo no esté muy bien mantenido.

Estaba echándole un vistazo y es correcto que devuelva undefined ya que la llamada finishTransactions no está destinada a devolver nada en obj-c.
He hecho algunas pruebas y en mi caso parece que las termino correctamente (prueba simple, pull de transacciones pendientes, si no hay nada, está funcionando bien)

@espenjanson No sé qué te hace pensar que los paquetes de la Expo no están bien mantenidos. Creo que Expo lanzó su módulo iap bastante recientemente. Si supiera que expo tenía un módulo de iap en el momento en que estaba implementando iap, habría elegido expo sin pensarlo dos veces.

¿Hay alguna forma de solucionar esto?
He probado esto en TestFlight incluso con un nuevo usuario de sandbox y aún sigue sucediendo.

Mi purchaseUpdateListener sigue recibiendo transacciones "antiguas".
Estoy llamando finishTransaction(purchase,false) porque estoy usando suscripciones autorrenovables.
El resultado de la llamada es undefined .

¿Alguien puede ofrecer una solución alternativa o una explicación de por qué sucede esto?

@zatloeri Ese es aparentemente un comportamiento deseado. Me tomó un tiempo darme cuenta de eso. App Store colocará un nuevo recibo para la renovación en StoreKit que activa al observador. Debe procesar ese recibo y finalizar la transacción.

https://developer.apple.com/videos/play/wwdc2018/705/
https://developer.apple.com/videos/play/wwdc2020/10671

(ver en Safari para calidad HD)

@ziyoshams Gracias por la rápida respuesta y por los recursos que

Pero primero solo quiero señalar una cosa porque no creo que lo hice aparente.
Lo que estás describiendo me parece lógico y esperaba que sucediera, pero lo que me desconcierta es esto:

El producto A ha caducado según lo verificado por receipt validation .
Recibo una transacción antigua (del día anterior) para el producto A cuando inicio o en primer plano la aplicación.
Luego, la próxima vez que vuelva a poner en primer plano la aplicación, recibo otra transacción anterior (tal vez un poco más nueva que la anterior, no estoy seguro) para el producto A.
En otro primer plano posiblemente otro y así sucesivamente.

Esperaría obtenerlos todos en una sola aplicación si la suscripción ya está vencida.
¿Es este también un comportamiento esperado o está sucediendo algo sospechoso?

@zatloeri Cada transacción que no esté terminada aparecerá en esa cola, incluso si está vencida. Para suscripciones mensuales, debe obtener ese recibo cada 5 minutos aproximadamente. Por ejemplo, si compra algo y vuelve a la aplicación al día siguiente, obtendrá 5-6 recibos al mismo tiempo. Recomiendo encarecidamente ver esos videos de la WWDC. Son muy útiles.

Tengo el mismo problema en iOS, la transacción no se finaliza, por lo que la cola no se vacía y el recibo vuelve a aparecer cada vez que se inicia la aplicación. He verificado la recepción en el lado del servidor y luego he terminado la transacción. Por favor, eche un vistazo a mi código a continuación.

He mencionado algunos fragmentos de mi código a continuación ...

''
importar RNIap, {
Aplicación en la compra,
Producto,
PurchaseError,
Suscripción,
SuscripciónCompra,
finishTransaction
finishTransactionIOS,
purchaseErrorListener,
purchaseUpdatedListener,
clearTransactionIOS,
} de 'react-native-iap';

async componentDidMount () {
resultado constante = espera RNIap.initConnection ();
const itemSubs = Platform.select ({
Android: [
obtener (this.props, 'subscriptionStore.subscription.android_product_id', null)
],
iOS: [
obtener (this.props, 'subscriptionStore.subscription.ios_product_id', null)
]
});

suscripciones const = aguardar RNIap.getSubscriptions (itemSubs);
purchaseUpdateSubscription = purchaseUpdatedListener (
async (compra) => {
recibo constante = purchase.transactionReceipt;
dejar suscripción = {
subscription_id: obtener (this.props, 'subscriptionStore.subscription.id', null)
};
if (Platform.OS === 'ios') {
suscripción = {
...suscripción,
order_id: obtener (compra, 'transactionId', nulo),
buy_token: get (compra, 'originalTransactionIdentifierIOS', null),
recibo: get (compra, 'transactionReceipt', null), // (Almacenarlo en TEXT)
os: 'IOS'
}
} else if (Platform.OS === 'android') {
datos constantes = JSON.parse (recibo);
suscripción = {
...suscripción,
order_id: obtener (datos, 'orderId', null),
buy_token: get (data, 'purchaseToken', null),
os: 'ANDROID'
}
}
tratar {
finishTransaction (compra, falso); // esto está aquí para la temperatura, se colocará con éxito más adelante.
this.props.notificationStore.showToast ('Suscrito correctamente. Espere ...', 'éxito', 5000);
const resp = await this.props.subscriptionStore.onPurchase (suscripción); // verificando transacciones en el servidor.
if (resp.success) {// respuesta exitosa
this.props.userStore.setUser ({is_premium: 1});
this.props.navigation.replace ('FixFooter');
}
} captura (error) {
console.log ("ERROR API onPurchase:", error);
}
}
)

purchaseErrorSubscription = purchaseErrorListener (
async (error) => {
console.log ('error de compra:', error);
}
)
}

/ * Botón de compra * /
async onPurchase () {
tratar {
const request = await RNIap.requestSubscription (Platform.OS === 'android'?
get (this.props, 'subscriptionStore.subscription.android_product_id', null):
get (this.props, 'subscriptionStore.subscription.ios_product_id', null))
} captura (error) {
console.log ('error:', error)
}
}

@ sufyan297 , ¿puedes compartir un fragmento de tu código del lado del servidor? También estoy tratando de configurar una verificación de recibo, pero el documento de Apple es extremadamente confuso

@ziyoshams ¿Está obteniendo un valor nulo también usando el método finishTransaction del módulo expo iap?

@bcbcbcbcbcl No estoy usando el módulo expo.

+1 para mí devuelve indefinido

@hyochan ¿ alguna actualización sobre este tema? Hemos estado estancados durante bastante tiempo y no pudimos publicar nuestra aplicación.

Hola, parece que no ha habido actividad sobre este tema recientemente. ¿Se ha solucionado el problema o aún requiere la atención de la comunidad? Este problema puede cerrarse si no se produce más actividad. También puede etiquetar este problema como "Para discusión" o "Buen primer número" y lo dejaré abierto. Gracias por sus aportaciones.

¿Fue útil esta página
0 / 5 - 0 calificaciones