Wednesday, December 28, 2011

in-app billing關於使用者退款後,Google的心態。

很好奇萬一使用者退款了,
那我們程式這邊要不要把使用介面還原成未付費的樣子。

底下是in-app billing範例程式中,
PurchaseDatabase.java裡的其中一個函式updatePurchase(),
這個函式在您的APP收到使用者退款通知時,
會做資料庫購買記錄的修改。

底下是原始碼︰
 

   /**
     * Adds the given purchase information to the database and returns the total
     * number of times that the given product has been purchased.
     * @param orderId a string identifying the order
     * @param productId the product ID (sku)
     * @param purchaseState the purchase state of the product
     * @param purchaseTime the time the product was purchased, in milliseconds
     * since the epoch (Jan 1, 1970)
     * @param developerPayload the developer provided "payload" associated with
     *            the order
     * @return the number of times the given product has been purchased.
     */
    public synchronized int updatePurchase(String orderId, String productId,

        PurchaseState purchaseState, long purchaseTime, String developerPayload) {

        insertOrder(orderId, productId, purchaseState, purchaseTime, developerPayload);

        Cursor cursor = mDb.query(PURCHASE_HISTORY_TABLE_NAME, HISTORY_COLUMNS,
                HISTORY_PRODUCT_ID_COL + "=?", new String[] { productId }, null, null, null, null);

        if (cursor == null) {
            return 0;
        }

        int quantity = 0;

        try {

           // Count the number of times the product was purchased
            while (cursor.moveToNext()) {

                int stateIndex = cursor.getInt(2);
                PurchaseState state = PurchaseState.valueOf(stateIndex);

                // Note that a refunded purchase is treated as a purchase. Such
                // a friendly refund policy is nice for the user.
                if (state == PurchaseState.PURCHASED || state == PurchaseState.REFUNDED) {
                    quantity += 1;
                }

            }

            // Update the "purchased items" table
            updatePurchasedItem(productId, quantity);

        } finally {

            if (cursor != null) {
                cursor.close();
            }

        }

        return quantity;

    }
 

以上這段code説的、也做的夠清楚了,
範例程式收到使用者退款的IN_APP_NOTIFY後,
直接把Purchase Database的購買數量減1
卻沒有對程式畫面做任何處理。

範例裡留了這一段註解︰
// Note that a refunded purchase is treated as a purchase. Such a friendly refund policy is nice for the user.
即使使用者退款了,
我們仍以使用者是已購買的狀態來對待他,
這是一種友善政策。

3 comments:

Anonymous said...

您好! 基於一個消費者, 我想請問的是, Google在退款政策上寫到, "還原應用程式內購買項目的工作是由開發人員所負責"。那麼我該怎麼知道在重新安裝軟體後會不會重新取得已購買的項目, 像是移除廣告或解鎖這種非消耗性的項目, 還是消費者無法事先知道, 除非開發者有在購買說明內明確指出。

另一個問題是, 應用程式內購買的項目是如同Android Market綁定在Google帳號上, 還是有不同的辨識方式?

因為一直找不到相關的議題, 而這又是目前台灣唯一正常的購買方式。所以麻煩您了, 謝謝!

小鰻 said...

您好,
針對第1點,in-app-billing商品被Google分成管理和未管理2大類,管理類的商品會被Google Server記錄,因此只要App端再次跟Google Server詢問該Google帳戶的user是否有購買過,若購買過,範例程式都有教導如何還原成已購買狀態。以最好的使用體驗來說,將"權限還原機制"設在每次程式初始化時是最好的選擇。(當然可以做的更好)

關於第2點,是的,仍然是綁定在Google帳戶上。

希望有回答到您的疑問。
小鰻

Anonymous said...

您好
我用了官方提供的範列,然後使用真的信用卡來購買sword_001之後,在下拉式列表中,有看到sword_001已經變成disable,因為已經買過,我也買了potion_001,但是為什麼下方的Items you own都沒有顯示東西呢?這是正常的嗎?