با فروش محصولات دیجیتال با استفاده از Play Billing از بازی خود درآمد کسب کنید. SDK رابطهای برنامهنویسی کاربردی (API) را برای نمایش محصولات موجود برای خرید، راهاندازی جریان خرید و پردازش خریدها ارائه میدهد. فراخوانی این APIهای پرداخت با استفاده از حساب گوگلی که بازی را در داخل کلاینت Google Play Games راهاندازی کرده است، انجام میشود و نیازی به مراحل ورود اضافی ندارد.
اگر با کتابخانه Android Play Billing ادغام شده باشید، این APIهای Play Billing باید برایتان آشنا به نظر برسند. هرگونه ادغام سمت سرور با Play Billing میتواند توسط عناوین PC دوباره استفاده شود زیرا در هر دو سیستم عامل اندروید و PC یکسان هستند.
پیشنیازها
تنظیمات SDK را کامل کنید.
نمای کلی سیستم پرداخت گوگل پلی را مطالعه کنید.
تنظیمات کامل پرداخت در Play را انجام دهید.
مرحله 1 : جستجوی خریدهای قبلی و خریدهایی که خارج از درخواست شما انجام شدهاند
وقتی برنامه شما شروع به کار میکند یا وقتی دوباره وارد پیشزمینه میشود، خریدها را جستجو کنید. این کار برای تشخیص خریدهایی که خارج از بازی شما انجام شدهاند یا برای باز کردن قفل دسترسی به خریدهایی که قبلاً توسط کاربر انجام شده است، ضروری است.
با استفاده از
BillingClient::QueryPurchasesخریدها را جستجو کنید.با پردازش خریدها ادامه دهید.
// Query for purchases when:
// - Application starts up
// - Application window re-enters the foreground
auto promise = std::make_shared<std::promise<QueryPurchasesResult>>();
billing_client.QueryPurchases([promise](QueryPurchasesResult result) {
promise->set_value(std::move(result));
});
auto query_purchases_result = promise->get_future().get();
if (query_purchases_result.ok()) {
auto purchases = query_purchases_result.value().product_purchase_details;
// Process the purchases
} else {
// Handle the error
}
مرحله ۲ : نمایش محصولات موجود برای خرید
شما آمادهاید تا محصولات موجود خود را جستجو کرده و آنها را به کاربران خود نمایش دهید. جستجوی جزئیات محصول گامی مهم قبل از نمایش محصولات به کاربران است، زیرا اطلاعات محصول بومیسازی شده را برمیگرداند.
قبل از ارائه محصول برای فروش، بررسی کنید که کاربر از قبل مالک آن محصول نباشد. اگر کاربر کالای مصرفی دارد که هنوز در سابقه خرید او موجود است، قبل از اینکه بتواند دوباره آن محصول را خریداری کند، باید آن را مصرف کنید.
- با استفاده از
BillingClient::QueryProductDetailsجزئیات محصول را جستجو کنید. شناسههای محصولی را که در کنسول گوگل پلی ثبت کردهاید، وارد کنید. -
ProductDetailsکه شامل نام محلی و قیمت پیشنهادی محصول است را رندر کنید. - یک ارجاع به
offer_tokenمحصول نگه دارید. این برای راهاندازی جریان خرید برای پیشنهاد استفاده میشود.
QueryProductDetailsParams params;
params.product_ids.push_back({"example_costmetic_1", ProductType::kTypeInApp});
params.product_ids.push_back({"example_costmetic_1", ProductType::kTypeInApp});
params.product_ids.push_back({"example_battle_pass", ProductType::kTypeInApp});
auto promise = std::make_shared<std::promise<QueryProductDetailsResult>>();
billing_client.QueryProductDetails(params, [promise](QueryProductDetailsResult result) {
promise->set_value(std::move(result));
});
auto query_product_details_result = promise->get_future().get();
if (query_product_details_result.ok()) {
auto product_details = query_product_details_result.value().product_details;
// Display the available products and their offers to the user
} else {
// Handle the error
}
مرحله ۳ : راهاندازی جریان خرید
وقتی کاربر قصد خرید محصولی را نشان میدهد، به او نشان دادهاید که آمادهی شروع فرآیند خرید هستید.
- با فراخوانی
BillingClient::LaunchPurchaseFlow()شروع کنید.offer_tokenکه هنگام جستجوی جزئیات محصول به دست آمده است را به آن ارسال کنید. - پس از تکمیل خرید، تابع continue با نتیجه فراخوانی میشود.
- در صورت موفقیت، ادامه شامل جزئیات
ProductPurchaseDetailsمیشود. با پردازش خرید ادامه دهید.
LaunchPurchaseFlowParams params { product_offer.offer_token };
auto promise = std::make_shared<std::promise<LaunchPurchaseFlowResult>>();
billing_client.LaunchPurchaseFlow(params, [promise](LaunchPurchaseFlowResult result) {
promise->set_value(std::move(result));
});
// The purchase flow has started and is now in progress.
auto launch_purchase_flow_result = promise->get_future().get();
// The purchase flow has now completed.
if (launch_purchase_flow_result.ok()) {
auto purchase = launch_purchase_flow_result.value().product_purchase_details;
// Process the purchase
} else if (launch_purchase_flow_result.code() == BillingError::kUserCanceled) {
// Handle an error caused by the user canceling the purchase flow
} else {
// Handle any other error codes
}
مرحله ۴ : پردازش خرید
پردازش با یک سرور پشتیبان
برای بازیهایی که سرور بکاند دارند، پردازش را با ارسال purchase_token به سرور بکاند خود تکمیل کنید. بقیه پردازش را با استفاده از APIهای Play Billing سمت سرور انجام دهید. این ادغام سمت سرور همان کاری است که برای یک بازی اندروید که با Play Billing ادغام شده است، انجام میشود.
void ProcessPurchasesWithServer(std::vector<ProductPurchaseDetails> purchases) {
std::vector<std::string> purchase_tokens;
for (const auto& purchase : purchases) {
purchase_tokens.push_back(purchase.purchase_token);
}
// Send purchase tokens to backend server for processing
}
فرآیند بدون سرور پشتیبان
با بررسی گزینهی
ProductPurchaseDetails::purchase_stateisPurchaseState::kPurchaseStatePurchased، مطمئن شوید که پرداخت کاربر در حال انتظار نیست. اگر وضعیت خرید در حال انتظار است، به کاربر اطلاع دهید که قبل از دریافت محصول خریداری شده، باید مراحل دیگری را انجام دهد.به کاربر دسترسی به محصول خریداری شده را اعطا کنید و فضای ذخیرهسازی حق استفاده از بازی خود را بهروزرسانی کنید.
برای خریدهای غیرمصرفی (محصولاتی که فقط یک بار میتوان آنها را خریداری کرد) با استفاده از
ProductPurchaseDetails::is_acknowledgedبررسی کنید که آیا خرید قبلاً تأیید شده است یا خیر.- اگر خرید تأیید نشده است، با فراخوانی
BillingClient::AcknowledgePurchaseبه گوگل اطلاع دهید که به کاربر حق استفاده از محصول اعطا شده است.
- اگر خرید تأیید نشده است، با فراخوانی
برای خریدهای مصرفی (محصولاتی که ممکن است بیش از یک بار خریداری شوند) با فراخوانی
BillingClient::ConsumePurchaseبه گوگل اطلاع دهید که به کاربر حق استفاده از محصول اعطا شده است.
void ProcessPurchasesWithoutServer(std::vector<ProductPurchaseDetails> purchases) {
std::vector<std::string> entitled_product_ids;
for (const auto& purchase : purchases) {
auto was_successful = ProcessPurchasePurchaseWithoutServer(purchase);
if (was_successful) {
entitled_product_ids.push_back(purchase.product_id);
}
}
// Note that non-consumable products that were previously purchased may have
// been refunded. These purchases will stop being returned by
// `QueryPurchases()`. If your game has given a user access to one of these
// products storage they should be revoked.
//
// ...
}
bool ProcessPurchasePurchaseWithoutServer(ProductPurchaseDetails purchase) {
auto is_purchase_completed =
purchase.purchase_state == PurchaseState::kPurchaseStatePurchased;
if (!is_purchase_completed) {
// Notify the user that they need to take additional steps to complete
// this purchase.
return false;
}
// Determine if the product ID is associated with a consumable product.
auto is_consumable = IsConsumableProductId(purchase.product_id);
if (is_consumable) {
// Grant an entitlement to the product to the user.
// ...
// Then, notify Google by consuming the purchase.
ConsumePurchaseParams params { purchase.purchase_token };
auto promise = std::make_shared<std::promise<ConsumePurchaseResult>>();
billing_client.ConsumePurchase(params, [promise](ConsumePurchaseResult result) {
promise->set_value(std::move(result));
});
auto consume_purchase_result = promise->get_future().get();
if (!consume_purchase_result.ok()) {
// Examine the failure code & message for more details & notify user
// of failure.
// ...
return false;
}
return true;
}
// Otherwise the product is assumed to be a non-consumable.
// Grant an entitlement to the product to the user.
// ...
// Then, notify Google by acknowledging the purchase (if not already done).
if (purchase.is_acknowledged) {
return true;
}
AcknowledgePurchaseParams params { purchase.purchase_token };
auto promise = std::make_shared<std::promise<AcknowledgePurchaseResult>>();
billing_client.AcknowledgePurchase(params, [promise](AcknowledgePurchaseResult result) {
promise->set_value(std::move(result));
});
auto acknowledge_purchase_result = promise->get_future().get();
if (!acknowledge_purchase_result.ok()) {
// Examine the failure code & message for more details & notify user
// of failure.
// ...
return false;
}
return true;
}
مرحله ۵ : یکپارچهسازی خود را آزمایش کنید
اکنون آمادهاید تا ادغام خود را با Play Billing آزمایش کنید. برای آزمایش در طول مرحله توسعه، توصیه میکنیم از آزمایشکنندگان مجوز استفاده کنید. آزمایشکنندگان مجوز به پرداختهای آزمایشی دسترسی دارند که از دریافت پول واقعی برای خریدها جلوگیری میکند.
برای راهنمایی در مورد نحوه تنظیم آزمایشکنندگان مجوز و مجموعهای از آزمایشهای دستی، توصیه میکنیم به مستندات مربوط به نحوه آزمایش ادغام کتابخانه صورتحساب Google Play خود مراجعه کنید.