使用Node.js集成Razorpay支付
支付网关是一种提供在线金融交易解决方案的技术,可以将其视为电子商务或任何在线业务的中间渠道,用于进行支付和接收任何目的的付款。
示例问题陈述: 这是一个简单的HTML页面,我们在页面上有一个按钮,用于支付499.00卢比的金额。最终,用户将点击该按钮,我们希望以某种方式接收该金额,然后我们可以决定如何提供课程的访问权限,但这不是本文章讨论的内容。
方法: Razorpay是一种流行的支付网关,它使我们能够访问包括信用卡、借记卡、网银、UPI和其他钱包(如airtel money、payZapp等)在内的所有支付方式。它还提供了一个仪表板,可以监控所有活动。它可以与任何在线应用程序集成,使在线企业与客户的互动变得更加容易。Razorpay帮助我们提供和处理所有必要的功能。在这里,我们将讨论如果我们的应用程序的后端是NodeJS,我们如何实现这一点。
服务器与前端之间的通信的示意流程图
这是内部所有事物如何相互交互的基本图表,如果从1到8的每个步骤都成功,则我们将成功地实现我们的目标。从步骤1到4,我们正在创建订单并接收响应,然后从步骤5到6,我们正在接收该订单的付款,最后两个步骤中,我们正在验证响应的真实性,即它是否来自Razorpay服务器。箭头根据时间进行设计。
步骤一步实施:
步骤1: 首先,在终端中输入以下命令以创建一个Node.js应用程序。
这将要求您针对您的项目进行一些配置,您可以相应地填写它们,还可以稍后从package.json文件中进行更改。然后为后端服务器创建一个 app.js 文件,并为前端创建一个 index.html 文件。
步骤2: 现在,安装所需的模块。
项目结构: 它将如下所示。
步骤3: 想要访问Razorpay的API,您必须先获取密钥,因此请前往Razorpay注册并进入仪表板中的设置部分, 点击生成API密钥,然后您将获得key_id和key_secret,通过这些密钥您可以获取到Razorpay实例。
步骤4: 导入Razorpay并创建一个 新实例 的Razorpay,该实例在访问Razorpay的任何资源时都是必需的。在构造函数中提供一个包含key_id和key_secret的对象。
以下是后端和前端的基本初始代码实现。
App.js
index.html
步骤5: 从前端向我们的NodeJS服务器发送订单信息。
在 app.js 中创建一个路由来接收用户请求的订单数据,这里我们使用express因为它更简单并且被许多开发者使用。我们在我们的NodeJS服务器app.js中设置了 ‘/createOrder’ 路由来接收来自客户端的数据,并且我们从‘ req. body’ 中发送订单数据。
为了简化事情,这里使用了Postman作为客户端,您可以根据自己的方式很容易地从前端发送post请求。
注意: 在与服务器交互之前,请确保每次成功运行服务器。
步骤6: 从我们的NodeJS服务器向Razorpay服务器发送订单信息。
我们从 req.body 提取出了订单信息在我们的服务器上,现在我们需要将它发送到Razorpay服务器进行进一步处理。之前我们创建的razorpayInstance将用于从Razorpay访问订单API,并且create是创建订单的方法,它接受两个参数,第一个是选项对象,另一个是回调函数,回调函数会根据成功或失败提供给我们响应。
App.js
步骤7: 收到来自Razorpay的订单响应并发送到我们的NodeJS服务器。
然后,Razorpay服务器处理收到的数据并从其服务器发送订单响应,这里我们合并了第3步和第4步,因为在这个小项目中将它们分开没有意义,分离在使用真实数据库和足够大的项目时可能会有用。下面是来自Razorpay服务器的成功返回响应。
说明:
我们从Razorpay服务器收到了一个JSON响应,状态码为200,这意味着一切正常,订单已成功创建。JSON的说明如下:
id :一个唯一的订单ID,在支付过程中会使用。
entity :一个缩写,表示该响应对应的任何订单。
amount :订单的总金额,以 货币的最小单位 表示。
amount_paid :订单的支付金额,用于部分支付时。
amount_due :总金额减去部分支付金额。
currency :金额的货币类型,可以在这里查看支持的货币列表。
receipt :订单的收据。
offer_id :用于享受某些优惠,当订单有折扣或特别优惠时使用。
status :订单的状态,例如:订单已创建、已尝试或已支付。
attempts :用户尝试支付的总次数。
notes :这是一个简单的附加信息对象。
created_at :订单创建的时间,采用UNIX时间格式。
下面是在Razorpay Dashboard上创建的订单和状态为”created”,这意味着订单刚刚被创建,如果后续的支付失败,状态将变为”attempted”,如果成功,状态将变为”paid”。
注意:我们正在一个API端点“/createOrder”中处理所有初始流程,但是随着项目的发展,根据需要将所有内容进行分离是很好的。
步骤8:从前端发送请求到Razorpay服务器以捕获付款。
现在,我们已经创建了一个订单,我们可以继续结账以接收金额。下面是Razorpay提供的在index.html中使用的代码片段,它自己处理所有事情,从在前端渲染模态UI到在后端处理付款结账,它需要的是一些配置、与银行/钱包相关的凭据和订单ID。
index.html
解释:
第一个脚本标签在加载一个来自Razorpay服务器的js文件。它里面有一些代码,负责执行整个代码片段。在第二个脚本标签中,我们创建了一个对象,稍后将发送到Razorpay服务器以进行付款处理。
这是关于选项的描述,带*的字段是必填的,其他字段是可选的,它们在Razorpay服务器上有默认值。
1. key: 您从仪表板获得的Razorpay key_id。
2. amount: 要支付的金额。
3. currency: 三个字符的货币字符串。
4. Name: 公司名称,将显示在UI模态框中。
5. order_id: 必须是由Razorpay生成的有效订单ID,我们将使用之前创建的订单ID。
6. description: 购买的简单描述,也将显示在模态框中。
7. image: Logo的链接,最小尺寸为256×256像素,最大大小为1MB,用于显示在模态框中的公司Logo,在我们的示例中,我们使用的是一个虚拟的Logo。
8. handler: 这是一个在付款成功时将被执行的函数,我们只是弹出一个警告和打印到控制台,但是可以很容易地修改以定制功能。
9. theme: 一个对象,可以用来根据您的应用程序UI设置模态框的主题,例如,您可以使用十六进制代码设置颜色和背景颜色。
10. prefill: 在UI呈现时要预填的详细信息,例如,您可以预填电子邮件和姓名,以免用户被询问。此外,如果您可以知道用户的历史,您还可以根据他的偏好预填付款方式。
11. notes: 这是一个用于附加信息的简单对象。
Razorpay还有更多在此未使用的选项,您可以根据它们自定义应用程序。现在,在所有这些之后,我们调用了Razorpay函数,该函数在第一个脚本标签所包含的文件中声明,它以对象参数形式接收,并返回一个Razorpay对象,该对象具有一些预定义的和用户定义的功能,这就是为什么Razorpay要求我们配置选项。让我们来看一下通过使用console.log来查看这些细节。
我们有很多返回的数据,比如,模态对话框在我们点击相应按钮后将在屏幕上呈现,事件’payment.failed’注册的函数意味着我们会在稍后看到如何使用它,还有id和其他必需的内容。现在回到代码解释,在获取Razorpay对象后,我们注册了一个回调函数,该函数在事件’ payment.failed ‘时执行,这是由Razorpay进行配置的。随后,我们使用了一个基本的Web API来根据id获取元素,该元素选择与该id相关联的按钮并执行函数。 razorpayObject.open(); 打开一个包含所有必要功能的模态窗口,以进行结账。
e.preventDefault(); 阻止浏览器对事件进行默认配置。
输出:
上述输出的解释如下:
- 用户点击与支付相关的按钮。
- Razorpay提供的模态框打开在窗口中央,您是否注意到在发送请求之前设置的公司名称、描述和徽标在这里呈现,联系电话和电子邮件也已预填。
- 即使我们预填了一些详细信息,但在进行付款过程中我们仍然可以更改它们。
- 然后,我们可以继续支付,假设我们选择了信用卡支付方式,在这里我们输入了一个虚拟信用卡详细信息“卡号4111 1111 1111 1111”,有效期可以是任意将来的月/年,CVV可以是任意三位数字,卡持有人的姓名也在此处预填,但您可以在继续之前进行编辑。
- 然后,Razorpay将立即处理支付。
- 付款完成后,Razorpay再次要求您是否同意支付,点击“成功”继续支付或点击“失败”拒绝。
步骤9: 从Razorpay接收付款响应到前端。
在成功完成步骤8后,我们将在前端收到Razorpay的响应,其中包括付款ID、签名、订单ID等。否则,响应将是失败的,同时还会附带一些失败的原因。下面是成功返回的响应的console.log。
步骤10: 从前端向我们的NodeJS服务器发送支付响应
我们在服务器上创建了一个名为 ‘/verifyOrder’ 的API端点来接收支付数据。在这里,我们使用Postman作为客户端发送数据,您可以以自己的方式发送数据的POST请求。
从支付响应中收到的签名已通过 自定义标头 “x-razorpay-signature”发送,将“x-”放在标头名称之前是一种惯例,而支付ID和订单ID则已从 请求体中发送。
步骤11:验证真实性并向用户发送相应的回应
尽管我们已经收到了付款,但如果没有验证,我们无法向用户发送响应。因此,这是验证步骤,正如您所知,我们收到了一些东西,如razorpay_payment_id、razorpay_order_id、razorpay_signature以及一些其他关于成功付款的信息。现在,您要如何知道这些信息对应于有效的付款,并且它必须已经在您的Razorpay仪表板中被捕获了呢?因为可能会有某些情况,某人可能以某种方式发送虚假的响应,而您将把该付款视为已捕获的。因此,为了验证,请使用服务器上使用已完成付款的order_id和从响应中返回的razorpay_payment_id创建一个签名,同时在此步骤中,您还将需要在生成API密钥时从控制面板上获得的key_secret。
现在使用 SHA256算法, 它是一个加密函数,接收一些参数并返回一个密码哈希,可以根据所给的密钥代码来验证某些内容。根据 预定义的Razorpay语法 构建一个 HMAC十六进制 摘要:
注意:- 如果您的应用程序足够大,并且不想每次都进行此验证,有一种简单的方法可以在Razorpay仪表板上设置webhook(webhook是根据实时事件将信息发送到另一个应用程序的方法),您可以探索一下。
app.js
输出:
这是我们从验证订单API接收到的响应,由于我们的付款是真实的,它返回了一个成功的响应,状态码200表示一切都正常。
现在就是这样了,通过这一系列操作,我们成功创建了一个订单,收到了款项,并且验证了其真实性。
这是支付和订单的 分账簿 ,显示在仪表板上,被捕获的状态意味着我们成功收到了款项,而已支付意味着订单金额已经支付。