Что делать, если проверка IAP не удалась?
В iOS, если пользователь пытается купить IAP, и проверка моего чека на сервере не проходит, каково правильное поведение? При тестировании в песочнице я просто получаю массу всплывающих окон с просьбой ввести мой пароль. Если я вызываю finishTransaction, он перестает спрашивать мой пароль, но я считаю, что это может привести к тому, что пользователь получит плату без получения продукта.
2 ответа
Я думаю, что обработка ошибок при совершении покупок в приложении - одна из немногих обсуждаемых трудностей в покупках внутри приложения. Здесь есть несколько вопросов. Например: 1) Если вы выполняете проверку квитанции о покупке на устройстве (т. Е. Проверку стиля расшифровки в стиле> iOS7) и эта проверка не проходит, что делать? 2) Если вы делаете проверку с помощью веб-сервера, и это не помогает, что вы должны сделать? 3) Если вы храните квитанции на свой собственный веб-сервер, и это не помогает, что вам следует делать? Я добавлю некоторые идеи из моего собственного приложения. Было бы здорово увидеть, что другие делают по поводу такого рода обработки ошибок.
1) Если вы выполняете проверку квитанции о покупке на устройстве (т. Е.>= Проверка стиля дешифрования iOS7), и эта проверка не проходит, что делать?
Apple рекомендует обновить квитанцию (SKReceiptRefreshRequest), если первоначальная проверка на устройстве не удалась. Но что если проверка после обновления завершится неудачно? Вы можете интерпретировать эту ситуацию, как что-то серьезно неправильное (например, пользователь каким-то образом взломал ваше приложение, чтобы преднамеренно выдать вам плохую квитанцию), сказать пользователю, что покупка не удалась с ошибкой проверки квитанции, и завершить транзакцию (SKPaymentQueue завершить транзакцию:), постоянно терпя неудачу. Однако я не люблю быть таким окончательным. Возможно, это моя уверенность, но что-то могло пойти не так с моим программированием. Мне нравится давать пользователю больше шансов. Итак, мое решение состоит в том, чтобы: 1) сообщить пользователю, что проверка не удалась, 2) перевести SKPaymentTransaction в состояние "удержания" и 3) вызвать finishTransaction. Эта идея состояния владения является моим изобретением, и ничто не предложено (или поддержано) Apple. Я сделал изменяемый подкласс SKPaymentTransaction, и у меня есть очередь этих объектов (назовите их SPASMutablePaymentTransaction), которые я сохраняю (используя NSCoding) в NSUserDefaults. Почти всегда эта очередь пуста, но если я получаю ошибку проверки, о которой я говорю, я создаю объект SPASMutablePaymentTransaction, копирую информацию SKPaymentTransaction (включая квитанцию, например, из пакета) и сохраняю эту транзакцию в мою очередь состояния удержания. Я делаю (обычно скрытую) часть моего пользовательского интерфейса видимой, что позволяет пользователю повторить попытку проведения транзакций состояния.
Сложно? Да, немного. Однако, поскольку мы имеем дело с пользователем, который дает вам деньги, я стараюсь быть надежным. Кажется, до сих пор хорошо работает в тестировании. У меня пока нет отзывов от пользователей (или аналитики), но они развернуты в магазине приложений.
2) Если вы делаете проверку с помощью веб-сервера, и это не помогает, что вы должны сделать?
Для меня это похоже на 1) выше. Вы попытались сделать проверку квитанции, но она не удалась. Вы можете сначала попытаться обновить квитанцию (см. Выше), а затем повторить попытку проверки сервера. В моем приложении, поскольку я всегда сначала проверяю квитанцию на устройстве, поэтому нет смысла обновлять квитанцию снова (поскольку я сделал бы это, если бы проверка квитанции на устройстве не удалась). Итак, я снова перевожу квитанцию в состояние "удержания" (как указано выше) и позволяю пользователю повторять транзакции в состоянии удержания по своему усмотрению.
3) Если вы храните квитанции на свой собственный веб-сервер, и это не помогает, что вам следует делать?
(а) Предположительно, это определенно не должен быть случай, когда вы навсегда не можете предоставить пользователю его покупку. Это сбой ваших услуг. В моем случае это может произойти, например, если я получаю сетевую ошибку при соединении с моим сервером. Я делаю что-то немного другое здесь. Я не сразу даю пользователю доступ к его покупке и не переводю транзакцию в состояние "удержания". Вместо этого я установил таймер, чтобы повторить процесс сохранения квитанции на моем сервере. Повторная попытка через пару минут. Я говорю пользователю, что я делаю. Я сохраняю данные квитанции в NSUserDefaults (снова используя объект SPASMutablePaymentTransaction), поэтому буду продолжать эту повторную попытку, даже если приложение аварийно завершит работу / завершится. Когда мне удается сохранить квитанцию на моем сервере, я даю пользователю доступ к покупке.
(б) В этом случае я вызываю finishTransaction: и пока не предоставляю пользователю доступ к покупке. Я мог бы избежать некоторых этих деталей, не вызывая finishTransaction: и просто позволить моему наблюдателю транзакций снова заняться этим процессом (например, при следующем запуске приложения), но пользователю, вероятно, придется снова вводить свой Apple Id. Я полагаю, что это моя проблема (т.е. я не смог сохранить информацию о квитанции на моем сервере), поэтому я пытаюсь справиться с этим под прикрытием.
Всплывающее UIAlertView. Смотрите код ниже...
self.alert("Purchase Failed", Message: "Please Make Sure You are connected to the internet and try agian")
func alert(title:String, Message:String){
let actionSheet:UIAlertController = UIAlertController(title: "\(title)", message: "\(Message)", preferredStyle: UIAlertControllerStyle.Alert)
// for alert add .Alert instead of .Action Sheet
// start copy
let firstAlertAction:UIAlertAction = UIAlertAction(title: "OK", style: UIAlertActionStyle.Default, handler:
{
(alertAction:UIAlertAction!) in
// action when pressed
})
actionSheet.addAction(firstAlertAction)
// end copy
self.presentViewController(actionSheet, animated: true, completion: nil)
}