超详细教程!手把手教你如何在轻流内实现支付宝扫码支付、银企直联

❓每次打款前,你都要核对三四遍卡号金额,生怕输错账户,打错款目

❓繁杂的付款工作占用大部分的工作时间,财务产出的整体价值不高

❓依靠人工手动从银端获取回款,不仅耗时长,而且效率低

用轻流,这些烦恼都可以统统甩开!

通过轻流丰富的 Open API 接口和强大的 Q-Linker、Webhook数据传输能力,直接在轻流系统内就可以实现支付宝收款/退款、银行卡转账并查询流水和电子回单啦!

(⚠️银企直联目前仅支持中国银行)

口说无凭,一起来看看实现效果吧👇

🌟实现步骤

教程目录:

⚠️Tips:

因步骤十分详尽所以较长,耐心些,按步骤操作就可以实现视频中的同款效果

(如果你还不是轻流用户,快点击👉注册👈,体验试用吧~)

 

支付宝扫码支付 教程

 

1、准备工作

  • 绑定产品——【当面付】,并进行开通

  • 接口加签方式设置

 

2、获取调用接口所需具体公共参数

以扫码付接口为例:alipay.trade.precreate(统一收单线下交易预创建)

  • appid:应用ID

其余参数根据文档要求来进行获取

3、表单设计

1. 支付宝订单预创建并支付

其中【生成支付链接】与【确认支付状态】为代码块,【生成支付二维码】为Q-Linker字段

1.1. 生成支付链接

1.1.1. 代码注释

具体调用接口文档:alipay.trade.precreate(统一收单线下交易预创建)

⚠️注意:所生成的二维码有效时间为2小时

app_id:需要替换成具体调用的应用ID

qf_field.{商品列表信息$$17B54DD0C$$},为表单中商品列表信息表格字段

其中以 field_169208787 为例,表示商品列表信息表格中商品数量子字段 ID

field_id 获取方式 《如何在代码块中分辨表格的不同列》

qf_field.{商户订单号$$17B54DD0A$$},为表单中商户订单号字段

qf_field.{订单总金额(单位为元)$$17B54DD0B$$},为表单中订单总金额(单位为元)字段

qf_field.{订单标题$$17B44C092$$},为表单中订单标题字段

应用私钥:只需要替换成具体调用的应用私钥


生成支付链接:

const axios = require(‘axios’);
const crypto = require(‘crypto’);
const { format } = require(‘date-fns’);const currentDate = new Date();
const formattedDate = format(currentDate, ‘yyyy-MM-dd HH:mm:ss’);
// 原始数据
const data = {
“timestamp”:formattedDate,
“method”: “alipay.trade.precreate”,
“app_id”: “2021003155650***”,
“sign_type”: “RSA2”,
“version”: “1.0”,
“charset”: “UTF-8”
};
const table = qf_field.{商品列表信息$$17B54DD0C$$};const goodsDetail = table.map(item => {
const newItem = {
“quantity”: item.field_169208787,
“goods_name”: item.field_169208786,
“goods_id”: item.field_169208785,
“price”: item.field_169208788
};
return newItem;
});//将新的 goods_detail 赋值给 data 中的 biz_content
data.biz_content =`{“out_trade_no”: qf_field.{商户订单号$$17B54DD0A$$},”total_amount”:qf_field.{订单总金额(单位为元)$$17B54DD0B$$},”subject”:qf_field.{订单标题$$17B44C092$$},”goods_detail”:${JSON.stringify(goodsDetail)}}`;// 第一步:剔除sign字段
const { sign, …dataWithoutSign } = data;// 第二步:剔除值为空的参数
const filteredData = Object.fromEntries(Object.entries(dataWithoutSign).filter(([key, value]) => value !== ”));// 第三步:按键的ASCII码值递增排序
const sortedParams = Object.keys(filteredData).sort();// 第四步:将排序后的参数与其对应的值按照”参数=参数值”的格式组合起来
const concatenatedParams = sortedParams.map(key => `${key}=${filteredData[key]}`).join(‘&’);// 第五步:生成待签名字符串
const signString = concatenatedParams;// 使用私钥对待签名字符串进行加密
const privateKey = `—–BEGIN PRIVATE KEY—–
MI****DANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAA……………
—–END PRIVATE KEY—–`;const signer = crypto.createSign(‘RSA-SHA256’);
signer.update(signString, ‘utf8’);
const signature = signer.sign(privateKey);
const sig=signature.toString(‘base64’);
const encodedSig = encodeURIComponent(sig);let config = {
method: ‘get’,
maxBodyLength: Infinity,
url: `https://openapi.alipay.com/gateway.do?timestamp=${formattedDate}&method=${data.method}&app_id=${data.app_id}&sign_type=${data.sign_type}&sign=${encodedSig}&version=${data.version}&charset=${data.charset}&biz_content=${data.biz_content}`
};axios(config).then(function (res) {
qf_output={‘data’:res.data}
});

 

1.1.2. 代码测试
1.1.3. 解析配置
1.1.4. 字段接收配置
1.2. 生成支付二维码

该字段为Q_Linker,调用接口将支付链接转为支付二维码(具体接口文档:生成二维码

  • 需要点击申请appid,去获取对应的app_id和app_srcret

1.2.1. Q-Linker 配置

  • URL:https://www.mxnzp.com/api/qrcode/create/single
  • QueryParam:

  • Method:GET
  • Json path:

  • 字段接收配置

 

1.3. 确认支付状态

1.3.1. 代码注释具体调用接口文档:alipay.trade.query(统一收单交易查询)

app_id:需要替换成具体调用的应用ID

qf_field.{商户订单号$$17B54DD0A$$},为表单中商户订单号字段

应用私钥:只需要替换成具体调用的应用私钥

 

确认支付状态:

const axios = require(‘axios’);
const crypto = require(‘crypto’);
const { format } = require(‘date-fns’);const currentDate = new Date();
const formattedDate = format(currentDate, ‘yyyy-MM-dd HH:mm:ss’);
// 原始数据
const data = {
“timestamp”:formattedDate,
“method”: “alipay.trade.query”,
“app_id”: “2021003155650***”,
“sign_type”: “RSA2”,
“version”: “1.0”,
“charset”: “UTF-8”
};
data.biz_content =`{“out_trade_no”: qf_field.{商户订单号$$17B54DD0A$$}}`;
// 第一步:剔除sign字段
const { sign, …dataWithoutSign } = data;

// 第二步:剔除值为空的参数
const filteredData = Object.fromEntries(Object.entries(dataWithoutSign).filter(([key, value]) => value !== ”));// 第三步:按键的ASCII码值递增排序
const sortedParams = Object.keys(filteredData).sort();// 第四步:将排序后的参数与其对应的值按照”参数=参数值”的格式组合起来
const concatenatedParams = sortedParams.map(key => `${key}=${filteredData[key]}`).join(‘&’);// 第五步:生成待签名字符串
const signString = concatenatedParams;// 使用私钥对待签名字符串进行加密
const privateKey = `—–BEGIN PRIVATE KEY—–
MII****BgkqhkiG9w0BAQEFAASCBKcwggSjAgEAA………………….
—–END PRIVATE KEY—–`;const signer = crypto.createSign(‘RSA-SHA256’);
signer.update(signString, ‘utf8’);
const signature = signer.sign(privateKey);
const sig=signature.toString(‘base64’);
const encodedSig = encodeURIComponent(sig);
let config = {
method: ‘get’,
maxBodyLength: Infinity,
url: `https://openapi.alipay.com/gateway.do?timestamp=${formattedDate}&method=${data.method}&app_id=${data.app_id}&sign_type=${data.sign_type}&sign=${encodedSig}&version=${data.version}&charset=${data.charset}&biz_content=${data.biz_content}`
};
axios(config).then(function (res) {
qf_output={‘data’:res.data}
});

1.3.2. 代码测试
1.3.3. 解析配置
1.3.4. 字段接收配置

1.4. 流程配置

1.4.1. 申请人节点配置
1.4.2. 确认支付信息并扫码支付
1.4.3. 告知用户

1.4.4. webhook节点

具体接口文档:单条数据流程回退接口
  • accessToken:轻商城——拓展插件——openAPI

  • 节点ID获取方式
可以调用接口来进行获取:获取单条数据的流程日志

2. 支付宝申请订单退款

2.1. 商户订单号

2.2. 订单总金额

 

2.3. 退款

2.3.1. 代码注释具体调用接口文档:alipay.trade.refund(统一收单交易退款接口)

⚠️注意:交易超过约定时间(签约时设置的可退款时间)的订单无法进行退款。

app_id:需要替换成具体调用的应用ID

qf_field.{商户订单号$$17B598970$$}:表单中商户订单号字段

qf_field.{退款金额$$17B598089$$}:表单中退款金额字段

qf_field.{退款原因说明$$17B59808A$$}:表单中退款原因说明字段

应用私钥:只需要替换成具体调用的应用私钥

退款:

const axios = require(‘axios’);
const crypto = require(‘crypto’);
const { format } = require(‘date-fns’);const currentDate = new Date();
const formattedDate = format(currentDate, ‘yyyy-MM-dd HH:mm:ss’);
// 原始数据
const data = {
“timestamp”:formattedDate,
“method”: “alipay.trade.refund”,
“app_id”: “2021003155650***”,
“sign_type”: “RSA2”,
“version”: “1.0”,
“charset”: “UTF-8”
};
data.biz_content =`{“out_trade_no”:qf_field.{商户订单号$$17B598970$$},”refund_amount”:qf_field.{退款金额$$17B598089$$},”refund_reason”:qf_field.{退款原因说明$$17B59808A$$}}`;
// 第一步:剔除sign字段
const { sign, …dataWithoutSign } = data;

// 第二步:剔除值为空的参数
const filteredData = Object.fromEntries(Object.entries(dataWithoutSign).filter(([key, value]) => value !== ”));// 第三步:按键的ASCII码值递增排序
const sortedParams = Object.keys(filteredData).sort();// 第四步:将排序后的参数与其对应的值按照”参数=参数值”的格式组合起来
const concatenatedParams = sortedParams.map(key => `${key}=${filteredData[key]}`).join(‘&’);// 第五步:生成待签名字符串
const signString = concatenatedParams;// 使用私钥对待签名字符串进行加密
const privateKey = `—–BEGIN PRIVATE KEY—–
MII*****NBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAA……………………
—–END PRIVATE KEY—–`;const signer = crypto.createSign(‘RSA-SHA256’);
signer.update(signString, ‘utf8’);
const signature = signer.sign(privateKey);
const sig=signature.toString(‘base64’);
const encodedSig = encodeURIComponent(sig);
let config = {
method: ‘get’,
maxBodyLength: Infinity,
url: `https://openapi.alipay.com/gateway.do?timestamp=${formattedDate}&method=${data.method}&app_id=${data.app_id}&sign_type=${data.sign_type}&sign=${encodedSig}&version=${data.version}&charset=${data.charset}&biz_content=${data.biz_content}`
};axios(config).then(function (res) {
qf_output={‘data’:res.data}});

2.3.2. 解析配置
2.3.3. 字段接收配置

 

 

银企直联(中国银行)教程

轻流实现中国银行的公对公转账公对私转账,查询流水,获取电子回执单功能

1、落地方案

需要二次开发,由中间件根据中国银行银企对接接口规范要求,封装以下四个接口:

    1. 公对公转账
    2. 公对私转账
    3. 查询流水
    4. 电子回单查询

1.1 转账

转账效果有两种:直接转出不提示,需要在中国银行app上确认,两种方式需要在银行柜台做变更

转账时序图

📚方案简述:

    • 在轻流发起转账,通过webhook携带三个参数访问中间件;
    • 中间件根据参数访问对应的前置机接口,前置机执行对应操作将转账消息加入银行队列
    • 根据转账的表现,银行执行转账操作时,会给中国银行app发送确认消息(或者直接转账成功,具体表现需要银行柜台进行修改)

 

1.2 查询流水

查询流水时序图

📚方案简述:

    • 查询银行流水为定时任务,根据业务需要可设置多久拉取一次
    • 拉取昨天和今天的流水数据,并在中间件解析成符合轻流要求的格式
    • 中间件通过QS被动将数据推送至轻流应用中,并比对更新

 

1.3 电子回单查询

电子回单查询时序图

📚方案简述:

  • 中间件访问回单下载接口后,前置机返回回单文件的名称
  • 银行生成请求时间段内的回单,回单为PDF文件,统一放在压缩文件内。
  • 中间件轮询是否已经生成回单文件,生成后将文件上传至对象存储服务,并返回文件的路径;
  • 中间件将返回的文件路径推送至轻流,并匹配至轻流上传附件字段。

🎉最终效果

  • 在轻流实现转账服务
  • 可在轻流应用中查询到流水和电子回单

⚠️备注

  • 银企直联属于银行系统,每年需要付款使用
  • 银行会提供前置机架构,所有对银行的请求都会先到前置机处理
  • 只有Windows的系统,不能云部署
  • 访问中国银行银企对接接口需要先签到,签到有效期为15分钟,可缓存登录状态

 

 

轻流

发表评论

电子邮件地址不会被公开。