Транзакции и проверки в Xamarin.iOSTransactions and Verification in Xamarin.iOS

Восстановление предыдущих транзакцийRestoring Past Transactions

Если приложение поддерживает типы продуктов, которые могут быть восстановлены, необходимо включить некоторые элементы пользовательского интерфейса, чтобы пользователи могли восстановить эти покупки.If your application supports product types that are restorable, you must include some user-interface elements to allow users to restore those purchases. Благодаря этому клиент для добавления продукта дополнительных устройств или восстановление продукта на то же устройство после очистить или удаления и переустановки приложения.This functionality allows a customer to add the product to additional devices or to restore the product to the same device after being wiped clean or removing and re-installing the app. Которые могут быть восстановлены являются следующие типы продуктов:The following product types are restorable:

  • Продукты не использоваться модельюNon-consumable products
  • Auto возобновляемую подписокAuto-renewable subscriptions
  • Бесплатные подпискиFree subscriptions

Процесс восстановления должен обновить записи сохранить на устройстве для удовлетворения ваших продуктов.The restore process should update the records you keep on the device to fulfill your products. Клиента можно восстановить в любое время, на любых устройствах.The customer can choose to restore at any time, on any of their devices. Процесс восстановления повторно отправляет все предыдущие транзакции для пользователя. код приложения следует определить какое действие необходимо выполнить с этими данными (например, проверка записи о покупке на устройстве уже существует, если нет, создается запись покупки и включение продукта для пользователя).The restore process re-sends all prior transactions for that user; the application code must then determine what action to take with that information (for example, checking if there is already a record of that purchase on the device, and if not, creating a record of the purchase and enabling the product for the user).

Реализация восстановленияImplementing Restore

Пользовательский интерфейс восстановить кнопка вызывает следующий метод, который запускает RestoreCompletedTransactions SKPaymentQueue.The user interface Restore button calls the following method, which triggers RestoreCompletedTransactions on the SKPaymentQueue.

public void Restore()
{
   // theObserver will be notified of when the restored transactions start arriving <- AppStore
   SKPaymentQueue.DefaultQueue.RestoreCompletedTransactions();
}

StoreKit отправит запрос на восстановление серверы Apple асинхронно.StoreKit will send the restore request to Apple’s servers asynchronously.

Так как CustomPaymentObserver регистрируется как наблюдатель транзакции, он будет получать сообщения при Apple серверы отвечают.Because the CustomPaymentObserver is registered as a transaction observer, it will receive messages when Apple’s servers respond. Ответ будет содержать все транзакции, которые этот пользователь операций в этом приложении (для всех своих устройств).The response will contain all the transactions this user has ever performed in this application (across all their devices). Этот код в цикле каждая транзакция обнаруживает состояние восстановления и вызовы UpdatedTransactions метод для его обработки, как показано ниже:The code loops through each transaction, detects the Restored state and calls the UpdatedTransactions method to process it as shown below:

// called when the transaction status is updated
public override void UpdatedTransactions (SKPaymentQueue queue, SKPaymentTransaction[] transactions)
{
   foreach (SKPaymentTransaction transaction in transactions)
   {
       switch (transaction.TransactionState)
       {
       case SKPaymentTransactionState.Purchased:
          theManager.CompleteTransaction(transaction);
           break;
       case SKPaymentTransactionState.Failed:
          theManager.FailedTransaction(transaction);
           break;
       case SKPaymentTransactionState.Restored:
           theManager.RestoreTransaction(transaction);
           break;
default:
           break;
       }
   }
}

Если отсутствуют продукты, которые могут быть восстановлены для пользователя, UpdatedTransactions не вызывается.If there are no restorable products for the user, UpdatedTransactions is not called.

Самый простой возможных код для восстановления данной транзакции в образце выполняет те же действия, что при Покупка выполняется, за исключением случаев, OriginalTransaction свойство используется для доступа к код продукта:The simplest possible code to restore a given transaction in the sample does the same actions as when a purchase takes place, except that the OriginalTransaction property is used to access the Product ID:

public void RestoreTransaction (SKPaymentTransaction transaction)
{
   // Restored Transactions always have an 'original transaction' attached
   var productId = transaction.OriginalTransaction.Payment.ProductIdentifier;
   // Register the purchase, so it is remembered for next time
   PhotoFilterManager.Purchase(productId); // it's as though it was purchased again
   FinishTransaction(transaction, true);
}

Более сложные реализации могут проверять другие transaction.OriginalTransaction свойства, такие как исходный номер даты и приемки.A more sophisticated implementation may check other transaction.OriginalTransaction properties, such as the original date and receipt number. Эти сведения будут полезны для некоторых типов продукта (например, подписки).This information will be useful for some product types (such as subscriptions).

Завершение восстановленияRestore Completion

CustomPaymentObserver Имеет две дополнительные методы, которые будут вызваны StoreKit после завершения процесса восстановления (успешно или со сбоем), показано ниже:The CustomPaymentObserver has two additional methods that will be called by StoreKit when the restore process has completed (either successfully or with a failure), shown below:

public override void PaymentQueueRestoreCompletedTransactionsFinished (SKPaymentQueue queue)
{
   Console.WriteLine(" ** RESTORE Finished ");
}
public override void RestoreCompletedTransactionsFailedWithError (SKPaymentQueue queue, NSError error)
{
   Console.WriteLine(" ** RESTORE FailedWithError " + error.LocalizedDescription);
}

В примере эти методы ничего не делать; Однако в реальном приложении, можно реализовать сообщение для пользователя или другие функциональные возможности.In the example these methods do nothing, however a real application may choose to implement a message to the user or some other functionality.

Обеспечение безопасности покупкиSecuring Purchases

В двух примерах этого документа используйте NSUserDefaults для отслеживания покупки:The two examples in this document use NSUserDefaults to track purchases:

Расходных — «баланс» покупки кредит — это простой NSUserDefaults целочисленное значение, которое увеличивается при каждой покупке.Consumables – the ‘balance’ of credit purchases is a simple NSUserDefaults integer value that is incremented with each purchase.

Non-расходных — каждой покупки фильтра photo сохраняется как пара "ключ значение" в NSUserDefaults.Non-Consumables – each photo filter purchase is stored as a key-value pair in NSUserDefaults.

С помощью NSUserDefaults сохраняют простой пример кода, но не предлагают решения очень надежным, как это возможно для пользователей с технической точки зрения стандартную для обновления параметров (обход механизма оплаты).Using NSUserDefaults keeps the example code simple, but does not offer a very secure solution as it may be possible for technically-minded users to update the settings (bypassing the payment mechanism).

Примечание. Реальные приложения следует внедрять безопасный механизм для хранения, приобретенных содержимое, которое не является уязвимы для несанкционированного доступа пользователя.Note: Real-world applications should adopt a secure mechanism for storing purchased content that is not subject to user tampering. Для этого может потребоваться шифрование и/или других методов, включая идентификацию удаленным сервером.This may involve encryption and/or other techniques including remote-server authentication.

Механизм должны разрабатываться также пользоваться преимуществами встроенных функций резервного копирования и восстановления операций ввода-вывода, iTunes и iCloud.The mechanism should also be designed to take advantage of the built-in backup and recovery features of iOS, iTunes and iCloud. Это гарантирует, что после пользователь восстанавливает резервную копию своих предыдущих покупок будут немедленно доступны.This will ensure that after a user restores a backup their previous purchases will be immediately available.

См. Apple безопасного кодирования руководстве Дополнительные инструкции для конкретных операций ввода-вывода.Refer to Apple’s Secure Coding Guide for more iOS-specific guidelines.

Проверки поступления и предоставление сервером продуктовReceipt Verification and Server-Delivered Products

Примеры в этом документе, в данный момент включал только приложение взаимодействует непосредственно с серверами App Store для проведения операций покупки, которые разблокировать функции и возможности, которые уже в коде в приложение.The examples in this document so far have consisted solely of the application communicating directly with the App Store servers to conduct purchase transactions, which unlock features or capabilities already coded into the app.

Apple предоставляет получить дополнительный уровень безопасности покупки, позволяя покупки независимо друг от друга проверяемую защищен другим сервером, что может оказаться полезным для проверки запроса перед доставкой цифрового содержимого в процессе покупки (таких как цифровые книги или журнал).Apple provides for an additional level of purchase security by allowing purchase receipts to be independently verified by another server, which can be useful to validate a request before delivering digital content as part of a purchase (such as a digital book or magazine).

Встроенные продуктов — как показано в примерах в этом документе приобретенный товар существует как функциональные возможности, в состав приложения.Built-In Products – Like the examples in this document, the product being purchased exists as functionality shipped with the application. Покупка из приложения позволяет пользователю доступ к функциям.An in-app purchase enables the user to access the functionality. Коды продуктов жестко запрограммированы.Product IDs are hardcoded.

Предоставление сервером продуктов — продукт состоит из загрузки содержимого, которое хранится на удаленном сервере, пока не будет успешно транзакция вызывает загрузку содержимого.Server-Delivered Products – The product consists of downloadable content that is stored on a remote server until a successful transaction causes the content to be downloaded. Примеры могут включать книги или выпуски magazine.Examples might include books or magazine issues. Коды продуктов обычно получают данные из внешнего сервера (где продукта также размещается содержимое).Product IDs are usually sourced from an external server (where the product content is also hosted). Приложения должны реализовать надежного записи после завершения транзакции, таким образом, если содержимое загрузка завершается ошибкой может быть повторена без запутать пользователя.Applications must implement a robust way of recording when a transaction has completed, so that if content download fails it can be re-attempted without confusing the user.

Предоставление сервером продуктовServer-Delivered Products

Некоторые продукта содержимого, такие как книг и журналов (или даже уровня игры) необходимо загрузить с удаленного сервера во время покупки.Some product’s content, such as books and magazines (or even a game level) need to be downloaded from a remote server during the purchase process. Это означает, что требуется для хранения и предоставления содержимого продукта после приобретения дополнительного сервера.This means an additional server is required to store and deliver the product content after it is purchased.

Получение цен для продуктов, предоставление серверомGetting Prices for Server-Delivered Products

Поскольку продукты предоставляются удаленно, это также можно добавить дополнительные продукты со временем (без изменения кода приложения), таких как добавление дополнительные книги или новых проблемах журнала.Because the products are remotely delivered, it is also possible to add more products over time (without updating the app code), such as adding more books or new issues of a magazine. Приложение может обнаружить эти продукты новостей и отображать их для пользователя, дополнительного сервера следует хранения и предоставления этой информации.So that the application can discover these news products and display them to the user, the additional server should store and deliver this information.

  1. Сведения о продукте, которые должны храниться в нескольких местах: на сервере и в iTunes Connect.Product information must be stored in multiple places: on your server and in iTunes Connect. Кроме того каждый продукт будет иметь файлы содержимого, связанные с ним.In addition, each product will have content files associated with it. Эти файлы будут доставлены после успешного покупки.These files will be delivered after a successful purchase.

  2. Когда пользователь хочет приобрести продукт, приложение должно определить, какие продукты доступны.When the user wishes to purchase a product, the application must determine what products are available. Эта информация может быть кэширован, но должно быть доставлено с удаленного сервера, где хранится список продуктов.This information may be cached, but should be delivered from a remote server where the master list of products is stored.

  3. Сервер возвращает список идентификаторов продукта для приложения для синтаксического анализа.The server returns a list of Product IDs for the application to parse.

  4. Затем приложение определяет, какие из этих кодов продуктов для отправки в StoreKit для получения цены и описания.The application then determines which of these Product IDs to send to StoreKit to retrieve prices and descriptions.

  5. StoreKit отправляет список идентификаторов продукта на серверах компании Apple.StoreKit sends the list of Product IDs to Apple’s servers.

  6. На время ответа сервера iTunes с соответствующим продуктом сведения (описание и текущая цена).The iTunes servers respond with valid product information (description and current price).

  7. Приложения SKProductsRequestDelegate передается сведения о продукте для отображения пользователю.The application’s SKProductsRequestDelegate is passed the product information for display to the user.

Приобретение предоставление сервером продуктовPurchasing Server-Delivered Products

Так как удаленный сервер требуется каким-либо образом проверки, что запрос на содержимое является допустимым (т. е. выплаченная для), о прочтении передается для проверки подлинности.Because the remote server requires some way of validating that a content request is valid (ie. has been paid for), the receipt information is passed along for authentication. Удаленный сервер пересылает их в iTunes для проверки подлинности и в случае успешного выполнения включает содержимое продукта в ответ на приложение.The remote server forwards that data to iTunes for verification and, if successful, includes the product content in the response to the application.

  1. Приложение добавляет SKPayment в очередь.The app adds an SKPayment to the queue. При необходимости, пользователю будет предложено ввести свой идентификатор Apple, а запрос на подтверждение оплаты.If required the user will be prompted for their Apple ID, and asked to confirm the payment.

  2. StoreKit отправляет запрос на сервер для обработки.StoreKit sends the request to the server for processing.

  3. После завершения транзакции, сервер отвечает с уведомлением о транзакции.When the transaction is complete, the server responds with a transaction receipt.

  4. SKPaymentTransactionObserver Подкласс получает приемки и обрабатывает его.The SKPaymentTransactionObserver subclass receives the receipt and processes it. Так как продукт должен загружаться с сервера, приложение инициирует сетевой запрос к удаленному серверу.Because the product must be downloaded from a server, the application initiates a network request to the remote server.

  5. Запрос на загрузку сопровождается поступления данных, удаленный сервер убедиться в том, что она авторизована для доступа к содержимому.The download request is accompanied by the receipt data so that the remote server can verify it is authorized to access the content. Приложения сетевой клиент ожидает ответа на этот запрос.The application’s network client waits for a response to this request.

  6. Когда сервер получает запрос на содержимое, он проводит анализ поступления данных и отправляет запрос непосредственно к серверам iTunes на проверку приемки является допустимым транзакции.When the server receives a request for content, it parses out the receipt data and sends a request directly to the iTunes servers to verify the receipt is for a valid transaction. Сервер должен использовать определенную логику, чтобы определить, следует ли отправлять запрос к URL-адрес рабочей среды или песочницы.The server should use some logic to determine whether to send the request to the production or sandbox URL. Apple предлагает всегда с помощью URL-адреса производственной и переключения на "песочницы", если ваш статус 21007 (поступление "песочницы" отправляемые рабочего сервера).Apple suggests always using the production URL and switching to sandbox if your receive status 21007 (sandbox receipt sent to production server). Ссылаться на Apple руководство по программированию проверки поступления для получения дополнительных сведений.Refer to Apple's Receipt Validation Programming Guide for more details.

  7. iTunes проверка приемки и возвращать нулевое состояние, если оно допустимо.iTunes will check the receipt and return a status of zero if it is valid.

  8. Сервер ждет ответа iTunes.The server waits for iTunes’ response. Если он получает допустимый ответ, код определит файл содержимого связанных продуктов для включения в ответ в приложение.If it receives a valid response, the code should locate the associated product content file to include in the response to the application.

  9. Приложение получает и анализирует ответ, сохранение содержимого продукта к файловой системе устройства.The application receives and parses the response, saving the product content to the device’s filesystem.

  10. Приложение позволяет продукта, а затем вызывает его StoreKit FinishTransaction.The application enables the product, and then calls StoreKit’s FinishTransaction. Приложение может при необходимости отображения приобретенных содержимого (например, show первой страницы приобретенных книги или magazine проблема).The application may then optionally display the purchased content (for example, show the first page of a purchased book or magazine issue).

Альтернативную реализацию для файлов содержимого очень большого продукта может включать просто хранения получение транзакции на шаге #9 таким образом, можно быстро выполнить транзакцию и предоставление пользовательского интерфейса для пользователя для загрузки содержимого программных продуктов через некоторое время.An alternative implementation for very large product content files could involve simply storing the transaction receipt in step #9 so that the transaction can be quickly completed, and providing a user-interface for the user to download the actual product content at some later time. Запрос на загрузку последующих можно повторно отправить хранимых получение доступа к файлу содержимого продукта.The subsequent download request can re-send the stored receipt to access the required product content file.

Написание кода проверки поступления на стороне сервераWriting Server-Side Receipt Verification Code

Проверка получения в серверный код может выполняться с помощью простого HTTP POST запрос ответ, охватывающий шаги с 5 # по #8 на схеме рабочего процесса.Validating a receipt in server-side code can be done with a simple HTTP POST request/response that encompasses steps #5 through #8 in the workflow diagram.

Извлеките SKPaymentTansaction.TransactionReceipt свойства в приложении.Extract the SKPaymentTansaction.TransactionReceipt property in the app. Это данные, необходимо отправить в iTunes для проверки подлинности (шаг #5).This is the data that needs to be sent to iTunes for verification (step #5).

Кодирование base64 поступления данных транзакций (либо на шаге #5 или #6).Base64-encode the transaction receipt data (either in step #5 or #6).

Создайте простой полезные данные JSON следующим образом:Create a simple JSON payload like this:

{
   "receipt-data" : "(base-64 encoded receipt here)"
}

HTTP POST JSON в https://buy.itunes.apple.com/verifyReceipt для рабочей среды или https://sandbox.itunes.apple.com/verifyReceipt для тестирования.HTTP POST the JSON to https://buy.itunes.apple.com/verifyReceipt for production or https://sandbox.itunes.apple.com/verifyReceipt for testing.

Ответ JSON, будет содержать следующие ключи:The JSON response will contain the following keys:

{
   "status" : 0,
   "receipt" : { (receipt repeated here) }
}

Состояние 0 указывает уведомление допустимым.A status of zero indicates a valid receipt. Сервер можно перейти к выполнения содержимое приобретаемой продукции.Your server can proceed to fulfill the purchased product’s content. Получение ключа содержит словарь JSON с теми же свойствами, что SKPaymentTransaction объекта, полученного приложением, поэтому серверный код можно запросить этот словарь для получения сведений, таких как Идентификатор_продукта и количество покупки.The receipt key contains a JSON dictionary with the same properties as the SKPaymentTransaction object that was received by the app, so the server code can query this dictionary to retrieve information such as the product_id and quantity of the purchase.

См. в разделе Apple руководство по программированию проверки поступления системному администратору.See Apple’s Receipt Validation Programming Guide documentation for additional information.