Teach you to access the V3 version of Google payment and explain with pictures and pictures (Android, Unity)

1, Foreword

Focus on not getting lost and continue to output Unity dry goods articles.
Hi, everyone. I'm Xinfa. I've been too busy recently. My blog hasn't been updated for several days.
If the project wants to go to sea, it needs to access Google payment. Today, let's talk about how to access Google payment.

To access Google payment, you need to register an account on Google Console and apply for an application,
Google Console website: https://developer.android.com/distribute/console
Account registration and Application application are not the focus of this article, which will not be discussed here. In addition, you need to surf the Internet scientifically to access Google Console.

2, Google payment official document

Official Google payment documents: https://developer.android.com/google/play/billing/integrate#java

3, Google pay Github Demo project

Github project address: https://github.com/android/play-billing-samples

After downloading the Demo, open the ClassyTaxiJava project using Android Studio.

Among them, billingclientlifecycle Java is the main demo script.

4, Google payment flow chart

The process of Google payment is a little complicated. In order to facilitate your understanding, I'll draw a picture of the process of Google payment, which can be enlarged.

What is easy to miss is the supplement.
SDK s of domestic hard core channels (such as app Bao, OPPO, VIVO, Xiaomi, Huawei, etc.) are generally paid through callback_url (usually an https request) is called back to the game server, and the game server delivers the goods.
Unlike Google payment, it doesn't have a callback_url, how does the game server know that the user has paid?
After the payment is completed, the game client needs to actively notify the server to deliver the goods, and then close the order after confirming the delivery.
It is precisely because the client notifies the server of shipment, so the order may be dropped. For example, after the client pays successfully, the client exits abnormally before notifying the server of shipment.
At this time, we need to make up the bill. After logging into the game server, the game client needs to actively call Google's order query interface to replenish and ship the missing orders. After the goods are delivered, the client closes the order.

5, Explanation of Google payment interface

1. Initialization (listening for payment events)

private PurchasesUpdatedListener purchasesUpdatedListener = new PurchasesUpdatedListener() {
    @Override
    public void onPurchasesUpdated(BillingResult billingResult, List<Purchase> purchases) {
        // To be implemented in a later section.
    }
};

private BillingClient billingClient = BillingClient.newBuilder(activity)
    .setListener(purchasesUpdatedListener)
    .enablePendingPurchases()
    .build();

Payment events are monitored in PurchasesUpdatedListener, such as payment completion:

  @Override
    public void onPurchasesUpdated(BillingResult billingResult, List<Purchase> purchases) {
        int responseCode = billingResult.getResponseCode();
        String debugMsg = billingResult.getDebugMessage();
        Log.d("GooglePay", "responseCode: $responseCode, debugMsg: $debugMsg");
        if(null != purchases) {
			for(Purchase purchase : purchases) {
				if(BillingResponseCode.OK == responseCode) {
					// TODO informs the server to deliver goods. After the delivery is successful, close the order
					// handlePurchase(purchase);   //  Note that you must ensure that the server is shipped successfully before executing handlepurchase
				}
			}
		}
    }

2. Connect to Google server (required)

billingClient.startConnection(new BillingClientStateListener() {
    @Override
    public void onBillingSetupFinished(BillingResult billingResult) {
        if (billingResult.getResponseCode() ==  BillingResponseCode.OK) {
            // The BillingClient is ready. You can query purchases here.
        }
    }
    @Override
    public void onBillingServiceDisconnected() {
        // Try to restart the connection on the next request to
        // Google Play by calling the startConnection() method.
    }
});

Determine whether it is connected

if(billingClient.isReady())
{
}

3. Query commodity information (through sku_id)

List<String> skuList = new ArrayList<> ();
skuList.add("sku_id");
SkuDetailsParams.Builder params = SkuDetailsParams.newBuilder();
params.setSkusList(skuList).setType(SkuType.INAPP);
billingClient.querySkuDetailsAsync(params.build(),
    new SkuDetailsResponseListener() {
        @Override
        public void onSkuDetailsResponse(BillingResult billingResult,
                List<SkuDetails> skuDetailsList) {
            // Process the result.
        }
    });

It is recommended to cache the query results. The checked goods can be directly obtained from the cache next time, for example:

private Map<String, SkuDetails> skuDetailsMap = new HashMap();

// ...
if(skuDetailsMap.containsKey("sku_id"))
{
	// skuDetailsMap.get("sku_id");
	return;
}

List<String> skuList = new ArrayList<> ();
skuList.add("sku_id");
SkuDetailsParams.Builder params = SkuDetailsParams.newBuilder();
params.setSkusList(skuList).setType(SkuType.INAPP);
billingClient.querySkuDetailsAsync(params.build(),
    new SkuDetailsResponseListener() {
        @Override
        public void onSkuDetailsResponse(BillingResult billingResult,
                List<SkuDetails> skuDetailsList) {
            // Process the result.
			int resultCode = billingResult.getResponseCode();
			if(BillingResponseCode.Ok == resultCode) {
				for(SkuDetails skuDetails : skuDetailsList) {
					// cache
					if(!skuDetailsMap.containsKey(skuDetails.getSku())) {
						skuDetailsMap.put(skuDetails.getSku(), skuDetails);
					}
				}
				
			}
        }
    });

4. Pull up the payment page (need to transfer sku and order number)

// An activity reference from which the billing flow will be launched.
Activity activity = ...;

// Retrieve a value for "skuDetails" by calling querySkuDetailsAsync().
BillingFlowParams billingFlowParams = BillingFlowParams.newBuilder()
        .setSkuDetails(skuDetails)
        .setObfuscatedAccountId(orderId)   // Insert order number
        .build();
int responseCode = billingClient.launchBillingFlow(activity, billingFlowParams).getResponseCode();

// Handle the result.

5. Close order (execute after shipment)

After the payment is successful and the delivery of the server is completed, the client needs to close the order.

void handlePurchase(Purchase purchase) {
    // Purchase retrieved from BillingClient#queryPurchases or your PurchasesUpdatedListener.
    Purchase purchase = ...;

    // Verify the purchase.
    // Ensure entitlement was not already granted for this purchaseToken.
    // Grant entitlement to the user.

    ConsumeParams consumeParams =
        ConsumeParams.newBuilder()
            .setPurchaseToken(purchase.getPurchaseToken())
            .build();

    ConsumeResponseListener listener = new ConsumeResponseListener() {
        @Override
        public void onConsumeResponse(BillingResult billingResult, String purchaseToken) {
            if (billingResult.getResponseCode() == BillingResponseCode.OK) {
                // Handle the success of the consume operation.
            }
        }
    };

    billingClient.consumeAsync(consumeParams, listener);
}

6. Order query (for replenishment)

After logging into the game server, the user needs to query the order. If there is a missing order, the user needs to notify the server to make up the shipment. After the shipment is completed, the client closes the order.

Purchase.PurchasesResult result = billingClient.queryPurchases(SkuType.INAPP);
if(BillingResponseCode.OK == result.getResponseCode()) {
	for(Purchase purchase : result.getPurchasesList()) {
		if(Purchase.PurchaseState.PURCHASED == purchase.getPurchaseState()) {
			// TODO notifies the server to make up the shipment. After the shipment is completed, the client closes the order.
		}
	}
}

6, How does Unity get the jar file of billing sdk

If you are a native application made by Android Studio, you can directly build Just configure it in gradle.

dependencies {
	// ...
	
    // Google Play Billing Library.
    implementation 'com.android.billingclient:billing:3.0.0'
    
	// ...
}

As follows:

If it is a Unity project, you need to copy the dependent jar files to the Assets/Plugins/Android/libs folder.
We can locate the jar file through Android Studio, move the mouse over the BillingClient class, hold down the Ctrl key and click to jump to Class file, you can pass Class file to The directory where the jar file is located.

As follows:

We put classes The jar file is renamed google_billing_3.0.0.jar, and then throw it into the Unity project.

7, Concluding remarks

complete.
If you like Unity, don't forget to click and pay attention. If you have any technical problems related to Unity, you are also welcome to leave messages or private letters~

Tags: Unity Unity3d SDK Google

Posted by electricblue on Sat, 19 Feb 2022 21:55:06 +1030