Nodejs-Krakenjs:PayPal Checkout服务器集成

时间:2018-08-29 05:15:43

标签: paypal-sandbox paypal

我尝试按照此处的说明进行操作:https://developer.paypal.com/docs/checkout/how-to/server-integration/#将Paypal结帐功能集成到我的网站(由Nodejs-krakenjs,Angularjs开发)

// FOR PAYPAL PAYMENT
function renderPaypalButton() {
paypal.Button.render({
    env: 'sandbox', // Or 'production'
    // Set up the payment:
    // 1. Add a payment callback
    payment: function (data, actions) {
        // 2. Make a request to your server
        console.log('Make a request to your server');
        return actions.request.post('/file/createPayment', {
            //_token:    csrf_token()
        }).then(function (res) {
            console.log('return res id');
            // 3. Return res.id from the response
            return res.id;
        });
    },
    // Execute the payment:
    // 1. Add an onAuthorize callback
    onAuthorize: function (data, actions) {
        // 2. Make a request to your server
        return actions.request.post('/file/executePayment', {
            paymentID: data.paymentID,
            payerID: data.payerID
        })
            .then(function (res) {
                // 3. Show the buyer a confirmation message.
                alert(res);
                console.log(res);
            });
    }
}, '#paypal-button');
}

服务器端:

// Set up the payment:
// 1. Set up a URL to handle requests from the PayPal button
router.post('/createPayment', function (req, res) {
    console.log('aa');
    // 2. Call /v1/payments/payment to set up the payment
    request.post(PAYPAL_API + '/v1/payments/payment',
        {
            auth:
            {
                user: CLIENT,
                pass: SECRET
            },
            body:
            {
                intent: 'sale',
                payer:
                {
                    payment_method: 'paypal'
                },
                transactions: [
                    {
                        amount:
                        {
                            total: '5.99',
                            currency: 'USD'
                        }
                    }],
                redirect_urls:
                {
                    return_url: 'http://localhost:1272',
                    cancel_url: 'http://localhost:1272'
                }
            },
            json: true
        }, function (err, response) {
            if (err) {
                console.error(err);
                return res.sendStatus(500);
            }
            // 3. Return the payment ID to the client
            res.json(
                {
                    id: response.body.id
                });
        });
});

// Execute the payment:
// 1. Set up a URL to handle requests from the PayPal button.
router.post('/executePayment', function (req, res) {
    // 2. Get the payment ID and the payer ID from the request body.
    var paymentID = req.body.paymentID;
    var payerID = req.body.payerID;
    // 3. Call /v1/payments/payment/PAY-XXX/execute to finalize the payment.
    request.post(PAYPAL_API + '/v1/payments/payment/' + paymentID + '/execute',
        {
            auth:
            {
                user: CLIENT,
                pass: SECRET
            },
            body:
            {
                payer_id: payerID,
                transactions: [
                    {
                        amount:
                        {
                            total: '10.99',
                            currency: 'USD'
                        }
                    }]
            },
            json: true
        },
        function (err, response) {
            if (err) {
                console.error(err);
                return res.sendStatus(500);
            }
            // 4. Return a success response to the client
            res.json(
                {
                    status: 'success'
                });
        });
});

}

paypal库已加载到index.html:

<script src="https://www.paypalobjects.com/api/checkout.js"></script>

并且以模态形式集成了贝宝结帐按钮:

<div id="paypal-button"></div>

<script>
     setTimeout(renderPaypalButton(), 3000);                
</script>

Paypal结帐按钮已呈现并显示在模式上,但单击该按钮后,Palpay登录模式出现几秒钟,然后消失,出现“错误:缺少CSRF令牌”:

POST http://localhost:1272/file/createPayment 500 (Internal Server Error) Uncaught Error: Error: Request to post /file/createPayment failed with 500 error. Correlation id: unknown

  • 主页
  • 内部服务器错误

    URL /file/createPayment具有以下错误Error: CSRF token missing

    < p>

    at XMLHttpRequest.<anonymous> (https://www.paypalobjects.com/api/checkout.js:14010:39)
    at Object._RECEIVE_MESSAGE_TYPE.(anonymous function) [as postrobot_message_response] (https://www.paypalobjects.com/api/checkout.js:2569:31)
    at receiveMessage (https://www.paypalobjects.com/api/checkout.js:2614:60)
    at messageListener (https://www.paypalobjects.com/api/checkout.js:2635:13)
    
    at XMLHttpRequest.<anonymous> (https://www.paypalobjects.com/api/checkout.js:14010:39)
    at Object._RECEIVE_MESSAGE_TYPE.(anonymous function) [as postrobot_message_response] (https://www.paypalobjects.com/api/checkout.js:2569:31)
    at receiveMessage (https://www.paypalobjects.com/api/checkout.js:2614:60)
    at messageListener (https://www.paypalobjects.com/api/checkout.js:2635:13)
    at deserializeError (https://www.paypalobjects.com/api/checkout.js:3302:23)
    at https://www.paypalobjects.com/api/checkout.js:3323:270
    at https://www.paypalobjects.com/api/checkout.js:3052:30
    at eachArray (https://www.paypalobjects.com/api/checkout.js:3035:51)
    at each (https://www.paypalobjects.com/api/checkout.js:3041:35)
    at replaceObject (https://www.paypalobjects.com/api/checkout.js:3051:13)
    at https://www.paypalobjects.com/api/checkout.js:3053:169
    at eachObject (https://www.paypalobjects.com/api/checkout.js:3038:65)
    at each (https://www.paypalobjects.com/api/checkout.js:3041:144)
    at replaceObject (https://www.paypalobjects.com/api/checkout.js:3051:13)
    

    你们都可以帮助我。我不明白是什么使Csrf在这里。谢谢大家!

    1 个答案:

    答案 0 :(得分:0)

    The example code shown in the PayPal documentation does not work. You
    

    必须向其传递QAuth访问令牌,而不是CLIENT / SECRET。我得到了代码  工作,但必须对其进行相当大的改动。

    Here's the node.js server code:
    
    var express = require('express');
    var request = require('request');
    
    var app = express();
    var port = 3000;
    var bodyParser = require('body-parser');
    app.use(bodyParser.json());
    // support json encoded bodies
    app.use(bodyParser.urlencoded({ extended: true })); // support encoded bodies
    
    
    var PAYPAL_API = 'https://api.sandbox.paypal.com';
    app.post('/my-api/create-payment/', function(req, res)
    {
      // Set up the payment:
      // 1. Set up a URL to handle requests from the PayPal button
    
        // 2. Allow cross-domain
        res.setHeader('access-control-allow-origin', '*');
    
        request.post(PAYPAL_API + '/v1/payments/payment',
        {
    
          headers: {
                Authorization: 'Bearer <your access token>'
          },
          body:
          {
            intent: 'sale',
            payer:
            {
              payment_method: 'paypal'
            },
            transactions: [
            {
              amount:
              {
                total: '5.99',
                currency: 'USD'
              }
            }],
            redirect_urls:
            {
              return_url: 'https://www.yourwebsite.com',
              cancel_url: 'https://www.yourwebsite.com'
            }
          },
          json: true
        }, function(err, response)
        {
          if (err)
          {
            console.error(err);
            return res.sendStatus(500);
          }
          // 3. Return the payment ID to the client
          res.json(
          {
            id: response.body.id
          });
        });
      })
      // Execute the payment:
      // 1. Set up a URL to handle requests from the PayPal button.
      app.post('/my-api/execute-payment/', function(req, res)
      {
        // 2. Get the payment ID and the payer ID from the request body.
        var paymentID = req.body.paymentID;
        var payerID = req.body.payerID;
    
        res.setHeader('access-control-allow-origin', '*');
    
        // 3. Call /v1/payments/payment/PAY-XXX/execute to finalize the payment.
        request.post(PAYPAL_API + '/v1/payments/payment/' + paymentID +
          '/execute',
          {
            headers: {
                Authorization: 'Bearer <your access token>'
            },
            body:
            {
              payer_id: payerID
            },
            json: true
          },
          function(err, response)
          {
            if (err)
            {
              console.error(err);
              return res.sendStatus(500);
            }
            // 4. Return a success response to the client
            res.json(
            {
              status: 'success'
            });
          });
      }).listen(3000, function()
      {
        console.log('Server listening at http://localhost:3000/');
      });
    
    
    Here's the HTML:
    
    <!DOCTYPE html>
    <html>
    <title>PayPal Client Test</title>
    
    <body>
        <p>This is the PayPal button for my client sandbox test</p>
        <script src="https://www.paypalobjects.com/api/checkout.js"></script>
    
        <div id="paypal-button"></div>
    
        <script>
          paypal.Button.render({
            env: 'sandbox', // Or 'production'
            // Set up the payment:
            // 1. Add a payment callback
            payment: function(data, actions) {
              // 2. Make a request to your server
              return actions.request.post('http://localhost:3000/my-api/create-payment/')
                .then(function(res) {
                  // 3. Return res.id from the response
                  //alert("Res ID="+res.id);
                  return res.id;
                });
            },
            // Execute the payment:
            // 1. Add an onAuthorize callback
            onAuthorize: function(data, actions) {
    
              return actions.request.post('http://localhost:3000/my-api/execute-payment/', {
                paymentID: data.paymentID,
                payerID:   data.payerID
              })
                .then(function(res) {
                  alert("Payment made!");
                });
            },
            onError: function (err) {
                  alert("err="+err);
            }
          }, '#paypal-button');
        </script>
    </body>
    
    </html>