{"id":137883,"date":"2021-08-26T00:00:00","date_gmt":"2021-08-26T00:00:00","guid":{"rendered":"https:\/\/adapty.io\/de-ios-in-app-purchases-part-4-server-side-purchase-validation\/"},"modified":"2021-08-26T00:00:00","modified_gmt":"2021-08-26T00:00:00","slug":"ios-in-app-purchases-part-4-server-side-purchase-validation","status":"publish","type":"post","link":"https:\/\/adapty.io\/de\/blog\/ios-in-app-purchases-part-4-server-side-purchase-validation\/","title":{"rendered":"iOS In-App-K\u00e4ufe, Teil 4: Serverseitige Kaufvalidierung"},"content":{"rendered":"\n

Was ist die Server-Kaufvalidierung?<\/h2>\n\n\n\n

Die Servervalidierung (serverseitige Empfangsvalidierung<\/a>) ist eine Methode, um die Echtheit eines Kaufs zu best\u00e4tigen. Im Gegensatz zur ger\u00e4tebasierten Validierung geschieht die Servervalidierung auf dem, Sie ahnen es, Server. Die Validierung umfasst nichts anderes als dass das Ger\u00e4t oder der Server eine Anfrage an Apple schickt, um herauszufinden, ob der Kauf tats\u00e4chlich stattgefunden hat und g\u00fcltig ist.<\/p>\n\n\n\n\n\n

Warum m\u00fcssen wir K\u00e4ufe validieren?<\/h2>\n\n\n\n

Wir sollten erw\u00e4hnen, dass die Servervalidierung keine Pflicht ist. In-App-K\u00e4ufe w\u00fcrden auch ohne sie funktionieren. Sie bietet Ihnen jedoch einige Vorteile:<\/p>\n\n\n\n

    \n
  1. Tiefgreifende Analysem\u00f6glichkeiten: <\/strong>Dies ist besonders bei Abonnements von Vorteil, da alles, was nach der Aktivierung geschieht, nicht vom Ger\u00e4t verarbeitet wird. Ohne die serverseitige Kaufvalidierung sind Sie nicht in der Lage, den aktuellen Status des Abonnements abzufragen und ob der Nutzer das Abonnement verl\u00e4ngert oder storniert hat. Auch Zahlungsprobleme usw. w\u00e4ren sonst nicht aufsp\u00fcrbar.<\/li>\n\n\n\n
  2. \u00dcberpr\u00fcfung der Echtheit des Kaufs: <\/strong>Sie k\u00f6nnen sichergehen, dass der Kauf wirklich stattgefunden hat und der Nutzer f\u00fcr Ihr Produkt bezahlt hat.<\/li>\n\n\n\n
  3. Plattform\u00fcbergreifende Abonnements: <\/strong>Wenn Sie den Status eines Abonnements in Echtzeit \u00fcberpr\u00fcfen k\u00f6nnen, haben Sie die Chance, dieses Abonnement \u00fcber mehrere Plattformen hinweg zu synchronisieren. Ein Nutzer, der beispielsweise das Abonnement \u00fcber ein iOS Ger\u00e4t gekauft hat, k\u00f6nnte es so auch auf einem Android Mobilger\u00e4t, auf Ihrer Website oder anderen Plattformen nutzen. <\/li>\n\n\n\n
  4. Zugriff auf Inhalte \u00fcber den Server:<\/strong> Dies sch\u00fctzt Sie vor Nutzern, die versuchen, ohne Abonnement auf Ihren Content zuzugreifen, indem sie einfach Anfragen an den Server durchf\u00fchren. <\/li>\n<\/ol>\n\n\n\n

    Allein der erste Vorteil reicht aus unserer Erfahrung aus, um eine Kaufabwicklung \u00fcber den Server einzurichten.<\/p>\n\n\n\n

    Kaufvalidierung<\/h2>\n\n\n\n

    In der Regel sieht der Vorgang der Kaufvalidierung auf iOS wie folgt aus:<\/p>\n\n\n\n

    \"\"<\/figure>\n\n\n\n

    Generieren des gemeinsamen Geheimnisses (shared secret)<\/h3>\n\n\n\n

    Sie m\u00fcssen das gemeinsame Geheimnis angeben, um eine Anforderung zur Zahlungsvalidierung zu autorisieren. Sie k\u00f6nnen es im App Store Connect generieren.<\/p>\n\n\n\n

    Das gemeinsame Geheimnis kann f\u00fcr eine bestimmte App (App-spezifisches Geheimnis) oder f\u00fcr alle Apps im Konto (prim\u00e4res Geheimnis) erstellt werden.<\/p>\n\n\n\n

    \u00d6ffnen Sie die Seite der App in App Store Connect, gehen Sie zu In-App-K\u00e4ufe \u2192 Verwalten und klicken Sie auf App-spezifisches gemeinsames Geheimnis, um ein App-spezifisches Geheimnis zu generieren. In dem sich nun \u00f6ffnenden Fenster k\u00f6nnen Sie einen neuen Token generieren oder das vorhandene kopieren.<\/p>\n\n\n\n

    \"\"
    Generieren eines App-spezifischen gemeinsamen Geheimnisses<\/em><\/figcaption><\/figure>\n\n\n\n
    \"\"<\/figure>\n\n\n\n

    \u00d6ffnen Sie die Seite \u201eBenutzer und Zugriff\u201c und w\u00e4hlen Sie die Registerkarte \u201eGemeinsames Geheimnis\u201c aus, um das Geheimnis f\u00fcr alle Apps in Ihrem Konto zu erhalten.<\/p>\n\n\n\n

    \"\"
    So finden Sie ein gemeinsames Geheimnis f\u00fcr alle Apps<\/figcaption><\/figure>\n\n\n\n

    Zahlungsvalidierung anfordern<\/h3>\n\n\n\n

    Sobald Sie das gemeinsame Geheimnis erhalten, k\u00f6nnen Sie die Quittungen versenden, um diese auf den Apple Servern zu validieren. Das erfolgt \u00fcber eine verifyReceipt<\/a> Anfrage. Senden Sie eine POST Anfrage an https:\/\/buy.itunes.apple.com\/verifyReceipt<\/a>. Im JSON Body der Anfrage geben Sie das gemeinsame Geheimnis im Password<\/em> Feld ein und die Quittung bei receipt-data<\/em>. Optional gibt es auch den exclude-old-transactions <\/em>Parameter. Ist dieser true<\/em>, erhalten Sie f\u00fcr jedes automatisch verl\u00e4ngerte Abonnement die letzte Transaktion statt des kompletten Verlaufs.<\/p>\n\n\n\n

    Hier ist der Payload der Anfrage zur Kaufvalidierung:<\/p>\n\n\n\n

    <\/path><\/path><\/svg><\/span>
    {<\/span><\/span>\n  <\/span>"<\/span>password<\/span>"<\/span>:<\/span> <\/span>"<\/span>f4d35830e3...52aae<\/span>"<\/span>,<\/span><\/span>\n  <\/span>"<\/span>receipt-data<\/span>"<\/span>:<\/span> <\/span>"<\/span>MIIUVQY...4rVpL8NlYh2\/8l7rk0BcStXjQ==<\/span>"<\/span>,<\/span><\/span>\n  <\/span>"<\/span>exclude-old-transactions<\/span>"<\/span>:<\/span> <\/span>false<\/span><\/span>\n}<\/span><\/span><\/code><\/pre><\/div>\n\n\n\n

    Beachten Sie, dass Sie eine in der Sandbox-Umgebung erstellte Quittung nicht auf einem Produktionsserver validieren k\u00f6nnen und umgekehrt. <\/em>Aus diesem Grund ist es in realen Systemen am besten, die erste Anfrage an den Produktionsserver zu leiten und sie an den Sandbox-Server umzuleiten, falls der Status Key den Fehlercode 21007 zur\u00fcckgibt. Dieses Verhalten ist ein Muss w\u00e4hrend der App-\u00dcberpr\u00fcfung. Nur so k\u00f6nnen Apple-Mitarbeiter K\u00e4ufe testen, w\u00e4hrend auch echte Nutzern die Chance haben, Ihre App zu kaufen.<\/p>\n\n\n\n

    Unter den vielen zu beachtenden Fehlern<\/a> gibt es den 21004 <\/em>Fehlercode. Dieser bedeutet, dass wir das falsche Geheimnis verwenden. Behalten Sie immer den \u00dcberblick, da es sich sowohl auf die Benutzererfahrung als auch auf die Genauigkeit der Analyse auswirkt. Im schlimmsten Fall kann die App aus dem App Store entfernt werden, wenn der Nutzer nach der Bezahlung nie Zugriff auf die Premium-Features erh\u00e4lt.<\/p>\n\n\n\n

    War die Validierung erfolgreich (Status<\/em>=0), enth\u00e4lt die Antwort die Details der Transaktionen des Nutzers.<\/p>\n\n\n\n

    Hier ist die Antwort auf die Anforderung zur Zahlungsvalidierung:<\/p>\n\n\n\n

    <\/path><\/path><\/svg><\/span>
    {<\/span><\/span>\n  <\/span>"<\/span>environment<\/span>"<\/span>:<\/span> <\/span>"<\/span>Production<\/span>"<\/span>,<\/span><\/span>\n  <\/span>"<\/span>receipt<\/span>"<\/span>:<\/span> <\/span>{<\/span><\/span>\n    <\/span>"<\/span>receipt_type<\/span>"<\/span>:<\/span> <\/span>"<\/span>Production<\/span>"<\/span>,<\/span><\/span>\n    <\/span>"<\/span>adam_id<\/span>"<\/span>:<\/span> <\/span>123<\/span>,<\/span><\/span>\n    <\/span>"<\/span>app_item_id<\/span>"<\/span>:<\/span> <\/span>123<\/span>,<\/span><\/span>\n    <\/span>"<\/span>bundle_id<\/span>"<\/span>:<\/span> <\/span>"<\/span>com.adapty.sample_app<\/span>"<\/span>,<\/span><\/span>\n    <\/span>"<\/span>application_version<\/span>"<\/span>:<\/span> <\/span>"<\/span>1<\/span>"<\/span>,<\/span><\/span>\n    <\/span>"<\/span>download_id<\/span>"<\/span>:<\/span> <\/span>123<\/span>,<\/span><\/span>\n    <\/span>"<\/span>version_external_identifier<\/span>"<\/span>:<\/span> <\/span>123<\/span>,<\/span><\/span>\n    <\/span>"<\/span>receipt_creation_date<\/span>"<\/span>:<\/span> <\/span>"<\/span>2021-04-28 19:42:01 Etc\/GMT<\/span>"<\/span>,<\/span><\/span>\n    <\/span>"<\/span>receipt_creation_date_ms<\/span>"<\/span>:<\/span> <\/span>"<\/span>1619638921000<\/span>"<\/span>,<\/span><\/span>\n    <\/span>"<\/span>receipt_creation_date_pst<\/span>"<\/span>:<\/span> <\/span>"<\/span>2021-04-28 12:42:01 America\/Los_Angeles<\/span>"<\/span>,<\/span><\/span>\n    <\/span>"<\/span>request_date<\/span>"<\/span>:<\/span> <\/span>"<\/span>2021-08-09 18:26:02 Etc\/GMT<\/span>"<\/span>,<\/span><\/span>\n    <\/span>"<\/span>request_date_ms<\/span>"<\/span>:<\/span> <\/span>"<\/span>1628533562696<\/span>"<\/span>,<\/span><\/span>\n    <\/span>"<\/span>request_date_pst<\/span>"<\/span>:<\/span> <\/span>"<\/span>2021-08-09 11:26:02 America\/Los_Angeles<\/span>"<\/span>,<\/span><\/span>\n    <\/span>"<\/span>original_purchase_date<\/span>"<\/span>:<\/span> <\/span>"<\/span>2017-04-09 21:18:41 Etc\/GMT<\/span>"<\/span>,<\/span><\/span>\n    <\/span>"<\/span>original_purchase_date_ms<\/span>"<\/span>:<\/span> <\/span>"<\/span>1491772721000<\/span>"<\/span>,<\/span><\/span>\n    <\/span>"<\/span>original_purchase_date_pst<\/span>"<\/span>:<\/span> <\/span>"<\/span>2017-04-09 14:18:41 America\/Los_Angeles<\/span>"<\/span>,<\/span><\/span>\n    <\/span>"<\/span>original_application_version<\/span>"<\/span>:<\/span> <\/span>"<\/span>1<\/span>"<\/span>,<\/span><\/span>\n    <\/span>"<\/span>in_app<\/span>"<\/span>:<\/span> <\/span>[<\/span><\/span>\n      <\/span>{<\/span><\/span>\n        <\/span>"<\/span>quantity<\/span>"<\/span>:<\/span> <\/span>"<\/span>1<\/span>"<\/span>,<\/span><\/span>\n        <\/span>"<\/span>product_id<\/span>"<\/span>:<\/span> <\/span>"<\/span>basic_subscription_1_month<\/span>"<\/span>,<\/span><\/span>\n        <\/span>"<\/span>transaction_id<\/span>"<\/span>:<\/span> <\/span>"<\/span>1000000831360853<\/span>"<\/span>,<\/span><\/span>\n        <\/span>"<\/span>original_transaction_id<\/span>"<\/span>:<\/span> <\/span>"<\/span>1000000831360853<\/span>"<\/span>,<\/span><\/span>\n        <\/span>"<\/span>purchase_date<\/span>"<\/span>:<\/span> <\/span>"<\/span>2021-04-28 19:41:58 Etc\/GMT<\/span>"<\/span>,<\/span><\/span>\n        <\/span>"<\/span>purchase_date_ms<\/span>"<\/span>:<\/span> <\/span>"<\/span>1619638918000<\/span>"<\/span>,<\/span><\/span>\n        <\/span>"<\/span>purchase_date_pst<\/span>"<\/span>:<\/span> <\/span>"<\/span>2021-04-28 12:41:58 America\/Los_Angeles<\/span>"<\/span>,<\/span><\/span>\n        <\/span>"<\/span>original_purchase_date<\/span>"<\/span>:<\/span> <\/span>"<\/span>2021-04-28 19:41:58 Etc\/GMT<\/span>"<\/span>,<\/span><\/span>\n        <\/span>"<\/span>original_purchase_date_ms<\/span>"<\/span>:<\/span> <\/span>"<\/span>1619638918000<\/span>"<\/span>,<\/span><\/span>\n        <\/span>"<\/span>original_purchase_date_pst<\/span>"<\/span>:<\/span> <\/span>"<\/span>2021-04-28 12:41:58 America\/Los_Angeles<\/span>"<\/span>,<\/span><\/span>\n        <\/span>"<\/span>expires_date<\/span>"<\/span>:<\/span> <\/span>"<\/span>2021-05-05 19:41:58 Etc\/GMT<\/span>"<\/span>,<\/span><\/span>\n        <\/span>"<\/span>expires_date_ms<\/span>"<\/span>:<\/span> <\/span>"<\/span>1620243718000<\/span>"<\/span>,<\/span><\/span>\n        <\/span>"<\/span>expires_date_pst<\/span>"<\/span>:<\/span> <\/span>"<\/span>2021-05-05 12:41:58 America\/Los_Angeles<\/span>"<\/span>,<\/span><\/span>\n        <\/span>"<\/span>web_order_line_item_id<\/span>"<\/span>:<\/span> <\/span>"<\/span>230000397200750<\/span>"<\/span>,<\/span><\/span>\n        <\/span>"<\/span>is_trial_period<\/span>"<\/span>:<\/span> <\/span>"<\/span>true<\/span>"<\/span>,<\/span><\/span>\n        <\/span>"<\/span>is_in_intro_offer_period<\/span>"<\/span>:<\/span> <\/span>"<\/span>false<\/span>"<\/span>,<\/span><\/span>\n        <\/span>"<\/span>in_app_ownership_type<\/span>"<\/span>:<\/span> <\/span>"<\/span>PURCHASED<\/span>"<\/span><\/span>\n      <\/span>}<\/span><\/span>\n    <\/span>]<\/span><\/span>\n  <\/span>},<\/span><\/span>\n  <\/span>"<\/span>latest_receipt_info<\/span>"<\/span>:<\/span> <\/span>[<\/span><\/span>\n    <\/span>{<\/span><\/span>\n      <\/span>"<\/span>quantity<\/span>"<\/span>:<\/span> <\/span>"<\/span>1<\/span>"<\/span>,<\/span><\/span>\n      <\/span>"<\/span>product_id<\/span>"<\/span>:<\/span> <\/span>"<\/span>basic_subscription_1_month<\/span>"<\/span>,<\/span><\/span>\n      <\/span>"<\/span>transaction_id<\/span>"<\/span>:<\/span> <\/span>"<\/span>230001020690335<\/span>"<\/span>,<\/span><\/span>\n      <\/span>"<\/span>original_transaction_id<\/span>"<\/span>:<\/span> <\/span>"<\/span>1000000831360853<\/span>"<\/span>,<\/span><\/span>\n      <\/span>"<\/span>purchase_date<\/span>"<\/span>:<\/span> <\/span>"<\/span>2021-08-04 19:41:58 Etc\/GMT<\/span>"<\/span>,<\/span><\/span>\n      <\/span>"<\/span>purchase_date_ms<\/span>"<\/span>:<\/span> <\/span>"<\/span>1628106118000<\/span>"<\/span>,<\/span><\/span>\n      <\/span>"<\/span>purchase_date_pst<\/span>"<\/span>:<\/span> <\/span>"<\/span>2021-08-04 12:41:58 America\/Los_Angeles<\/span>"<\/span>,<\/span><\/span>\n      <\/span>"<\/span>original_purchase_date<\/span>"<\/span>:<\/span> <\/span>"<\/span>2021-04-28 19:41:58 Etc\/GMT<\/span>"<\/span>,<\/span><\/span>\n      <\/span>"<\/span>original_purchase_date_ms<\/span>"<\/span>:<\/span> <\/span>"<\/span>1619638918000<\/span>"<\/span>,<\/span><\/span>\n      <\/span>"<\/span>original_purchase_date_pst<\/span>"<\/span>:<\/span> <\/span>"<\/span>2021-04-28 12:41:58 America\/Los_Angeles<\/span>"<\/span>,<\/span><\/span>\n      <\/span>"<\/span>expires_date<\/span>"<\/span>:<\/span> <\/span>"<\/span>2021-08-11 19:41:58 Etc\/GMT<\/span>"<\/span>,<\/span><\/span>\n      <\/span>"<\/span>expires_date_ms<\/span>"<\/span>:<\/span> <\/span>"<\/span>1628710918000<\/span>"<\/span>,<\/span><\/span>\n      <\/span>"<\/span>expires_date_pst<\/span>"<\/span>:<\/span> <\/span>"<\/span>2021-08-11 12:41:58 America\/Los_Angeles<\/span>"<\/span>,<\/span><\/span>\n      <\/span>"<\/span>web_order_line_item_id<\/span>"<\/span>:<\/span> <\/span>"<\/span>230000438372383<\/span>"<\/span>,<\/span><\/span>\n      <\/span>"<\/span>is_trial_period<\/span>"<\/span>:<\/span> <\/span>"<\/span>false<\/span>"<\/span>,<\/span><\/span>\n      <\/span>"<\/span>is_in_intro_offer_period<\/span>"<\/span>:<\/span> <\/span>"<\/span>false<\/span>"<\/span>,<\/span><\/span>\n      <\/span>"<\/span>in_app_ownership_type<\/span>"<\/span>:<\/span> <\/span>"<\/span>PURCHASED<\/span>"<\/span>,<\/span><\/span>\n      <\/span>"<\/span>subscription_group_identifier<\/span>"<\/span>:<\/span> <\/span>"<\/span>272394410<\/span>"<\/span><\/span>\n    <\/span>},<\/span><\/span>\n    <\/span>{<\/span><\/span>\n      <\/span>"<\/span>quantity<\/span>"<\/span>:<\/span> <\/span>"<\/span>1<\/span>"<\/span>,<\/span><\/span>\n      <\/span>"<\/span>product_id<\/span>"<\/span>:<\/span> <\/span>"<\/span>basic_subscription_1_month<\/span>"<\/span>,<\/span><\/span>\n      <\/span>"<\/span>transaction_id<\/span>"<\/span>:<\/span> <\/span>"<\/span>230001017218955<\/span>"<\/span>,<\/span><\/span>\n      <\/span>"<\/span>original_transaction_id<\/span>"<\/span>:<\/span> <\/span>"<\/span>1000000831360853<\/span>"<\/span>,<\/span><\/span>\n      <\/span>"<\/span>purchase_date<\/span>"<\/span>:<\/span> <\/span>"<\/span>2021-07-28 19:41:58 Etc\/GMT<\/span>"<\/span>,<\/span><\/span>\n      <\/span>"<\/span>purchase_date_ms<\/span>"<\/span>:<\/span> <\/span>"<\/span>1627501318000<\/span>"<\/span>,<\/span><\/span>\n      <\/span>"<\/span>purchase_date_pst<\/span>"<\/span>:<\/span> <\/span>"<\/span>2021-07-28 12:41:58 America\/Los_Angeles<\/span>"<\/span>,<\/span><\/span>\n      <\/span>"<\/span>original_purchase_date<\/span>"<\/span>:<\/span> <\/span>"<\/span>2021-04-28 19:41:58 Etc\/GMT<\/span>"<\/span>,<\/span><\/span>\n      <\/span>"<\/span>original_purchase_date_ms<\/span>"<\/span>:<\/span> <\/span>"<\/span>1619638918000<\/span>"<\/span>,<\/span><\/span>\n      <\/span>"<\/span>original_purchase_date_pst<\/span>"<\/span>:<\/span> <\/span>"<\/span>2021-04-28 12:41:58 America\/Los_Angeles<\/span>"<\/span>,<\/span><\/span>\n      <\/span>"<\/span>expires_date<\/span>"<\/span>:<\/span> <\/span>"<\/span>2021-08-04 19:41:58 Etc\/GMT<\/span>"<\/span>,<\/span><\/span>\n      <\/span>"<\/span>expires_date_ms<\/span>"<\/span>:<\/span> <\/span>"<\/span>1628106118000<\/span>"<\/span>,<\/span><\/span>\n      <\/span>"<\/span>expires_date_pst<\/span>"<\/span>:<\/span> <\/span>"<\/span>2021-08-04 12:41:58 America\/Los_Angeles<\/span>"<\/span>,<\/span><\/span>\n      <\/span>"<\/span>web_order_line_item_id<\/span>"<\/span>:<\/span> <\/span>"<\/span>230000849023623<\/span>"<\/span>,<\/span><\/span>\n      <\/span>"<\/span>is_trial_period<\/span>"<\/span>:<\/span> <\/span>"<\/span>false<\/span>"<\/span>,<\/span><\/span>\n      <\/span>"<\/span>is_in_intro_offer_period<\/span>"<\/span>:<\/span> <\/span>"<\/span>false<\/span>"<\/span>,<\/span><\/span>\n      <\/span>"<\/span>in_app_ownership_type<\/span>"<\/span>:<\/span> <\/span>"<\/span>PURCHASED<\/span>"<\/span>,<\/span><\/span>\n      <\/span>"<\/span>subscription_group_identifier<\/span>"<\/span>:<\/span> <\/span>"<\/span>272394410<\/span>"<\/span><\/span>\n    <\/span>}<\/span><\/span>\n  <\/span>],<\/span><\/span>\n  <\/span>"<\/span>latest_receipt<\/span>"<\/span>:<\/span> <\/span>"<\/span>MIIUVQY...4rVpL8NlYh2\/8l7rk0BcStXjQ==<\/span>"<\/span>,<\/span><\/span>\n  <\/span>"<\/span>pending_renewal_info<\/span>"<\/span>:<\/span> <\/span>[<\/span><\/span>\n    <\/span>{<\/span><\/span>\n      <\/span>"<\/span>auto_renew_product_id<\/span>"<\/span>:<\/span> <\/span>"<\/span>basic_subscription_1_month<\/span>"<\/span>,<\/span><\/span>\n      <\/span>"<\/span>product_id<\/span>"<\/span>:<\/span> <\/span>"<\/span>basic_subscription_1_month<\/span>"<\/span>,<\/span><\/span>\n      <\/span>"<\/span>original_transaction_id<\/span>"<\/span>:<\/span> <\/span>"<\/span>1000000831360853<\/span>"<\/span>,<\/span><\/span>\n      <\/span>"<\/span>auto_renew_status<\/span>"<\/span>:<\/span> <\/span>"<\/span>1<\/span>"<\/span><\/span>\n    <\/span>}<\/span><\/span>\n  <\/span>],<\/span><\/span>\n  <\/span>"<\/span>status<\/span>"<\/span>:<\/span> <\/span>0<\/span><\/span>\n}<\/span><\/span><\/code><\/pre><\/div>\n\n\n\n

    Abrufen des Abonnementstatus und des Transaktionsverlaufs<\/h3>\n\n\n\n

    Sie ben\u00f6tigen eine M\u00f6glichkeit, den Abonnementstatus zu ermitteln, damit Sie wissen, ob der Nutzer Zugriff auf die Premium-Funktionen der App hat oder nicht. In der aktuellen Version der API gibt es keine spezielle Anfrage zum Abrufen des Abonnementstatus, sodass Sie in jedem Fall mit dem Transaktionsverlauf arbeiten m\u00fcssen.<\/p>\n\n\n\n

    Der latest_receipt_info<\/em><\/a> Array enth\u00e4lt standardm\u00e4\u00dfig alle In-App-K\u00e4ufe des jeweiligen Nutzers, au\u00dfer verbrauchbare Produkte, die direkt innerhalb der App erfolgen. So k\u00f6nnen Sie den gesamten Kaufverlauf des Nutzers abrufen. Das ist sowohl f\u00fcr Analysen als auch f\u00fcr die Bestimmung des aktuellen Abonnementstatus sehr n\u00fctzlich. <\/p>\n\n\n\n

    Die Transaktionen werden immer schon sortiert, sodass die neuesten zuerst angezeigt werden. Um sicherzugehen, empfehle ich dennoch, eine eigene Sortierung nach Datum f\u00fcr Transaktionen zu implementieren.<\/p>\n\n\n\n

    Der Transaktions-Payload:<\/p>\n\n\n\n

    <\/path><\/path><\/svg><\/span>
    {<\/span><\/span>\n  <\/span>"<\/span>quantity<\/span>"<\/span>:<\/span> <\/span>"<\/span>1<\/span>"<\/span>,<\/span><\/span>\n  <\/span>"<\/span>product_id<\/span>"<\/span>:<\/span> <\/span>"<\/span>basic_subscription_1_month<\/span>"<\/span>,<\/span><\/span>\n  <\/span>"<\/span>transaction_id<\/span>"<\/span>:<\/span> <\/span>"<\/span>1000000831360853<\/span>"<\/span>,<\/span><\/span>\n  <\/span>"<\/span>original_transaction_id<\/span>"<\/span>:<\/span> <\/span>"<\/span>1000000831360853<\/span>"<\/span>,<\/span><\/span>\n  <\/span>"<\/span>purchase_date<\/span>"<\/span>:<\/span> <\/span>"<\/span>2021-04-28 19:41:58 Etc\/GMT<\/span>"<\/span>,<\/span><\/span>\n  <\/span>"<\/span>purchase_date_ms<\/span>"<\/span>:<\/span> <\/span>"<\/span>1619638918000<\/span>"<\/span>,<\/span><\/span>\n  <\/span>"<\/span>purchase_date_pst<\/span>"<\/span>:<\/span> <\/span>"<\/span>2021-04-28 12:41:58 America\/Los_Angeles<\/span>"<\/span>,<\/span><\/span>\n  <\/span>"<\/span>original_purchase_date<\/span>"<\/span>:<\/span> <\/span>"<\/span>2021-04-28 19:41:58 Etc\/GMT<\/span>"<\/span>,<\/span><\/span>\n  <\/span>"<\/span>original_purchase_date_ms<\/span>"<\/span>:<\/span> <\/span>"<\/span>1619638918000<\/span>"<\/span>,<\/span><\/span>\n  <\/span>"<\/span>original_purchase_date_pst<\/span>"<\/span>:<\/span> <\/span>"<\/span>2021-04-28 12:41:58 America\/Los_Angeles<\/span>"<\/span>,<\/span><\/span>\n  <\/span>"<\/span>expires_date<\/span>"<\/span>:<\/span> <\/span>"<\/span>2021-05-05 19:41:58 Etc\/GMT<\/span>"<\/span>,<\/span><\/span>\n  <\/span>"<\/span>expires_date_ms<\/span>"<\/span>:<\/span> <\/span>"<\/span>1620243718000<\/span>"<\/span>,<\/span><\/span>\n  <\/span>"<\/span>expires_date_pst<\/span>"<\/span>:<\/span> <\/span>"<\/span>2021-05-05 12:41:58 America\/Los_Angeles<\/span>"<\/span>,<\/span><\/span>\n  <\/span>"<\/span>web_order_line_item_id<\/span>"<\/span>:<\/span> <\/span>"<\/span>230000397200750<\/span>"<\/span>,<\/span><\/span>\n  <\/span>"<\/span>is_trial_period<\/span>"<\/span>:<\/span> <\/span>"<\/span>true<\/span>"<\/span>,<\/span><\/span>\n  <\/span>"<\/span>is_in_intro_offer_period<\/span>"<\/span>:<\/span> <\/span>"<\/span>false<\/span>"<\/span>,<\/span><\/span>\n  <\/span>"<\/span>in_app_ownership_type<\/span>"<\/span>:<\/span> <\/span>"<\/span>PURCHASED<\/span>"<\/span>,<\/span><\/span>\n  <\/span>"<\/span>subscription_group_identifier<\/span>"<\/span>:<\/span> <\/span>"<\/span>272394410<\/span>"<\/span><\/span>\n}<\/span><\/span><\/code><\/pre><\/div>\n\n\n\n

    Es reicht aus, die letzte Transaktion der Kette abzurufen und sich die Eigenschaft expires_date<\/em> anzusehen, um den aktuellen Abonnementstatus zu \u00fcberpr\u00fcfen. Die Ausnahme davon w\u00e4re die Gnadenfrist, auf die wir sp\u00e4ter noch eingehen werden.<\/p>\n\n\n\n

    Zur Analyse empfehle ich, die folgenden Eigenschaften zu speichern:<\/p>\n\n\n\n

    Die Antwort ist ziemlich umst\u00e4ndlich und wurde in der neuen Version der App Store Server API<\/a> vereinfacht. Die aktuelle Implementierung ist jedoch nicht allzu umzusetzen.<\/p>\n\n\n\n\n\n

    Wenn Sie in einer Sandbox-Umgebung arbeiten (also zu Testzwecken), senden Sie die Validierungsanfragen an https:\/\/sandbox.itunes.apple.com\/verifyReceipt<\/a>. Das gemeinsame Geheimnis sowie der Payload und die Antwortformate bleiben gleich. <\/p>\n\n\n\n