สร้างรายได้จากเกมด้วยการขายไอเทมดิจิทัลโดยใช้ Play Billing SDK มี API เพื่อแสดงผลิตภัณฑ์ที่พร้อมจำหน่าย เปิดใช้งานขั้นตอนการซื้อ และประมวลผลการซื้อ การเรียก API การเรียกเก็บเงินเหล่านี้จะดำเนินการโดยใช้บัญชี Google ที่เปิดเกมภายในไคลเอ็นต์ Google Play Games และไม่จําเป็นต้องลงชื่อเข้าใช้เพิ่มเติม
หากคุณผสานรวมกับไลบรารีการเรียกเก็บเงินของ Android Play API การเรียกเก็บเงินของ Play เหล่านี้จะดูคุ้นเคย เกมบน PC สามารถนำการผสานรวมฝั่งเซิร์ฟเวอร์กับ Play Billing มาใช้ซ้ำได้ เนื่องจากทั้ง Android และ PC ใช้การผสานรวมเดียวกัน
สิ่งที่ต้องมีก่อน
ตั้งค่า SDK ให้เสร็จสมบูรณ์
อ่านภาพรวมของระบบการเรียกเก็บเงินของ Google Play
ตั้งค่าการเรียกเก็บเงินของ 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
}
ขั้นตอนที่ 2: แสดงผลิตภัณฑ์ที่พร้อมจำหน่าย
คุณพร้อมที่จะค้นหาผลิตภัณฑ์ที่พร้อมจำหน่ายและแสดงต่อผู้ใช้แล้ว การค้นหารายละเอียดผลิตภัณฑ์เป็นขั้นตอนสำคัญก่อนแสดงผลิตภัณฑ์ต่อผู้ใช้ เนื่องจากจะแสดงข้อมูลผลิตภัณฑ์ที่แปลแล้ว
ก่อนเสนอผลิตภัณฑ์เพื่อขาย ให้ตรวจสอบว่าผู้ใช้ไม่ได้เป็นเจ้าของผลิตภัณฑ์นั้นอยู่แล้ว หากผู้ใช้มีสินค้าที่บริโภคได้ซึ่งยังอยู่ในประวัติการซื้อ คุณต้องบริโภคผลิตภัณฑ์ดังกล่าวก่อนผู้ใช้จะซื้อผลิตภัณฑ์นั้นอีกครั้งได้
- ค้นหารายละเอียดผลิตภัณฑ์โดยใช้
BillingClient::QueryProductDetails
ส่งรหัสผลิตภัณฑ์ที่คุณลงทะเบียนไว้ใน Google Play Console - แสดงผล
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
}
ขั้นตอนที่ 3: เปิดใช้งานขั้นตอนการซื้อ
เมื่อผู้ใช้แสดงเจตนาที่จะซื้อผลิตภัณฑ์ที่คุณแสดงให้ผู้ใช้เห็น แสดงว่าคุณพร้อมที่จะเปิดใช้งานขั้นตอนการซื้อ
- เริ่มต้นด้วยการโทรไปที่
BillingClient::LaunchPurchaseFlow()
ส่งoffer_token
ที่ได้รับเมื่อค้นหารายละเอียดผลิตภัณฑ์ - เมื่อการซื้อเสร็จสมบูรณ์ ระบบจะเรียกใช้ฟังก์ชันการดำเนินการต่อพร้อมผลลัพธ์
- หากดำเนินการสำเร็จ การดําเนินการต่อจะมี
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
}
ขั้นตอนที่ 4: ดำเนินการซื้อ
ประมวลผลด้วยเซิร์ฟเวอร์แบ็กเอนด์
สำหรับเกมที่มีเซิร์ฟเวอร์แบ็กเอนด์ ให้ดำเนินการประมวลผลให้เสร็จสมบูรณ์โดยส่ง purchase_token
ไปยังเซิร์ฟเวอร์แบ็กเอนด์ ทําการประมวลผลที่เหลือโดยใช้ Play Billing API ฝั่งเซิร์ฟเวอร์ การผสานรวมฝั่งเซิร์ฟเวอร์นี้เหมือนกับการผสานรวมสำหรับเกม Android ที่ผสานรวมกับ 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_state
เป็นPurchaseState::kPurchaseStatePurchased
หากสถานะการซื้ออยู่ระหว่างรอดำเนินการ โปรดแจ้งให้ผู้ใช้ทราบว่าต้องดำเนินการตามขั้นตอนเพิ่มเติมให้เสร็จสมบูรณ์ก่อนจึงจะได้รับผลิตภัณฑ์ที่ซื้อให้สิทธิ์ผู้ใช้เข้าถึงผลิตภัณฑ์ที่ซื้อและอัปเดตพื้นที่เก็บข้อมูลการให้สิทธิ์ของเกม
สำหรับการซื้อที่บริโภคไม่ได้ (ผลิตภัณฑ์ที่ซื้อได้เพียงครั้งเดียว) ให้ตรวจสอบว่ามีการยอมรับการซื้อแล้วโดยใช้
ProductPurchaseDetails::is_acknowledged
หรือไม่- หากยังไม่มีการยอมรับการซื้อ โปรดแจ้งให้ Google ทราบว่าผู้ใช้ได้รับสิทธิ์ใช้ผลิตภัณฑ์แล้วโดยโทรไปที่
BillingClient::AcknowledgePurchase
- หากยังไม่มีการยอมรับการซื้อ โปรดแจ้งให้ Google ทราบว่าผู้ใช้ได้รับสิทธิ์ใช้ผลิตภัณฑ์แล้วโดยโทรไปที่
สำหรับการซื้อสินค้าที่ใช้แล้วหมดไป (ผลิตภัณฑ์ที่ซื้อได้มากกว่า 1 ครั้ง) ให้แจ้ง Google ว่าผู้ใช้ได้รับสิทธิ์ในผลิตภัณฑ์แล้วโดยโทรไปที่
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;
}
ขั้นตอนที่ 5: ทดสอบการผสานรวม
ตอนนี้คุณพร้อมที่จะทดสอบการผสานรวมกับ Play Billing แล้ว หากต้องการทดสอบในขั้นตอนการพัฒนา เราขอแนะนำให้ใช้ผู้ทดสอบที่ได้รับอนุญาต ผู้ทดสอบใบอนุญาตจะมีสิทธิ์เข้าถึงการชําระเงินทดสอบที่จะไม่เรียกเก็บเงินจริงสําหรับการซื้อ
โปรดดูวิธีการตั้งค่าผู้ทดสอบใบอนุญาตและชุดการทดสอบด้วยตนเองในเอกสารประกอบเกี่ยวกับวิธีทดสอบการผสานรวม Google Play Billing Library