Reminder: By Aug 31, 2025, all new apps and updates to existing apps must use Billing Library version 7 or newer. If you need more time to update your app, you can request an extension until Nov 1, 2025. Learn about Play Billing Library version deprecation.
با مجموعهها، منظم بمانید
ذخیره و طبقهبندی محتوا براساس اولویتهای شما.
همانطور که محبوبیت برنامه شما افزایش می یابد، می تواند توجه ناخواسته کاربران مخربی را که ممکن است بخواهند از برنامه شما سوء استفاده کنند، به خود جلب کند. این مبحث توصیههایی را شرح میدهد که باید از آنها برای جلوگیری از این حملات به یکپارچهسازی صورتحسابتان و کاهش تأثیر سوءاستفاده در برنامهتان استفاده کنید.
منطق حساس را به باطن خود منتقل کنید
تا آنجایی که طراحی اپلیکیشن شما اجازه می دهد، داده های حساس و منطق را به یک سرور پشتیبان که کنترل می کنید منتقل کنید. هرچه داده ها و منطق بیشتری در یک دستگاه frontend داشته باشید، آسیب پذیرتر از تغییر یا دستکاری آن است.
به عنوان مثال، یک بازی شطرنج آنلاین به جای اعتماد به اینکه فرانت اند همیشه حرکات قانونی را ارسال می کند، باید تمام حرکات در بک اند را تأیید کند.
علاوه بر این، اگر آسیبپذیریها یا مشکلات امنیتی پیدا کردید، بسته به طراحی سیستمتان، ممکن است اشکالزدایی، رفع و عرضه بهروزرسانیها در باطن به جای فرانتاند آسانتر باشد.
قبل از اعطای حق، خریدها را تأیید کنید
یک مورد خاص از داده های حساس و منطقی که باید در باطن مدیریت شود، تأیید خرید و تأیید است. پس از خرید کاربر، باید موارد زیر را انجام دهید:
purchaseToken مربوطه را به باطن خود ارسال کنید. این بدان معنی است که شما باید یک رکورد از تمام مقادیر purchaseToken برای همه خریدها نگه دارید.
بررسی کنید که مقدار purchaseToken برای خرید فعلی با مقادیر purchaseToken قبلی مطابقت نداشته باشد. purchaseToken در سطح جهانی منحصر به فرد است، بنابراین می توانید با خیال راحت از این مقدار به عنوان کلید اصلی در پایگاه داده خود استفاده کنید.
اگر خرید قانونی باشد و در گذشته استفاده نشده باشد، میتوانید با خیال راحت حق اشتراک یا مورد درونبرنامه را اعطا کنید.
برای اشتراکها، وقتی linkedPurchaseToken در Purchases.subscriptionsv2:get تنظیم شده است، باید linkedPurchaseToken نیز از پایگاه داده خود حذف کنید و حقی را که به linkedPurchaseToken اعطا شده است لغو کنید تا اطمینان حاصل شود که چندین کاربر حق خرید یکسان را ندارند.
شما باید فقط زمانی که وضعیت خرید PURCHASED است، این حق را اعطا کنید و مطمئن شوید که خریدهای PENDING را به درستی انجام می دهید. اگر خریدهای CANCELED زیاد باشد، ممکن است زمانی که خرید هنوز در حالت PENDING است، حقوقی را اعطا کنید. میتوانید اطلاعات بیشتری را در بخش رسیدگی به معاملات معلق بیابید.
پس از اعطای حق، اگر میخواهید یک محصول مصرفی را مصرف کنید و آن را تأیید کنید، از Purchases.products:consume Play Developer API در سرور باطن امن خود استفاده کنید. برای تأیید یک محصول غیرقابل مصرف یا یک اشتراک، با نقطه پایانی Play Developer API مربوطه تماس بگیرید، Purchases.products:acknowledge یا Purchases.subscriptions:acknowledge در سرور پشتیبان امن خود. تأیید لازم است، زیرا به Google Play اطلاع می دهد که به کاربر حق خرید داده شده است. شما باید بلافاصله پس از اعطای حق، خرید را تایید کنید.
توجه داشته باشید که در حالی که می توانید خرید را در سمت مشتری از طریق برنامه خود تأیید یا مصرف کنید، API های سمت سرور محافظت بیشتری در برابر مشکلاتی مانند اتصال ضعیف شبکه و فعالیت های مخرب ارائه می دهند. به عنوان مثال، در نظر بگیرید که کاربر موردی را از برنامه شما خریداری کرده است اما در حین تأیید اعتبار، اتصال شبکه را از دست داده است. بدون تأیید سرور، ممکن است لازم باشد دوباره از طریق برنامه وارد سیستم شوند تا فرآیند تأیید را تکمیل کنند. در غیر این صورت، اگر کاربر ظرف مدت سه روز دوباره وارد سیستم نشود، به دلیل عدم تایید خرید، خرید به صورت خودکار بازپرداخت می شود. تأیید سرور با ارسال تأییدیه به محض اینکه Google Play معتبر بودن خرید را به سرور اطلاع دهد، از این سناریو جلوگیری می کند.
برای اطلاعات بیشتر درباره تأیید خرید و مصرف، به پردازش خریدها مراجعه کنید.
محافظت از محتوای آنلاک شده شما
برای جلوگیری از توزیع مجدد محتوای قفل شده توسط کاربران مخرب، آن را در فایل APK خود قرار ندهید. در عوض، یکی از موارد زیر را انجام دهید:
از یک سرویس بلادرنگ برای ارائه محتوای خود استفاده کنید، مانند فید محتوا. ارائه محتوا از طریق یک سرویس بلادرنگ نیز به شما امکان می دهد تا محتوای خود را تازه نگه دارید.
از یک سرور راه دور برای ارائه محتوای خود استفاده کنید.
وقتی محتوا را از یک سرور راه دور یا یک سرویس بیدرنگ تحویل میدهید، میتوانید محتوای قفلشده را در حافظه دستگاه ذخیره کنید یا آن را در کارت SD دستگاه ذخیره کنید. اگر محتوا را روی کارت SD ذخیره میکنید، حتماً محتوا را رمزگذاری کنید و از یک کلید رمزگذاری مخصوص دستگاه استفاده کنید.
خریدهای باطل شده را شناسایی و مدیریت کنید
خریدهای باطل شده، خریدهایی هستند که لغو، باطل شده اند، یا هزینه بازپرداخت شده اند. اگر یک خرید باطل شده قبلاً موارد درونبرنامه یا محتوای دیگری را به کاربر اعطا کرده است، میتوانید از Voided Purchases API استفاده کنید تا دلیل باطل شدن خرید را به همراه هر محتوای مرتبطی که میتوانید پس بگیرید، دریافت کنید.
خرید اقلام درونبرنامه و اشتراکها را میتوان به دلایل مختلفی از جمله موارد زیر لغو کرد:
خرید یا توسط کاربر، توسعهدهنده یا Google لغو میشود (از جمله خریدهای لغو شده خودکار تایید نشده). برای اشتراکها، توجه داشته باشید که این به لغو خرید اشتراک اشاره دارد، نه لغو خود اشتراک .
هزینه خرید برگشت داده می شود.
توسعهدهنده برنامه سفارش کاربر را لغو یا بازپرداخت میکند و گزینه «لغو» را در کنسول بررسی میکند.
بر اساس دلیل خرید باطل و با در نظر گرفتن داده های رفتاری قبلی کاربر، می توانید در مورد یک اقدام تصمیم بگیرید. ما اجرای یک یا چند مورد از موارد زیر را توصیه می کنیم:
انجام clawback: هنگامی که خریدی باطل می شود، می توانید اقلام استفاده نشده را به گونه ای پس بگیرید که گویی هرگز خریداری نشده اند. به عنوان مثال، اگر خرید ارز درون بازی باطل شد، میتوانید ارزی را که قبلاً به کاربر اعطا شده است، پس بگیرید. در مواردی که کاربر قبلاً ارز را خرج کرده است، موجودی ارز را روی منفی و محدود کردن فعالیت برنامه و خریدهای آتی تا مثبت شدن مانده ارز در نظر بگیرید.
اجرای حملات چندگانه: اقدامات کمتر شدیدتری را برای متخلفانی که برای اولین بار انجام می دهند، مانند نمایش هشدارهای درون برنامه ای در نظر بگیرید. برای مجرمان مکرر، اقدامات شدیدتری را در نظر بگیرید.
خریدها را موقتاً غیرفعال کنید: مشابه اجرای چند اخطار، خریدها را برای کاربرانی که خریدهای باطل دارند غیرفعال کنید تا زمانی که بتوانید به طور کامل تری بررسی کنید که چرا خریدها باطل شده اند.
به طور موقت یا دائمی دسترسی به برنامه خود را ممنوع کنید: برای موارد شدید با فعالیت های مخرب مکرر، اجازه دسترسی به برنامه خود را، به طور موقت یا دائم، در نظر بگیرید.
برقراری تماس های مکرر با Voided Purchases API: هنگامی که یک یا چند خرید باطل را شناسایی می کنید، تماس های مکرر بیشتری با Voided Purchases API داشته باشید تا قبل از اینکه کاربر بتواند آنها را مصرف کند، خریدها را پس بگیرید. میتوانید اطلاعات بیشتر در مورد سهمیههای API خریدهای باطل را در اسناد API خریدهای باطل بیابید.
به Google کمک کنید تقلب را قبل از وقوع پیدا کند
برخی از انواع کلاهبرداری مربوط به کاربران مخربی است که چندین حساب Google و درون برنامه ایجاد می کنند تا فعالیت خود را پنهان کنند.
Google از این دادهها برای شناسایی رفتارهای مشکوک و مسدود کردن برخی از انواع تراکنشهای جعلی قبل از تکمیل استفاده میکند.
اقدام در برابر نقض علائم تجاری و کپی رایت
اگر از سرور راه دور برای ارائه یا مدیریت محتوا استفاده میکنید، هر زمان که کاربر به محتوا دسترسی پیدا کرد، از برنامهتان بخواهید وضعیت خرید محتوای قفلشده را تأیید کند. این به شما امکان می دهد در صورت لزوم استفاده را لغو کنید و دزدی دریایی را به حداقل برسانید. اگر مشاهده کردید که محتوای شما در حال توزیع مجدد در Google Play است، حتماً سریع و قاطعانه عمل کنید. برای جزئیات بیشتر، به صفحه سؤالات متداول حق نسخهبرداری در مرکز راهنمایی حق نسخهبرداری مراجعه کنید.
محتوا و نمونه کدها در این صفحه مشمول پروانههای توصیفشده در پروانه محتوا هستند. جاوا و OpenJDK علامتهای تجاری یا علامتهای تجاری ثبتشده Oracle و/یا وابستههای آن هستند.
تاریخ آخرین بهروزرسانی 2025-07-29 بهوقت ساعت هماهنگ جهانی.
[null,null,["تاریخ آخرین بهروزرسانی 2025-07-29 بهوقت ساعت هماهنگ جهانی."],[],[],null,["# Fight fraud and abuse\n\nAs your app grows in popularity, it can also attract the unwanted\nattention of malicious users that might want to abuse your app. This topic\ndescribes recommendations that you should use to help prevent these attacks on\nyour billing integration and decrease the impact of abuse in your app.\n\nMove sensitive logic to your backend\n------------------------------------\n\nAs much as your app design permits, move sensitive data and logic to a backend\nserver that you control. The more data and logic you have in a frontend device,\nthe more vulnerable it is to being modified or tampered with.\n\nFor example, an online chess game should validate all moves in the backend\ninstead of trusting that the frontend always sends legal moves.\n\nFurthermore, if you find vulnerabilities or security issues, depending on your system design, it might be easier to debug, fix, and roll out updates on the\nbackend rather than the frontend.\n\nVerify purchases before granting entitlements\n---------------------------------------------\n\nA special case of sensitive data and logic that should be handled in the backend\nis purchase verification and acknowledgement. After a user has made a purchase,\nyou should do the following:\n\n1. Send the corresponding `purchaseToken` to your backend. This means that you should maintain a record of all `purchaseToken` values for all purchases.\n2. Verify that the `purchaseToken` value for the current purchase does not match any previous `purchaseToken` values. `purchaseToken` is globally unique, so you can safely use this value as a primary key in your database.\n3. Use the [`Purchases.products:get`](https://developers.google.com/android-publisher/api-ref/rest/v3/purchases.products/get) or [`Purchases.subscriptionsv2:get`](https://developers.google.com/android-publisher/api-ref/rest/v3/purchases.subscriptionsv2/get) endpoints in the Google Play Developer API to verify with Google that the purchase is legitimate.\n4. If the purchase is legitimate and has not been used in the past, you can then safely grant entitlement to the in-app item or subscription.\n5. For subscriptions, when [`linkedPurchaseToken`](https://developers.google.com/android-publisher/api-ref/rest/v3/purchases.subscriptionsv2) is set in `Purchases.subscriptionsv2:get`, you should also remove the `linkedPurchaseToken` from your database and revoke the entitlement that is granted to the `linkedPurchaseToken` to ensure that multiple users are not entitled for the same purchase.\n6. You should grant entitlement only when the purchase state is `PURCHASED` and make sure to handle the `PENDING` purchases correctly. If there is a spike of `CANCELED` purchases, you may be granting entitlements when the purchase is still in `PENDING` state. You can find more information at [Handling pending transactions](/google/play/billing/integrate#pending).\n7. After granting entitlement, if you want to consume and acknowledge a\n consumable product, use the\n [`Purchases.products:consume`](https://developers.google.com/android-publisher/api-ref/rest/v3/purchases.products/consume)\n Play Developer API on your secure backend server.\n To acknowledge a non-consumable product or a subscription,\n call the relevant Play Developer API endpoint, either\n [`Purchases.products:acknowledge`](https://developers.google.com/android-publisher/api-ref/rest/v3/purchases.products/acknowledge)\n or\n [`Purchases.subscriptions:acknowledge`](https://developers.google.com/android-publisher/api-ref/rest/v3/purchases.subscriptions/acknowledge)\n on your secure backend server.\n Acknowledgment is required, as it notifies Google Play that the user has\n been granted entitlement to the purchase. You should acknowledge the\n purchase immediately after granting entitlement.\n\n Note that while you can acknowledge or consume the purchase on the client\n side through your app, server side APIs provide additional protection\n against issues like poor network connectivity and malicious activity. For\n example, consider if a user has purchased an item from your app but they\n lost network connectivity while the purchase was being validated. Without\n server acknowledgment, they might need to log back in through the app to\n complete the acknowledgement process. Otherwise, if the user does not log\n back in within three days, the purchase is automatically refunded due to\n lack of purchase acknowledgement. Server acknowledgment prevents this\n scenario by sending acknowledgment as soon as Google Play notifies the\n server that the purchase is valid.\n\n For more information about purchase acknowledgment and consumption, see\n [Processing purchases](https://developer.android.com/google/play/billing/integrate#process).\n\n| **Note:** Do not grant entitlement when the purchase state is `PENDING`.\n| **Note:** Do not use `orderId` to check for duplicate purchases or as a primary key in your database, as not all purchases are guaranteed to generate an `orderId`. In particular, purchases made with promo codes do not generate an `orderId`.\n\nProtecting your unlocked content\n--------------------------------\n\nTo prevent malicious users from redistributing your unlocked content, do not\nbundle it in your APK file. Instead, do one of the following:\n\n- Use a real-time service to deliver your content, such as a content feed. Delivering content through a real-time service also enables you to keep your content fresh.\n- Use a remote server to deliver your content.\n\nWhen you deliver content from a remote server or a real-time service, you can\nstore the unlocked content in device memory or store it on the device's SD card.\nIf you store content on an SD card, be sure to encrypt the content and use a\ndevice-specific encryption key.\n\nDetect and handle voided purchases\n----------------------------------\n\n*Voided purchases* are purchases that have been canceled, revoked, or\ncharged back. If a voided purchase had previously granted in-app items or other\ncontent to a user, you can use the\n[Voided Purchases API](https://developers.google.com/android-publisher/voided-purchases)\nto obtain the reason the purchase was voided along with any associated\ncontent that you can claw back.\n| **Note:** Voided purchases without any associated clawback content are not exposed by the Voided Purchases API.\n\nPurchases for in-app items and subscriptions can be voided for a variety of\nreasons, including the following:\n\n- A purchase is canceled, either by the user, by the developer, or by Google (including unacknowledged auto-canceled purchases). For subscriptions, note that this refers to canceling the *purchase* of a subscription, rather than [canceling the subscription itself](https://support.google.com/googleplay/answer/7018481?co=GENIE.Platform%3DAndroid).\n- A purchase is charged back.\n- The app developer cancels or refunds a user order and checks the \"revoke\" option in the console.\n\nBased on the reason for the voided purchase, and taking previous user\nbehavioral data into account, you can decide on a course of action. We recommend\nimplementing one or more of the following:\n\n- **Perform clawbacks:** When a purchase is voided, you can claw back unused items as if they were never purchased. For example, if an in-game currency purchase was voided, you could claw back currency that was already granted to the user. In the case where the user has already spent the currency, consider setting the currency balance to negative and limiting app activity and future purchases until the currency balance is positive.\n- **Multiple strikes implementation:** Consider taking less drastic actions for first-time offenders, such as displaying in-app warnings. For repeat offenders, consider more severe measures.\n- **Temporarily disable purchases:** Similar to the multiple strikes implementation, consider disabling purchases for users with voided purchases until you can more thoroughly investigate why the purchases were voided.\n- **Temporarily or permanently disallow access to your app:** For extreme cases with repeated malicious activity, consider disallowing access to your app, either temporarily or permanently.\n- **Make frequent calls to the Voided Purchases API:** When you detect one or more voided purchases, consider making more frequent calls to the Voided Purchases API to claw back purchases before the user can consume them. You can find more information on Voided Purchases API quotas in the [Voided Purchases API documentation](https://developers.google.com/android-publisher/voided-purchases#quotas).\n\nHelp Google detect fraud before it happens\n------------------------------------------\n\nSome types of fraud are related to malicious users who create multiple Google\nand in-app accounts to hide their activity.\n\nUse the\n[`setObfuscatedAccountId`](/reference/com/android/billingclient/api/BillingFlowParams.Builder#setObfuscatedAccountId(java.lang.String))\nand\n[`setObfuscatedProfileId`](/reference/com/android/billingclient/api/BillingFlowParams.Builder#setobfuscatedprofileid)\nmethods in the builder for\n[`BillingFlowParams`](/reference/com/android/billingclient/api/BillingFlowParams.Builder)\nto help Google map Google Accounts to in-app accounts.\n\nGoogle uses this data to detect suspicious behavior and block some types of fraudulent transactions before they are completed.\n\nTaking action against trademark and copyright infringement\n----------------------------------------------------------\n\nIf you are using a remote server to deliver or manage content, have your\napp verify the purchase state of the unlocked content whenever a user accesses\nthe content. This allows you to revoke use when necessary and minimize piracy.\nIf you see your content being redistributed on Google Play, be sure to act\nquickly and decisively. For more details, see the\n[Frequently Asked Copyright Questions](https://support.google.com/legal/answer/4558836)\npage in the Copyright Help Center."]]