react-native-iap": "^2.3.17
iOS
Платеж должен проходить только тогда, когда вызывается finishTransaction
Сумма определяется после добавления способа оплаты, например кредитной карты.
Но до метода RNIap.buyProductWithoutFinishTransaction(sku)
дошло.
Настоящее устройство - 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
}}
К сожалению, в вашем коде много синтаксических ошибок. Пожалуйста, обратитесь к нашему примеру проекта в нашем репо и сначала сравните с вашим кодом.
@dooboolab
Спасибо за ответ, размещенный здесь код приведен только для примера, это не совсем то, что используется в реальном приложении.
я постараюсь объяснить, в чем проблема
RNIap.initConnection();
RNIap.getProducts(product)
когда пользователь нажимает кнопку покупки
RNIap.clearTransaction();
вызывается только для того, чтобы убедиться, что не осталось незавершенных транзакций.RNIap.buyProductWithoutFinishTransaction(sku)
вызывается в случае успешного вызова сервера приложений, если сервер дает успешное значение true, тогда вызывается RNIap.finishTransaction();
для завершения платежа.componentWillUnmount ()
RNIap.endConnection()
для завершения соединения.Этот процесс работает нормально, если пользователь уже добавил способ оплаты. Если у пользователя нет добавленного способа оплаты, требуется страница добавления способа оплаты, и сумма списывается до достижения RNIap.finishTransaction();
Спасибо за подробности. Теперь ваша проблема ясна. cc @JJMoon
@JJMoon
@ zohaibahmed-22 Это тестовый пример в песочнице?
@JJMoon Нет, это реальный случай окружающей среды.
Я понимаю, что эта ошибка возникает, когда пользователь вышел из системы или отсутствует информация о кредитной карте.
Если методы работают нормально, причина этой ошибки в другом.
Нам нужно подготовить это действие, которое покидает приложение, viewDidDisappear и т. Д.
В режиме песочницы этот симптом проявляется несколько иначе.
Когда я создаю новую учетную запись в песочнице, и первая покупка не работает.
Во второй раз устройство входит в состояние и работает нормально.
Я понятия не имею об этой ошибке.
@dooboolab @JJMoon взгляните на это
https://forums.developer.apple.com/thread/6431
https://forums.developer.apple.com/thread/64489
@dooboolab и @JJMoon также я думаю, что обнаружил проблему при просмотре нашего кода iOS. В методе updatedTransactions, когда мы получаем сообщение об SKPaymentTransactionStateDeferred
или SKPaymentTransactionStateFailed
мы не предполагаем, что finishTransaction
.
Поскольку во многих случаях за результатом SKPaymentTransactionStateFailed
следует SKPaymentTransactionStatePurchased
как указано в приведенном выше потоке 6431 . Я не уверен в коде Objective-C, поэтому проверьте и подтвердите, очищаем ли мы транзакцию в случае сбоя.
@anandwahed Я согласен с тобой. Это моя вина. Простите за это.
Я просмотрю ветку Apple и позабочусь о проблеме.
@anandwahed Я думаю, это правильный способ finish transaction
когда он потерпел неудачу. Пожалуйста, посмотрите эту ветку. https://stackoverflow.com/questions/11008636/inapp-purchase-skpaymentqueue-finish-transaction-doesnt-work
В случае неудачи квитанции не будет, поэтому вы не применяете приобретенный продукт. И завершающая сделка не всегда означает «покупку».
А пока я исследую ветку 6431.
Я только что прочитал ветку 6431 (https://forums.developer.apple.com/thread/6431#14562)
Суть. Проблема не решается с 2015 года. Вау ..
Есть два разных способа справиться с этим эффектом «потока комплектов».
И я узнал две вещи.
A. Мы должны finishTransaction
когда это не удалось. (Я думаю, с опцией или без, всегда)
B. Поток Storekit делает неудачный и успешный с получением обоих. (это плохо)
Я предлагаю вам всем прочитать эту ветку и вернуться к этому вопросу.
Думаю, какой путь вы выберете (1 или 2), все зависит от вас.
В случае отказа нам может потребоваться обратный звонок.
@JJMoon означает ли это, что мы не должны использовать buyProductWithoutFinishTransaction?
@ maxs15 Я не это имел в виду. Извините за запутанность.
Поток StoreKit может произойти при любой покупке. Это проблема iOS, а не этого модуля.
На данный момент я тоже ничего не понимаю. Это происходит в любых нативных приложениях iOS. Правильно?
В свободное время будем копать еще.
Сегодня я попытался отладить эту проблему, потому что создал эту проблему. Платеж finishTransanction
и завершен, но не получает callback
при изменении метода payMethod. Я попытался отладить запись некоторых console.log
но не смог проверить реальный биллинг в среде dev
. Может ли кто-нибудь предложить мне, как отладить этот процесс, чтобы я мог debug
это за real purchase
? Должен ли я использовать это в режиме sandbox
? Он отлично работает в песочнице, поэтому я не знаю, как это отладить. Это очень неохотно.
Давайте соберем несколько идей, потому что я думаю, что это очень важно исправить.
Я всегда получаю эту ошибку, когда пытаюсь совершить покупку у пользователя, не являющегося песочницей.
@hyochan Если вы подключаете реальный сервер (ваш), не имеет значения, находитесь ли вы в режиме отладки или в режиме выпуска. Думаю, у вас есть 2 варианта.
@JJMoon Да, я уже понял это, но все же я не мог провести тестирование покупок в реальном времени на ios. Это правда stackoverflow ? Тогда как мне решить эту проблему? Мы должны протестировать живую покупку.
Любой, кто сталкивается с этой проблемой, я уверен, что все они, пожалуйста, дайте нам представление о том, как столкнуться с этой проблемой. in-app purchase fail when payment method added live
как описано в заголовке проблемы. Как я мог это отладить? @anandwahed Вы когда-нибудь связывались с Apple по поводу этой проблемы?
@hyochan Нет, мы не
Я думаю, нам нужно связаться с apple
для этого, и это выглядит ужасно из-за того, что существует другой тестовый пример, который не воспроизводится в среде sandbox
. Для тех, кто хочет разобраться в проблеме, я записал экран, и вы можете посмотреть ролик здесь . @anandwahed Не могли бы вы также связаться с Apple по этому
Сегодня мы получили ответ от Apple. Обратный вызов может быть возвращен снова после failure
. Мы работаем над решением проблемы # 348, но я боюсь, что это может быть очень неприятно.
Я выполнил 2.4.0-beta1
, пытаясь найти обходной путь для этой проблемы. В эту версию добавлен PR
# 348, и вы также можете увидеть файл readme для этой функции . Обратите внимание, что это тестируется.
Я тестировал это при реальной покупке и, похоже, работает. Однако имейте в виду, что вы должны добавлять слушателя только тогда, когда произошел сбой, или он может быть продублирован с успешным результатом.
Ребята, спасибо что потратили время на эту проблему! 🙏
Я думаю, что текущая документация должна быть более ясной в отношении использования addAdditionalSuccessPurchaseListenerIOS
. Это то, что я пытался решить по номеру 414.
Но я также думаю, что это оставляет место для улучшения API. Не могли бы вы, ребята, обсудить изменение в API, которое может лучше приспособиться к так называемому «потоку комплектов магазина»? Что-то может быть с использованием RxJS, например:
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
)
Или что-то другое, что лучше скрывает дополнительную подписку для iOS?
@Edgpaez Это здорово, но это изменит поведение покупки, совершаемой в android
. Я надеюсь, что смогу исследовать version 3
этого модуля в 2019
.
привет @hyochan , AFAICT, нам не нужно изменять внутреннее поведение пакета, только общедоступный интерфейс. Мы можем оставить метод buyItemByType, разрешающий обещания, и просто добавить немного Rx поверх этого в index.js .
например, у нас было бы это в 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
})();
Моя цель не в этой конкретной реализации, а в том, чтобы скрыть детали, относящиеся к «потоку комплектов магазина».
Ты думаешь, это хорошая идея?
Хотели бы вы PR?
@Edgpaez Хорошо. Теперь я понимаю детали. Однако мне кажется, что добавление RxJS
слишком много для реализации feature
поскольку я думаю, что это можно решить без него.
Кроме того, я чувствую, что ниже будет что-то другое.
RNIap.buyProduct('com.example.coins100')
.subscribe(
purchase => console.log(purchase), // successful payment
err => console.log(err) // err.code and err.message are available
)
Если вы вызываете buyProduct
для двух пунктов, как показано ниже,
RNIap.buyProduct('com.example.coins100');
RNIap.buyProduct('com.example.coins200');
Мы не можем гарантировать, какой из них завершится первым, поэтому я думаю, что мы должны справиться с этим в нативном режиме до sendEvent
до JS
.
Мне кажется, реализация должна выглядеть так
RNIap.buyProduct('com.example.coins100');
RNIap.buyProduct('com.example.coins200');
// receiving events
const subs = RNIap.purchaseUpdateListener(purchase => {
...
});
Скажите, пожалуйста, если я что-то пропустил.
Давайте займемся дальнейшим disccustin в # 423
Самый полезный комментарий
Я думаю, нам нужно связаться с
apple
для этого, и это выглядит ужасно из-за того, что существует другой тестовый пример, который не воспроизводится в средеsandbox
. Для тех, кто хочет разобраться в проблеме, я записал экран, и вы можете посмотреть ролик здесь . @anandwahed Не могли бы вы также связаться с Apple по этому