⡖⠒⠒⠒⠤⢄⠀⠀⠀
⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢸ ⠀⠀⠀⡼⠀⠀⠀⠀ ⠀
⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢶⣲⡴⣗⣲⡦⢤⡏⠀⠀⠀⠀⠀
⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣰⠋⠉⠉⠓⠛⠿⢷⣶⣦⠀⠀⠀
⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢠⠇⠀⠀⠀⠀⠀⠀⠘⡇⠀⠀⠀⠀
⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⡞⠀⠀⠀⠀⠀⠀⠀⢰⠇⠀⠀⠀⠀
⠀⠀⠀⠀⠀⠀⠀⠀⡴⠊⠉⠳⡄⠀⢀⣀⣀⡀⠀⣸⠀⠀⠀⠀⠀
⠀⠀⠀⠀⠀⠀⠀⢸⠃⠀⠰⠆⣿⡞⠉⠀⠀⠉⠲⡏⠀⠀⠀⠀⠀
⠀⠀⠀⠀⠀⠀⠀⠈⢧⡀⣀⡴⠛⡇⠀⠈⠃⠀⠀⡗⠀⠀⠀⠀⠀
⠀⠀⠀⠀⠀⠀⠀⠀⠀⣿⣱⠃⡴⠙⠢⠤⣀⠤⡾⠁⠀⠀⠀⠀⠀
⠀⠀⠀⠀⠀⠀⠀⠀⢀⡇⣇⡼⠁⠀⠀⠀⠀⢰⠃⠀⠀⠀⠀⠀⠀
⠀⠀⠀⠀⠀⠀⠀⠀⣸⢠⣉⣀⡴⠙⠀⠀⠀⣼⠀⠀⠀⠀⠀⠀⠀
⠀⠀⠀⠀⠀⠀⠀⠀⡏⠀⠈⠁⠀⠀⠀⠀⢀⡇⠀⠀⠀⠀⠀⠀⠀
⠀⠀⠀⠀⠀⠀⠀⢸⠃⠀⠀⠀⠀⠀⠀⠀⡼⠀⠀⠀⠀⠀⠀⠀⠀
⠀⠀⠀⠀⠀⠀⠀⢸⠀⠀⠀⠀⠀⠀⠀⣰⠃⠀⠀⠀⠀⠀⠀⠀⠀
⠀⠀⠀⠀⠀⣀⠤⠚⣶⡀⢠⠄⡰⠃⣠⣇⠀⠀⠀⠀⠀⠀⠀⠀⠀
⠀⢀⣠⠔⣋⣷⣠⡞⠀⠉⠙⠛⠋⢩⡀⠈⠳⣄⠀⠀⠀⠀⠀⠀⠀
⠀⡏⢴⠋⠁⠀⣸⠁⠀⠀⠀⠀⠀ ⠀⣹⢦⣶⡛⠳⣄⠀⠀⠀⠀⠀
⠀⠙⣌⠳⣄⠀⡇ 不能 ⡏⠀⠀ ⠈⠳⡌⣦⠀⠀⠀⠀
⠀⠀⠈⢳⣈⣻⡇ 白嫖 ⢰⣇⣀⡠⠴⢊⡡⠋⠀⠀⠀⠀
⠀⠀⠀⠀⠳⢿⡇⠀⠀⠀⠀⠀⠀⢸⣻⣶⡶⠊⠁⠀⠀
⠀⠀⠀⠀⠀⢠⠟⠙⠓⠒⠒⠒⠒⢾⡛⠋⠁⠀⠀⠀⠀⠀⠀⠀⠀
⠀⠀⠀⠀⣠⠏⠀⣸⠏⠉⠉⠳⣄⠀⠙⢆⠀⠀⠀⠀⠀⠀⠀⠀⠀
⠀⠀⠀⡰⠃⠀⡴⠃⠀⠀⠀⠀⠈⢦⡀⠈⠳⡄⠀⠀⠀⠀⠀⠀⠀
⠀⠀⣸⠳⣤⠎⠀⠀⠀⠀⠀⠀⠀⠀⠙⢄⡤⢯⡀⠀⠀⠀⠀⠀⠀
⠀⠐⡇⠸⡅⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠹⡆⢳⠀⠀⠀⠀⠀⠀
⠀⠀⠹⡄⠹⡄⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣇⠸⡆⠀⠀⠀⠀⠀
⠀⠀⠀⠹⡄⢳⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢹⡀⣧⠀⠀⠀⠀⠀
⠀⠀⠀⠀⢹⡤⠳⡄⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⣷⠚⣆⠀⠀⠀⠀
⠀⠀⠀⡠⠊⠉⠉⢹⡀⠀⠀⠀⠀⠀⠀⠀⠀⢸⡎⠉⠀⠙⢦⡀⠀
⠀⠀⠾⠤⠤⠶⠒⠊⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠉⠙⠒⠲⠤⠽
Node.js
是一个javascript运行环境。它让javascript可以开发后端程序
,实现几乎其他后端语言实现的所有功能,可以与```PHP、Java、Python、.NET、Ruby等后端语言平起平坐。Ryan Dahl
把这V8搬到了服务器上,用于做服务器的软件。Copyright © [SYFStrive],未经许可,禁止转载 ~~~
沙箱环境
: 是协助开发者进行功能测试,模拟了开放平台产品的主要功能,逻辑。可用于在产品上线前进行功能测试。
Node.js 8 以上版本
–
官方 : https://openhome.alipay.com/
配置步骤 :使用支付宝登录 进入我的控制台 下方的开发工具推荐 点击沙箱 沙箱应用 启动公钥模式
获取公钥和私钥 网关地址
npm install koa
npm install koa-router
npm install alipay-sdk
或
npm install koa koa-router alipay-sdk
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/axios.min.js"></script>
<title>支付宝沙箱支付</title>
</head>
<body>
<button>支付宝</button>
</body>
<script>
const but = document.querySelector('button')
but.addEventListener('click', () => {
axios({
method: 'get',
url: 'http://127.0.0.1:8000/payment'
}).then(reason => {
console.log(reason.data);
})
})
</script>
</html>
const koa = require("koa");
const app = new koa();//实例
const koaRouter = require('koa-router')
const router = new koaRouter()
router.get("/payment", (ctx, next) => {
ctx.set('Access-Control-Allow-Origin', '*')
ctx.set('Access-Control-Allow-Methods', "OPTIONS, GET, PUT, POST, DELETE")
ctx.body = ({
code: 200
})
next()
})
app.use(router.routes(), router.allowedMethods())
app.listen(8000, function () {
console.log("HTTP服务已启动");
})
初始化 SDK 准备参数
appId、应用私钥、应用公钥证书文件、支付宝公钥证书文件、支付宝证书文件
appId、应用私钥、应用公钥、支付宝公钥
const AlipaySdk = require('alipay-sdk').default
const fs = require('fs')
// 普通公钥模式
const alipaySdk = new AlipaySdk({
appId: '2021000122664484', //开放平台上创建应用时生成的 appId
signType: 'RSA2',//签名算法,默认 RSA2
gateway: 'https://openapi.alipaydev.com/gateway.do',//支付宝网关地址
privateKey: fs.readFileSync('private-key.pem', 'ascii'),//应用私钥
alipayPublicKey: fs.readFileSync('alipay-public-key.pem', 'ascii'),//支付宝公钥
});
// 证书模式
// const alipaySdk = new AlipaySdk({
// appId: '2021000122664484',
// privateKey: fs.readFileSync('private-key.pem', 'ascii'),
// // 传入支付宝根证书、支付宝公钥证书和应用公钥证书。
// alipayRootCertPath: path.join(__dirname, 'alipayRootCert.crt'),
// alipayPublicCertPath: path.join(__dirname, 'alipayCertPublicKey_RSA2.crt'),
// appCertPath: path.join(__dirname, 'appCertPublicKey.crt'),
// });
module.exports = alipaySdk
//参数 商品订单 商品名称 商品详细 商品价格
const AlipayForm = (orderNumber, goodsName, goodsDetail, price) => {
return new Promise((resolve, reject) => {
// 创建支付宝需要的表单表 对接支付宝
const formData = new AlipayFormData();
formData['setMethod']('get');
// 支付成功回调地址,必须为可以直接访问的地址,不能带参数
formData['addField']('returnUrl', 'http://localhost:9999/#/paysuccess');
// 然后就是需要的订单参数
formData['addField']('bizContent', {
outTradeNo: orderNumber, // 商户订单号,64个字符以内、可包含字母、数字、下划线,且不能重复
productCode: 'FAST_INSTANT_TRADE_PAY', // 销售产品码,与支付宝签约的产品码名称,仅支持FAST_INSTANT_TRADE_PAY
totalAmount: `${price}`, // 订单总金额,单位为元,精确到小数点后两位
subject: goodsName, // 订单标题
body: goodsDetail, // 订单描述
});
// 业务处理
// result 为可以跳转到支付链接的 url
//'alipay.trade.page.pay' 统一收单下单并支付页面接口
//{} api 请求的参数(包含“公共请求参数”和“业务参数”)
alipaySdk.exec(
'alipay.trade.page.pay',
{},
{formData: formData},
).then(reason => {
resolve({
message: '支付成功❗',
code: 200,
data: reason,
ok: true
})
}, err => {
resolve({
message: '支付失败❗',
code: 404,
data: {},
ok: false
})
})
})
}
//参数 订单号 交易号
const AlipayFormStatus = (out_trade_no, trade_no) => {
return new Promise((resolve, reject) => {
// 创建支付宝需要的表单表 对接支付宝
const formData = new AlipayFormData();
formData.setMethod('get');
// 然后就是需要的订单参数
formData.addField('bizContent', {
out_trade_no,
trade_no,
});
alipaySdk.exec(
'alipay.trade.query',
{},
{formData: formData},
).then(result => {
axios({
url: result,
method: 'get'
}).then(reason => {
let saveData = reason.data['alipay_trade_query_response']
if (saveData.code === '10000') {
switch (saveData['trade_status']) {
case 'WAIT_BUYER_PAY':
resolve({
message: '通知不会返回,不能申请修改',
code: 199,
data: '支付宝有交易记录,没付款',
ok: true
})
break;
case 'TRADE_FINISHED':
resolve({
message: '交易结束,不可退款',
code: 200,
data: '交易完成',
ok: true
})
break;
case 'TRADE_SUCCESS':
resolve({
message: '高级即时到帐状态下',
code: 201,
data: '交易完成',
ok: true
})
break;
case 'TRADE_CLOSED':
resolve({
message: '默认通知不返回,可申请修改(条件需开通高级即时到帐功能,且非常需要退款的同步)。出现该情况在开通高级即时到帐时的人工操作退款时、买家没付款系统自动或卖家手动关闭了该笔交易',
code: 202,
data: '交易关闭',
ok: true
})
break;
default:
resolve({
message: '交易不存在❗',
code: 404,
data: {},
ok: false
})
break;
}
} else {
resolve({
message: '交易不存在❗',
code: 404,
data: {},
ok: false
})
}
}, err => {
resolve({
message: '交易不存在❗',
code: 404,
data: {},
ok: false
})
})
}, err => {
resolve({
message: '交易不存在❗',
code: 404,
data: {},
ok: false
})
})
})
}
const alipaySdk = require('./alipay.sdk')
const AlipayFormData = require('alipay-sdk/lib/form').default
const axios = require('axios')
//参数 商品订单 商品名称 商品详细 商品价格
const AlipayForm = (outTradeNo, goodsName, goodsDetail, price) => {
return new Promise((resolve, reject) => {
// 创建支付宝需要的表单表 对接支付宝
const formData = new AlipayFormData();
formData['setMethod']('get');
// 支付成功回调地址,必须为可以直接访问的地址,不能带参数
formData['addField']('returnUrl', 'http://127.0.0.1:3005/#/paysuccess');
// 然后就是需要的订单参数
formData['addField']('bizContent', {
outTradeNo: outTradeNo, // 商户订单号,64个字符以内、可包含字母、数字、下划线,且不能重复
productCode: 'FAST_INSTANT_TRADE_PAY', // 销售产品码,与支付宝签约的产品码名称,仅支持FAST_INSTANT_TRADE_PAY
totalAmount: `${price}`, // 订单总金额,单位为元,精确到小数点后两位
subject: goodsName, // 订单标题
body: goodsDetail, // 订单描述
});
// 业务处理
// result 为可以跳转到支付链接的 url
//'alipay.trade.page.pay' 统一收单下单并支付页面接口
//{} api 请求的参数(包含“公共请求参数”和“业务参数”)
alipaySdk.exec(
'alipay.trade.page.pay',
{},
{ formData: formData },
).then(reason => {
resolve({
message: '支付成功❗',
code: 200,
data: reason,
ok: true
})
}, err => {
resolve({
message: '支付失败❗',
code: 404,
data: {},
ok: false
})
})
})
}
//参数 订单号 交易号
const AlipayFormStatus = (out_trade_no, trade_no) => {
return new Promise((resolve, reject) => {
// 创建支付宝需要的表单表 对接支付宝
const formData = new AlipayFormData();
formData.setMethod('get');
// 然后就是需要的订单参数
formData.addField('bizContent', {
out_trade_no,
trade_no,
});
alipaySdk.exec(
'alipay.trade.query',
{},
{ formData: formData },
).then(result => {
axios({
url: result,
method: 'get'
}).then(reason => {
let saveData = reason.data['alipay_trade_query_response']
if (saveData.code === '10000') {
switch (saveData['trade_status']) {
case 'WAIT_BUYER_PAY':
resolve({
message: '通知不会返回,不能申请修改',
code: 199,
data: '支付宝有交易记录,没付款',
ok: true
})
break;
case 'TRADE_FINISHED':
resolve({
message: '交易结束,不可退款',
code: 200,
data: '交易完成',
ok: true
})
break;
case 'TRADE_SUCCESS':
resolve({
message: '高级即时到帐状态下',
code: 201,
data: '交易完成',
ok: true
})
break;
case 'TRADE_CLOSED':
resolve({
message: '默认通知不返回,可申请修改(条件需开通高级即时到帐功能,且非常需要退款的同步)。出现该情况在开通高级即时到帐时的人工操作退款时、买家没付款系统自动或卖家手动关闭了该笔交易',
code: 202,
data: '交易关闭',
ok: true
})
break;
default:
resolve({
message: '交易不存在❗',
code: 404,
data: {},
ok: false
})
break;
}
} else {
resolve({
message: '交易不存在❗',
code: 404,
data: {},
ok: false
})
}
}, err => {
resolve({
message: '交易不存在❗',
code: 404,
data: {},
ok: false
})
})
}, err => {
resolve({
message: '交易不存在❗',
code: 404,
data: {},
ok: false
})
})
})
}
module.exports = {
AlipayForm,
AlipayFormStatus
}
参数 | 类型 | 描述 |
---|---|---|
Param | Type | Description |
Config | AlipaySdkConfig | 初始化 SDK 配置 |
参数 | 说明 | 类型 | 必须 |
---|---|---|---|
appId | 应用ID | string | 是 |
privateKey | 应用私钥字符串 | string | 是 |
signType | 签名种类 | “RSA2”|“RSA” | 否 |
alipayPublicKey | 支付宝公钥(需要对返回值做验签时候必填) | string | 否 |
gateway | 网关 | string | 否 |
timeout | 网关超时时间(单位毫秒,默认 5s) | number | 否 |
camelcase | 是否把网关返回的下划线 key 转换为驼峰写法 | boolean | 否 |
keyType | 指定private key类型, 默认: PKCS1, PKCS8: PRIVATE KEY, PKCS1: RSA PRIVATE KEY | “PKCS1”|“PKCS8” | 否 |
appCertPath | 应用公钥证书文件路径 | string | 否 |
appCertContent | 应用公钥证书文件内容 | string|Buffer | 否 |
appCertSn | 应用公钥证书sn | string | 否 |
alipayRootCertPath | 支付宝根证书文件路径 | string | 否 |
alipayRootCertContent | 支付宝根证书文件内容 | string|Buffer | 否 |
alipayRootCertSn | 支付宝根证书 | sn | string 否 |
alipayPublicCertPath | 支付宝公钥证书文件路径 | string | 否 |
alipayPublicCertContent | 支付宝公钥证书文件内容 | string|Buffer | 否 |
alipayCertSn | 支付宝公钥证书 | sn string | 否 |
encryptKey | AES密钥,调用AES加解密相关接口时需要 | string | 否 |
wsServiceUrl | 服务器地址 | string | 否 |
作用 : 生成请求字符串,用于客户端进行调用 ~ Returns: string - 请求字符串
Param | Type | Description |
---|---|---|
method | string | 方法名 |
params | IRequestParams | 请求参数 |
params.bizContent | object | 业务请求参数 |
作用 :生成网站接口请求链接或表单 ~ Returns: string - 请求链接或表单 HTML
Param | Type | Description |
---|---|---|
method | string | 方法名 |
params | IRequestParams | 请求参数 |
params.bizContent | object | 业务请求参数 |
params.method | string | 后续进行请求的方法。如为 GET,即返回 http 链接;如为 POST,则生成表单 html |
作用 :执行请求,调用支付宝服务端
Returns: Promise.<(AlipaySdkCommonResult|string)> - 请求执行结果
Param | Type | Description |
---|---|---|
method | string | 调用接口方法名,比如 alipay.ebpp.bill.add |
params | IRequestParams | 请求参数 |
params.bizContent | object | 业务请求参数 |
option | IRequestOption | 选项 |
option.validateSign | Boolean | 是否验签 |
args.log | object | 可选日志记录对象 |
作用 : 响应结果
参数 | 说明 | 类型 | 必须 |
---|---|---|---|
code | 响应码。10000 表示成功,其余详见 https://opendocs.alipay.com/common/02km9f | string | 是 |
msg | 响应讯息。Success 表示成功。 | string | 是 |
sub_code | 错误代号 | string | 否 |
sub_msg | 错误辅助信息 | string | 否 |
作用 :请求参数
参数 | 说明 | 类型 | 必须 |
---|---|---|---|
bizContent | 业务请求参数 | object | 否 |
needEncrypt | 自动AES加解密 | boolean | 否 |
作用 :通知验签 ~ Returns: Boolean - 是否验签成功
Param | Type | Description |
---|---|---|
postData | JSON | 服务端的消息内容 |
raw | Boolean | 是否使用 raw 内容而非 decode 内容验签 |
以上是个人学习Node的相关知识点,一点一滴的记录了下来,有问题请评论区指正,共同进步,这才是我写文章的原因之,如果这篇文章对您有帮助请三连支持一波