Nhận Khoản thanh toán qua Google Play Billing bằng API Hàng hoá kỹ thuật số và API Yêu cầu thanh toán

André Cipriani Bandarra
André Cipriani Bandarra

Nếu ứng dụng của bạn được phân phối thông qua Google Play và muốn bán hàng hoá kỹ thuật số hoặc cung cấp gói thuê bao, bạn phải sử dụng dịch vụ Google Play Billing. Google Play Billing cung cấp các công cụ để quản lý danh mục, giá và gói thuê bao, các báo cáo hữu ích và quy trình thanh toán do Cửa hàng Play cung cấp đã quen thuộc với người dùng của bạn.

Đối với các ứng dụng được tạo bằng Hoạt động đáng tin cậy trên web và được phân phối thông qua Cửa hàng Google Play, giờ đây, bạn có thể sử dụng API Yêu cầu thanh toánAPI Hàng hoá kỹ thuật số để tích hợp với Google Play Billing. Chính sách này có trên Chrome 101 trở lên dành cho Android và ChromeOS.

Trong hướng dẫn này, bạn sẽ tìm hiểu cách thêm dịch vụ hỗ trợ của Google Play Billing vào PWA và đóng gói dịch vụ đó để phân phối trên Cửa hàng Google Play cho cả ChromeOS và Cửa hàng Play.

Bạn sẽ sử dụng hai API nền tảng web để thêm dịch vụ hỗ trợ của Play Billing vào PWA của mình. Digital Merchandise API (API Hàng hoá kỹ thuật số) dùng để thu thập thông tin về SKU và kiểm tra các giao dịch mua cũng như quyền trên Cửa hàng Play. Payment Request API dùng để định cấu hình Cửa hàng Google Play làm phương thức thanh toán và hoàn tất quy trình mua.

Cách kiếm tiền từ các ứng dụng trên Cửa hàng Play

Có hai cách để ứng dụng của bạn có thể kiếm tiền với Google Play Billing trên Cửa hàng Play:

  • Tính năng mua hàng trong ứng dụng cho phép bán cả hàng hoá ảo lâu bền và tiêu dùng, chẳng hạn như các tính năng bổ sung hoặc loại bỏ quảng cáo.
  • Gói thuê bao, cung cấp cho người dùng quyền truy cập liên tục vào nội dung hoặc dịch vụ có tính phí định kỳ, chẳng hạn như gói thành viên hoặc gói thuê bao tin tức.

Yêu cầu

Để thiết lập Google Play Billing, bạn cần có:

Cập nhật dự án Bubblewrap

Nếu chưa cài đặt Bubblewrap, bạn sẽ cần cài đặt. Hãy xem Hướng dẫn bắt đầu nhanh để biết thông tin chi tiết về cách bắt đầu. Nếu bạn đã có Bubblewrap, hãy nhớ cập nhật lên phiên bản 1.8.2 trở lên.

Bubblewrap cũng có tính năng đằng sau một lá cờ. Để bật tính năng này, bạn cần sửa đổi cấu hình dự án trong twa-manifest.json, nằm ở gốc của dự án và bật cả alphaDependencies lẫn tính năng playBilling:

  ...,
  "enableNotifications": true,
  "features": {
    "playBilling": {
      "enabled": true
    }
  },
  "alphaDependencies": {
    "enabled": true
  },
  ...

Khi tệp cấu hình được cập nhật, hãy chạy bubblewrap update để áp dụng cấu hình cho dự án, tiếp theo là bubblewrap build, để tạo một gói Android mới rồi tải gói này lên Cửa hàng Play.

Tính năng phát hiện API hàng hoá kỹ thuật số và phạm vi cung cấp của Google Play Billing

Hiện tại, Chrome chỉ hỗ trợ API hàng hoá kỹ thuật số khi PWA đang được thực thi trong một Hoạt động đáng tin cậy trên web. Bạn có thể phát hiện xem API này có sẵn hay không bằng cách kiểm tra getDigitalGoodsService trên đối tượng window:

if ('getDigitalGoodsService' in window) {
 // Digital Goods API is supported!
}

Digital Merchandise API có thể hoạt động trong mọi trình duyệt và hỗ trợ nhiều cửa hàng. Để kiểm tra xem một phần phụ trợ của cửa hàng cụ thể có được hỗ trợ hay không, bạn cần gọi getDigitalGoodsService(), truyền mã cửa hàng dưới dạng tham số. Cửa hàng Google Play được xác định bằng chuỗi https://play.google.com/billing:

if ('getDigitalGoodsService' in window) {
  // Digital Goods API is supported!
  try {
    const service =
        await window.getDigitalGoodsService('https://play.google.com/billing');
    // Google Play Billing is supported!

  } catch (error) {
    // Google Play Billing is not available. Use another payment flow.
    return;
  }
}

Truy xuất thông tin chi tiết về SKU

Digital Merchandise API cung cấp getDetails() cho phép truy xuất các thông tin như tiêu đề, nội dung mô tả và quan trọng nhất là giá sản phẩm từ phần phụ trợ thanh toán.

Sau đó, bạn có thể sử dụng thông tin này trong giao diện sử dụng và cung cấp thêm chi tiết cho người dùng:

const skuDetails = await service.getDetails(['shiny_sword', 'gem']);
for (item of skuDetails) {
  // Format the price according to the user locale.
  const localizedPrice = new Intl.NumberFormat(
      navigator.language,
      {style: 'currency', currency: item.price.currency}
    ).format(item.price.value);

  // Render the price to the UI.
  renderProductDetails(
        item.itemId, item.title, localizedPrice, item.description);
}

Xây dựng quy trình mua

Hàm khởi tạo cho PaymentRequest có 2 tham số: danh sách phương thức thanh toán và danh sách thông tin thanh toán.

Khi ở trong Hoạt động đáng tin cậy trên web, bạn phải sử dụng phương thức thanh toán Google Play Billing bằng cách đặt https://play.google.com/billing làm giá trị nhận dạng và thêm SKU sản phẩm làm thành phần dữ liệu:

async function makePurchase(service, sku) {
   // Define the preferred payment method and item ID
   const paymentMethods = [{
       supportedMethods: "https://play.google.com/billing",
       data: {
           sku: sku,
       }
   }];

   ...
}

Mặc dù thông tin thanh toán là bắt buộc, nhưng Play Billing sẽ bỏ qua các giá trị đó và sử dụng các giá trị được đặt khi tạo SKU trong Play Console, do đó, các giá trị này có thể được điền bằng giá trị không có thật:

const paymentDetails = {
    total: {
        label: `Total`,
        amount: {currency: `USD`, value: `0`}
    }
};

const request = new PaymentRequest(paymentMethods, paymentDetails);

Gọi show() trên đối tượng yêu cầu thanh toán để bắt đầu quy trình thanh toán. Nếu Lời hứa thành công, thì có thể khoản thanh toán đã được thực hiện. Nếu thanh toán không thành công, người dùng có thể đã huỷ thanh toán.

Nếu giao dịch mua được thực hiện thành công, bạn sẽ phải xác minh và xác nhận giao dịch mua. Để ngăn chặn hành vi gian lận, bạn phải triển khai bước này bằng phần phụ trợ. Hãy xem tài liệu Play Billing để tìm hiểu cách triển khai quy trình xác minh trong phần phụ trợ. Nếu bạn không xác nhận giao dịch mua, sau 3 ngày, người dùng sẽ được hoàn tiền và Google Play sẽ thu hồi giao dịch mua đó.

...
const request = new PaymentRequest(paymentMethods, paymentDetails);
try {
    const paymentResponse = await request.show();
    const {purchaseToken} = paymentResponse.details;

    // Call backend to validate and acknowledge the purchase.
    if (await acknowledgePurchaseOnBackend(purchaseToken, sku)) {
        // Optional: tell the PaymentRequest API the validation was
        // successful. The user-agent may show a "payment successful"
        // message to the user.
        const paymentComplete = await paymentResponse.complete('success');
    } else {
        // Optional: tell the PaymentRequest API the validation failed. The
        // user agent may show a message to the user.
        const paymentComplete = await paymentResponse.complete('fail');
    }
} catch(e) {
    // The purchase failed, and we can handle the failure here. AbortError
    // usually means a user cancellation
}
...

Nếu muốn, bạn có thể gọi consume() trên một purchaseToken để đánh dấu giao dịch mua này là đã sử dụng hết và cho phép mua lại.

Kết hợp mọi thứ lại với nhau, phương thức mua sẽ có dạng như sau:

async function makePurchase(service, sku) {
    // Define the preferred payment method and item ID
    const paymentMethods = [{
        supportedMethods: "https://play.google.com/billing",
        data: {
            sku: sku,
        }
    }];

    // The "total" member of the paymentDetails is required by the Payment
    // Request API, but is not used when using Google Play Billing. We can
    // set it up with bogus details.
    const paymentDetails = {
        total: {
            label: `Total`,
            amount: {currency: `USD`, value: `0`}
        }
    };

    const request = new PaymentRequest(paymentMethods, paymentDetails);
    try {
        const paymentResponse = await request.show();
        const {purchaseToken} = paymentResponse.details;

        // Call backend to validate and acknowledge the purchase.
        if (await acknowledgePurchaseOnBackend(purchaseToken, sku)) {
            // Optional: consume the purchase, allowing the user to purchase
            // the same item again.
            service.consume(purchaseToken);

            // Optional: tell the PaymentRequest API the validation was
            // successful. The user-agent may show a "payment successful"
            // message to the user.
            const paymentComplete =
                    await paymentResponse.complete('success');
        } else {
            // Optional: tell the PaymentRequest API the validation failed.
            // The user agent may show a message to the user.
            const paymentComplete = await paymentResponse.complete('fail');
        }
    } catch(e) {
        // The purchase failed, and we can handle the failure here.
        // AbortError usually means a user cancellation
    }
}

Kiểm tra trạng thái của các giao dịch mua hiện tại

API Hàng hoá kỹ thuật số cho phép bạn kiểm tra xem người dùng có quyền nào (giao dịch mua hàng trong ứng dụng chưa được sử dụng hoặc gói thuê bao đang diễn ra) trong các giao dịch mua trước đó, cho dù là trên một thiết bị khác, từ lần cài đặt trước, đã sử dụng qua mã khuyến mãi, hay chỉ lần gần nhất họ mở ứng dụng.


const service =
     await window.getDigitalGoodsService('https://play.google.com/billing');
...
const existingPurchases = await service.listPurchases();
for (const p of existingPurchases) {
    // Update the UI with items the user is already entitled to.
    console.log(`Users has entitlement for ${p.itemId}`);
}

Đây cũng là thời điểm thích hợp để kiểm tra những giao dịch mua đã được thực hiện trước đó nhưng chưa được xác nhận. Bạn nên xác nhận giao dịch mua hàng càng sớm càng tốt để đảm bảo quyền của người dùng được phản ánh chính xác trong ứng dụng.

const service =
     await window.getDigitalGoodsService("https://play.google.com/billing");
...
const existingPurchases = await service.listPurchases();
for (const p of existingPurchases) {
    await verifyOrAcknowledgePurchaseOnBackend(p.purchaseToken, p.itemId);

    // Update the UI with items the user is already entitled to.
    console.log(`Users has entitlement for ${p.itemId}`);
}

Kiểm tra quá trình tích hợp

Trên thiết bị Android dành cho nhà phát triển

Bạn có thể bật Digital Merchandise API trên thiết bị Android đang phát triển để kiểm thử:

  • Đảm bảo bạn đang sử dụng Android 9 trở lên và bật chế độ nhà phát triển.
  • Cài đặt Chrome 101 trở lên.
  • Bật các cờ sau trong Chrome bằng cách chuyển đến chrome://flags và tìm kiếm cờ theo tên:
    • #enable-debug-for-store-billing
  • Đảm bảo rằng trang web được lưu trữ bằng giao thức https. Việc sử dụng http sẽ khiến API trở thành undefined

Trên thiết bị ChromeOS

Digital Merchandise API sẽ có trên ChromeOS ổn định kể từ phiên bản 89. Trong thời gian gần đây, bạn có thể kiểm thử Digital Merchandise API:

  • Cài đặt ứng dụng của bạn từ Cửa hàng Play trên thiết bị.
  • Đảm bảo rằng trang web được lưu trữ bằng giao thức https. Việc sử dụng http sẽ khiến API trở thành undefined

Với người dùng thử nghiệm và nhóm đảm bảo chất lượng

Cửa hàng Play cung cấp các thành phần hướng dẫn kiểm thử, bao gồm cả tài khoản kiểm thử người dùng và SKU kiểm thử. Hãy xem tài liệu kiểm thử Google Play Billing để biết thêm thông tin.

Bạn muốn đi đâu tiếp theo?

Như đã thảo luận trong tài liệu này, API Play Billing có các thành phần phía máy khách do API Hàng hoá kỹ thuật số quản lý và các thành phần phía máy chủ.