如何使用 google-play-purchase-validator 在应用程序和 node.js 服务器之间验证购买

How to valid purchase between an app and node.js server using google-play-purchase-validator

我有一个正在测试的应用程序,它可以免费使用,但需要在应用程序内购买。我在 google Play 商店的 alpha 版中有它 运行,我过去使用 android.test SKU,然后安装了我自己的作品。现在,当有人购买时,我希望该应用程序向我的服务器传达我的服务器所需的信息,以便我的服务器询问 google 应用程序购买是否合法,然后转身并适当地记入他们的帐户,因为控制服务由服务器完成。到目前为止我有这个:

在我的节点服务器的 index.js 文件中,我有一个这样的段:

var Verifier = require('google-play-purchase-validator');

function validUserPurchases (receipt) {
    var options = {
        email: "#################@developer.gserviceaccount.com",
        key: "-----BEGIN PRIVATE madness -----END PRIVATE KEY-----\n",
        keyFile: "./Google Play Android Developer-##########.json"
    };

    var verifier = new Verifier(options);

    verifier.verify(receipt, function cb(err, response) {
        if (err) {
            console.log("there was an error validating the receipt");
            console.log(err);
        } else {
            console.log("sucessfully validated the receipt");
            //do crap on my server to grant that account new privileges
            console.log(response);
        }
    });
    
}

其中 receipt 是一个字符串,是我的 mainactivity.java 应用程序中以下代码行中的 purchase.getOriginalJson() 对象:

@Override
public void StartPayment(String payment) {
    pricing = payment; // this is a SKU set by the user in a fragment
    my_socket.getDeveloperPayload(); //this gets a public key for the app from my server

}

@Override
public void yourDeveloperPayLoad(String s) {
    your_pay_load = s; //something I am doing to uniquely stamp each transaction on my end
    if (your_pay_load.isEmpty()) {
        toastShort("Your account was not billed, something went wrong, try again.");
    } else {
        mHelper.launchPurchaseFlow(this, pricing, 100001,
                mPurchaseFinishedListener, your_pay_load);
    }
}

@Override
protected void onActivityResult(int requestCode, int resultCode,
                                Intent data)
{
    if (!mHelper.handleActivityResult(requestCode,
            resultCode, data)) {
        super.onActivityResult(requestCode, resultCode, data);
    }
}


IabHelper.OnIabPurchaseFinishedListener mPurchaseFinishedListener =
        new IabHelper.OnIabPurchaseFinishedListener() {

            @Override
            public void onIabPurchaseFinished(IabResult result, Purchase info) {
                if (result.isFailure()) {
                    //handle errors
                    return;
                } else if (info.getSku().equals(pricing)) {
                    consumeItem();
                }
            }
        };

private void consumeItem() {
    mHelper.queryInventoryAsync(mReceivedInventoryListener);

}

IabHelper.QueryInventoryFinishedListener mReceivedInventoryListener
        = new IabHelper.QueryInventoryFinishedListener() {

    @Override
    public void onQueryInventoryFinished(IabResult result, Inventory inv) {
        if (result.isFailure()) {
            //handle failure
        } else {
            mHelper.consumeAsync(inv.getPurchase(pricing),
                    mConsumeFinishedListener);
        }
    }
};

IabHelper.OnConsumeFinishedListener mConsumeFinishedListener
        = new IabHelper.OnConsumeFinishedListener() {

        @Override
        public void onConsumeFinished(Purchase purchase, IabResult result) {
            if (result.isSuccess()) {
                System.out.println("Checkout was successful");
                //System.out.println("Purchase has: " + purchase);
                //System.out.println("Purchase SKU: " + purchase.getSku());
                System.out.println("Purchase getDeveloperPayload: " + purchase.getDeveloperPayload());
                System.out.println("Purchase getItemType: " + purchase.getItemType());
                System.out.println("Purchase getOriginalJson(): " + purchase.getOriginalJson());
                System.out.println("Purchase getOrderId(): " + purchase.getOrderId());
                System.out.println("Purchase getPackageName(): " + purchase.getPackageName());
                System.out.println("Purchase getSignature(): " + purchase.getSignature());
                System.out.println("Purchase getToken(): " + purchase.getToken());
                System.out.println("Purchase getPurchaseState(): " + purchase.getPurchaseState());
                System.out.println("Purchase getPurchaseTime(): " + purchase.getPurchaseTime());
                System.out.println("Purchase hashCode(): " + purchase.hashCode());
                my_socket.sendPaymentVerification(purchase.getOriginalJson());

            } else {
                System.out.println("Checkout was not successful");
            }
        }
};

我认为 purchase.getOriginalJson() 将构成服务器需要通过 verifier.verify(receipt, function cb(err, response) 发送到 google 的所有内容,但是当我尝试使用测试购买时,我得到:

there was an error validating the receipt

[Error: No application was found for the given package name.]

不确定我做错了什么,purchase.getOriginalJson() 不构成我需要在 google 的收据中输入的内容以验证这是真实的购买吗?我是否无法在 alpha 或 beta 测试渠道中测试此功能?时间不多了。

我更改了这个函数:

IabHelper.OnConsumeFinishedListener mConsumeFinishedListener
            = new IabHelper.OnConsumeFinishedListener() {

        @Override
        public void onConsumeFinished(Purchase purchase, IabResult result) {
            if (result.isSuccess()) {
                System.out.println("Checkout was successful");
                System.out.println("Purchase getDeveloperPayload: " + purchase.getDeveloperPayload());
                System.out.println("Purchase getItemType: " + purchase.getItemType());
                System.out.println("Purchase getOriginalJson(): " + purchase.getOriginalJson());
                System.out.println("Purchase getOrderId(): " + purchase.getOrderId());
                System.out.println("Purchase getPackageName(): " + purchase.getPackageName());
                System.out.println("Purchase getSignature(): " + purchase.getSignature());
                System.out.println("Purchase getToken(): " + purchase.getToken());
                System.out.println("Purchase getPurchaseState(): " + purchase.getPurchaseState());
                System.out.println("Purchase getPurchaseTime(): " + purchase.getPurchaseTime());
                System.out.println("Purchase hashCode(): " + purchase.hashCode());
                try {
                    JSONObject json = new JSONObject(purchase.getOriginalJson());
                    JSONObject obj = new JSONObject();
                    obj.put("data",json);
                    obj.put("signature", purchase.getSignature());
                    my_socket.sendPaymentVerification(obj);
                } catch (JSONException e) {
                    e.printStackTrace();
                }

            } else {
                System.out.println("Checkout was not successful");
            }
        }
    };

我正在使用 node.js,我选择了 'iab_verifier' 模块:

var IABVerifier = require('iab_verifier');

function validUserPurchases(purchase) {
    var receiptData = JSON.stringify(purchase.data);
    var receiptSignature = JSON.stringify(purchase.signature);
    console.log("data: " + receiptData);
    console.log("signature: " + receiptSignature);

    var googleplayVerifier = new IABVerifier(googleplay_public_key);
    Receipts.findOne({ data: receiptData, signature: receiptSignature }, function (err, result) {
        if (err) {
            console.log("In receipt error");
        } else if (result == null) {
            console.log("No result for receipt found");
            var isValid = googleplayVerifier.verifyReceipt(receiptData, receiptSignature);
            if (isValid) {
                console.log("The receipt is valid");
                Clients.findOne({ socket_id: socket.id }, function (err, client) {
                    if (client) {
                        var receipt = new Receipts({
                            client_ID: client._id,
                            data: receiptData, unique: true,
                            signature: receiptSignature, unique: true
                        });
                        receipt.save(function (err, result) {
                            if (err) {
                                console.log("Error saving the receipt");
                            } else {
                                console.log("Update the clients account time");
                                var productID = JSON.parse(receiptData).productId;
                                updateSubscription(productID);
                            }
                        });
                    }
                });
            } else {
                console.log("The receipt is not valid");
            }
        } else {
            console.log("This receipt is already in use");
        }
    });  
}

希望这能为其他人节省一些时间,gl。