How to Remove Purchases From Buy Again Amazon

Server-side validation tin can assist yous validate purchase authenticity. The device will make a request to Google servers to find out whether the purchase has actually taken identify and whether it is valid.

In this guide, nosotros'll talk over how to configure server-side validation for Android apps.

This is the 5th commodity in our series near implementing in-app purchases for Android apps. I recommend you await through the others likewise:

  1. Android in-app purchases, part 1: configuration and adding to the project
  2. Android in-app purchases, part 2: processing purchases with the Google Play Billing Library
  3. Android in-app purchases, part 3: retrieving active purchases and subscription change
  4. Android in-app purchases, part 4: billing Library Fault Codes and how not to screw up with testing
  5. Android in-app purchases, role v: server-side buy validation

Why validate purchases

It should be noted that server-side validation isn't mandatory — in-app purchases will still piece of work without it. In that location are some pregnant benefits to it, though:

  1. Avant-garde payment analytics, which is especially important for subscriptions since everything that happens afterwards the activation isn't processed by the device. With no server-side purchase processing, yous won't exist able to call back the current subscription status and know whether the user has renewed the subscription or canceled it, whether in that location are any payment issues, and so on.
  2. Being able to verify the purchase's authenticity. You lot'll be sure that the transaction isn't fraudulent, and the user has actually paid for your product.
  3. Cross platform subscriptions. If you tin check the user's subscription status in existent time, y'all can synchronize it with other platforms. For example, the user who purchased the subscription from an iOS device will exist able to use it on Android, the Web, and other platforms.
  4. Being able to command content admission from the server side, which protects you lot from users trying to access the data with no subscription by but executing requests to the server.

Speaking from our experience, the first reward solitary is enough to set upwards server-side purchase processing.

⭐️ Download our guide on in-app techniques which will make in-app purchases in your app perfect

Payment validation

We tin can summarize Android payment validation with this scheme:

Authentication for Google Play Developer API requests

To work with Google Play Developer API, you'll first need to generate a central to sign requests. Outset, you lot'll have to link your Google Play Console account (where you manage your app) to your Google Cloud business relationship (where yous'll generate a key for request signing). Once everything's configured, you lot'll take to grant the user purchase direction rights. Information technology'd take a dedicated commodity to describe this process. Luckily, we've already covered information technology in a step-past-stride guide found in Adapty documentation.

Notation that usually, you'll have to wait for 24 hours or more after generating a fundamental for it to beginning working. To avoid that, just update the description for any  in-app product or subscription, which will instantly activate the fundamental.

Nosotros apply the official google-api-python-customer library to piece of work with Google Play Developer API. This library is available for the majority of popular languages, and I recommend using it as it supports all the methods you might need.

Validation for subscription transactions

Unlike iOS server-side validation, in Android, both subscription and other production validation are implemented using a variety of methods. Therefore, when validating a transaction, you demand to know whether you're dealing with a product or a subscription. In practice, this means you'll demand to transfer this data from the mobile app, as well as keep the flag in the database in case token re-validation will be necessary.

The second important difference is that while each transaction has its ain token in Android, all iOS transactions utilise an app-specific shared secret to shop the entire transaction history. This ways that if you want to exist able to restore the user'due south purchases at any moment, you'll demand to shop all purchase tokens, equally opposed to picking out an capricious single one.

To validate the subscription, you'll demand to invoke the purchases.subscriptions.get method.  Basically, it'southward a Get request call

            https://androidpublisher.googleapis.com/androidpublisher/v3/applications/{packageName}/purchases/subscriptions/{subscriptionId}/tokens/{token}          

All parameters are required:

  • packageName: App identifier, e.thou., com.adapty.sample_app.
  • subscriptionId: Subscription identifier for the subscription that'due south to be validated, e.g., com.adapty.sample_app.weekly_sub.
  • token: Unique transaction token. It appears in one case the buy is processed on the mobile app side.

Outset, let's wait at the error messages you demand to accept care of to brand sure everything works as intended:

  • 400, Invalid grant: account not establish: This error message means that the request authentication key was generated incorrectly. Make sure that your accounts are linked, you're using the correct one that has enough permissions, and all the required APIs are activated. See the section below for a guide on how to configure everything. Annotation the tip on production clarification update.
  • 400, The purchase token does non lucifer the parcel proper name: This error message is usually encountered in fraudulent transactions. If you see it while testing, make sure you aren't using an app buy token that belongs to a dissimilar app.
  • 403, Quota exceeded for quota metric 'Queries' and limit 'Queries per twenty-four hour period' of service 'androidpublisher.googleapis.com': This means the Google API requests daily quota was exceeded. By default, you tin can execute upwards to 200,000 requests per day. This quota tin can be increased, but it should suffice for most apps. If you come up against this limit, you should probably double-bank check your app's logic and make sure everything's correct.
  • 410, The subscription buy is no longer available for query because information technology has been expired for too long: This fault message appears in transactions where the subscription has expired more than 60 days ago. It'southward not an actual error message and shouldn't be candy every bit such.

Subscription transaction

If the validation was successful, you'll receive transaction data every bit your response.

Transaction data (for a subscription):

            {     "expiryTimeMillis": "1631116261362",     "paymentState": 1,     "acknowledgementState": one,     "kind": "androidpublisher#subscriptionPurchase",     "orderId": "GPA.3382-9215-9042-70164",     "startTimeMillis": "1630504367892",     "autoRenewing": truthful,     "priceCurrencyCode": "USD",     "priceAmountMicros": "1990000",     "countryCode": "United states",     "developerPayload": "" }          

To understand whether the user can access the premium options offered by the app — that is, whether they have an active subscription — you demand to:

  1. Bank check the startTimeMillis and expiryTimeMillis parameters. The electric current fourth dimension should be between these.
  2. What'south more, you have to make certain the paymentState parameter doesn't have the '1' value. This would hateful the subscription buy's notwithstanding pending, therefore, at that place'south no need to grant the user premium function access just nonetheless.
  3. If the transaction has the autoResumeTimeMillis property, then the subscription is paused. This means that the user shouldn't be granted premium function access before the specified date.

Let's see the key properties of a subscription transaction:

  • kind: Transaction type. For subscription, information technology always has the androidpublisher#subscriptionPurchase value. With this parameter, you can sympathize whether you lot're dealing with a subscription or a product, and cull the processing logic accordingly.
  • paymentState: Payment status. This property isn't present for expired transactions. The possible values are:
    0: This buy hasn't been candy notwithstanding. In some countries, the user can pay for the subscription onsite. That is, the user volition initiate the subscription purchase from their device and pay for it at a nearby last. Overall, it's a quite rare case, simply it should even so exist kept in mind.
    1: Subscription was purchased.
    two: Subscription is in the trial period.
    3: Subscription will be up- or downgraded in the next menstruation. This means the subscription plan is to alter.
  • acknowledgementState: Purchase confirmation status. It's an important parameter that acknowledges whether the user has received the access to what they paid for. The '0' value means they oasis't, and '1' means they have. The developer is responsible for defining this status, which can exist washed on both the mobile app and the server sides. If you don't admit the purchase within 3 days after it's been made, information technology'll be automatically be refunded. I recommend implementing this logic: once you lot receive a transaction containing acknowledgementState=0, the parameter gets inverse past the server. I'll talk over how to do that beneath.
  • orderId: Unique transaction identifier. Each subscription purchase or renewal will take its own identifier, which can be used to learn whether this transaction has already been processed before. Each renewal identifier will take a constant outset one-half, to which two dots and the subscription renewal count (which starts with 0) are appended. If the subscription had the GPA.3382-9215-9042-70164 identifier when activated, and then the first renewal will exist identified past GPA.3382-9215-9042-70164..0, the 2d one by GPA.3382-9215-9042-70164..i, etc. This manner, yous tin build transaction bondage and keep rails of renewal count.
  • startTimeMillis: Subscription starting time date.
  • expiryTimeMillis: Subscription expiration date.
  • autoRenewing: Flag showing whether or not the subscription is to be renewed into the next period.
  • priceCurrencyCode: Purchase currency in a three-letter of the alphabet format, e.yard., USD.
  • priceAmountMicros: Purchase toll. To get the normal toll value, divide this value past 1000000. That is, 1990000 actually ways 1,99.
  • countryCode: Purchase country in two-alphabetic character format, due east.1000., US.
  • purchaseType: Purchase type. This key won't be nowadays in most cases. Information technology's still important to business relationship for, because it helps you sympathise whether the purchase was made in Sandbox environs. The possible values are:
    0: The purchase was fabricated in Sandbox environment, therefore, it shouldn't be included in the analytics information.
    1: The purchase was made with a promo code.
  • autoResumeTimeMillis: Subscription renewal appointment. Information technology's but present for subscriptions that have previously been paused. If this parameter is present, you don't demand to grant the user premium function access before the given engagement.
  • cancelReason: The reason why the subscription won't be renewed. The possible values are:
    0: The user canceled the subscription automobile-renewal.
    1: Subscription was canceled by the system. This is most often caused by a billing issue.
    2: The user switched to a different subscription programme.
    3: The developer canceled the subscription.
  • userCancellationTimeMillis: Subscription renewal cancellation information. It's merely present if cancelReason is 0. The subscription can still exist active — to make sure, see the expiryTimeMillis parameter's value.
  • cancelSurveyResult: Object that stores the reason backside subscription counterfoil, which will exist present if the user has left any feedback on this matter.
  • introductoryPriceInfo: Object that stores introductory price data. For example, this tin be a special offer of 1 month with 50% off.
  • promotionType: Promo code type that was used to activate the subscription. The possible values are:
    0: One-time promo lawmaking.
    ane: Custom promo lawmaking that can exist applied by multiple customers. Such codes are usually used for blogger partnerships.
  • promotionCode: Custom promo lawmaking that was used to activate the subscription. This parameter isn't present for erstwhile promo codes.
  • priceChange: Object that stores future price change data, besides as whether the user has agreed to it.

Subscription acknowledgement

Every bit it was already mentioned higher up, in case the subscription isn't acknowledged within 3 days later on the buy is made, it'll get canceled and refunded automatically. To be honest, I don't really understand the logic behind information technology, and I've never encountered it in whatsoever other payment processing systems, the iOS 1 included. Withal, if you receive a transaction containing acknowledgementState=0, y'all are to acknowledge the subscription.

To practise and then, you'll demand to invoke the purchases.subscriptions.acknowledge method. This method executes a Post asking

            https://androidpublisher.googleapis.com/androidpublisher/v3/applications/{packageName}/purchases/subscriptions/{subscriptionId}/tokens/{token}:acknowledge          

The parameters are the same as for request validation. If the asking is successfully executed, the subscription will become best-selling, which means you won't lose your money.

If the subscription hasn't been fully purchased yet, there'south no need to acknowledge information technology.

Subscription renewal cancellation, revocation, refund, and deferral

Apart from subscription validation and acknowledgement, Google Play Developer API can also exist used for other subscription operations. It should exist noted that these are quite rare and, with the exception of renewal, are supported by Google Play Panel. I'll still list them to give you lot a general understanding of API solutions scope. All these requests accept the aforementioned parameters required as the previously mentioned methods, namely, packageName, subscriptionId, and token.

  • Renewal cancellation. The purchases.subscriptions.cancel method. It cancels automobile-renewal for the selected subscription. However, the subscription volition still be bachelor throughout the current billing menstruation.
  • Subscription refund. The purchases.subscriptions.refund method. It refunds the subscription. However, the user will even so retain subscription access, and it volition be automatically renewed in the next period. In near cases, you should also revoke the subscription when issuing a refund.
  • Subscription revocation. The purchases.subscriptions.revoke method. It immediately revokes the subscription, which means the user will be unable to access the premium functions. The subscription won't be renewed. This method is usually invoked along with issuing a refund.
  • Subscription buy deferral. The purchases.subscriptions.defer method. Information technology extends the subscription up to the specified date. In the request, specify the subscription expiry appointment, as well every bit the date you desire to supervene upon it with. The latter must result in a longer subscription menstruum than the erstwhile.

Production (not subscription) validation

Production validation is similar to subscription validation. You lot need to invoke the purchases.products.become method to execute the GET asking.

            https://androidpublisher.googleapis.com/androidpublisher/v3/applications/{packageName}/purchases/products/{productId}/tokens/{token}          

We're already familiar with all these parameters from looking at the examples outlined above.

Transaction data (for a product):

            {   "purchaseTimeMillis": "1630529397125",   "purchaseState": 0,   "consumptionState": 0,   "developerPayload": "",   "orderId": "GPA.3374-2691-3583-90384",   "acknowledgementState": i,   "kind": "androidpublisher#productPurchase",   "regionCode": "RU" }          

Production transactions include much fewer properties than subscription transactions. Let'due south take a look at some important ones:

  • kind: Transaction type. In products, it always has the androidpublisher#productPurchase value. With this parameter, you can understand whether yous're dealing with a subscription or a product, and choose the processing logic accordingly.
  • purchaseState: Payment status. Note that the cardinal values here are dissimilar from the paymentState parameter for subscriptions. The possible values are:
    0: Purchase was completed.
    1: Buy was canceled. This means that the purchase was pending, but the user never paid for it.
    2: Purchase is awaiting. In some countries, the user can pay for the subscription onsite. That is, the user will initiate the subscription purchase from their device and pay for information technology at a nearby final. Overall, it'due south a quite rare case, but information technology should yet be kept in mind.
  • acknowledgementState: Purchase confirmation status. Information technology's an of import parameter that acknowledges whether the user has received the access to what they paid for. The '0' value ways they haven't, and 'ane' means they have. The developer is responsible for defining this condition, which tin can be done on both the mobile app and the server sides. If you don't acknowledge the buy inside 3 days after it'southward been made, it'll automatically be refunded. I recommend implementing this logic: in one case you receive a transaction containing acknowledgementState=0, the parameter gets changed past the server. I'll hash out how to exercise that below.
  • consumptionState: Product consumption condition. That'southward what iOS calls a 'consumable'. It'south defined on the mobile app side. If it has the '0' value, it means the product wasn't consumed; if information technology'southward '1', then information technology was. If y'all're selling lifetime access to your app or some specific premium feature, then such a product shouldn't be consumed, that is, they should have the 0 condition. If you're selling coins the user can buy time and time again, such products should be consumed, that is, they should have the one status. consumptionState=0 means the production tin but be purchased once, whereas consumptionState=1 means it can be purchased many times.
  • orderId: Unique transaction identifier. Each subscription purchase or renewal will have its own identifier, which can be used to learn whether this transaction has already been candy earlier.
  • purchaseTimeMillis: Purchase date.
  • regionCode: Buy land in two-letter format, east.chiliad., US. Annotation that this parameter's name is different from the ane in subscriptions, where it'southward named countryCode.
  • purchaseType: Purchase type. This cardinal won't exist nowadays in most cases. It's however of import to account for, because it helps you understand whether the purchase was made in Sandbox environment. The possible values are:
    0: The purchase was fabricated in Sandbox surround, therefore, it shouldn't be included in the analytics data.
    1: The buy was made with a promo code.
    two: The buy was granted for a target action, e.one thousand., watching an in-app ad in place of payment.

As y'all can see, product validation is quite similar to subscription validation. There are some points to take note of, though:

  • The price doesn't get returned, although that would be quite handy for analytics.
  • The purchaseState parameter'south values are significantly dissimilar from the values of the paymentState parameter institute in subscriptions. It will cause bugs if not accounted for.
  • regionCode gets returned, even though information technology's named countryCode for subscriptions.

Just as subscription purchases, product purchases need to be best-selling. To do so, invoke the purchases.products.acknowledge method which will execute a Mail request

            https://androidpublisher.googleapis.com/androidpublisher/v3/applications/{packageName}/purchases/products/{productId}/tokens/{token}:acknowledge          

If the purchase hasn't yet been completed, there's no demand to acknowledge information technology.

Refund tracking for subscriptions and products

Loftier-quality analytics is impossible without accounting for refunds. Unfortunately, refund information is neither present in the transaction nor gets prompted as a separate issue, as it works in iOS. To receive the list of refunded transactions, you'll need to invoke the purchases.voidedpurchases.list on a regular basis — for case, once per solar day. This method volition execute a Become asking:

            https://androidpublisher.googleapis.com/androidpublisher/v3/applications/{packageName}/purchases/voidedpurchases          

In response to the request, you'll receive the list of all refunded transactions. I recommend searching for transactions in the database by the orderId parameter, as opposed to the purchaseToken one. Starting time, this will take less time. 2d, all subscription renewals will share the same token, and you lot'll just need to fetch the almost recent one.

Server notifications for transactions

Server notifications (Real-time developer notifications) help you lot learn of events that occurred on Google's side, on your server, and virtually live. Once these are configured, you'll be notified about new purchases, renewals, payment problems, etc. This can help you lot collect better analytics, likewise as make subscriber status management much easier.

To start receiving server notifications, you demand to create a Google Deject Pub/Sub topic, which will send notifications to your desired address. This topic should then exist indicated in the Monetization setup section of the Google Play Panel. For a detailed guide with screenshots included, run across Adapty docs.

Server notification:

            {   "message": {     "data": "eyJ2ZXJzaW9uIjoiMS4wIiwicGFja2FnZU5hbWUiOiJjb20uYWRhcHR5LnNhbXBsZV9hcHAiLCJldmVudFRpbWVNaWxsaXMiOiIxNjMwNTI5Mzk3MTI1Iiwic3Vic2NyaXB0aW9uTm90aWZpY2F0aW9uIjp7InZlcnNpb24iOiIxLjAiLCJub3RpZmljYXRpb25UeXBlIjo2LCJwdXJjaGFzZVRva2VuIjoiY2o3anAuQU8tSjFPelIxMjMiLCJzdWJzY3JpcHRpb25JZCI6ImNvbS5hZGFwdHkuc2FtcGxlX2FwcC53ZWVrbHlfc3ViIn19",     "messageId": "2829603729517390",     "message_id": "2829603729517390",     "publishTime": "2021-09-01T20:49:59.124Z",     "publish_time": "2021-08-04T20:49:59.124Z"   },   "subscription": "projects/935083/subscriptions/adapty-rtdn" }          

Nosotros're mostly concerned with the data central that contains transaction data encoded with base64. The messageId cardinal tin can be used for bulletin deduplication, so that y'all don't need to process duplicate messages.

Here'southward a transaction in a server notification:

            {   "version": "1.0",   "packageName": "com.adapty.sample_app",   "eventTimeMillis": "1630529397125",   "subscriptionNotification": {     "version": "1.0",     "notificationType": six,     "purchaseToken": "cj7jp.AO-J1OzR123",     "subscriptionId": "com.adapty.sample_app.weekly_sub"   } }          

The packageName key helps you sympathize which app this outcome belongs to. The subscriptionId central tells you which subscription is involved, and purchaseToken helps you find the specific transaction. With subscriptions, you'll always be looking for the concluding transaction in the renewal chain, as it's the one this event will belong to. The notificationType key contains the consequence blazon. In my opinion, these are the near handy ones for subscriptions:

  • (2) SUBSCRIPTION_RENEWED: The subscription has successfully been renewed.
  • (3) SUBSCRIPTION_CANCELED: The user has disabled subscription auto-renewal. If auto-renewal is disabled, you'll need to try to get the user back as an agile subscriber.
  • (5) SUBSCRIPTION_ON_HOLD, (6) SUBSCRIPTION_IN_GRACE_PERIOD: The subscription couldn't have been renewed because of payment issues. You should notify the user about it so that their subscription doesn't go canceled automatically.
  • (12) SUBSCRIPTION_REVOKED: the subscription has been revoked. This ways the user should lose admission to the premium functions previously granted by the subscription.

In products (not subscriptions), you'll receive oneTimeProductNotification in place of the subscriptionNotification central. It volition also contain the sku key instead of the subscriptionId key. Moreover, you'll but always receive 2 types of events for products:

  • (1) ONE_TIME_PRODUCT_PURCHASED: Successful production purchase.
  • (ii) ONE_TIME_PRODUCT_CANCELED: Product purchase was canceled, as the user hadn't paid for information technology.

Conclusion

Server-side validation supercharges the analytics you'll be able to collect for your app. Information technology makes it harder for fraudsters to admission the premium content and tin can be used to implement cross-platform subscriptions. However, server-side validation can accept quite a while to implement, especially if loftier data accurateness is a must. To provide high-quality information, you lot'd need to account for a multitude of side cases, such every bit subscription upgrade, subscription crossgrade, trial periods, promo and introductory offers, grace period, refunds, etc. Y'all'd too have to know of and business relationship for all the policy minutiae, such equally Google just charging a 15% (as opposed to 30%) commission on subscriptions that get renewed for more than than a year.

stokesaremin.blogspot.com

Source: https://adapty.io/blog/android-in-app-purchases-part-5-server-side-purchase-validation

0 Response to "How to Remove Purchases From Buy Again Amazon"

Post a Comment

Iklan Atas Artikel

Iklan Tengah Artikel 1

Iklan Tengah Artikel 2

Iklan Bawah Artikel