网站接入支付宝/微信支付教程:从零到成功收款
对于面向国内用户的网站,支付宝和微信支付是必不可少的支付方式。相比 Stripe 等国际支付平台,国内支付的接入流程稍复杂,但一旦配置完成,支付体验非常流畅。整体链路大致是:用户在网页下单 → 跳转到支付宝收银台或拉起微信扫码/小程序支付 → 支付完成后平台异步通知你的服务器 → 你的服务端校验签名并更新订单 → 前端轮询或跳回回跳地址确认结果。理解这条链路,后续每一步就都只是往里面填参数。
从申请资质到真正跑通一笔交易,通常需要 3 个工作日到 2 周,视资质材料与联调速度而定:
| 阶段 | 预计耗时 | 说明 |
|---|---|---|
| 资质申请与审核 | 1-3 个工作日 | 企业营业执照 + 法人信息核验 |
| 应用创建与签约 | 1-2 个工作日 | 支付宝开放平台 / 微信商户平台 |
| 接口联调 | 1-3 天 | 用沙箱或小额真实订单验证 |
| 上线观察 | 1 周 | 重点核对回调成功率与对账 |
一、接入前的准备工作
1.1 所需资质
| 支付方式 | 所需资质 | 说明 |
|---|---|---|
| 支付宝 | 企业营业执照(或个体工商户) | 个人版功能受限 |
| 微信支付 | 企业营业执照(或个体工商户) | 个人版部分功能不可用 |
注意:2026 年支付宝和微信支付均已收紧个人商户的申请条件,建议使用企业资质申请。
1.2 网站要求
- 已完成 ICP 备案
- 已启用 HTTPS
- 有完整的商品/服务页面
- 有明确的退款和售后政策
二、支付宝接入
2.1 注册与认证
- 登录 支付宝开放平台
- 创建应用 → 选择"网页/移动应用"
- 填写应用基本信息(应用名称、应用图标等)
- 配置接口加签方式(推荐 RSA2)
- 提交审核(通常 1-3 个工作日)
2.2 获取关键参数
// 支付宝关键配置参数
$config = [
'app_id' => '202100...',
'merchant_private_key' => 'MIIEv...', // 商户私钥
'alipay_public_key' => 'MIIBI...', // 支付宝公钥
'notify_url' => 'https://yourdomain.com/alipay/notify',
'return_url' => 'https://yourdomain.com/alipay/return',
'charset' => 'UTF-8',
'sign_type' => 'RSA2',
'gateway_url' => 'https://openapi.alipay.com/gateway.do',
];
2.3 发起支付请求
// 使用支付宝 SDK(PHP 示例)
$aop = new AopClient();
$aop->gatewayUrl = $config['gateway_url'];
$aop->appId = $config['app_id'];
$aop->rsaPrivateKey = $config['merchant_private_key'];
$aop->alipayrsaPublicKey = $config['alipay_public_key'];
$request = new AlipayTradePagePayRequest();
$request->setNotifyUrl($config['notify_url']);
$request->setReturnUrl($config['return_url']);
$request->setBizContent(json_encode([
'out_trade_no' => 'ORDER_' . time(),
'product_code' => 'FAST_INSTANT_TRADE_PAY',
'total_amount' => '99.99',
'subject' => '商品名称',
]));
$result = $aop->pageExecute($request);
// 输出 $result,用户会被重定向到支付宝收银台
三、微信支付接入
3.1 注册与认证
- 登录 微信支付商户平台
- 提交商户资料(营业执照、法人身份证、银行账户信息)
- 完成账户验证(打款验证或法人人脸识别)
- 签署协议后获得商户号
3.2 配置参数
微信支付比支付宝多一个 APIv3 密钥的配置:
// 微信支付 Node.js 示例
const wechatPay = {
appid: 'wx...', // 公众号/小程序 AppID
mchid: '123000...', // 商户号
apiV3Key: '...', // APIv3 密钥
serialNo: '...', // 证书序列号
notifyUrl: 'https://yourdomain.com/wechat/notify',
};
3.3 Native 支付(适用于 PC 网站)
// 生成支付二维码
const { code_url } = await wechatPay.native({
description: '商品名称',
out_trade_no: 'ORDER_' + Date.now(),
amount: {
total: 9999, // 金额单位:分(¥99.99)
currency: 'CNY',
},
});
// 前端展示二维码
// 使用 qrcode.js 将 code_url 转为二维码展示
// 轮询查询支付状态
3.4 JSAPI 支付(适用于移动端)
// 获取用户的 openid(需要 OAuth2 授权)
// 然后发起 JSAPI 支付
const payment = await wechatPay.jsapi({
description: '商品名称',
out_trade_no: 'ORDER_' + Date.now(),
amount: { total: 9999, currency: 'CNY' },
payer: { openid: userOpenId },
});
// 前端调起支付
WeixinJSBridge.invoke('getBrandWCPayRequest', payment, (res) => {
if (res.err_msg === 'get_brand_wcpay_request:ok') {
// 支付成功
}
});
四、支付通知处理
4.1 支付宝异步通知
// 验证通知签名
$aop = new AopClient();
$result = $aop->rsaCheckV1($_POST, $config['alipay_public_key'], 'RSA2');
if ($result && $_POST['trade_status'] == 'TRADE_SUCCESS') {
// 更新订单状态
$orderId = $_POST['out_trade_no'];
updateOrderStatus($orderId, 'paid');
echo 'success'; // 告诉支付宝已收到通知
}
4.2 微信支付回调
app.post('/wechat/notify', async (req, res) => {
try {
const { id, event_type, resource } = req.body;
if (event_type === 'TRANSACTION.SUCCESS') {
const orderId = resource.out_trade_no;
updateOrderStatus(orderId, 'paid');
}
res.json({ code: 'SUCCESS', message: '成功' });
} catch (error) {
res.status(500).json({ code: 'FAIL', message: error.message });
}
});
五、费用对比
| 项目 | 支付宝 | 微信支付 |
|---|---|---|
| 费率 | 0.6%-1.2% | 0.6%-1.0% |
| 行业标准费率 | 0.6%(多数行业) | 0.6%(多数行业) |
| 提现手续费 | 免费 | 免费 |
| 退款手续费 | 不退 | 不退 |
| 结算周期 | T+1 | T+1 |
六、支付状态流转与安全要点
支付状态流转
一个订单在支付系统中通常经历:待支付 → 已支付 → (可退款)已退款,以及超时未付的已关闭。判断"是否真的付了钱",唯一可信的来源是服务端的异步通知,而不是前端回调——前端结果可以伪造,异步通知则带有平台签名。
因此务必把两件事都做对:一是异步通知的签名校验和金额比对(订单金额、订单号必须与数据库一致);二是幂等处理,同一个 out_trade_no 的通知可能到达多次,处理前先查订单状态,已支付的直接返回成功,避免重复发货或重复记账。最后用"主动查单"兜底:如果异步通知因网络问题丢失,可在下单后定时调用查询接口补齐状态,推荐超时后每 5 分钟查一次,最多查 12 次。
支付安全与合规要点
- 回调必须验签:通知里的参数要用平台公钥验签,不验签等于把"改订单状态"的权限公开挂在公网上。
- 金额二次校验:以你自己数据库里的订单金额为准,回调里声称的金额只能作为参考,防止中间人篡改。
- 全站 HTTPS:支付页与回调接口都应在 HTTPS 下运行,避免参数被截获,见 HTTPS 迁移指南。
- 敏感信息不落库:商户私钥、APIv3 密钥等放环境变量或密钥管理系统,别写死在代码仓库里。
- 风控与防刷:同一账号高频下单、频繁更换收款方式等异常行为可配合风控策略拦截,见 支付反欺诈策略。
七、常见问题
申请被拒的原因
最常见的原因:营业执照信息不完整、网站未备案、经营范围与申请类型不匹配。建议仔细阅读平台要求,确保资质齐全。
支付回调没有收到
- 检查 notify_url 是否可以公网访问
- 确认没有 IP 白名单限制
- 查看服务器日志,确保能正常接收 POST 请求
- 在支付宝/微信商户后台查看回调记录
双通道同时集成
建议同时在网站提供支付宝和微信支付选项。也可以使用第三方聚合支付(如收钱吧、利楚扫呗)一次对接支持两个渠道。
签名验证一直失败
先核对三件事:加签方式是否统一为 RSA2(两端都要是 RSA2,不要一边 RSA2 一边 RSA1);公钥是否上传正确(商户上传的是应用公钥,回调验签用的是支付宝/微信平台公钥);服务器时间与标准时间是否偏差过大。联调期建议先用 支付沙箱测试环境把签名链路跑通,再切换真实密钥。
沙箱环境怎么用
支付宝开放平台和微信支付都提供沙箱/测试环境。沙箱里用测试账号与测试密钥完成全流程联调,确认回调、退款、对账都正常后再切换线上。注意沙箱与线上的密钥、证书、回调地址通常是隔离的,切换时最容易漏改的就是这三处。
八、总结
国内支付接入虽然流程上比 Stripe 繁琐,但对于面向国内用户的网站是必须的。建议同时接入支付宝和微信支付,覆盖超过 95% 的国内移动支付用户。如果技术资源有限,也可以考虑使用第三方支付服务商提供的聚合支付 SDK,一次接入即可支持多个支付渠道。费率、到账周期与退款政策各平台口径不同,对比可看 支付渠道费率对比;多币种或海外收款场景则参考 跨境收款方案对比。
参考:支付宝开放平台文档 https://opendocs.alipay.com/;微信支付开发者文档 https://pay.weixin.qq.com/docs/developer/apis/platsolution/platsolution.html