gpt4 book ai didi

php - 如何在 Xero Webhook 中向 Xero API 提交发布请求

转载 作者:行者123 更新时间:2023-12-04 14:09:55 25 4
gpt4 key购买 nike

我的 Xero 帐户上有一个用于发票的 Webhook。创建新发票时,我想使用来自 Webhook 的数据访问 Xero Api 向用户发送发票电子邮件。我有这方面的所有代码,但我的问题是 Webhook 期望响应为 200,当我从 Webhook 中调用 Xero Api 代码时,我在 Xero 上收到错误消息,说响应包含一个正文。这是有道理的,因为我正在从 Api 提交和获取数据。
那么如何在不干扰 Xero Webhook 响应的情况下向 Xero Api 发出请求呢?
网络钩子(Hook)代码:

<?php
///////////////////////////////////////////////////////////////////////////
// WEBHOOK AUTHENTICATION - START
///////////////////////////////////////////////////////////////////////////
//hook section
$rawPayload = file_get_contents("php://input");
// Update your webhooks key here
$webhookKey = 'myWebhookKey';

// Compute the payload with HMACSHA256 with base64 encoding
$computedSignatureKey = base64_encode(
hash_hmac('sha256', $rawPayload, $webhookKey, true)
);

// Signature key from Xero request
$xeroSignatureKey = $_SERVER['HTTP_X_XERO_SIGNATURE'];

$isEqual = false;

if (hash_equals($computedSignatureKey, $xeroSignatureKey)) {
$isEqual = true;
http_response_code(200);

// getting and passing the data to the api functionality
$data = json_decode($rawPayload);
xero_api($data);
} else {
http_response_code(401);
}
///////////////////////////////////////////////////////////////////////////
// WEBHOOK AUTHENTICATION - END
///////////////////////////////////////////////////////////////////////////
?>
api代码:
<?php
///////////////////////////////////////////////////////////////////////////
// XERO API FUNCITONALITY - START
///////////////////////////////////////////////////////////////////////////
function xero_api($data) {
if ($data->events[0]->eventType === 'CREATE') {
$resourseId = $data->events[0]->resourceId;

///////////////////////////////////////////////////////////////////////////
// GET XERO CREDENTIALS - START
///////////////////////////////////////////////////////////////////////////
global $wpdb;

$xeroKeys = $wpdb->get_row("SELECT * FROM {$wpdb->prefix}xero_keys WHERE ID = 0", ARRAY_A);

$clientId = $xeroKeys['client_id'];
$clientSecret = $xeroKeys['client_secret'];
$refreshToken = $xeroKeys['refresh_token'];
$tenantId = $xeroKeys['tenant_id'];
///////////////////////////////////////////////////////////////////////////
// GET XERO CREDENTIALS - END
///////////////////////////////////////////////////////////////////////////

///////////////////////////////////////////////////////////////////////////
// GET ACCESS TOKEN AND GENERATE NEW REFRESH TOKEN - START
///////////////////////////////////////////////////////////////////////////
$args = array(
'headers' => array(
'grant_type' => 'refresh_token',
),
'body' => array(
'grant_type' => 'refresh_token',
'refresh_token' => $refreshToken,
'client_id' => $clientId,
'client_secret' => $clientSecret
)
);

$refreshTokenRes = wp_remote_post('https://identity.xero.com/connect/token?=', $args);
$refreshTokenBody = json_decode($refreshTokenRes['body']);

if (isset($refreshTokenBody->refresh_token) && isset($refreshTokenBody->access_token)) {
$updateTokens = $wpdb->update(
$wpdb->prefix . 'xero_keys',
array(
'refresh_token' => $refreshTokenBody->refresh_token,
'access_token' => $refreshTokenBody->access_token
),
array('ID' => 0),
array('%s', '%s'),
array('%d')
);
}
///////////////////////////////////////////////////////////////////////////
// GET ACCESS TOKEN AND GENERATE NEW REFRESH TOKEN - End
///////////////////////////////////////////////////////////////////////////

$args = array(
'headers' => array(
'xero-tenant-id' => $tenantId,
'Authorization' => 'Bearer ' . $refreshTokenBody->access_token,
'Accept' => 'application/json',
'Content-Type' => 'application/json'
),
);

$response = wp_remote_post('https://api.xero.com/api.xro/2.0/Invoices/' . $resourseId . '/Email', $args);
}
}
///////////////////////////////////////////////////////////////////////////
// XERO API FUNCITONALITY - END
///////////////////////////////////////////////////////////////////////////
?>

最佳答案

问题是您需要将这些调用分开。
正如对您的问题的评论所说,您需要首先处理 webhook,然后将触发您的 API 的作业排队。像这样的事情会做

<?php
///////////////////////////////////////////////////////////////////////////
// WEBHOOK AUTHENTICATION - START
///////////////////////////////////////////////////////////////////////////
//hook section
$rawPayload = file_get_contents("php://input");
// Update your webhooks key here
$webhookKey = 'myWebhookKey';

// Compute the payload with HMACSHA256 with base64 encoding
$computedSignatureKey = base64_encode(
hash_hmac('sha256', $rawPayload, $webhookKey, true)
);

// Signature key from Xero request
$xeroSignatureKey = $_SERVER['HTTP_X_XERO_SIGNATURE'];

$isEqual = false;

if (hash_equals($computedSignatureKey, $xeroSignatureKey)) {
$isEqual = true;
http_response_code(200);

// getting and passing the data to the api functionality
$data = json_decode($rawPayload);

wp_schedule_single_event(
time() + 10,
'send_xero_api_call',
['data' => $data]
);
} else {
http_response_code(401);
}
///////////////////////////////////////////////////////////////////////////
// WEBHOOK AUTHENTICATION - END
///////////////////////////////////////////////////////////////////////////
然后你需要注册一个WP Cron
add_action('send_xero_api_call', 'xero_api_cron', 10);

function xero_api_cron($data) {
if ($data->events[0]->eventType === 'CREATE') {
$resourseId = $data->events[0]->resourceId;

///////////////////////////////////////////////////////////////////////////
// GET XERO CREDENTIALS - START
///////////////////////////////////////////////////////////////////////////
global $wpdb;

$xeroKeys = $wpdb->get_row("SELECT * FROM {$wpdb->prefix}xero_keys WHERE ID = 0", ARRAY_A);

$clientId = $xeroKeys['client_id'];
$clientSecret = $xeroKeys['client_secret'];
$refreshToken = $xeroKeys['refresh_token'];
$tenantId = $xeroKeys['tenant_id'];
///////////////////////////////////////////////////////////////////////////
// GET XERO CREDENTIALS - END
///////////////////////////////////////////////////////////////////////////

///////////////////////////////////////////////////////////////////////////
// GET ACCESS TOKEN AND GENERATE NEW REFRESH TOKEN - START
///////////////////////////////////////////////////////////////////////////
$args = array(
'headers' => array(
'grant_type' => 'refresh_token',
),
'body' => array(
'grant_type' => 'refresh_token',
'refresh_token' => $refreshToken,
'client_id' => $clientId,
'client_secret' => $clientSecret
)
);

$refreshTokenRes = wp_remote_post('https://identity.xero.com/connect/token?=', $args);
$refreshTokenBody = json_decode($refreshTokenRes['body']);

if (isset($refreshTokenBody->refresh_token) && isset($refreshTokenBody->access_token)) {
$updateTokens = $wpdb->update(
$wpdb->prefix . 'xero_keys',
array(
'refresh_token' => $refreshTokenBody->refresh_token,
'access_token' => $refreshTokenBody->access_token
),
array('ID' => 0),
array('%s', '%s'),
array('%d')
);
}
///////////////////////////////////////////////////////////////////////////
// GET ACCESS TOKEN AND GENERATE NEW REFRESH TOKEN - End
///////////////////////////////////////////////////////////////////////////

$args = array(
'headers' => array(
'xero-tenant-id' => $tenantId,
'Authorization' => 'Bearer ' . $refreshTokenBody->access_token,
'Accept' => 'application/json',
'Content-Type' => 'application/json'
),
);

$response = wp_remote_post('https://api.xero.com/api.xro/2.0/Invoices/' . $resourseId . '/Email', $args);
}
}
这种程度的东西。 $data 参数应包含您传递的数据(不是 100% 确定它如何查找您)。此外,您需要检查 API 的限制,因此您可以调整作业执行的时间。如果您的后台工作成功完成,请确保您有存储的地方。
我建议的一件事是,由于您将敏感信息存储在数据库中(访问和刷新 token ),因此在将它们存储在数据库中时对它们进行加密,并在获取它们时解密。
您可以检查我如何在我的插件中实现后台作业
https://github.com/dingo-d/woo-solo-api/tree/develop/src/BackgroundJobs
https://github.com/dingo-d/woo-solo-api/blob/develop/src/Request/SoloApiRequest.php#L428-L438
您可以使用来自deliciousbrains 的WP Queue lib: https://github.com/deliciousbrains/wp-queue/
它是 WP Cron 的包装器,带有用于处理队列的自定义数据库表,这将允许您检查作业是否正确执行。

关于php - 如何在 Xero Webhook 中向 Xero API 提交发布请求,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65090519/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com