اگر PWA شما در گوگل پلی فهرست شده است و میخواهید با فروش محصولات درونبرنامهای یا اشتراکها از آن کسب درآمد کنید، سیاست Play شما را ملزم به پیادهسازی Play Billing میکند. دو API وجود دارد که باید در PWA خود پیادهسازی کنید: API کالاهای دیجیتال و API درخواست پرداخت .
رابط برنامهنویسی کاربردی کالاهای دیجیتال
رابط برنامهنویسی کاربردی کالاهای دیجیتال (Digital Goods API) رابطی بین برنامه شما و گوگل پلی است. این رابط به شما امکان میدهد محصولات دیجیتال و جزئیاتی را که برای محصولات درونبرنامهای و اشتراکهای خود در کنسول پلی وارد کردهاید، و همچنین خریدهای فعلی کاربر را بازیابی کنید. اگر هنوز محصولات درونبرنامهای یا اشتراکها را در کنسول پلی اضافه نکردهاید، حتماً تنظیمات کنسول پلی را برای پرداخت در پلی (Play Billing) دنبال کنید.
در تاریخ 30 نوامبر 2021، ChromeOS 96 با پیادهسازی Digital Goods API 2.0 منتشر شد.
دوره آزمایشی اولیه برای اولین نسخه از رابط برنامهنویسی کاربردی کالاهای دیجیتال در تاریخ 30 ژانویه 2022 به پایان رسید. بنابراین، اکنون منسوخ شده و فقط نسخه 2 این رابط در دسترس است.
در ۲۳ ژوئن ۲۰۲۲، ChromeOS 103 با پیادهسازی Digital Goods API 2.1 منتشر شد. این نسخه هیچ تغییر مهمی ندارد و فقط شامل متدهای جدید و فیلدهای اضافی است: listPurchaseHistory() و itemType .
برای دوره آزمایشی Origin ثبت نام کنید
توجه: API کالاهای دیجیتال در حال حاضر از طریق نسخه آزمایشی Origin در دسترس است - مکانیسمی که به توسعهدهندگان امکان دسترسی زودهنگام به APIهای وب جدید را میدهد. شما باید برای نسخه آزمایشی Origin API نسخه ۲ کالاهای دیجیتال ثبت نام کنید و یک توکن درخواست کنید که باید آن را در هر صفحهای در Origin خود ارائه دهید .
هنگام ثبت نام برای دوره آزمایشی Origin، یک تاریخ «معتبر تا» مشاهده خواهید کرد که نشان میدهد توکن شما تا چه زمانی کار خواهد کرد. به یاد داشته باشید که برای ادامه شرکت در دوره آزمایشی، با نزدیک شدن به آن تاریخ، توکنهای خود را تمدید کنید. APIهای ارائه شده به عنوان دوره آزمایشی Origin ممکن است تغییر کنند، بنابراین حتماً از آخرین تغییرات در هر دوره آزمایشی Origin که در آن شرکت میکنید، مطلع باشید. در صورت بروز هرگونه مشکل، به مستندات API کالاهای دیجیتال مراجعه کنید.
رابط برنامهنویسی کاربردی درخواست پرداخت
API درخواست پرداخت، تراکنش پرداخت واقعی را هنگام انجام خرید مدیریت میکند. این API از جزئیات کالایی که API کالاهای دیجیتال ارائه میدهد برای انجام خرید درونبرنامهای با استفاده از روش پرداخت مناسب، که در مورد ما Google Play Billing است، استفاده میکند.
قابلیت تشخیص API کالاهای دیجیتال
شما میتوانید با بررسی متد getDigitalGoodsService در شیء window ، از طریق نسخه آزمایشی origin، تشخیص دهید که آیا API را به درستی در وبسایت خود فعال کردهاید یا خیر.
if ('getDigitalGoodsService' in window) { // Digital Goods API is supported! } else { console.log('DigitalGoodsService is not available.'); // Use another payment method }
اتصال به سرویس پرداخت گوگل پلی
رابط برنامهنویسی کاربردی کالاهای دیجیتال (Digital Goods API) به گونهای طراحی شده است که با مرورگرها و فروشگاههای دیجیتال مختلف سازگار باشد، مشابه نحوهی عملکرد رابط برنامهنویسی کاربردی درخواست پرداخت (Payment Request API) که مستقل از مرورگر است و میتواند با ارائهدهندگان پرداخت مختلف مورد استفاده قرار گیرد. برای دریافت نمونهای از سرویس مرتبط با Google Play Billing، رشتهی "https://play.google.com/billing" را به عنوان روش پرداخت به getDigitalGoodsService() ارسال کنید.
اگر این روش خطا بدهد، روش پرداخت صورتحساب گوگل پلی در دسترس نیست (مثلاً کاربر از طریق مرورگر به PWA شما دسترسی دارد). در عوض، باید روش پرداخت دیگری برای تراکنشها ارائه دهید.
if ('getDigitalGoodsService' in window) { // Digital Goods API is supported! try { const service = await window.getDigitalGoodsService('https://play.google.com/billing'); // Google Play Billing service is available } catch (error) { // Google Play Billing service is not available. Use another payment flow. } }
جزئیات کالا را دریافت کنید
پس از اتصال سرویس کالاهای دیجیتال به گوگل پلی، میتوانید از API برای بازیابی اطلاعات مربوط به محصولات و خریدها استفاده کنید.
متد getDetails() به شما امکان میدهد اطلاعاتی در مورد مواردی که در کنسول Play تنظیم کردهاید، دریافت کنید. اطلاعاتی مانند عنوان محصول، توضیحات و قیمت باید در رابط کاربری برنامه شما به کاربر نمایش داده شود تا بداند چه چیزی برای خرید و با چه قیمتی در دسترس است.
متد getDetails() به فهرستی از شناسههای آیتم نیاز دارد که با شناسههای محصول محصولات درونبرنامهای و اشتراکهایی که در کنسول Play ایجاد کردهاید، مطابقت داشته باشند.
const itemDetails = await service.getDetails(['product_1', 'product_2', 'product_3']); for (const item of itemDetails) { // Display item information to user displayItem(item.title, item.description, item.price); }
برای دریافت قیمت مناسب برای زبان کاربر، باید قالببندیهای بیشتری انجام دهید:
const localePrice = new Intl.NumberFormat(navigator.language, { style: 'currency', currency: item.price.currency, }).format(item.price.value);
توجه: API کالاهای دیجیتال روشی برای دریافت لیستی از شناسههای کالا در اختیار شما قرار نمیدهد. در عوض، یا باید آنها را به صورت کدنویسی شده در کلاینت خود قرار دهید یا از سرور بکاند خود دریافت کنید. API توسعهدهندگان گوگل پلی به شما امکان میدهد لیست شناسههای کالا را از بکاند جستجو کنید . (درباره پیادهسازی اجزای کلیدی Play Billing در سرور بکاند خود بیشتر بدانید. هر راهحلی را که انتخاب میکنید، مطمئن شوید که شناسههای کالا با آنچه در کنسول پلی دارید، سازگار باشد.)
در نسخه ۲.۱ این API، یکی از فیلدهایی که توسط getDetails() برگردانده میشود، itemType است. این یک enum است که مقدار آن ”product” یا ”subscription” است تا مشخص کند که آیا آیتم مربوطه به ترتیب یک محصول درونبرنامهای است یا یک اشتراک. توانایی تمایز بین دو نوع محصول میتواند مفید باشد اگر نیاز به اعمال روشهای مختلف برای هر نوع محصول داشته باشید. به عنوان مثال، ممکن است یک صفحه خاص برای اشتراک کاربران و صفحه دیگری برای سایر محصولات غیر اشتراکی داشته باشید. همچنین برای دانستن منبع مناسب API REST توسعهدهنده Google Play برای استفاده در backend شما ( purchases.products یا purchases.subscriptions ) مفید است.
خرید یک کالا
پس از نمایش محصولات و جزئیات آنها به کاربر، میتوانید جریان خرید را با API درخواست پرداخت ایجاد کنید. هنگام استفاده از آن در کنار API کالاهای دیجیتال، فقط یک پارامتر ورودی مورد نیاز است: methodData .
پرداخت در بازی فقط امکان خرید یک کالا را در یک زمان فراهم میکند؛ قیمت و جزئیات کالا از قبل توسط سرور بازی مشخص است، بنابراین پارامتر details ضروری نیست. برای توضیحات بیشتر به توضیحدهنده مراجعه کنید.
از عضو supportedMethods از پارامتر methodData در PaymentRequest برای شناسایی Google Play Billing به عنوان روش پرداخت با رشته "https://play.google.com/billing" استفاده کنید. سپس در عضو data ، شناسه کالا را به عنوان sku ارسال کنید.
const paymentMethodData = [ { supportedMethods: 'https://play.google.com/billing', data: { sku: item.itemId, }, }, ];
سپس درخواست پرداخت را ایجاد کرده و برای شروع جریان پرداخت، تابع show() را فراخوانی کنید:
const request = new PaymentRequest(paymentMethodData); const paymentResponse = await request.show();
این کار رابط کاربری خرید Play را به کاربر نمایش میدهد، جایی که جزئیات مربوط به محصولی که قصد خرید آن را دارد، مشاهده میکند. کاربر میتواند تراکنش را رها کند یا به پرداخت ادامه دهد. اگر کاربر پرداخت را لغو کند، promise برگردانده شده توسط show() با خطا رد میشود. اگر با موفقیت پرداخت کند و خرید را تکمیل کند، promise با یک PaymentResponse حل میشود. در ویژگی details پاسخ پرداخت، یک توکن خرید برگردانده میشود.
برای جلوگیری از کلاهبرداری، تأیید خرید و توکن خرید در سرور back-end شما بسیار مهم است. همچنین ایده خوبی است که کاربران و توکنهای خرید مرتبط با آنها را پیگیری کنید. یاد بگیرید که چگونه تأیید را در سرور back-end خود پیادهسازی کنید .
پس از تأیید خرید، تابع complete() را در پاسخ پرداخت فراخوانی کنید تا جریان پرداخت تکمیل شود و رابط کاربری صورتحساب بسته شود. همچنین میتوانید یک رشته result اختیاری برای نشان دادن وضعیت فرآیند پرداخت ارسال کنید. این به مرورگر بستگی دارد که آیا نشانهای از این نتیجه را به کاربر ارائه دهد یا خیر. کروم هیچ نشانه قابل مشاهدهای برای کاربر ایجاد نمیکند، بنابراین توصیه میشود پیامهای خطا یا موفقیت خود را در PWA خود نمایش دهید.
/* Changes were recently made so that the PaymentResponse `details` property returns the purchase token as `purchaseToken` instead of `token`. Note that `token` will be deprecated at some point in the future. To ensure that your app won't be affected by this, make the change to `purchaseToken` in your client code and use the latest version of Bubblewrap (v1.13.5 and later) to update and generate a new app package to upload to the Play Console. */ const { purchaseToken } = paymentResponse.details; let paymentComplete; if (validatePurchaseOnBackend(purchaseToken)) { paymentComplete = await paymentResponse.complete('success'); // Let user know their purchase transaction has successfully completed and been verified } else { paymentComplete = await paymentResponse.complete('fail'); // Let user know their purchase transaction failed to verify }
ارتقاء و تنزل اشتراک
این جریان خرید برای محصولات درونبرنامهای و خریدهای اشتراکی یکسان است. با این حال، برای اشتراکها، گوگل پلی گزینههای خرید دیگری نیز دارد که میتوانید پیادهسازی کنید: ارتقا و تنزل رتبه. هنگام ساخت data برای روش پرداخت، برای شروع جریان ارتقا یا تنزل رتبه، باید موارد زیر را ارسال کنید:
-
sku: این شناسهی آیتم برای اشتراک جدید است که قرار است به آن ارتقا یا تنزل یابد. -
oldSku: این شناسهی آیتم برای اشتراک فعلی کاربر است. -
purchaseToken: این توکن خرید برای اشتراک فعلی کاربر است. همانطور که قبلاً اشاره شد، ایده خوبی است که توکنهای خرید را در backend خود پیگیری کنید. و برای این سناریو و سناریوهای دیگر، باید یک کاربر را به خریدهای فعلی و توکنهای خرید او نیز مرتبط کنید. -
prorationMode: نحوهی محاسبهی هزینهی اشتراک جدید هنگام جایگزینی با اشتراک فعلی کاربر به این صورت است.
| حالت تکثیر | توضیحات |
|---|---|
قیمت فوری و متناسب با قیمت | اشتراک بلافاصله ارتقا مییابد و چرخه صورتحساب ثابت میماند. سپس مابهالتفاوت قیمت برای دوره باقیمانده از کاربر دریافت میشود. |
فوری وشارژقیمت کامل | اشتراک ارتقا یا کاهش مییابد و بلافاصله هزینه کامل اشتراک جدید از کاربر دریافت میشود. مبلغ باقیمانده از اشتراک قبلی به نسبت زمان به اشتراک جدید محاسبه میشود. این حالت تناسب اخیراً در نسخه ۴.۰ کتابخانه صورتحساب گوگل پلی اضافه شده است. اکنون از طریق Bubblewrap و از نسخه ۱.۱۳.۵ به بعد در دسترس است. |
فوریبدون نیاز به پرداخت | غیرفعال موقت با این حالت سهمیهبندی، یک مسیر کلاهبرداری بالقوه وجود دارد که در آن کاربران میتوانند اشتراک ارتقا یافته را بدون پرداخت هزینه اضافی برای یک چرخه صورتحساب دریافت کنند. لطفاً توجه داشته باشید که ما این حالت را به طور موقت غیرفعال کردهایم تا زمانی که روی رفع مشکل کار میکنیم. |
فوریWithTimeProration | اشتراک بلافاصله ارتقا یا کاهش مییابد. زمان باقیمانده بر اساس اختلاف قیمت تنظیم میشود و با جلو بردن تاریخ صورتحساب بعدی، به اشتراک جدید اضافه میشود. این رفتار پیشفرض است. |
به تعویق افتاده | اشتراک فقط زمانی ارتقا یا تنزل مییابد که اشتراک تمدید شود. این امر به ویژه برای تنزل رتبهها مفید است. |
سیاست اشتراکناشناسارتقاتنسلتحریف | هیچ سیاست مشخصی وجود ندارد. این توصیه نمیشود. |
برای کسب اطلاعات بیشتر در مورد حالتهای مختلف تقسیمبندی، به مستندات مرجع کتابخانه پرداخت گوگل پلی مراجعه کنید. برای اطلاعات بیشتر در مورد ارتقاء و کاهش اشتراک و توصیههای حالت تقسیمبندی، به مستندات توسعهدهندگان اندروید مراجعه کنید.
نحوهی استفاده از این فیلدهای اضافی چیزی شبیه به این خواهد بود:
const paymentMethod = [ { supportedMethods: 'https://play.google.com/billing', data: { sku: item.itemId, oldSku: oldPurchase.itemId, purchaseToken: oldPurchase.purchaseToken, prorationMode: 'immediateAndChargeProratedPrice', }, }, ];
در اینجا، item مربوط به ItemDetails اشتراک جدیدی است که کاربر سعی در ارتقا یا تنزل به آن دارد، و oldPurchase مربوط به PurchaseDetails اشتراک فعلی کاربر است.
تایید خرید
پس از اینکه کاربر یک کالا را خریداری کرد، باید به او حقوق مناسب (دسترسی به کالا یا محتوایی که اخیراً خریداری کرده است) را اعطا کنید. سپس، خرید را تأیید کنید. تأیید خرید به Google Play این امکان را میدهد که بداند شما خرید را به درستی دریافت و پردازش کردهاید.
توجه: اگر خریدی ظرف ۷۲ ساعت از زمان خرید تأیید نشود، وجه به کاربر بازپرداخت شده و خرید لغو میشود. توکن خرید دیگر معتبر نخواهد بود، بنابراین وقتی برای خریدهای موجود درخواست میدهید، خرید لغو شده بازگردانده نمیشود. این امر تضمین میکند که در صورت بروز خطای شبکه که باعث میشود حق استفاده از کالای مورد نظر به کاربر داده نشود، هزینه به طور نامناسب از کاربر کسر نمیشود.
شما باید خریدها را از سرور بکاند خود با استفاده از API توسعهدهندگان گوگل پلی تأیید کنید. توصیه میکنیم ابتدا مجوزهای لازم را اعطا کنید و سپس خرید را با هم در سرور بکاند خود تأیید کنید.
- پس از اینکه کاربر خریدی را در سمت کلاینت انجام داد، توکن خرید و شناسه کالا را در یک درخواست به سرور بکاند خود ارسال کنید.
- در پشت صحنه، برای دریافت جزئیات خرید و تأیید آن، با شماره زیر تماس بگیرید:
- purchases.products.get برای موارد درون برنامهای.
- purchases.subscriptions.get برای اشتراکها.
- مجوز مناسب را در پایگاه داده backend خود اعطا کنید.
- سپس با تماس با شماره زیر، خرید را تایید کنید:
- purchases.products.acknowledge برای موارد درون برنامهای.
- purchases.subscriptions.acknowledge برای اشتراکها.
خرید را مصرف کنید
وقتی خریدی را تأیید میکنید، به گوگل پلی اطلاع میدهید که کاربر اکنون مالک آن کالا است و نباید اجازه خرید مجدد آن را داشته باشد. اگر این کالایی باشد که کاربر فقط یک بار نیاز به خرید آن دارد و برای همیشه مالک آن خواهد بود (مثلاً پوسته شخصیت بازی)، آن کالا قابل مصرف نیست.
از طرف دیگر، ممکن است کالا چیزی باشد که شما کاربر را به خرید یکی از آنها در یک زمان محدود کنید. در این صورت، کاربر قبل از اینکه بتواند کالای دیگری را خریداری کند، باید از آن کالا استفاده کند. وقتی کاربر از کالا «استفاده» میکند، برای اینکه به گوگل پلی اطلاع دهد که کاربر کالا را مصرف کرده است، باید متد consume() را فراخوانی کنید. سپس گوگل پلی کالا را برای خرید مجدد کاربر در دسترس قرار میدهد.
برای اقلامی که به کاربر اجازه میدهید چندین برابر از آنها را داشته باشد، باید بتوان آنها را بدون نیاز به استفاده اولیه، بارها خریداری کرد (ما به این اقلام، اقلام تکرارپذیر میگوییم). به طور مشابه، این اقلام باید قبل از اینکه گوگل پلی به کاربر اجازه خرید مجدد آن را بدهد، "مصرف" شوند. بنابراین، حتی اگر کاربر هنوز از آن کالا استفاده نکرده باشد، باید متد consume() را برای علامتگذاری کالا به عنوان مصرفشده فراخوانی کنید.
// After the user purchases the item, send the purchase token and item ID to your backend to grant the entitlement and acknowledge it right away . . . // When the user uses the item or if it is a repeatable item, consume it so it’s available for purchase again. service.consume(purchaseToken); }
بررسی خریدهای موجود
آخرین جریان کلیدی کاربر، بررسی خریدهای موجود (محصولات درونبرنامهای که هنوز مصرف نشدهاند و اشتراکهای در حال انجام) است تا به کاربران خود اطلاع دهید که در حال حاضر چه اشتراک یا اقلامی را در اختیار دارند. این خریدهای موجود از خریدهای قبلی گوگل پلی در هر دستگاهی که از داخل برنامه یا در فروشگاه پلی انجام شده باشد، خواهد بود. خریدهایی که از خارج از برنامه در فروشگاه پلی انجام میشوند، خریدهای خارج از برنامه نامیده میشوند.
هنگام بازیابی خریدهای موجود، باید وضعیت تأیید را نیز بررسی کنید و خریدهایی را که قبلاً انجام شده اما به درستی تأیید نشدهاند، تأیید کنید. توصیه میشود خریدها در اسرع وقت تأیید شوند تا حقوق کاربر بهروز بوده و به درستی در برنامه منعکس شود.
متد listPurchases() از API کالاهای دیجیتال، فهرستی از PurchaseDetails را برمیگرداند که شامل itemId و purchaseToken برای هر یک از خریدها است. شما باید از Google Play Developer API در سرور backend خود برای بررسی وضعیت خریدها و تأیید مناسب آنها استفاده کنید. شما باید:
- برای بازیابی لیست خریدهای کاربر، متد
listPurchases()از API کالاهای دیجیتال را در سمت کلاینت فراخوانی کنید. - برای هر خرید،
purchaseTokenوitemIdبه backend خود ارسال کنید. - در صورت لزوم، در پایگاه داده backend خود، مجوز دسترسی اعطا کنید.
- سپس فراخوانی کنید: و
acknowledgementStateرا بررسی کنید.- purchases.products.get برای موارد درون برنامهای.
- purchases.subscriptions.get برای اشتراکها.
- اگر مقدار 0 است (هنوز تأیید نشده است)، سپس تماس بگیرید:
- purchases.products.acknowledge برای موارد درون برنامهای.
- purchases.subscriptions.acknowledge برای اشتراکها.
قبل از اعطای مجوز، درباره نحوه تأیید خریدها در سرور پشتیبان خود بیشتر بدانید.
سابقه خرید
در حالی که listPurchases اطلاعات مربوط به خریدهای فعلی کاربر را برمیگرداند، متد listPurchaseHistory() (در نسخه ۲.۱ API) جدیدترین خرید انجام شده توسط کاربر را برای هر کالا، صرف نظر از اینکه خرید منقضی، لغو شده یا مصرف شده باشد، برمیگرداند. متد listPurchaseHistory() لیستی از PurchaseDetails حاوی itemId و purchaseToken برای هر خرید برمیگرداند که برای بازیابی اطلاعات بیشتر باید از آن به همراه Google Play Developer API در سرور backend خود استفاده کنید.
خریدهای خارج از برنامه
خریدهای خارج از برنامه، خریدهایی هستند که در جریان معمول خرید درون برنامهای انجام نمیشوند. این خریدها معمولاً به جای برنامه شما، در فروشگاه Play انجام میشوند. دو روش اصلی وجود دارد که کاربران میتوانند خرید خارج از برنامه انجام دهند:
- استفاده از کد تخفیف : در منوی کاربری فروشگاه پلی استور، در بخش «پیشنهادات و اعلانها» -> «استفاده از کد تخفیف» یا در بخش «پرداختها و اشتراکها» -> «استفاده از کد هدیه» .
- اشتراک مجدد : در منوی کاربری فروشگاه Play، در «پرداختها و اشتراکها» -> «اشتراکها» . در اینجا، کاربران میتوانند تمام اشتراکهای خود را در برنامههای مختلف مدیریت کنند. برای اشتراکهای منقضی شده یا لغو شده، کاربران میتوانند «اشتراک مجدد» را انتخاب کنند.
وقتی کاربران دوباره در فروشگاه Play مشترک میشوند، خریدهای آنها به طور خودکار تأیید نمیشود که ممکن است منجر به بازپرداخت وجه آنها شود. این رفتار عمدی است زیرا کاربران فقط در صورتی که برنامه را برای استفاده باز کنند، باید هزینه اشتراک خود را پرداخت کنند. کاربر ممکن است عبارت «تأیید اشتراک» را مشاهده کند که به او یادآوری میکند برنامه را باز کند.

به عنوان توسعهدهنده، پیادهسازی تأیید این موارد پس از راهاندازی برنامه توسط کاربر، به شما بستگی دارد. به همین دلیل توصیه میکنیم خریدهای موجود را بررسی کنید (معمولاً هنگام راهاندازی اولیه برنامه) و خریدهایی را که هنوز تأیید نشدهاند، تأیید کنید.
به کاربران اجازه دهید اشتراکها را مدیریت کنند
برای یک تجربه کاربری خوب، ارائه راهی برای کاربران جهت مدیریت و لغو اشتراکهایشان در برنامه بسیار مهم است. توصیه میکنیم یک لینک عمیق (deep link) در صفحه تنظیمات یا منو ایجاد کنید که کاربر را به صفحه مدیریت اشتراک برنامه شما در فروشگاه Play هدایت کند. آدرس اینترنتی (url) زیر را با "sub-product-id" و "app-package-name" مناسب خود جایگزین کنید:
https://play.google.com/store/account/subscriptions?sku=sub-product-id&package=app-package-nameمراحل بعدی
این جریانهای کاربری و قطعه کدهای مربوطه، پیادهسازی اولیهای برای نشان دادن نحوه استفاده از API کالاهای دیجیتال و API درخواست پرداخت در PWA شما برای پیادهسازی Play Billing هستند. شما باید از APIها به گونهای استفاده کنید که در زمینه و موارد استفاده برنامه شما منطقی به نظر برسند. برای مثالی از پیادهسازی سرتاسری، نمونه متنباز ما را بررسی کنید.
سپس، نگاهی به نحوه پیادهسازی اجزای حیاتی Play Billing در سرور back-end خود بیندازید تا برنامه شما ایمن و همیشه با حقوق کاربر بهروز باشد.