<a name="I3xFC"></a>
一、面试题回答
- 首先需要注册支付宝开发者账号并登录支付宝开放平台
- 在支付宝开放平台上创建一个应用,获取应用的 App ID 和相关密钥等信息。
- 在应用的开发设置中配置好return_url和notify_url
- return_url: 是前端页面,商户可以利用 return_url 页面展示支付结果,比如显示支付成功或支付失败的页面。
- notify_url : 是后台接口。主要用于接收支付宝的服务器异步通知,以处理支付结果和更新商户系统订单状态等操作
- 用户提交支付后,请求后台处理支付的接口,同时向接口传递参数:订单号,总金额,订单标题
- 后台会携带这些参数调支付宝支付接口,支付宝响应给后台一段用于提交支付的表单代码,后台把表单给前端,
- 前端在页面中动态写入表单,表单会自动提交,跳至支付宝页面让用户支付
- 用户支付成功后,页面跳转回return_url, 会展示给用户支付成功或失败。
- 同时支付宝会异步把支付状态传给后端的notify_url ,后端可以把对应订单的状态修改为已支付
<a name="thXO3"></a>
二、简单了解相关流程
<a name="r2q57"></a>
1、个人收款码和商家收款码
<a name="KfcRC"></a>
1.1区别
<a name="TU46K"></a>
1.2个人收款码不能用来营业性收款
<br /> 一个普通用户正常来说一天也就会使用几次收付款。 如果个人收款码一天被使用了几百上千次,很明显就是用作了经营收款,就会被系统限定。
<a name="orci7"></a>
1.3.如何成为支付宝商家
<a name="Te1QN"></a>
1.3.1参考官网截图
<a name="pGXoM"></a>
1.3.2 流程
如果你想在你的网站中集成支付宝支付功能,通常是需要先申请支付宝商家账户的。支付宝商家账户可以让你接收用户的支付款项,并将其转移到你的银行账户中。<br />具体流程如下:
- 注册支付宝账号:首先,你需要在支付宝官网或者使用支付宝手机应用程序注册一个个人或者企业账户。
- 完善账户信息:登录到支付宝账号后,你需要提供一些个人或者企业信息,例如身份证明、银行账户等。确保按照要求提供准确的信息。
- 申请支付宝商家功能:登录到你的支付宝商家账号后,你需要填写一些必要的商户信息,例如经营范围、联系方式等。
- 提供必要的证明文件:根据支付宝的要求,你可能需要提供一些相关的证明文件,例如身份证明、营业执照等。确保提供准确、完整的证明文件。
- 等待审核:提交商家资料后,支付宝会进行审核。审核时间一般在几个工作日内完成。请耐心等待。
- 开通支付功能:一旦你的申请通过审核,你就可以登录到支付宝账号,进入商家后台开通支付功能。支付宝会提供相应的接口和文档,供你在你的网站中集成支付宝支付功能。
<a name="tot2C"></a>
2、开发者如何接入电脑网站支付宝支付
<a name="wv7G3"></a>
2.1.官网参考
https://opendocs.alipay.com/open/270/01didh?pathHash=a6ccbe9a<br />
<a name="Liq7N"></a>
2.2接入流程
<a name="TsRCC"></a>
2.2.1 注册支付宝开发者账号
访问支付宝开放平台(open.alipay.com)注册一个开发者账号。
<a name="ZHv2h"></a>
2.2.2 创建应用
登录支付宝开放平台,创建一个应用。<br />在创建应用时,需要提供应用的相关信息,如应用名称、应用类别、主要功能等。<br />
<br />
<a name="HqngM"></a>
2.2.3 获取应用的 AppID 及支付宝公钥
创建应用成功后,可以获取到 AppID 及支付宝公钥。这些信息将在后续的支付过程中用到。<br /><br />
<br />
<a name="mUC2R"></a>
2.2.4 集成支付宝支付 SDK
根据开发语言选择相应的支付宝支付 SDK 进行集成。支付宝提供了多种语言的 SDK,如Java、PHP、Python等。根据自己的开发语言选择相应的 SDK。 <a name="WXTL6"></a>
2.2.5 后端借助支付宝支付SDK的接口实现支付的业务代码
<a name="PDhTP"></a>
三、慕课网电脑网站支付宝支付流程
<a name="RmLqW"></a>
1.选择商品,确认订单
用户单击【提交订单】,接下来会向开发者服务器发起创建订单的接口请求 <a name="VPGfX"></a>
提交订单页面
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<!-- 订单中的商品信息 -->
<div class="goods-info" style="border:1px solid #000; width:400px;">
<p>商品id: 89</p>
<p>商品名称: 《 从0-1训练私有大模型 》</p>
<p>商品价格: 299.00</p>
<p>商品数量: 1件</p>
</div>
<p>总金额: 299.00</p>
<p><button id="submitOrder">提交订单</button></p>
<script>
//提交订单
let submitOrder = document.querySelector("#submitOrder")
submitOrder.addEventListener("click", function () {
axios.get("/createOrder", {
params: {
// 用户id
customer_id: 4389439,
// 金额
total_amount: 299.00,
// 商品id
product_id: 89,
// 数量
quantity: 1,
// 价格
price: 300
}
})
.then(res => {
//接收到订单号
let { order_id,total_amount } = res.data
//跳转至提交选择支付页面,并携带订单号和金额
window.location.href = '支付页面.html?order_id=398303083439943&total_amount=299.00'
})
})
</script>
</body>
</html>
<a name="mblp0"></a>
2.选择支付宝,单击"立即支付"
<a name="Bh47X"></a>
提交支付页面
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<!-- 1. 拿到提交订单页面传来的订单号和金额 -->
订单号: 3535353
金额: 299.00
<!-- 2. 选择支付方式 -->
支付宝
微信
京东
<button>立即支付</button>
<!-- 3. 自动提交支付的表单-->
<div class="form">
<!-- <form action="https://openapi.alipay.com/gateway.do?method=alipay.trade.app.pay&app_id=2021002182632749&charset=utf-8&version=1.0&sign_type=RSA2×tamp=2023-02-28%2011%3A48%3A28&app_auth_token=202302BBbcfad868001a4df3bbfa99e8a6913F10&sign=j9DjDGgxLt3jbOQZy7q7Qu8baKWTl4hZlxOHa%2B46hC1djmFx%2FIyBqzQntPMurzz3f8efXJsalZz3nqZ9ClowCCxBfBvqE0cdzCDAeQ1GMgjd7dbWgjfNNcqKgmJPsIkLaHnP5vTvj%2BA27SqkeZCMbeVfv%2B4nYurXaFB9dNBtA%3D%3D" method="post" name="alipaySDKSubmit1677556108819" id="alipaySDKSubmit1677556108819">
<input type="hidden" name="alipay_sdk" value="alipay-sdk-nodejs-3.3.0" /><input type="hidden" name="biz_content" value="{"out_trade_no":"ziheng-test-eeee","product_code":"QUICK_MSECURITY_PAY","subject":"订单标题","total_amount":"0.01","body":"订单描述"}" />
</form>
<script>document.forms["alipaySDKSubmit1677556108819"].submit();</script> -->
</div>
<script>
let btn = document.querySelector("button")
let form = document.querySelector(".form")
// 当选择了支付宝,并单击"立即支付"按钮时
btn.addEventListener("click",function(){
if (payType === '支付宝'){
axios.get("/pay?order_id=398303083439943&total_amount=299.00")
.then(res=>{
let {html} = res.data
form.innerHTML = html //表单写入当前页面,之后表单自动提交,进入支付宝支付,支付成功后返回return_url页面
})
}
})
</script>
</body>
</html>
<a name="w5aQp"></a>
3.跳转到支付宝网站的支付页面
<a name="h45g7"></a>
4.支付成功后返回页面
<!DOCTYPE html>
<html>
<head>
<title>支付结果</title>
</head>
<body>
支付结果:
<p id="paymentStatus"></p>
<script>
window.onload = function() {
// 从 URL 查询参数中获取支付结果信息
const urlParams = new URLSearchParams(window.location.search);
const paymentStatus = urlParams.get('paymentStatus');
// 根据支付结果信息,显示对应的文本
const paymentStatusText = paymentStatus === 'success' ? '支付成功' : '支付失败';
document.getElementById('paymentStatus').innerText = paymentStatusText;
};
</script>
</body>
</html>
<a name="GGXjX"></a>
5.后端
https://www.npmjs.com/package/alipay-sdk
- 安装依赖
// 支付宝sdk
npm install alipay-sdk --save
//引入支付宝SDK
const AlipaySdk = require('alipay-sdk');
const alipaySdk = new AlipaySdk({
//应用的appid
appId: '2016123456789012',
//下面是证书和密钥
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'),
});
//生成订单
/**
* orders 表
列名 数据类型 主键 自增 描述
order_id INT 是 是 订单ID
customer_id INT 客户ID
order_date TIMESTAMP 订单日期
product_id INT 产品ID
quantity INT 订单项数量
price DECIMAL(8,2) 订单项价格
total_amount DECIMAL(10, 2) 订单总金额
status VARCHAR(20) 订单状态(未支付,已支付,已取消)
*/
//生成订单
app.get("/createOrder", (req, res) => {
let {
userid,
account,
goodid,
count
} = req.query
// 生成唯一订单号 (uuid, Date.now())
let order_id = '398303083439943'
//存入订单表中,生成新的订单
//返回客户端订单号和金额
res.send({
code: 0,
msg: '生成订单',
order_id,
total_amount
})
})
//调用支付接口
app.get("/pay", async (req, res) => {
const bizContent = {
// 商户订单号(必选,由商户生成)
// 在支付过程中具有重要的作用,用于标识每一笔交易,并保证交易的唯一性。
out_trade_no: "398303083439943",
//销售产品码(必选)
// 电脑网站支付场景固定传值FAST_INSTANT_TRADE_PAY
product_code: "FAST_INSTANT_TRADE_PAY",
//订单标题(必选)
// 出现在支付宝支付页面的订单详情中的商品名称一栏,向用户展示了购买的商品。
subject: "华为笔记本",
// 订单总金额(必选)
total_amount: "0.01"
}
// 支付页面接口,返回 html 代码片段,内容为 Form 表单
const result = await alipaySdk.pageExec('alipay.trade.page.pay', {
method: 'POST',
bizContent,
// 商户可以利用 return_url 页面展示支付结果,比如显示支付成功或支付失败的页面。
returnUrl: 'https://www.yunhe.cn/payReturn.html',
// 作用:notify_url 主要用于接收支付宝的服务器异步通知,以处理支付结果和更新商户系统订单状态等操作。
// 特点:支付宝会向 notify_url 发送 HTTP POST 请求,携带交易相关的信息,比如订单号、支付状态等。商户需要在 notify_url 页面中编写相应的业务逻辑代码,来验证支付宝发送的通知内容的真实性,
// 并根据通知内容进行相应的订单处理,比如更新订单状态、发货等操作。
notify_url: 'https://www.yunhe.cn/notify'
});
/**
* <form action="https://openapi.alipay.com/gateway.do?method=alipay.trade.app.pay&app_id=2021002182632749&charset=utf-8&version=1.0&sign_type=RSA2×tamp=2023-02-28%2011%3A48%3A28&app_auth_token=202302BBbcfad868001a4df3bbfa99e8a6913F10&sign=j9DjDGgxLt3jbOQZy7q7Qu8baKWTl4hZlxOHa%2B46hC1djmFx%2FIyBqzQntPMurzz3f8efXJsalZz3nqZ9ClowCCxBfBvqE0cdzCDAeQ1GMgjd7dbWgjfNNcqKgmJPsIkLaHnP5vTvj%2BA27SqkeZCMbeVfv%2B4nYurXaFB9dNBtA%3D%3D" method="post" name="alipaySDKSubmit1677556108819" id="alipaySDKSubmit1677556108819">
<input type="hidden" name="alipay_sdk" value="alipay-sdk-nodejs-3.3.0" /><input type="hidden" name="biz_content" value="{"out_trade_no":"ziheng-test-eeee","product_code":"QUICK_MSECURITY_PAY","subject":"订单标题","total_amount":"0.01","body":"订单描述"}" />
</form>
<script>document.forms["alipaySDKSubmit1677556108819"].submit();</script>
*/
res.send({
result // 提交支付的表单
})
})
// 设置 notify_url 路由
app.post('/notify_url', (req, res) => {
// 解析请求的参数 out_trade_no是商户数据库中订单号
const { out_trade_no, paymentStatus } = req.body;
// 处理支付宝异步通知的业务逻辑,比如更新订单状态、发货等操作
// ...
// 把相应订单的支付状态改为已支付
// 返回支付宝通知处理结果
res.send('success');
});
<a name="kRKOS"></a>
<a name="otLcP"></a>
四、CSDN电脑网站支付宝支付流程
<a name="ais4n"></a>
1.后端生成二维码
const QRCode = require('qrcode');
//H5页面,前端下单,需要生成二维码让用户扫码付款
app.post("/createQRCode",(req,res)=>{
// 客户端传来的订单信息
const orderInfo = {
orderId: '123456',
amount: 100.00,
// 其他订单信息...
};
// const paymentUrl = 'https://www.baidu.com'; // 二维码中携带的url, 扫码后就会跳转到百度首页
// 扫码后跳转的支付页面,如果是单页面应用,url为前端路由
const paymentUrl = 'https://www.csdn.net/payment'; // 处理支付的页面
// 封装生成支付二维码的函数
const generatePaymentQRCode = async (orderInfo) => {
const qrCodeOptions = {
width: 300, // 二维码宽度
height: 300, // 二维码高度
margin: 1 // 二维码白边大小
};
//二维码中的参数
const paymentData = {
orderInfo: orderInfo,
paymentUrl: paymentUrl //扫码后跳转的支付页面
};
try {
const qrCodeText = JSON.stringify(paymentData);
const qrCodeImage = await QRCode.toDataURL(qrCodeText, qrCodeOptions);
res.send({
qrCode: qrCodeImage
})
} catch (error) {
console.error('生成支付二维码失败:', error);
}
};
generatePaymentQRCode(orderInfo)
})
<a name="mlXIJ"></a>
2.如何判断支付方式
/**
* 手机扫码后跳转至该页面,(http://www.csdn.net/payment)
* 该页面会区分是用支付宝扫码还是微信扫码,从而实现不同的支付
*/
// 接收二维码携带信息
// 从 URL 参数中获取扫码的信息
// http://www.csdn.net/payment?orderId=123456&amount=100.00
var queryString = window.location.search;
var urlParams = new URLSearchParams(queryString);
var orderId = urlParams.get('orderId');
var amount = urlParams.get('amount');
// 获取 User-Agent 字符串
var userAgent = navigator.userAgent;
// 判断是否是支付宝客户端
if (userAgent.indexOf('AlipayClient') !== -1) {
console.log('用户来自支付宝');
// 在这里执行支付宝客户端的业务逻辑
}
// 判断是否是微信客户端
if (userAgent.indexOf('MicroMessenger') !== -1) {
console.log('用户来自微信');
// 在这里执行微信客户端的业务逻辑
}
<a name="cvTZQ"></a>
3.用户下单
<a name="zH49h"></a>
页面逻辑
- 用户在【vip会员权益】页面,单击"详情", 进入csdn【会员购买】页面
- 会员购买页面初始化请求订单接口(比如: createOrder), 默认请求【vip年卡】的订单信息
- 在用户切换vip类型时,会重新请求订单接口
- 后端的订单接口会接收订单信息(商品id,用户id), <a name="BDOGk"></a>
效果图
- vip会员权益页面
- 会员购买页面
<a name="KQleQ"></a>
<br />
- <br /> <a name="TRxpa"></a>