结论
当前在PC端生成二维码后,用户通过支付宝app扫码进入生活号完成支付操作是行不通。
https://opendocs.alipay.com/fw/guide这个地址是生活号快速接入的文档,但是是旧文档,不要再看!
目前没有生活号了,均升级为生活号+,生活号+是不支持调用开放平台产品接口的。生活号+支持商家平台(https://b.alipay.com/page/home)或者个人账户(https://c.alipay.com/page/portal/home)进行创建,但是生活号+不能做支付操作(我是通过支付宝开放平台的技术支持沟通过了解到的,支付宝开放平台的技术支持咨询方式放在文档最后)。

公告地址:https://open.alipay.com/portal/forum/post/158401031
这里我把商家创建生活号+的步骤放出来,有条件的话可以尝试一下。注意:个人账号创建生活号+请在互联网环境下进行,内网环境无法上传头像(个人创建生活号+的必填项)的




下面是与支付宝技术支持的沟通记录

解决方案
通过创建小程序来完成,核心链路:PC生成带参二维码 -> 小程序获取参数 -> 小程序向服务端请求支付 -> 服务端调用支付宝创建交易 -> 小程序发起支付 -> 服务端处理异步通知 -> 服务端通知PC端。此时的二维码是专门为小程序生成的二维码时,它会直接拉起对应的小程序,并打开指定的页面,同时将二维码中携带的参数传递给这个页面。
详细步骤
-
支付宝小程序注册
支付宝小程序需要注册个人账号(必须完成个体工商户认证)或者企业账号,没有认证个体工商户的个人账号可以用于开发和调试小程序,但不能提审和发布。
- 个人账号注册及实名认证(https://opendocs.alipay.com/common/02kg61?pathHash=f705b4eb)
- 个人账号认证个体工商户(https://opendocs.alipay.com/common/02kkul?pathHash=7777cc49)
- 企业账号注册及实名认证(https://opendocs.alipay.com/common/02kkum?pathHash=e8db7ff6)
-
创建支付宝小程序
- 登录开放平台(https://open.alipay.com/),使用个人账号或者企业账号登录,然后登陆成功后点击
接入开发下的小程序开发,进入如下页面:
- 登录开放平台(https://open.alipay.com/),使用个人账号或者企业账号登录,然后登陆成功后点击

-
点击
去创建小程序
我是用自己的账号创建的小程序,如下图所示:

-
在开放平台完成基础配置(开放平台首页-右上角
控制台-选择你的小程序-点击详情按钮,内容如下图)

-
配置密钥(左侧的开发设置菜单)
-
在您的应用详情页,找到 「接口加签方式」。
-
生成您的应用私钥(可以使用开放平台提供的工具生成)。
具体操作步骤补充
-
生成密钥对(密钥相关文档:https://opendocs.alipay.com/common/02kipl)
# 使用支付宝官方工具(推荐) # 下载地址:https://opendocs.alipay.com/common/02kipl # 生成2048位的RSA2密钥 -
配置应用公钥
- 登录 支付宝开放平台
- 进入「控制台」→ 选择你的小程序
- 点击「开发设置」→ 「接口加签方式」
- 点击「设置/查看」→ 「启用公钥」
- 粘贴你的应用公钥内容
-
获取支付宝公钥
-
在同一个「接口加签方式」页面
-
系统会自动显示对应的支付宝公钥
-
复制这个公钥到你的后端配置中
// 在你的后端配置中 const alipaySdk = new AlipaySdk({ appId: '你的小程序APPID', privateKey: '你的应用私钥', // 从app_private_key.pem读取 alipayPublicKey: '支付宝公钥', // 从开放平台获取 gateway: 'https://openapi.alipay.com/gateway.do' });
-
-
后端配置验证
// 验证配置是否正确 const result = await alipaySdk.exec('alipay.system.oauth.token', { grantType: 'authorization_code', code: 'test_code' });
-
-
设置支付宝公钥:将支付宝提供的公钥配置到您的平台上。
-
-
配置域名白名单
- 在 「开发设置」 中,配置 「授权回调域名」 和 「小程序应用域名」。
- 将您后端API所在的服务器域名填入其中。只有在此白名单中的域名才能被小程序访问。
-
申请所需功能
- 在 「功能列表」 中,找到并申请 「小程序支付(必须是完成个体工商户认证的个人账号或者企业账号才会有)」。通常名称是 “小程序支付” 或 “JSAPI支付”。
- 点击右侧的 “申请” 或 “添加” 按钮。
- 根据指引完成协议的签约。这是实现支付功能的前提。
-
其他的关于小程序的基础信息也要完成配置

-
-
-
准备开发环境
- 安装开发工具(工具概述地址:https://opendocs.alipay.com/mini/ide,下载小程序开发者工具)
- 初始化项目,最主要的一步是关联APPID

PC端二维码选择
URL Scheme 解析(存在兼容性问题)
二维码内容:alipays://platformapi/startapp?appId=xxx&page=pages/pay/pay&query=orderId=ORDER_123456
各组成部分的作用:
| 组件 | 作用 | 示例 |
|---|---|---|
alipays:// | 支付宝专用协议头 | 告诉系统用支付宝App打开 |
platformapi/ | 平台API路由 | 固定路径,标识为平台功能 |
startapp | 启动应用动作 | 固定参数,表示启动应用 |
appId=xxx | 小程序唯一标识 | 关键参数,告诉支付宝要打开哪个小程序 |
page=pages/pay/pay | 小程序页面路径 | 指定要打开的具体页面 |
query=orderId=ORDER_123456 | 页面参数 | 传递给目标页面的数据 |
如果跳转失败,可以检查:
- 小程序状态:是否已上架或处于开发版
- 页面路径:
pages/pay/pay是否在app.json中正确定义 - 参数编码:复杂的query参数需要URL编码
- APPID核对:确认APPID与目标小程序一致
前面已经给出了**URL Scheme **地址的解析参数,后端可以根据这些参数手动拼接,然后通过qrcode 库(Node.js)将 urlScheme 字符串生成二维码图片(base64格式)。
URL Scheme二维码的兼容性问题
-
浏览器拦截与提示(最常见)
// iOS Safari 提示 "支付宝"想打开"支付宝" [取消] [打开] // 某些安卓浏览器提示 "是否允许支付宝打开此链接?" [拒绝] [允许] // 微信内置浏览器(最严重) "已停止访问该网页" "网页包含诱导分享、关注等诱导行为内容..." -
支付宝未安装
// 用户未安装支付宝时: 1. 部分浏览器:提示"未安装应用" 2. 部分浏览器:跳转到应用商店 3. 部分浏览器:完全无反应 -
支付宝版本过旧
// 旧版本支付宝可能: 1. 无法识别新的Scheme格式 2. 跳转到错误的页面 3. 直接报错 -
URL长度限制
// 某些浏览器对URL长度有限制 const longScheme = `alipays://platformapi/startapp?appId=xxx&page=pages/pay/pay&query=orderId=ORDER_123456×tamp=xxx&sign=xxx`; // 可能被截断,导致参数丢失
替代方案:小程序码(推荐)
优势
- 无浏览器拦截:不依赖系统浏览器,无确认弹窗
- 无应用屏蔽:在支付宝内,微信/QQ等无法干扰
- 无系统限制:不触发iOS/安卓的系统级安全提示
- 用户体验流畅:扫码 → 直接进入小程序,一步到位
小程序码的生成步骤
接入准备:https://opendocs.alipay.com/mini/02owto?pathHash=10e164cb
接入指南:https://opendocs.alipay.com/mini/02owtp?pathHash=cc9e3957
-
调用支付宝API:使用
alipay.open.app.qrcode.create接口。 -
组装关键参数:在调用API时,你需要传入以下核心参数(bizContent):
url_param: 指定要跳转的小程序页面路径,例如pages/pay/pay。query_param: 这里放入你系统的订单号,这是后续支付的唯一凭证,例如orderId=202410310001。describe: 二维码的描述信息,可为空。
-
后端代码示例 (Node.js)
// 引入支付宝SDK等依赖 const AlipaySdk = require('alipay-sdk').default; const AlipayFormData = require('alipay-sdk/lib/form').default; // 初始化 const alipaySdk = new AlipaySdk({ appId: '你的小程序APPID', privateKey: '你的应用私钥', alipayPublicKey: '支付宝公钥', gateway: 'https://openapi.alipay.com/gateway.do' }); // 生成小程序码的函数 async generatePayQRCode(orderId) { const formData = new AlipayFormData(); formData.setMethod('get'); formData.addField('bizContent', { url_param: 'pages/pay/pay', // 你的支付页面路径 query_param: `orderId=${orderId}`, // 将订单号作为参数 describe: '订单支付' }); try { const result = await alipaySdk.exec('alipay.open.app.qrcode.create', {}, { formData }); if (result.code === '10000' && result.qrCodeUrl) { // 返回小程序码图片的URL地址 return { success: true, qrCodeUrl: result.qrCodeUrl }; } return { success: false, message: result.msg }; } catch (error) { console.error('生成小程序码失败:', error); return { success: false, message: '系统异常' }; } }
小程序码使用的前置条件清单
## 必需条件
- [ ] 小程序已完成企业认证或个体工商户认证
- [ ] 小程序支付功能已申请并通过审核
- [ ] 小程序支付签约已完成
- [ ] 目标页面(pages/pay/pay)在app.json中正确定义
- [ ] 后端API域名已配置到小程序域名白名单
- [ ] 域名已完成ICP备案且支持HTTPS
## 环境要求
- [ ] 开发环境:开发版小程序 + 真机调试
- [ ] 测试环境:体验版小程序 + 体验成员权限
- [ ] 生产环境:小程序已上架
## 配置验证
- [ ] 密钥配置正确(应用公钥/支付宝公钥)
- [ ] 支付参数配置正确(APPID、PID等)
- [ ] 异步通知地址配置正确且可访问
URL Scheme二维码与小程序码的比喻
-
URL Scheme二维码:房间的门
// 用户站在房间外(各种浏览器、微信等) 用户 → 看到门(URL Scheme二维码) → 需要:1. 找到钥匙(支付宝App) → 2. 开门(确认跳转) → 3. 进入房间(小程序) // 风险:可能没带钥匙、门锁坏了、不想开门... -
小程序码:人在房间内
// 用户已经在房间里(支付宝App内) 用户 → 看到室内指引牌(小程序码) → 直接:走到目标位置(跳转小程序页面) // 优势:没有门的阻碍,直达目标
自研商家接入JSAPI支付文档:https://opendocs.alipay.com/mini/05xmim?pathHash=e9ca29c2
JSAPI接入指南:https://opendocs.alipay.com/mini/05x9ku?pathHash=a7b61cca
支付相关API列表:https://opendocs.alipay.com/mini/05xhsr?pathHash=d4709298
// 页面逻辑:pay.js
Page({
data: {
orderId: '',
productName: '',
amount: '0.00',
loading: false,
pollTimer: null, // 轮询定时器
pollCount: 0, // 轮询次数计数
maxPollCount: 30, // 最大轮询次数
retryCount: 0, // 重试次数
maxRetryCount: 3 // 最大重试次数
},
onLoad(options) {
if (options.orderId) {
this.setData({ orderId: options.orderId });
this.fetchOrderAndPay();
} else {
this.showErrorAlert('参数错误', '未找到订单信息,请重新扫描二维码。', () => {
my.navigateBack();
});
}
},
onUnload() {
// 防止内存泄漏,确保组件卸载时清理定时器。
this.clearPolling();
},
clearPolling() {
if (this.data.pollTimer) {
clearTimeout(this.data.pollTimer);
this.setData({ pollTimer: null });
}
},
// 统一的错误提示方法
showErrorAlert(title, content, callback = null) {
my.alert({
title,
content,
success: () => {
callback && callback();
}
});
},
// 显示重试确认框
showRetryConfirm(title, content) {
return new Promise((resolve) => {
my.confirm({
title,
content,
confirmButtonText: '重试',
cancelButtonText: '退出',
success: (res) => {
resolve(res.confirm);
}
});
});
},
// 网络请求重试机制
async requestWithRetry(requestConfig, retryTimes = 3) {
for (let i = 0; i < retryTimes; i++) {
try {
const response = await my.request({
timeout: 10000, // 10秒超时
...requestConfig
});
return response;
} catch (error) {
console.warn(`网络请求第${i + 1}次失败:`, error);
if (i === retryTimes - 1) {
throw new Error('网络不稳定,请检查网络连接后重试');
}
// 等待一段时间后重试
await new Promise(resolve => setTimeout(resolve, 1000 * (i + 1)));
}
}
},
async fetchOrderAndPay() {
this.setData({ loading: true });
try {
// 1. 获取订单详情(仅用于展示,不用于支付)
const orderResponse = await this.requestWithRetry({
url: 'https://您的后端域名.com/api/getOrderDetail',
method: 'POST',
data: { orderId: this.data.orderId }
});
if (!orderResponse.data.success) {
throw new Error(orderResponse.data.message || '获取订单失败');
}
const orderData = orderResponse.data.data;
// 检查订单状态,避免重复支付
if (orderData.status === 'PAID') {
this.showErrorAlert('订单已支付', '该订单已完成支付,请勿重复操作', () => {
this.notifyPCSuccess();
my.navigateBack();
});
return;
}
if (orderData.status === 'CLOSED' || orderData.status === 'EXPIRED') {
throw new Error('订单已关闭或超时,请重新下单');
}
// 2. 更新页面展示信息
this.setData({
productName: orderData.productName,
amount: orderData.amount,
});
// 3. 创建支付订单(后端会调用支付宝创建交易)
await this.createPayment();
} catch (error) {
console.error('处理订单失败:', error);
const shouldRetry = await this.showRetryConfirm(
'获取订单失败',
`${error.message},是否重试?`
);
if (shouldRetry && this.data.retryCount < this.data.maxRetryCount) {
this.setData({ retryCount: this.data.retryCount + 1 });
this.fetchOrderAndPay();
} else {
this.setData({ loading: false });
this.showErrorAlert('操作失败', '请重新扫描二维码或联系客服');
}
}
},
async createPayment() {
try {
// 只传递orderId,不传递金额信息
const payResponse = await this.requestWithRetry({
url: 'https://您的后端域名.com/api/createPayment',
method: 'POST',
data: { orderId: this.data.orderId }
});
if (!payResponse.data.success) {
const errorMsg = payResponse.data.message;
const errorCode = payResponse.data.code;
// 根据错误码进行不同的处理
switch (errorCode) {
case 'ORDER_ALREADY_PAID':
// 订单已支付,跳转到成功页面
this.handleOrderAlreadyPaid();
return;
case 'ORDER_CLOSED':
throw new Error('订单已关闭或过期,请重新下单');
case 'MAX_RETRY_EXCEEDED':
throw new Error('支付尝试次数过多,请重新下单');
case 'ALIPAY_TRADE_SUCCESS':
// 支付宝侧显示已支付,但本地状态不同步,需要特殊处理
this.handleAlipayTradeSuccess();
return;
case 'SYSTEM_BUSY':
throw new Error('支付系统繁忙,请稍后重试');
default:
if (errorMsg.includes('余额不足')) {
throw new Error('账户余额不足,请充值或更换支付方式');
} else if (errorMsg.includes('风险')) {
throw new Error('交易存在风险,暂无法完成支付');
} else if (errorMsg.includes('频率')) {
throw new Error('操作过于频繁,请稍后再试');
} else {
throw new Error(errorMsg);
}
}
}
// 如果是重复使用的支付订单,给用户提示
if (payResponse.data.reused) {
my.showToast({
content: '检测到未完成支付,继续支付流程...',
type: 'none',
duration: 2000
});
}
// 使用支付宝返回的tradeNO发起支付
const result = await my.tradePay({
tradeNO: payResponse.data.tradeNO
});
this.handlePaymentResult(result);
} catch (error) {
console.error('创建支付订单异常:', error);
const shouldRetry = await this.showRetryConfirm(
'创建支付失败',
`${error.message},是否重试?`
);
if (shouldRetry) {
this.createPayment();
} else {
this.setData({ loading: false });
}
}
},
// 处理订单已支付的情况
handleOrderAlreadyPaid() {
this.clearPolling();
this.showErrorAlert('支付成功', '该订单已完成支付,请勿重复支付', () => {
this.notifyPCSuccess();
my.navigateBack();
});
this.setData({ loading: false });
},
handlePaymentResult(result) {
console.log('支付同步返回结果:', result);
// 开始轮询后端确认最终状态
this.startPollingOrderStatus();
// 同步结果用于用户界面快速响应和特殊错误处理
switch(result.resultCode) {
case '9000':
my.showToast({
content: '支付请求成功,确认中...',
type: 'success',
duration: 2000
});
break;
case '6001':
my.showToast({
content: '支付已取消',
type: 'none',
duration: 2000
});
this.handleUserCancel();
break;
case '4000':
this.showErrorAlert('支付失败', '系统异常,请稍后重试');
this.setData({ loading: false });
break;
case '5000':
this.showErrorAlert('支付失败', '重复请求,请勿重复支付');
this.setData({ loading: false });
break;
case '6002':
this.showErrorAlert('网络错误', '网络连接失败,请检查网络设置');
this.setData({ loading: false });
break;
case '8000':
my.showToast({
content: '支付处理中,请确认支付结果',
type: 'none',
duration: 3000
});
break;
case 'ACQ.SYSTEM_ERROR':
case 'ACQ.INVALID_PARAMETER':
this.showErrorAlert('系统错误', '支付系统繁忙,请稍后重试');
this.setData({ loading: false });
break;
case 'ACQ.ACCESS_FORBIDDEN':
this.showErrorAlert('支付限制', '暂无支付权限,请联系客服');
this.setData({ loading: false });
break;
case 'ACQ.EXIST_FORBIDDEN_WORD':
this.showErrorAlert('商品信息异常', '商品描述包含敏感词,请联系商家修改');
this.setData({ loading: false });
break;
case 'ACQ.PAYMENT_AUTH_CODE_INVALID':
this.showErrorAlert('支付码无效', '请刷新支付码后重试');
this.setData({ loading: false });
break;
case 'ACQ.BUYER_BALANCE_NOT_ENOUGH':
this.showErrorAlert('余额不足', '支付宝余额不足,请更换支付方式');
this.setData({ loading: false });
break;
case 'ACQ.CONTEXT_INCONSISTENT':
this.showErrorAlert('交易环境异常', '请返回后重新扫码支付');
this.setData({ loading: false });
break;
case 'ACQ.TRADE_HAS_CLOSE':
this.showErrorAlert('交易已关闭', '支付超时已关闭,请重新下单');
this.setData({ loading: false });
break;
default:
my.showToast({
content: '支付处理中...',
type: 'none',
duration: 2000
});
}
},
// 处理用户取消支付的场景
handleUserCancel() {
this.clearPolling();
this.setData({ loading: false });
// 可以额外通知服务端用户取消了支付
my.request({
url: 'https://您的后端域名.com/api/cancelPayment',
method: 'POST',
data: { orderId: this.data.orderId },
fail: (error) => {
console.error('通知取消支付失败:', error);
}
});
},
// 处理支付宝侧显示已支付但本地状态异常的情况
async handleAlipayTradeSuccess() {
try {
// 强制查询一次订单状态
const statusResponse = await this.requestWithRetry({
url: 'https://您的后端域名.com/api/checkOrderStatus',
method: 'POST',
data: { orderId: this.data.orderId }
});
if (statusResponse.data.success && statusResponse.data.data.status === 'PAID') {
this.handlePaymentSuccess();
} else {
// 如果查询不到支付状态,需要人工干预
this.showErrorAlert('状态异常', '支付状态异常,请联系客服处理', () => {
this.setData({ loading: false });
});
}
} catch (error) {
this.showErrorAlert('状态查询失败', '支付状态确认失败,请联系客服', () => {
this.setData({ loading: false });
});
}
},
// 修改轮询逻辑,增加支付订单状态检查
startPollingOrderStatus() {
this.clearPolling();
this.setData({ pollCount: 0 });
const poll = async () => {
if (this.data.pollCount >= this.data.maxPollCount) {
this.handlePollTimeout();
return;
}
try {
const statusResponse = await this.requestWithRetry({
url: 'https://您的后端域名.com/api/checkOrderStatus',
method: 'POST',
data: { orderId: this.data.orderId }
}, 2);
if (statusResponse.data.success) {
const orderData = statusResponse.data.data;
const orderStatus = orderData.status;
switch (orderStatus) {
case 'PAID':
this.handlePaymentSuccess();
return;
case 'CLOSED':
this.handleOrderClosed();
return;
case 'FAILED':
this.handlePaymentFailed();
return;
case 'EXPIRED':
this.handleOrderExpired();
return;
case 'CREATED':
// 检查支付订单是否已创建但未支付
if (orderData.paymentCreated &&
this.data.pollCount > 10) { // 轮询10次后仍未支付
this.showErrorAlert('支付超时', '支付订单已创建但未支付,请重新发起支付', () => {
this.setData({ loading: false });
});
return;
}
// 继续轮询
break;
default:
break;
}
}
// 继续轮询
this.setData({ pollCount: this.data.pollCount + 1 });
this.setData({
pollTimer: setTimeout(poll, 2000)
});
} catch (error) {
console.error('轮询查询失败:', error);
this.setData({ pollCount: this.data.pollCount + 1 });
this.setData({
pollTimer: setTimeout(poll, 2000)
});
}
};
poll();
},
handlePaymentSuccess() {
this.clearPolling();
this.showErrorAlert('支付成功', `订单 ${this.data.orderId} 支付成功!`, () => {
this.notifyPCSuccess();
my.navigateBack();
});
this.setData({ loading: false });
},
handleOrderClosed() {
this.clearPolling();
this.showErrorAlert('订单已关闭', '订单已关闭,如需购买请重新下单');
this.setData({ loading: false });
},
async handlePaymentFailed() {
this.clearPolling();
const shouldRetry = await this.showRetryConfirm(
'支付失败',
'支付失败,是否重新尝试支付?'
);
if (shouldRetry) {
this.createPayment();
} else {
this.setData({ loading: false });
}
},
handleOrderExpired() {
this.clearPolling();
this.showErrorAlert('订单已过期', '支付超时,订单已过期,请重新下单');
this.setData({ loading: false });
},
handlePollTimeout() {
this.clearPolling();
this.showErrorAlert('查询超时', '支付结果确认超时,请稍后在订单中心查看状态', () => {
this.setData({ loading: false });
my.navigateBack();
});
},
notifyPCSuccess() {
my.request({
url: 'https://您的后端域名.com/api/notifyPCSuccess',
method: 'POST',
data: { orderId: this.data.orderId },
fail: (error) => {
console.error('通知PC端失败:', error);
}
});
}
});
代码解析
-
方法执行流程解析

支付流程:
扫码进入 → 订单验证 → 防重检查 → 创建支付 → 调起支付宝 → 轮询确认 → 状态同步 → 结果通知 -
核心方法详解
-
onLoad(options) - 页面入口
onLoad(options) { if (options.orderId) { this.setData({ orderId: options.orderId }); this.fetchOrderAndPay(); // 自动开始支付流程 } }作用:页面加载时的生命周期函数,从二维码URL中解析订单参数并自动启动支付流程。
参数来源:
alipays://platformapi/startapp?appId=xxx&page=pages/pay/pay&query=orderId=ORDER_123456这里的
orderId=ORDER_123456会解析到options.orderId中。 -
网络请求优化
async requestWithRetry(requestConfig, retryTimes = 3) { for (let i = 0; i < retryTimes; i++) { try { const response = await my.request({ timeout: 10000, // 10秒超时 ...requestConfig }); return response; } catch (error) { // 指数退避重试 await new Promise(resolve => setTimeout(resolve, 1000 * (i + 1))); } } }优势:
- 自动重试机制
- 超时控制
- 指数退避策略
-
订单状态检查与防重复支付
// 检查订单状态,避免重复支付 if (orderData.status === 'PAID') { this.showErrorAlert('订单已支付', '该订单已完成支付,请勿重复操作', () => { this.notifyPCSuccess(); my.navigateBack(); }); return; }关键安全特性:有效防止重复支付,提升用户体验。
-
createPayment() - 支付核心
async createPayment() { // 请求后端创建支付订单 // 只传递orderId,不传递金额信息 const payResponse = await this.requestWithRetry({ url: 'https://您的后端域名.com/api/createPayment', method: 'POST', data: { orderId: this.data.orderId } }); // 调起支付宝支付 const result = await my.tradePay({ tradeNO: payResponse.data.tradeNO }); }关键点:
tradeNO:由支付宝生成,是调起支付的唯一凭证my.tradePay():支付宝小程序的支付API
-
handlePaymentResult() - 结果处理
// 同步结果用于用户界面快速响应和特殊错误处理 switch(result.resultCode) { case '9000': my.showToast({ content: '支付请求成功,确认中...', type: 'success', duration: 2000 }); break; case '6001': my.showToast({ content: '支付已取消', type: 'none', duration: 2000 }); this.handleUserCancel(); break; case '4000': this.showErrorAlert('支付失败', '系统异常,请稍后重试'); this.setData({ loading: false }); break; case '5000': this.showErrorAlert('支付失败', '重复请求,请勿重复支付'); this.setData({ loading: false }); break; case '6002': this.showErrorAlert('网络错误', '网络连接失败,请检查网络设置'); this.setData({ loading: false }); break; case '8000': my.showToast({ content: '支付处理中,请确认支付结果', type: 'none', duration: 3000 }); break; case 'ACQ.SYSTEM_ERROR': case 'ACQ.INVALID_PARAMETER': this.showErrorAlert('系统错误', '支付系统繁忙,请稍后重试'); this.setData({ loading: false }); break; case 'ACQ.ACCESS_FORBIDDEN': this.showErrorAlert('支付限制', '暂无支付权限,请联系客服'); this.setData({ loading: false }); break; case 'ACQ.EXIST_FORBIDDEN_WORD': this.showErrorAlert('商品信息异常', '商品描述包含敏感词,请联系商家修改'); this.setData({ loading: false }); break; case 'ACQ.PAYMENT_AUTH_CODE_INVALID': this.showErrorAlert('支付码无效', '请刷新支付码后重试'); this.setData({ loading: false }); break; case 'ACQ.BUYER_BALANCE_NOT_ENOUGH': this.showErrorAlert('余额不足', '支付宝余额不足,请更换支付方式'); this.setData({ loading: false }); break; case 'ACQ.CONTEXT_INCONSISTENT': this.showErrorAlert('交易环境异常', '请返回后重新扫码支付'); this.setData({ loading: false }); break; case 'ACQ.TRADE_HAS_CLOSE': this.showErrorAlert('交易已关闭', '支付超时已关闭,请重新下单'); this.setData({ loading: false }); bre default: my.showToast({ content: '支付处理中...', type: 'none', duration: 2000 }); }支付状态码说明:
9000:订单支付成功6001:用户中途取消支付6002:网络连接出错4000:订单支付失败(系统异常)5000:重复请求6002:网络错误8000:支付处理中
-
轮询状态确认机制
startPollingOrderStatus() { const poll = async () => { // 轮询检查订单状态 const orderStatus = orderData.status; switch (orderStatus) { case 'PAID': this.handlePaymentSuccess(); return; case 'CLOSED': this.handleOrderClosed(); return; case 'FAILED': this.handlePaymentFailed(); return; case 'EXPIRED': this.handleOrderExpired(); return; } }; }优势:以后端异步通知为最终依据,确保支付状态准确性。
后端接口要求
-
获取订单详情接口
POST https://您的后端域名.com/api/getOrderDetail 请求参数:{ orderId: "ORDER_123456" } 响应格式:{ success: true, data: { productName: "商品名称", amount: "0.01" } } -
创建支付订单接口(幂等性实现)
// 后端:/api/createPayment - 幂等性版本 app.post('/api/createPayment', async (req, res) => { const { orderId } = req.body; // 参数验证 if (!orderId) { return res.json({ success: false, message: '订单号不能为空' }); } const db = await getDatabaseConnection(); const transaction = await db.startTransaction(); try { // 1. 使用 SELECT ... FOR UPDATE 锁定订单记录 const order = await transaction.query( `SELECT * FROM orders WHERE order_id = ? FOR UPDATE`, [orderId] ); if (!order || order.length === 0) { await transaction.rollback(); return res.json({ success: false, message: '订单不存在' }); } const orderData = order[0]; // 2. 检查订单状态 - 幂等性关键判断 if (orderData.status === 'PAID') { await transaction.rollback(); return res.json({ success: false, message: '订单已支付', code: 'ORDER_ALREADY_PAID' }); } if (orderData.status === 'CLOSED' || orderData.status === 'EXPIRED') { await transaction.rollback(); return res.json({ success: false, message: '订单已关闭或过期', code: 'ORDER_CLOSED' }); } // 3. 检查是否已经创建过支付订单(防重复创建) if (orderData.payment_created && orderData.alipay_trade_no) { // 如果支付订单已创建且在15分钟内,返回相同的tradeNO const createTime = new Date(orderData.payment_create_time); const now = new Date(); const diffMinutes = (now - createTime) / (1000 * 60); if (diffMinutes < 15) { // 15分钟内返回相同的支付订单 await transaction.rollback(); return res.json({ success: true, tradeNO: orderData.alipay_trade_no, reused: true // 标记是重复使用的支付订单 }); } } // 4. 检查重试次数 if (orderData.retry_count >= 5) { await transaction.rollback(); return res.json({ success: false, message: '支付尝试次数过多,请重新下单', code: 'MAX_RETRY_EXCEEDED' }); } // 5. 调用支付宝创建交易 const alipayResponse = await alipaySdk.exec('alipay.trade.create', { notify_url: 'https://您的域名.com/api/alipay/notify', bizContent: { out_trade_no: orderId, // 使用商户订单号,确保唯一性 total_amount: orderData.amount, subject: orderData.product_name, time_expire: '15m', // 15分钟过期 // 其他参数... } }); if (!alipayResponse.trade_no) { throw new Error('支付宝创建交易失败'); } // 6. 更新订单状态(标记支付订单已创建) await transaction.query( `UPDATE orders SET payment_created = TRUE, alipay_trade_no = ?, payment_create_time = NOW(), retry_count = retry_count + 1, update_time = NOW() WHERE order_id = ?`, [alipayResponse.trade_no, orderId] ); await transaction.commit(); res.json({ success: true, tradeNO: alipayResponse.trade_no, reused: false }); } catch (error) { await transaction.rollback(); console.error('创建支付订单失败:', error); // 根据错误类型返回不同的提示 if (error.message.includes('ACQ.TRADE_HAS_SUCCESS')) { res.json({ success: false, message: '该订单已支付成功,请勿重复支付', code: 'ALIPAY_TRADE_SUCCESS' }); } else if (error.message.includes('ACQ.SYSTEM_ERROR')) { res.json({ success: false, message: '支付系统繁忙,请稍后重试', code: 'SYSTEM_BUSY' }); } else { res.json({ success: false, message: '创建支付订单失败,请重试', code: 'CREATE_PAYMENT_FAILED' }); } } }); -
异步通知处理接口 (
/api/alipay/notify)// 后端:处理支付宝异步通知 app.post('/api/alipay/notify', async (req, res) => { try { // 1. 验证签名(必须做!) const signVerified = verifyAlipaySignature(req.body); if (!signVerified) { return res.send('fail'); } // 2. 获取通知参数 const { out_trade_no, total_amount, trade_status, trade_no } = req.body; // 3. 【安全增强】验证金额一致性 const order = await getOrderById(out_trade_no); if (!order) { return res.send('fail'); } // 验证支付宝通知的金额与数据库订单金额是否一致 if (parseFloat(total_amount) !== parseFloat(order.amount)) { console.error(`金额不一致: 订单${order.amount}, 支付宝${total_amount}`); return res.send('fail'); } // 4. 处理支付成功 if (trade_status === 'TRADE_SUCCESS') { await updateOrderStatus(out_trade_no, 'PAID', { alipayTradeNo: trade_no, paidAt: new Date(), actualAmount: total_amount // 记录实际支付金额 }); // 通知PC端 notifyPCOrderSuccess(out_trade_no); } res.send('success'); } catch (error) { console.error('处理支付宝通知失败:', error); res.send('fail'); } }); -
订单状态查询接口 (
/api/checkOrderStatus)// 查询订单状态 app.post('/api/checkOrderStatus', async (req, res) => { const { orderId } = req.body; const order = await getOrderById(orderId); if (!order) { return res.json({ success: false, message: '订单不存在' }); } res.json({ success: true, data: { status: order.status, // CREATED, PAID, CLOSED, FAILED orderId: order.id, amount: order.amount } }); });
-
支付宝开放平台技术支持咨询方式(有问题可以咨询)
- 进入支付宝开放平台(open.alipay.com)
- 点击页面右侧的蚂蚁头的图标,进入经营助手进行提问
- 可通过机器人客服进行咨询,若机器人未能解答您的问题,点击解答内容右下方的向下的大拇指图标
- 点【转人工客服】咨询支付宝技术支持(支付宝技术支持客服的人工服务时间为工作日9:00-22:00,非工作日9:00-18:00)
479

被折叠的 条评论
为什么被折叠?



