You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Express PayPal支付流程的外部函数中获取amount变量?

How to Pass amount from /pay to /success Route in Express PayPal Integration

Got it, let's work through this problem. The key issue here is that after redirecting the user to PayPal's approval page and then back to your /success route, you lose access to the original req.body data from the /pay request. Here are three reliable approaches to share the amount value between these routes:

Session storage is a secure way to persist user-specific data across requests. Here's how to implement it:

First, install the express-session package if you haven't already:

npm install express-session

Then configure session middleware in your Express app (add this before your route definitions):

const session = require('express-session');

app.use(session({
  secret: 'your-strong-unique-secret-key', // Replace with a secure, unique secret
  resave: false,
  saveUninitialized: false,
  cookie: { secure: process.env.NODE_ENV === 'production' } // Enable secure cookies in production
}));

Modify your /pay route to store the amount in the session:

app.post("/pay", (req, res) => { 
  console.log(req.body); 
  const { amount , description , name } = req.body; 
  
  // Store the amount in the user's session
  req.session.paymentAmount = amount;

  const create_payment_json = { 
    intent: "sale", 
    payer: { 
      payment_method: "paypal", 
    }, 
    redirect_urls: { 
      return_url: "http://localhost:3000/success", 
      cancel_url: "http://localhost:3000/cancel", 
    }, 
    transactions: [ 
      { 
        item_list: { 
          items: [ 
            { 
              name: name, 
              sku: "001", 
              price: amount, 
              currency: "USD", 
              quantity: 1, 
            }, 
          ], 
        }, 
        amount: { 
          currency: "USD", 
          total: amount, 
        }, 
        description: description, 
      }, 
    ], 
  }; 
  paypal.payment.create(create_payment_json, function (error, payment) { 
    if (error) { 
      throw error; 
    } else { 
      for (let i = 0; i < payment.links.length; i++) { 
        if (payment.links[i].rel === "approval_url") { 
          res.redirect(payment.links[i].href); 
        } 
      } 
    } 
  }); 
}); 

Update your /success route to retrieve the amount from the session (and clear it after use):

app.get("/success", (req, res) => { 
  const payerId = req.query.PayerID; 
  const paymentId = req.query.paymentId;
  const amount = req.session.paymentAmount; // Fetch amount from session

  // Optional: Clear the session value to prevent accidental reuse
  delete req.session.paymentAmount;

  const execute_payment_json = { 
    payer_id: payerId, 
    transactions: [ 
      { 
        amount: { 
          currency: "USD", 
          total: amount, 
        }, 
      }, 
    ], 
  }; 
  paypal.payment.execute( 
    paymentId, 
    execute_payment_json, 
    function (error, payment) { 
      if (error) { 
        console.log(error.response); 
      } else { 
        console.log(JSON.stringify(payment)); 
        res.send("Success"); 
      } 
    } 
  ); 
});

2. Store Amount in PayPal Payment's Custom Field

You can embed the amount directly into the PayPal payment object using the custom field, then retrieve it when handling the success callback. This ties the data directly to the payment itself:

Modify the /pay route's create_payment_json to include the custom field:

const create_payment_json = { 
  intent: "sale", 
  payer: { 
    payment_method: "paypal", 
  }, 
  redirect_urls: { 
    return_url: "http://localhost:3000/success", 
    cancel_url: "http://localhost:3000/cancel", 
  }, 
  transactions: [ 
    { 
      item_list: { 
        items: [ 
          { 
            name: name, 
            sku: "001", 
            price: amount, 
            currency: "USD", 
            quantity: 1, 
          }, 
        ], 
      }, 
      amount: { 
        currency: "USD", 
        total: amount, 
      }, 
      description: description,
      custom: amount // Store the amount in this custom field
    }, 
  ], 
}; 

In the /success route, first fetch the payment details to get the custom value:

app.get("/success", (req, res) => { 
  const payerId = req.query.PayerID; 
  const paymentId = req.query.paymentId;

  // First retrieve the payment details to get the stored amount
  paypal.payment.get(paymentId, function(error, payment) {
    if (error) {
      console.log(error.response);
      return res.send("Error retrieving payment details");
    }

    const amount = payment.transactions[0].custom; // Extract amount from custom field

    const execute_payment_json = { 
      payer_id: payerId, 
      transactions: [ 
        { 
          amount: { 
            currency: "USD", 
            total: amount, 
          }, 
        }, 
      ], 
    }; 

    paypal.payment.execute( 
      paymentId, 
      execute_payment_json, 
      function (error, payment) { 
        if (error) { 
          console.log(error.response); 
        } else { 
          console.log(JSON.stringify(payment)); 
          res.send("Success"); 
        } 
      } 
    );
  });
});

3. Avoid: Pass Amount via Return URL Parameters

While you could append the amount to your return_url like http://localhost:3000/success?amount=${amount}, this is not recommended. URLs are easily tampered with, so a malicious user could modify the amount parameter before returning to your site, leading to incorrect payment execution. Only use this method for non-sensitive data.


内容的提问来源于stack exchange,提问作者AnonymousKing

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.30 09:42:30