接入教程
1. 登录Adyen账户控制台
2. 在Webhooks设置中启用转账通知
3. 配置接收通知的服务器端点
4. 验证并处理收到的Webhook数据
5. 根据通知更新您的系统余额
6. 测试完整的转账通知流程
Flask Webhook 处理器
from flask import Flask, request, jsonify
import hmac
import hashlib
import json
app = Flask(__name__)
# 请替换为您的实际Webhook密钥
WEBHOOK_SECRET = 'YOUR_WEBHOOK_SECRET'
@app.route('/webhooks/transfers', methods=['POST'])
def handle_webhook():
# 获取签名头和原始数据
signature = request.headers.get('X-Adyen-Signature')
payload = request.get_data(as_text=True)
# 验证签名(示例)
expected_signature = hmac.new(
WEBHOOK_SECRET.encode(),
payload.encode(),
hashlib.sha256
).hexdigest()
if not hmac.compare_digest(expected_signature, signature):
return jsonify({'error': 'Invalid signature'}), 401
# 处理Webhook数据
data = json.loads(payload)
transfer_event = data.get('notificationItems', [{}])[0]
# 示例:记录转账事件
print(f"收到转账通知: {transfer_event.get('eventCode')}")
return jsonify({'status': 'accepted'}), 200
if __name__ == '__main__':
app.run(host='0.0.0.0', port=5000)
Laravel Webhook 控制器
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Hash;
class TransferWebhookController extends Controller
{
private $webhookSecret = 'YOUR_WEBHOOK_SECRET';
public function handle(Request $request)
{
// 获取签名和原始内容
$signature = $request->header('X-Adyen-Signature');
$payload = $request->getContent();
// 验证签名
$expectedSignature = hash_hmac('sha256', $payload, $this->webhookSecret);
if (!hash_equals($expectedSignature, $signature)) {
return response()->json(['error' => 'Invalid signature'], 401);
}
// 解析数据
$data = json_decode($payload, true);
$notificationItem = $data['notificationItems'][0] ?? null;
if ($notificationItem) {
// 记录转账事件
Log::info('Transfer webhook received', [
'event_code' => $notificationItem['eventCode'],
'transfer_id' => $notificationItem['transferId'] ?? 'N/A'
]);
// 业务逻辑:更新余额等
// $this->updateBalance($notificationItem);
}
return response()->json(['status' => 'accepted']);
}
}
Express Webhook 端点
const express = require('express');
const crypto = require('crypto');
const bodyParser = require('body-parser');
const app = express();
app.use(bodyParser.json({ verify: (req, res, buf) => { req.rawBody = buf; } }));
const WEBHOOK_SECRET = 'YOUR_WEBHOOK_SECRET';
app.post('/webhooks/transfers', (req, res) => {
const signature = req.headers['x-adyen-signature'];
const payload = req.rawBody.toString();
// 验证签名
const expectedSignature = crypto
.createHmac('sha256', WEBHOOK_SECRET)
.update(payload)
.digest('hex');
if (!crypto.timingSafeEqual(
Buffer.from(expectedSignature),
Buffer.from(signature)
)) {
return res.status(401).json({ error: 'Invalid signature' });
}
const data = req.body;
const notificationItem = data.notificationItems?.[0];
if (notificationItem) {
console.log('Transfer webhook received:', {
eventCode: notificationItem.eventCode,
amount: notificationItem.amount,
currency: notificationItem.currency
});
// 示例业务逻辑
// updateDashboardBalance(notificationItem);
}
res.json({ status: 'accepted' });
});
app.listen(3000, () => {
console.log('Webhook server listening on port 3000');
});
常见问题
Webhook签名验证失败怎么办?
请检查以下配置:1)确认使用的Webhook密钥与Adyen平台配置一致;2)确保使用原始请求体计算签名,而非解析后的JSON对象;3)验证签名算法是否为HMAC SHA256。建议在开发环境先打印签名进行调试。
如何确保Webhook端点的高可用性?
建议采取以下措施:1)部署多个实例并使用负载均衡器;2)实现幂等性处理,防止重复通知导致数据不一致;3)设置合理的超时和重试机制;4)监控HTTP状态码,Adyen会根据返回状态自动重试失败的推送。
测试Webhook时需要注意什么?
测试时请注意:1)使用Adyen提供的测试工具或模拟请求验证端点逻辑;2)准备有效的测试数据,包括模拟转账事件和签名;3)在沙盒环境中完整测试所有事件类型(如transfer.success、transfer.failed);4)验证业务逻辑如余额更新的正确性。
Aitishiku.com