/** Verifies the developer payload of a purchase. */ boolean verifyDeveloperPayload(Purchase p) { String payload = p.getDeveloperPayload(); /* * TODO: verify that the developer payload of the purchase is correct. It will be * the same one that you sent when initiating the purchase. * * WARNING: Locally generating a random string when starting a purchase and * verifying it here might seem like a good approach, but this will fail in the * case where the user purchases an item on one device and then uses your app on * a different device, because on the other device you will not have access to the * random string you originally generated. * * So a good developer payload has these characteristics: * * 1. If two different users purchase an item, the payload is different between them, * so that one user's purchase can't be replayed to another user. * * 2. The payload must be such that you can verify it even when the app wasn't the * one who initiated the purchase flow (so that items purchased by the user on * one device work on other devices owned by the user). * * Using your own server to store and verify developer payloads across app * installations is recommended. */ return true; }
public void onIabPurchaseFinished(IabResult result, Purchase purchase) { Log.d(TAG, "Purchase finished: " + result + ", purchase: " + purchase); if (result.isFailure()) { complain("Error purchasing: " + result); setWaitScreen(false); return; } if (!verifyDeveloperPayload(purchase)) { complain("Error purchasing. Authenticity verification failed."); setWaitScreen(false); return; } Log.d(TAG, "Purchase successful."); if (purchase.getSku().equals(SKU_GAS)) { // bought 1/4 tank of gas. So consume it. Log.d(TAG, "Purchase is gas. Starting gas consumption."); mHelper.consumeAsync(purchase, mConsumeFinishedListener); } else if (purchase.getSku().equals(SKU_PREMIUM)) { // bought the premium upgrade! Log.d(TAG, "Purchase is premium upgrade. Congratulating user."); alert("Thank you for upgrading to premium!"); mIsPremium = true; updateUi(); setWaitScreen(false); } else if (purchase.getSku().equals(SKU_INFINITE_GAS)) { // bought the infinite gas subscription Log.d(TAG, "Infinite gas subscription purchased."); alert("Thank you for subscribing to infinite gas!"); mSubscribedToInfiniteGas = true; mTank = TANK_MAX; updateUi(); setWaitScreen(false); } }
public void onConsumeFinished(Purchase purchase, IabResult result) { Log.d(TAG, "Consumption finished. Purchase: " + purchase + ", result: " + result); purchase.setSku( SkuManager.getInstance().getSku(purchase.getAppstoreName(), purchase.getSku())); if (result.isFailure()) { Log.e(TAG, "Error while consuming: " + result); UnityPlayer.UnitySendMessage( EVENT_MANAGER, CONSUME_PURCHASE_FAILED_CALLBACK, result.getMessage()); return; } Log.d(TAG, "Consumption successful. Provisioning."); String jsonPurchase; try { jsonPurchase = purchaseToJson(purchase); } catch (JSONException e) { UnityPlayer.UnitySendMessage( EVENT_MANAGER, CONSUME_PURCHASE_FAILED_CALLBACK, "Couldn't serialize the purchase"); return; } UnityPlayer.UnitySendMessage( EVENT_MANAGER, CONSUME_PURCHASE_SUCCEEDED_CALLBACK, jsonPurchase); }
/** * Serialize purchase data to json * * @param purchase purchase data * @return json string * @throws JSONException */ private String purchaseToJson(Purchase purchase) throws JSONException { return new JSONStringer() .object() .key("itemType") .value(purchase.getItemType()) .key("orderId") .value(purchase.getOrderId()) .key("packageName") .value(purchase.getPackageName()) .key("sku") .value(purchase.getSku()) .key("purchaseTime") .value(purchase.getPurchaseTime()) .key("purchaseState") .value(purchase.getPurchaseState()) .key("developerPayload") .value(purchase.getDeveloperPayload()) .key("token") .value(purchase.getToken()) .key("originalJson") .value(purchase.getOriginalJson()) .key("signature") .value(purchase.getSignature()) .key("appstoreName") .value(purchase.getAppstoreName()) .endObject() .toString(); }