【问题标题】:Verify a Purchase using Firebase Functions使用 Firebase 函数验证购买
【发布时间】:2018-03-18 09:02:57
【问题描述】:

我想使用 Firebase Functions 和 Purchases.products: get 在我的应用中验证购买 但我不知道如何使用链接中的授权范围或如何在 Firebase Functions 中构建请求。 这是我目前所拥有的:

const functions = require('firebase-functions');
const admin = require('firebase-admin');
const google = require("googleapis");
const publisher = google.androidpublisher('v2');
admin.initializeApp(functions.config().firebase);

exports.validatePurchases = functions.database
    .ref('/purchases/{uId}/{orderId}')
    .onWrite((event) => {
        const purchase = event.data.val();
        const token = purchase.token;
        const packageName = purchase.package_name;
        const sku = purchase.sku;
        const signature = purchase.signature;
        const uri = "https://www.googleapis.com/androidpublisher/v2/applications/" + packageName + "/purchases/products/" + sku + "/tokens/" + token;

        return TODO;
    });

我已经设置了几乎所有东西,但我的 JavaScript 知识非常有限,不知道如何构建请求并在 Firebase 函数中获取结果

【问题讨论】:

    标签: node.js firebase in-app-purchase google-cloud-functions google-play-developer-api


    【解决方案1】:

    我对 JavaScript 知之甚少,我得到这个函数的部分原因是从我读过的所有内容中猜测出来的,我将不胜感激,我知道还有改进的余地,但它会进行验证。

    这是我用来验证购买的功能:

    const functions = require('firebase-functions');
    const admin = require('firebase-admin');
    const {google} = require("googleapis");
    const publisher = google.androidpublisher('v2');
    const authClient = new google.auth.JWT({
        email: 'Service Account Email',
        key: '-----BEGIN PRIVATE KEY-----\n**********************************************************************************==\n-----END PRIVATE KEY-----\n',
        scopes: ['https://www.googleapis.com/auth/androidpublisher']
    });
    admin.initializeApp();
    
    exports.validatePurchases = functions.database
        .ref('/purchases/{uId}/{orderId}')
        .onCreate((event, context) => {
            const purchase = event.val();
            if (purchase.is_processed === true) {
                console.log('Purchase already processed!, exiting');
                return null;
            }
            const orderId = context.params.orderId;
            const dbRoot = event.ref.root;
            const package_name = purchase.package_name;
            const sku = purchase.sku;
            const my_token = purchase.token;
    
            authClient.authorize((err, result) => {
                if (err) {
                    console.log(err);
                }
                publisher.purchases.products.get({
                    auth: authClient,
                    packageName: package_name,
                    productId: sku,
                    token: my_token
                }, (err, response) => {
                    if (err) {
                        console.log(err);
                    }
                    // Result Status must be equals to 200 so that the purchase is valid
                    if (response.status === 200) {
                        return event.ref.child('is_validated').set(true);
                    } else {
                        return event.ref.child('is_validated').set(false);
                    }
                });
            });
            return null;
        });
    

    更新: 我刚刚发现,当使用 Promo Codes 时,这会失败,因为 orderId 对于 Promo Codes 是空的。

    使用承诺

    return authClient.authorize()
            // authClient.authorize() returns a credentials Object
            .then(credentials => {
                return publisher.purchases.products.get({
                    auth: authClient,
                    packageName: packageName,
                    productId: sku,
                    token: token
                });
            })
            // publisher.purchases.products.get() Returns a axiosResponse object with Purchase data within and the status that should be enough for the validation
            .then(axiosResponse => {
                    if (axiosResponse.status === 200 && axiosResponse.data.purchaseState === 0) {
                    // Your purchase is valid, do your thing
                    } else {
                        return event.ref.set(null);
                    }
                })
                .catch(reason => {
                    console.log(`Rejection Code: ${reason.code}`);
                    console.log(`Rejection Message: ${reason.message}`);
                    return event.ref.set(null);
                });
    

    据我了解,axiosResponse.status === 200 应该足以验证购买,但请注意axiosResponse.data 保存来自purchase Schema$ProductPurchase 的数据,您可以在其中检查购买的其他值。如果您使用“许可测试”或“促销代码”,我会觉得这很有趣。在这个示例中,我使用axiosResponse.data.purchaseState 来检查购买是否仍然有效(可能是不必要的......)

    【讨论】:

    • 我收到此错误:拒绝消息:错误:0906D066:PEM 例程:PEM_read_bio:bad end line。这个问题有什么解决办法吗?
    • 我正在为订阅尝试这个,我收到一个无效值错误stackoverflow.com/questions/64148137/…
    猜你喜欢
    • 1970-01-01
    • 2014-03-25
    • 2014-03-01
    • 1970-01-01
    • 1970-01-01
    • 2019-02-12
    • 1970-01-01
    • 1970-01-01
    • 2013-06-11
    相关资源
    最近更新 更多