金融与汇率

报表Webhooks

Adyen通过webhook发送通知,告知您的系统报表已生成并可下载。您可通过HTTP GET请求编程下载,或手动从客户区域获取。

查看官方文档 ↗

接入教程

1. 在Adyen后台配置webhook接收地址
2. 监听POST请求获取报表生成通知
3. 解析通知中的reportId参数
4. 使用reportId发起HTTP GET请求下载报表
5. 或登录客户区域手动下载报表文件

Python Webhook验证与处理

python
import hashlib
import hmac
import json
from flask import Flask, request

app = Flask(__name__)
WEBHOOK_SECRET = 'YOUR_WEBHOOK_SECRET'

@app.route('/webhook', methods=['POST'])
def handle_webhook():
    # 验证签名
    signature = request.headers.get('Adyen-Signature')
    payload = request.get_data(as_text=True)
    
    # 使用HMAC验证签名(示例逻辑)
    expected_signature = hmac.new(
        WEBHOOK_SECRET.encode(),
        payload.encode(),
        hashlib.sha256
    ).hexdigest()
    
    if not hmac.compare_digest(signature, expected_signature):
        return 'Invalid signature', 401
    
    # 处理通知
    data = json.loads(payload)
    report_id = data.get('reportId')
    
    # 下载报表(示例)
    import requests
    download_url = f'https://api.example.com/reports/{report_id}/download'
    headers = {'Authorization': 'Bearer YOUR_API_KEY'}
    response = requests.get(download_url, headers=headers)
    
    if response.status_code == 200:
        # 保存报表文件
        with open(f'report_{report_id}.csv', 'wb') as f:
            f.write(response.content)
        return 'Report processed', 200
    
    return 'Download failed', 500

if __name__ == '__main__':
    app.run(port=3000)

PHP Webhook接收实现

php
<?php

$webhookSecret = 'YOUR_WEBHOOK_SECRET';
$apiKey = 'YOUR_API_KEY';

// 获取请求头和内容
$signature = $_SERVER['HTTP_ADYEN_SIGNATURE'] ?? '';
$payload = file_get_contents('php://input');

// 验证签名
$expectedSignature = hash_hmac('sha256', $payload, $webhookSecret);
if (!hash_equals($signature, $expectedSignature)) {
    http_response_code(401);
    exit('Invalid signature');
}

// 解析通知
$data = json_decode($payload, true);
$reportId = $data['reportId'] ?? '';

if ($reportId) {
    // 下载报表
    $downloadUrl = "https://api.example.com/reports/{$reportId}/download";
    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, $downloadUrl);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_HTTPHEADER, [
        'Authorization: Bearer ' . $apiKey
    ]);
    
    $reportContent = curl_exec($ch);
    $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
    curl_close($ch);
    
    if ($httpCode === 200 && $reportContent) {
        // 保存文件
        file_put_contents("report_{$reportId}.csv", $reportContent);
        http_response_code(200);
        echo 'Report downloaded';
    } else {
        http_response_code(500);
        echo 'Download failed';
    }
} else {
    http_response_code(400);
    echo 'Invalid payload';
}

?>

Node.js Webhook服务器

javascript
const express = require('express');
const crypto = require('crypto');
const axios = require('axios');

const app = express();
const WEBHOOK_SECRET = 'YOUR_WEBHOOK_SECRET';
const API_KEY = 'YOUR_API_KEY';

app.use(express.text({ type: '*/*' }));

app.post('/webhook', async (req, res) => {
    try {
        const signature = req.headers['adyen-signature'];
        const payload = req.body;
        
        // 验证签名
        const expectedSignature = crypto
            .createHmac('sha256', WEBHOOK_SECRET)
            .update(payload)
            .digest('hex');
        
        if (!crypto.timingSafeEqual(
            Buffer.from(signature),
            Buffer.from(expectedSignature)
        )) {
            return res.status(401).send('Invalid signature');
        }
        
        // 解析通知
        const data = JSON.parse(payload);
        const reportId = data.reportId;
        
        // 下载报表
        const downloadUrl = `https://api.example.com/reports/${reportId}/download`;
        const response = await axios.get(downloadUrl, {
            headers: {
                'Authorization': `Bearer ${API_KEY}`
            },
            responseType: 'stream'
        });
        
        // 保存文件(示例)
        const fs = require('fs');
        const writer = fs.createWriteStream(`report_${reportId}.csv`);
        response.data.pipe(writer);
        
        writer.on('finish', () => {
            res.status(200).send('Report processed');
        });
        
        writer.on('error', () => {
            res.status(500).send('Save failed');
        });
        
    } catch (error) {
        console.error('Webhook error:', error);
        res.status(500).send('Processing failed');
    }
});

app.listen(3000, () => {
    console.log('Webhook server listening on port 3000');
});

常见问题

Webhook通知的签名如何验证?

Adyen使用HMAC SHA256算法生成签名,签名位于'Adyen-Signature'请求头中。您需要使用相同的密钥和算法计算载荷的签名,并进行比对验证。

报表下载失败应如何处理?

建议检查API密钥权限、报表ID有效性及网络连接。可设置重试机制,若持续失败请联系Adyen技术支持。下载链接通常有时效性,请及时处理通知。

Webhook服务器需要满足哪些要求?

服务器需支持HTTPS、正确处理POST请求、及时返回2xx状态码(避免重试)。建议设置超时处理、日志记录和监控告警机制以保证可靠性。

相似接口推荐

AWS Import/Export

AWS Import/Export服务通过邮寄物理存储设备的方式,在AWS云和用户本地环境间高效传输海量数据。该服务利用亚马逊高速内部网络直接读写存储设备,适用于大规模数据迁移场景。

待确认
AWS Greengrass

AWS IoT Greengrass可将AWS功能无缝扩展至物理设备,使设备能够本地处理生成的数据,同时仍利用云端进行管理、分析和持久存储。该服务确保设备能够快速响应本地事件,并在间歇性连接下稳定运行。

待确认
Amazon ElastiCache

Amazon ElastiCache是一项Web服务,可简化云端分布式缓存的设置、操作和扩展。它让客户能够获得高性能内存缓存的所有优势,同时减少管理负担。

待确认
Amazon Elastic Inference

Elastic Inference是AWS提供的弹性推理服务公共API。自2023年4月15日起,AWS不再接受新客户使用该服务,并协助现有客户迁移至性价比更优的替代方案。该API用于管理云端AI推理的加速计算资源。

待确认