如何捕获Shopify Webhook发送的HTTP POST请求

时间:2012-06-07 17:57:17

标签: php ruby-on-rails shopify webhooks

我有点像菜鸟,并且不怕承认,我正在研究这个项目作为学习经验,以便通过php和服务器端脚本/处理来改善。

我正试图想出一种方法来使用Shopify,并在每次从Shopify购物车完成订单时同时更新关闭服务器数据库。例如,有人从我的在线商店购买了一些东西,我希望它能够更新我的家庭数据库库存,以显示它现在只有一个项目。

我得出的结论是,最好的方法是设置一个webhook notification向我的服务器发送HTTP POST请求,然后我让我的服务器捕获POST并解析它到XML。然后,我将通过将更新我的数据库的PHP脚本读取XML。

我没有问题的PHP,但我似乎无法弄清楚是如何抓住我的服务器上的webhook。 Webhook要求我提供一个发送POST请求的URL,我的问题是你;什么是网址?

我做了一些研究,发现你可以通过html,php,Access-Control-Allow-Origin等多种方式捕获POST请求。但是,由于我还是新手,我真的不明白如何做到这些。我尝试过使用HTML隐藏的动作表单,但似乎无法捕获XML。

我想做的就是让webhook发送POST请求,并将其作为.xml捕获。这样我就可以在每天结束时读取xml,并相应地更新数据库。

如果您能想出更好或更简单的方法,请务必向我提出建议。我希望这是安全的,所以像Access-Control-Allow-Origin这样的方法是不可能的。

TL; DR: 我在服务器上要做什么来捕获webhook通知?我应该在服务器上使用什么脚本来提供给webhook?如何编写回调脚本?

5 个答案:

答案 0 :(得分:31)

http://example.com/whatever.php创建公共网址,其中example.com是您的域名,whatever.php是您可以编辑的PHP文件。

然后将此代码放入whatever.php:

<?php
$webhookContent = "";

$webhook = fopen('php://input' , 'rb');
while (!feof($webhook)) {
    $webhookContent .= fread($webhook, 4096);
}
fclose($webhook);

error_log($webhookContent);
?>

然后在Shopify管理员中,您可以创建一个新的webhook并将其指向http://example.com/whatever.php,当您点击Shopify管理员中的“测试webhook”按钮时,Shopify将POST到您上面的脚本,该脚本应该在将webhook的主体写入PHP错误日志。

答案 1 :(得分:4)

抱歉,我没有足够的声誉来发表评论,但这里是Edward Ocampo-Gooding的答案中死链接的内容:

  

PHP示例w / SimpleXML(PHP 5 +)

     

下面的脚本向您展示了如何将Shopify中的XML数据导入到您的脚本中,归档文件并发送正确的标题......

     

鉴于webhook管理员中的新订单订阅设置为:http://example.com/some-script.php?key=123456789

     

http://example.com/上的some-script.php的内容:

<?     
// Protect URL from rogue attacks/exploits/spiders
// Grab from GET variable as given in Shopify admin URL
// for the webhook
//
// NOTE: This is not necessary, just a simple verification
//
// A digital signature is also passed along from Shopify,
// as is the shop's domain name, so you can use one or both of those
// to ensure a random person isn't jacking with your script (or some
// spider just randomly hitting it to see what's there).
//
// If $key doesn't matched what should be passed in from the
// webhook url, the script simply exits
$key = $_GET['key']; 

if ($key != '123456789') {
  header('HTTP/1.0 403 Forbidden');
  exit();
}

// Variables used for processing/saving
$xmlString = ;  // Used to get data from Shopify into script
$name = ;  // Saves the billing address name to be used for later ...
$email = ;  // Save the email address of the user to be used for later ...
$productTitles = array();  // Saves all titles of products purchased to be used for later ... 

// Get XML data and read it into a string for use with SimpleXML
// Thanks to David Oxley (http://www.numeriq.co.uk) for help with this
$xmlData = fopen('php://input' , 'rb'); 
while (!feof($xmlData)) { $xmlString .= fread($xmlData, 4096); }
fclose($xmlData);

// Save order XML in file in orders directory
// This creates a file, write the xml for archival purposes, and closes the file ...
// If the file already exists, it appends the data ... this should create a separate
// file for every order but if two orders are processed the same second, they'll both
// be in the same file
file_put_contents('orders/order' . date('m-d-y') . '-' . time() . '.xml', $xmlString, FILE_APPEND);

// Use SimpleXML to get name, email, and product titles
// SimpleXML allows you to use the $xml object to easily
// retrieve the data ...
// Please note, if hyphens are used in the xml node, you must
// surround the call to that member with {'member-name'} as is
// shown below when getting the billing-address name & the
// line items
$xml = new SimpleXMLElement($xmlString);

$name = trim($xml->{'billing-address'}->name);
$email = trim($xml->email);

// Create productTitles array with titles from products
foreach ($xml->{'line-items'}->{'line-item'} as $lineItem) {
  array_push($productTitles, trim($lineItem->title));
}

// You would then go on using $name, $email, $productTitles in your script
// to do whatever the heck you please ...

// Once you are done doing what you need to do, let Shopify know you have 
// the data and all is well!
header('HTTP/1.0 200 OK');
exit();

// If you want to tell Shopify to try sending the data again, i.e. something
// failed with your processing and you want to try again later
header('HTTP/1.0 400 Bad request');
exit();
?>

答案 2 :(得分:3)

听起来你最熟悉PHP,所以我会基于此回答。

您需要一个可以作为公共URL访问的PHP脚本/页面,该URL可以获取HTTP POST Shopify中发送的数据,并将其转换为数据库所需的格式。

以下是PHP脚本的示例:http://wiki.shopify.com/WebHook#PHP_Example_w.2F_SimpleXML_.28PHP_5.2B.29

答案 3 :(得分:1)

要回答有关URL的问题,这是服务器上将要处理接收webhook的端点。设置大多数Web框架非常简单,它只需要处理发布请求并以200 OK响应。

在服务器上设置端点后,您可以在shopify上创建webhook,其中URL是网络服务器上的端点。

答案 4 :(得分:-1)

Shopify webhook没有使用常见的GET或POST请求方法传递数据。您可以在PHP中使用fopen()方法并传入php://输入流。

假设您为购物车更新创建了一个webhook并设置了URL http://example.com/cart_update_hook.php,然后将以下代码放入cart_update_hook.php以获取shopify webhook发送的数据。

<?php
$webhookContent = "";
$webhook = fopen('php://input' , 'rb');
while (!feof($webhook)) {
    $webhookContent .= fread($webhook, 4096);
}
fclose($webhook);
$data = json_decode($webhookContent, true);
//do whatever you want with the data
?>