我有一个Webhook在我的Xero帐户上为你服务。当一个新的发票被创建时,我想使用Webhook中的数据访问Xero API,向用户发送发票电子邮件。我有所有的代码,但我的问题是,Webhook期望响应200,当我从webhook内部调用Xero API代码时,我在Xero上得到一个错误,说响应包含一个body。这是有意义的,因为我提交并从API获取数据。
那么,我如何向Xero API发出请求而不干扰Xero Webhook响应呢?
Webhook代码:
<?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
///////////////////////////////////////////////////////////////////////////
?>
1条答案
按热度按时间9jyewag01#
问题是你需要把这些电话分开。
正如对你的问题的评论所说,你需要首先处理webhook,然后排队将触发你的API的作业。像这样的东西
然后你需要注册一个WP Cron
到这种程度的东西。$data参数应该包含你传递的数据(不是100%确定它是如何为你服务的)。此外,您还需要检查API的节流情况,以便调整作业的执行时间。并确保您有地方存储,如果您的后台作业成功完成。
我的一个建议是,既然你在数据库中存储敏感信息(访问和刷新令牌),那就在数据库中存储它们时加密它们,在获取它们时解密。
你可以检查我是如何在我的插件实现后台作业
https://github.com/dingo-d/woo-solo-api/blob/develop/src/Request/SoloApiRequest.php#L428-L438
您可以使用deliciousbrains中的WP队列库:https://github.com/deliciousbrains/wp-queue/
它是WP Cron的 Package 器,带有用于处理队列的自定义DB表,这将允许您检查作业是否正确执行。