node支付宝支付及同步、异步通知、主动查询支付宝订单状态

一、 如何开通支付宝支付

1.1、 支付宝认证

先要说明一点,个人和企业,都可以开通支付宝支付。但两者都需要经过认证后,才能在项目中集成支付宝支付功能。要求是:

  • 个人用户:要通过个体工商户验证,需要个体工商户营业执照。
  • 企业用户:要通过企业实名认证,需要企业营业执照。
    也就说,无论你是用个人身份,还是企业身份,都得有对应的营业执照。所以,如果没有注册个体工商户,没有注册企业,项目里是无法集成支付宝支付的。

支付宝个人账号认证个体工商户
支付宝企业账号注册及实名认证

1.2、创建应用

认证通过后,现在就可以去创建应用了,打开支付宝开放平台链接。在登录后,按照表单要求,先创建一个应用。

在这里插入图片描述

  • 各种信息,大家根据需要自己填写就好。
  • 应用类型,选择网页应用。
  • 这里要注意,用来集成支付的站点,必须是通过 ICP 备案的!
    完成后,点击控制台,切换到网页/移动应用里,可以看到刚才创建的应用了。

1.3、应用的appId

在这里插入图片描述

  • 注意看,在应用名字下面的那一串数字叫做appId,每个人的都不同。
  • 再打开 Node 项目的.env文件,环境变量里加上:
ALIPAY_APPID=
  • 将刚才复制的appId,粘贴进去。

1.4、 配置接口加签方式

接着,点击右侧的详情,这里能看到自己应用的一些信息,点击左侧的开发设置

在这里插入图片描述
里需要将自己的密钥,或者证书传进来,才能使用支付宝的相关接口。密钥和证书,两种方式的区别是:

  • 使用密钥方式,除了不能支出资金,其他全都适用。
  • 所以如果你的项目要实现转账出去,或者发红包等支出操作,就要选择证书了。

我们的项目,并不涉及到支出操作,仅仅是为了收款。所以我们这里就简单点,选择密钥方式。
在这里插入图片描述

1.5、 密钥工具

按照网站的说明,我们下载密钥工具。完成后,大家直接安装就好。

在这里插入图片描述
在这里插入图片描述

1.6、 应用公钥与支付宝公钥

现在就会生成一对应用公钥应用私钥,先复制一下上面的应用公钥。

在这里插入图片描述
回到刚才支付宝的网站里,点击下一步,粘贴到里面,再点击确认上传。

在这里插入图片描述
在这里插入图片描述
支付宝会生成一个支付宝公钥给你。大家不要搞混了。我们上传的是应用公钥,而支付宝给我们的是支付宝公钥

这个支付宝公钥,才是在 Node 项目里,调用支付宝接口所需要的。点击下复制

在这里插入图片描述
打开项目的.env文件,增加

ALIPAY_PUBLIC_KEY=

并把刚才复制的支付宝公钥粘贴进来。

1.7、应用私钥

密钥工具里,还生成了个应用私钥。但它这里生成的是PKCS8格式,这种格式是给Java用的。我们在Node项目里,或者在其他语言里使用,需要转换为PKCS1格式。复制一下应用私钥

在这里插入图片描述
然后点击格式转换,将刚复制的应用私钥粘贴进去,点击转换,就得到了转好的格式了。

在这里插入图片描述
我们将转换好的应用私钥复制一下,打开.env,增加:

ALIPAY_APP_PRIVATE_KEY=

1.8、 回顾各种密钥

至此,各种密钥就都配置完成了。流程有点繁琐,回顾一下刚才的操作,这里一共有三个密钥,应用公钥、应用私钥和支付宝公钥,其中:

  • 应用公钥、应用私钥都是用密钥工具生成的。
  • 然后将应用公钥上传到支付宝的网站里,它会换给我们支付宝公钥,要将这个值保存在环境变量中。
  • 应用私钥,需要将格式转换一下后,也保存在环境变量中。
  • 这样环境变量中,目前一共是三个值:appId、支付宝公钥、转换了格式的应用私钥。大家一定要仔细些,不要搞错了。

1.9、 上线应用

在这里插入图片描述

1.10、 开通产品

最后一步,需要开通产品,访问产品中心网址

在这里插入图片描述

二、 实现支付宝支付

现在基础的准备工作就完成了,我们终于可以开始开发了。站点中集成支付宝,需要使用:Alipay SDK。

2.1. 安装 alipay-sdk

npm i alipay-sdk

2.2、 初始化 SDK

继续看文档,它这里提供了初始化 SDK 的方法,可以使用公钥或者证书。我们这用的是公钥,那就看第一种方式:普通公钥模式
在这里插入图片描述
它这里是将密钥保存为文件了,然后用 Node 直接读取文件。而我们是将密钥放在环境变量了,所以不用这么麻烦,直接调用就行。新建utils/alipay.js文件,参考它这里的写法,将参数值,全都改为环境变量中读取。

const {
   
    AlipaySdk } = require('alipay-sdk');

const alipaySdk = new AlipaySdk({
   
   
  appId: process.env.ALIPAY_APPID,
  privateKey: process.env.ALIPAY_APP_PRIVATE_KEY,
  alipayPublicKey: process.env.ALIPAY_PUBLIC_KEY
});

module.exports = alipaySdk;

2.3、 查询订单

新建一个路由文件:routes/alipay.js,在这里,我们要查询订单,和实现支付功能

const express = require('express')
const router = express.Router()
const {
   
    User, Order } = require('../models');
const {
   
    success, failure } = require('../utils/responses');
const {
   
    NotFound, BadRequest } = require('http-errors');
const alipaySdk = require('../utils/alipay');
const userAuth = require('../middlewares/user-auth');
const moment = require('moment');
const logger = require('../utils/logger');

/**
 * 公共方法:查询当前订单
 * @param req
 * @returns {Promise<*>}
 */
async function getOrder(req) {
   
   
  const {
   
    outTradeNo } = req.body;
  if (!outTradeNo) {
   
   
    throw new BadRequest('订单号不能为空。');
  }

  const order = await Order.findOne({
   
   
    where: {
   
   
      outTradeNo: outTradeNo,
      userId: req.userId
    }
  });

  // 用户只能查看自己的订单
  if (!order) {
   
   
    throw new NotFound(`订单号: ${
     
     outTradeNo} 的订单未找到。`)
  }

  if (order.status > 0) {
   
   
    throw new BadRequest('订单已经支付或失效,无法付款。')
  }

  return order;
}

module.exports = router;

  • 在查询的时候,还要指明userId是当前登录用户的id,因为用户只能对自己订单进行支付。
  • 继续要判断下,如果订单的状态大于1,就表示订单已经支付,或者取消了,是不能支付的。
  • 只有状态是0的订单,才是未付款的,能正常支付的订单。

2.4、 实现支付代码

我们要做的是网站支付,找到 pageExecute 这个地方,这就是网站里集成支付的方法。但这里的文档写的十分简陋,我们先一起简单看一下。

在这里插入图片描述

  • 里面的bizContent,很显然,这是订单相关的一些参数。
  • 下面有两处都调用了pageExecute,第一个是用了POST,它是生成了一个HTML格式的Form表单。用户可以通过这个表单,直接付款。
  • 第二个的代码,是将POST改为了GET。用这种方式,可以生成了一个支付链接。用户访问这个链接地址,就可以跳转到支付宝网站上付款了。

生成表单的方式,我觉得用户体验不太好。我们选择第二种方法,使用GET参数,跳转到支付宝网站去付款。继续添加一个路由,实现支付

/**
 * 支付宝支付
 * POST /alipay/pay/page    电脑页面
 * POST /alipay/pay/wap     手机页面
 */
router.post('/pay/:platform', userAuth, async function (req, res, next) {
   
   
  try {
   
   
    // 判断是电脑页面,还是手机页面
    const isPC = req.params.platform === 'page';
    const method = isPC ? 'alipay.trade.page.pay' : 'alipay.trade.wap.pay';
    const productCode = isPC ? 'FAST_INSTANT_TRADE_PAY' : 'QUICK_WAP_WAY';

    // 支付订单信息
    const order = await getOrder(req);
    const {
   
    outTradeNo, totalAmount, subject } = order;
    const bizContent = {
   
   
      product_code: productCode,
      out_trade_no: outTradeNo,
      subject: subject,
      total_amount: totalAmount
    };

    // 支付页面接口,返回 HTML 代码片段
    
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值