Skip to content Skip to sidebar Skip to footer

Google Android In-app Purchases "content Delivery" How To Correctly Deliver Content?

I am currently trying to code up in-app purchases. I was looking for documentation, information, tutorials on best practices for some of the stuff Google doesn't handle. What I hav

Solution 1:

You'll have to make some changes to the billing service client code from the sample.

First, you should call your server to get the nonce that will be used to either RestoreTransactions or make the purchase, to make things as secure as possible.

Let's follow what happens. Here is the BillingReceiver that gets called by Google Play:

/**
 * This is called when Android Market sends information about a purchase state
 * change. The signedData parameter is a plaintext JSON string that is
 * signed by the server with the developer's private key. The signature
 * for the signed data is passed in the signature parameter.
 * @param context the context
 * @param signedData the (unencrypted) JSON string
 * @param signature the signature for the signedData
 */privatevoid purchaseStateChanged(Context context, String signedData, String signature) {
    Intent intent = new Intent(Consts.ACTION_PURCHASE_STATE_CHANGED);
    intent.setClass(context, BillingService.class);
    intent.putExtra(Consts.INAPP_SIGNED_DATA, signedData);
    intent.putExtra(Consts.INAPP_SIGNATURE, signature);
    context.startService(intent);
}

If you look at handleCommand within BillingService.java, it handles this intent:

/**
 * The {@link BillingReceiver} sends messages to this service using intents.
 * Each intent has an action and some extra arguments specific to that action.
 * @param intent the intent containing one of the supported actions
 * @param startId an identifier for the invocation instance of this service
 */publicvoidhandleCommand(Intent intent, int startId) {
    Stringaction= intent.getAction();
    if (Consts.DEBUG) {
        Log.i(TAG, "handleCommand() action: " + action);
    }
    if (Consts.ACTION_CONFIRM_NOTIFICATION.equals(action)) {
        String[] notifyIds = intent.getStringArrayExtra(Consts.NOTIFICATION_ID);
        confirmNotifications(startId, notifyIds);
    } elseif (Consts.ACTION_GET_PURCHASE_INFORMATION.equals(action)) {
        StringnotifyId= intent.getStringExtra(Consts.NOTIFICATION_ID);
        getPurchaseInformation(startId, newString[] { notifyId });
    } elseif (Consts.ACTION_PURCHASE_STATE_CHANGED.equals(action)) {
        StringsignedData= intent.getStringExtra(Consts.INAPP_SIGNED_DATA);
        Stringsignature= intent.getStringExtra(Consts.INAPP_SIGNATURE);
        purchaseStateChanged(startId, signedData, signature);
    } elseif (Consts.ACTION_RESPONSE_CODE.equals(action)) {
        longrequestId= intent.getLongExtra(Consts.INAPP_REQUEST_ID, -1);
        intresponseCodeIndex= intent.getIntExtra(Consts.INAPP_RESPONSE_CODE,
                ResponseCode.RESULT_ERROR.ordinal());
        ResponseCoderesponseCode= ResponseCode.valueOf(responseCodeIndex);
        checkResponseCode(requestId, responseCode);
    }
}

This then calls thePurchaseStateChanged function. This function should be replaced by a call to your server to create a session for your content delivery. The code from Security.java should be ported to the server side to validate the transaction within the cloud.

/**
 * Verifies that the data was signed with the given signature, and calls
 * {@link ResponseHandler#purchaseResponse(Context, PurchaseState, String, String, long)}
 * for each verified purchase.
 * @param startId an identifier for the invocation instance of this service
 * @param signedData the signed JSON string (signed, not encrypted)
 * @param signature the signature for the data, signed with the private key
 */privatevoid purchaseStateChanged(int startId, String signedData, String signature) {
    ArrayList<Security.VerifiedPurchase> purchases;
    purchases = Security.verifyPurchase(signedData, signature);
    if (purchases == null) {
        return;
    }

    ArrayList<String> notifyList = new ArrayList<String>();
    for (VerifiedPurchase vp : purchases) {
        if (vp.notificationId != null) {
            notifyList.add(vp.notificationId);
        }
        ResponseHandler.purchaseResponse(this, vp.purchaseState, vp.productId,
                vp.orderId, vp.purchaseTime, vp.developerPayload);
    }
    if (!notifyList.isEmpty()) {
        String[] notifyIds = notifyList.toArray(newString[notifyList.size()]);
        confirmNotifications(startId, notifyIds);
    }
}

Make sure to put your public key on the server side in the ported Security.java file.

Post a Comment for "Google Android In-app Purchases "content Delivery" How To Correctly Deliver Content?"