如何将 Paypal IPN 分派到 Google 云功能?

How to dispatch a Paypal IPN to a Google Cloud function?

我读到 可以将 IPN 直接发送到 Google 云函数。我在 Firebase 上的 index.js 文件上有我的 Google 云函数 运行。

我已经设置了我的 Paypal 按钮以将 IPN 发送到我的网络应用程序上的页面。

这是我 运行 关闭 Google Cloud Functions/Firebase:

的功能之一的示例
// UPDATE ROOMS INS/OUTS
exports.updateRoomIns = functions.database.ref('/doors/{MACaddress}').onWrite((change, context) => {
    const beforeData = change.before.val(); 
    const afterData = change.after.val(); 
    const roomPushKey = afterData.inRoom; 
    const insbefore = beforeData.ins; 
    const insafter = afterData.ins; 
    if ((insbefore === null || insbefore === undefined) && (insafter === null || insafter === undefined) || insbefore === insafter) {
        return 0;
    } else {
        const updates = {};
        Object.keys(insafter).forEach(key => {
            updates['/rooms/' + roomPushKey + '/ins/' + key] = true;
        });
        return admin.database().ref().update(updates); // do the update} 
    }   
    return 0;
});

现在提问:

1) 我想添加另一个功能,以便在我有交易时立即处理来自 Paypal 的 IPN。我该怎么做?

如果解决了第一个问题,我会将答案标记为正确。

2) Google 云功能会是什么样子?

如果你能解决这个问题,我会创建另一个问题。

注意我正在使用 Firebase(没有其他数据库,也没有 PHP)。

IPN 只是一个试图到达给定端点的服务器。

首先,您必须确保您的 firebase 计划支持第 3 方请求(它在免费计划中不可用)。

之后,您需要创建一个 http 端点,如下所示:

exports.ipn = functions.http.onRequest((req, res) => {
    // req and res are instances of req and res of Express.js
    // You can validate the request and update your database accordingly.
});

它将在 https://www.YOUR-FIREBASE-DOMAIN.com/ipn

中可用

基于@Eliya Cohen 的回答:

在您的 firebase 函数上创建一个函数,例如:

exports.ipn = functions.https.onRequest((req, res) => {
    var reqBody = req.body;
    console.log(reqBody);
    // do something else with the req.body i.e: updating a firebase node with some of that info
    res.sendStatus(200);
});

当您部署函数时,请转到您的 firebase 控制台项目并检查您的函数。你应该有这样的东西:

复制 url,转到 paypal,编辑触发购买的按钮,向下滚动到第 3 步并在底部键入:

notify_url= paste that url here

保存更改。

您现在可以测试您的按钮并检查您的 firebase 云功能日志选项卡上的 req.body。

感谢这里的答案,尤其是这个要点:https://gist.github.com/dsternlicht/fdef0c57f2f2561f2c6c477f81fa348e

..终于想出一个解决方案来验证云函数中的IPN请求:

let CONFIRM_URL_SANDBOX = 'https://ipnpb.sandbox.paypal.com/cgi-bin/webscr';

exports.ipn = functions.https.onRequest((req, res) => {

    let body = req.body;
    logr.debug('body: ' + StringUtil.toStr(body));

    let postreq = 'cmd=_notify-validate';

    // Iterate the original request payload object
    // and prepend its keys and values to the post string
    Object.keys(body).map((key) => {
        postreq = `${postreq}&${key}=${body[key]}`;
        return key;
    });

    let request = require('request');

    let options = {
        method: 'POST',
        uri   : CONFIRM_URL_SANDBOX,
        headers: {
            'Content-Length': postreq.length,
        },
        encoding: 'utf-8',
        body: postreq
    };

    res.sendStatus(200);

    return new Promise((resolve, reject) => {

        // Make a post request to PayPal
        return request(options, (error, response, resBody) => {

            if (error || response.statusCode !== 200) {
                reject(new Error(error));
                return;
            }

            let bodyResult = resBody.substring(0, 8);
            logr.debug('bodyResult: ' + bodyResult);

            // Validate the response from PayPal and resolve / reject the promise.
            if (resBody.substring(0, 8) === 'VERIFIED') {
                return resolve(true);
            } else if (resBody.substring(0, 7) === 'INVALID') {
                return reject(new Error('IPN Message is invalid.'));
            } else {
                return reject(new Error('Unexpected response body.'));
            }
        });

    });

});

同时感谢:

To receive IPN message data from PayPal, your listener must follow this request-response flow:

Your listener listens for the HTTPS POST IPN messages that PayPal sends with each event. After receiving the IPN message from PayPal, your listener returns an empty HTTP 200 response to PayPal. Otherwise, PayPal resends the IPN message. Your listener sends the complete message back to PayPal using HTTPS POST.

Prefix the returned message with the cmd=_notify-validate variable, but do not change the message fields, the order of the fields, or the character encoding from the original message.