在您的 React 应用中集成 Razorpay 支付网关
什么是 Razorpay?
Razorpay 是印度的一种支付解决方案,允许企业使用所有支付方式,包括信用卡、借记卡、网上银行、UPI 和其他流行的钱包。
Don't confuse India-only business with single currency payments.
Razorpay accepts payments in almost all currencies.
在我们的应用程序中集成支付网关之前,让我们了解一下razorpay 的支付流程。
付款流程
- 客户在您的网站或应用上下订单
- 您使用 Razorpay 实例从您的服务器创建订单。
- 然后,您将订单 ID 传递给结账处并收集付款详情。
- 然后,通过验证 Razorpay 返回的签名,在您的后端对付款进行身份验证。
- 捕获付款。
这是 Razorpay 支付流程的概览图。
您可以点击此处实时试用该支付流程。
让我们将 Razorpay 集成到我们的应用中
创建 Razorpay 账户
前往Razorpay 控制面板并创建一个您自己的账户。无需激活,因为我们将立即开始操作Test mode
。
前往Settings
选项卡,生成您的文件API keys
并将其保存到某个地方。我们稍后会用到它。
创建我们的服务器
在您的电脑上创建一个文件夹并npm
在该文件夹上进行初始化。
npm init
我们需要为服务器安装一些依赖项。
安装这些依赖项。
- 表达
- razorpay
- dotenv
- 加密(用于最后一步验证签名)
- mongoose(可选:如果您想将详细信息保存在数据库中)
npm i express razorpay dotenv crypto mongoose
server.js
现在在根目录中创建一个文件并初始化您的 express 服务器。
const express = require("express");
const app = express();
const port = process.env.PORT || 5000;
// middlewares
app.use(express.json({ extended: false }));
app.listen(port, () => console.log(`server started on port ${port}`));
现在我们的服务器正在运行localhost:5000
,我们需要在后端添加一些路线来处理支付步骤。
保存 API 密钥
我们将使用.env
文件来保存密钥。.env
在根目录中创建一个文件。在文件
中添加以下代码.env
,并将值替换为您的密钥。
RAZORPAY_SECRET=<your razorpay secret>
RAZORPAY_KEY_ID=<your razorpay ket id>
Don't add any quotes.
添加创建订单的路线
routes
在根目录中创建一个名为的新文件夹,并在文件夹payment.js
中添加一个新文件routes
。
- 我们需要创建一条
POST
路线来创建订单。 - 为此,我们必须创建 Razorpay 的一个实例。
- 然后我们会打电话
instance.orders.create()
require("dotenv").config();
const express = require("express");
const Razorpay = require("razorpay");
const router = express.Router();
router.post("/orders", async (req, res) => {
try {
const instance = new Razorpay({
key_id: process.env.RAZORPAY_KEY_ID,
key_secret: process.env.RAZORPAY_SECRET,
});
const options = {
amount: 50000, // amount in smallest currency unit
currency: "INR",
receipt: "receipt_order_74394",
};
const order = await instance.orders.create(options);
if (!order) return res.status(500).send("Some error occured");
res.json(order);
} catch (error) {
res.status(500).send(error);
}
});
Note:
金额需要采用最小货币单位,例如,对于 500 卢比,您必须在金额变量中指定 50000
现在将此payment.js
路由文件导入到你的server.js
文件中以启用路由。现在你的server.js
文件将如下所示……
const express = require("express");
const app = express();
const port = process.env.PORT || 5000;
// middlewares
app.use(express.json({ extended: false }));
// route included
app.use("/payment", require("./routes/payment"));
app.listen(port, () => console.log(`server started on port ${port}`));
现在我们需要一个前端表单,用于发出创建订单的请求。
创建 React 应用
我们将在根目录中创建 React 应用程序。
npx create-react-app client
我已将应用命名为client
。您可以随意命名。
完成这些之后,让我们回顾一下文件夹结构,以免您感到困惑。
现在让我们清理所有 React 样板代码。
清理完成后,你的 React 应用文件夹应该如下所示。你可以从文件夹中删除所有无用的文件。
还可以安装axios
在您的 react app 文件夹中,以便向后端发出请求。
cd client
npm i axios
添加按钮以启动付款流程
转到App.js
文件并用以下内容替换所有代码。
import React from "react";
import logo from "./logo.svg";
import "./App.css";
import axios from "axios";
function App() {
return (
<div className="App">
<header className="App-header">
<img src={logo} className="App-logo" alt="logo" />
<p>Buy React now!</p>
<button className="App-link" onClick={displayRazorpay}>
Pay ₹500
</button>
</header>
</div>
);
}
export default App;
可以看到,我只添加了一个按钮,并displayRazorpay
为onClick
事件分配了一个函数。现在让我们创建这个函数。
点击按钮时,我们需要执行三件事。
- 加载
Razorpay checkout script
为我们在后台完成所有工作的。 POST
向我们的后端路由发出请求/payment/orders
以创建一个新订单,该订单将返回订单的详细信息,包括id
和amount
。- 然后使用它
id
并amount
最终显示 Razorpay 弹出窗口。
为了加载脚本,我添加了一个函数loadScript
,该函数以script src
字符串作为输入并返回Promise
加载脚本的函数。
function loadScript(src) {
return new Promise((resolve) => {
const script = document.createElement("script");
script.src = src;
script.onload = () => {
resolve(true);
};
script.onerror = () => {
resolve(false);
};
document.body.appendChild(script);
});
}
然后我将添加displayRazorpay
函数first load the script
,then make a post request to our back-end route
和finally show the popup
。
async function displayRazorpay() {
const res = await loadScript(
"https://checkout.razorpay.com/v1/checkout.js"
);
if (!res) {
alert("Razorpay SDK failed to load. Are you online?");
return;
}
// creating a new order
const result = await axios.post("http://localhost:5000/payment/orders");
if (!result) {
alert("Server error. Are you online?");
return;
}
// Getting the order details back
const { amount, id: order_id, currency } = result.data;
const options = {
key: "rzp_test_r6FiJfddJh76SI", // Enter the Key ID generated from the Dashboard
amount: amount.toString(),
currency: currency,
name: "Soumya Corp.",
description: "Test Transaction",
image: { logo },
order_id: order_id,
handler: async function (response) {
const data = {
orderCreationId: order_id,
razorpayPaymentId: response.razorpay_payment_id,
razorpayOrderId: response.razorpay_order_id,
razorpaySignature: response.razorpay_signature,
};
const result = await axios.post("http://localhost:5000/payment/success", data);
alert(result.data.msg);
},
prefill: {
name: "Soumya Dey",
email: "SoumyaDey@example.com",
contact: "9999999999",
},
notes: {
address: "Soumya Dey Corporate Office",
},
theme: {
color: "#61dafb",
},
};
const paymentObject = new window.Razorpay(options);
paymentObject.open();
}
对于每笔成功付款,结帐都会返回:
- razorpay_payment_id
- razorpay_order_id
- razorpay_签名
我们可以在属性中访问这些值handler
。正如您所见,我向新的后端路由发出了请求,并将order id
之前创建订单时收到的详细信息发送到了 。这是为了验证付款是否合法。
Don't confuse the "razorpay_order_id" with the "order_id" we got
while creating a new order. These two are entirely different.
现在您的App.js
文件应该如下所示。
import React from "react";
import logo from "./logo.svg";
import "./App.css";
import axios from "axios";
function App() {
function loadScript(src) {
return new Promise((resolve) => {
const script = document.createElement("script");
script.src = src;
script.onload = () => {
resolve(true);
};
script.onerror = () => {
resolve(false);
};
document.body.appendChild(script);
});
}
async function displayRazorpay() {
const res = await loadScript(
"https://checkout.razorpay.com/v1/checkout.js"
);
if (!res) {
alert("Razorpay SDK failed to load. Are you online?");
return;
}
const result = await axios.post("http://localhost:5000/payment/orders");
if (!result) {
alert("Server error. Are you online?");
return;
}
const { amount, id: order_id, currency } = result.data;
const options = {
key: "rzp_test_r6FiJfddJh76SI", // Enter the Key ID generated from the Dashboard
amount: amount.toString(),
currency: currency,
name: "Soumya Corp.",
description: "Test Transaction",
image: { logo },
order_id: order_id,
handler: async function (response) {
const data = {
orderCreationId: order_id,
razorpayPaymentId: response.razorpay_payment_id,
razorpayOrderId: response.razorpay_order_id,
razorpaySignature: response.razorpay_signature,
};
const result = await axios.post("http://localhost:5000/payment/success", data);
alert(result.data.msg);
},
prefill: {
name: "Soumya Dey",
email: "SoumyaDey@example.com",
contact: "9999999999",
},
notes: {
address: "Soumya Dey Corporate Office",
},
theme: {
color: "#61dafb",
},
};
const paymentObject = new window.Razorpay(options);
paymentObject.open();
}
return (
<div className="App">
<header className="App-header">
<img src={logo} className="App-logo" alt="logo" />
<p>Buy React now!</p>
<button className="App-link" onClick={displayRazorpay}>
Pay ₹500
</button>
</header>
</div>
);
}
export default App;
如果你启动 React 应用,该应用在浏览器中应该看起来像这样
如果您单击该Pay ₹500
按钮,就会出现一个弹出窗口。
但不要立即付款。我们需要在后端添加另一条路由来验证付款。
验证付款
这一步我们只需要在后端自己创建一个签名,并检查我们的签名是否与razorpay发送的签名相同。
记住,付款成功后,我们的React应用会将四个值发送回后端路由/payment/success
。
- orderCreationId(订单 ID,我们在创建订单时获取)
- razorpay付款ID
- razorpay订单号
- razorpay签名
我们需要使用 SHA256 算法,使用razorpayPaymentId
和orderCreationId
构建 HMAC 十六进制摘要。然后将digest
和进行比较razorpaySignature
。如果两者相等,则我们的付款已验证。
创建验证路线
导航到文件夹payment.js
内的文件routes
并遵循以下POST
路线。
router.post("/success", async (req, res) => {
try {
// getting the details back from our font-end
const {
orderCreationId,
razorpayPaymentId,
razorpayOrderId,
razorpaySignature,
} = req.body;
// Creating our own digest
// The format should be like this:
// digest = hmac_sha256(orderCreationId + "|" + razorpayPaymentId, secret);
const shasum = crypto.createHmac("sha256", "w2lBtgmeuDUfnJVp43UpcaiT");
shasum.update(`${orderCreationId}|${razorpayPaymentId}`);
const digest = shasum.digest("hex");
// comaparing our digest with the actual signature
if (digest !== razorpaySignature)
return res.status(400).json({ msg: "Transaction not legit!" });
// THE PAYMENT IS LEGIT & VERIFIED
// YOU CAN SAVE THE DETAILS IN YOUR DATABASE IF YOU WANT
res.json({
msg: "success",
orderId: razorpayOrderId,
paymentId: razorpayPaymentId,
});
} catch (error) {
res.status(500).send(error);
}
});
现在所有步骤都已完成。
您可以继续付款,如果付款成功,您可以在标签页中查看付款Razorpay Dashboard
。Transactions
以下
是一些演示卡的详细信息,您可以使用它们来测试付款流程Test mode
。
使用未来任何有效的到期日期和任何随机 CVV 码即可成功付款。
准备就绪后,您可以在正式开始使用之前切换并激活您的账户。您将获得Live mode
一套新的。API keys
Live mode
您可以在我的Github repo中找到所有源代码。
当你在那里时,不要忘记在 Github 上关注我
非常感谢您的阅读。
我还会写一篇关于Stripe 与 React 集成的文章。敬请期待!
在网络上找到我🕸:
- 💻访问我的网站
- 🌟 查看我的Substack
- 😸 在 GitHub 上查看我的Repos
- 🦊 在 GitLab 上查看我的仓库
- 📦 在 NPM 上检查我的软件包
- 🔗在 LinkedIn 上查看我的个人资料
- 📝在 Dev.to 上查看我的博客
- 😜 在Instagram上关注我
- 📚 查看我的Goodreads 个人资料
- 📪在这里联系我