接入教程
1. 在Adyen后台启用Webhooks功能
2. 配置接收通知的服务器URL地址
3. 验证服务器签名以确保安全性
4. 处理接收到的POST请求数据
5. 根据事件类型执行相应业务逻辑
Python Flask Webhook 处理器
from flask import Flask, request, jsonify
import hmac
import hashlib
app = Flask(__name__)
WEBHOOK_SECRET = 'YOUR_WEBHOOK_SECRET'
@app.route('/webhook', methods=['POST'])
def webhook_handler():
# 获取原始请求体和签名头
payload = request.get_data(as_text=True)
signature_header = request.headers.get('X-Adyen-Signature')
# 验证签名
expected_signature = hmac.new(
WEBHOOK_SECRET.encode(),
payload.encode(),
hashlib.sha256
).hexdigest()
if signature_header != expected_signature:
return jsonify({'error': 'Invalid signature'}), 403
# 处理通知数据
notification_data = request.json
event_type = notification_data.get('type')
# 根据事件类型执行业务逻辑
if event_type == 'balancePlatform.capabilityUpdated':
# 处理账户权限更新
account_id = notification_data['data']['accountHolderId']
print(f'Account {account_id} capabilities updated')
return jsonify({'status': 'received'}), 200
if __name__ == '__main__':
app.run(port=3000)
PHP Webhook 接收端点
<?php
$webhook_secret = 'YOUR_WEBHOOK_SECRET';
// 获取请求内容和签名
$payload = file_get_contents('php://input');
$signature_header = $_SERVER['HTTP_X_ADYEN_SIGNATURE'] ?? '';
// 计算HMAC签名
$expected_signature = hash_hmac('sha256', $payload, $webhook_secret);
// 验证签名
if (!hash_equals($expected_signature, $signature_header)) {
http_response_code(403);
echo json_encode(['error' => 'Invalid signature']);
exit;
}
// 解析通知数据
$notification_data = json_decode($payload, true);
$event_type = $notification_data['type'] ?? '';
// 根据事件类型处理
switch ($event_type) {
case 'balancePlatform.sweepConfigurationUpdated':
$sweep_id = $notification_data['data']['sweepConfigurationId'];
error_log("Sweep configuration {$sweep_id} updated");
break;
case 'balancePlatform.accountHolderCreated':
$account_id = $notification_data['data']['accountHolderId'];
error_log("Account holder {$account_id} created");
break;
}
// 返回成功响应
http_response_code(200);
echo json_encode(['status' => 'received']);
?>
Node.js Express Webhook 监听器
const express = require('express');
const crypto = require('crypto');
const app = express();
const WEBHOOK_SECRET = 'YOUR_WEBHOOK_SECRET';
app.use(express.json({ verify: (req, res, buf) => {
req.rawBody = buf.toString();
}}));
app.post('/webhook', (req, res) => {
const signature = req.headers['x-adyen-signature'];
const payload = req.rawBody;
// 验证HMAC签名
const expectedSignature = crypto
.createHmac('sha256', WEBHOOK_SECRET)
.update(payload)
.digest('hex');
if (signature !== expectedSignature) {
return res.status(403).json({ error: 'Invalid signature' });
}
const notification = req.body;
const eventType = notification.type;
// 处理不同事件类型
switch (eventType) {
case 'balancePlatform.capabilityUpdated':
console.log(`Capabilities updated for account: ${notification.data.accountHolderId}`);
// 更新本地数据库或触发其他业务逻辑
break;
case 'balancePlatform.sweepConfigurationCreated':
console.log(`New sweep configuration created: ${notification.data.sweepConfigurationId}`);
break;
}
res.status(200).json({ status: 'received' });
});
app.listen(3000, () => {
console.log('Webhook server listening on port 3000');
});
常见问题
如何验证Webhook请求的真实性?
Adyen使用HMAC SHA256签名验证Webhook请求。您需要在服务器端使用相同的Webhook密钥重新计算签名,并与请求头中的X-Adyen-Signature进行比较。如果签名匹配,则请求是真实的。
Webhook服务器需要满足哪些要求?
Webhook服务器必须:1) 支持HTTPS协议,2) 在15秒内返回HTTP 200响应,3) 正确处理重复通知(幂等性),4) 能够处理Adyen的批量通知。建议实现重试机制和日志记录。
如何处理失败的Webhook通知?
如果Adyen在15秒内未收到200响应,或收到4xx/5xx错误,会按指数退避策略重试发送通知,最多持续24小时。建议您的系统设计为幂等的,并记录失败通知以便后续排查。
Aitishiku.com