首页 > 解决方案 > Shopify webhook 不断删除

问题描述

我正在使用 webhook 将 Shopify 中的数据存储在 Zoho CRM 中,使用 webhook 进行订单履行(如果您不知道 Zoho CRM 是什么,可以解释为从 Shopify 将数据保存在数据库中),但出于某种原因,它每 3-4 天被删除一次。
根据文档,我需要验证 webhook 并在 5 秒内发送响应 200,否则将被解释为错误。如果 webhook 没有收到成功响应,它会再尝试 19 次,然后删除 webhook。我正在完成所有这些步骤,即便如此,我的 webhook 也被删除了。我做错了什么,我该如何解决?

以下是我的代码(我为此使用 PHP)-

<?php 
ini_set('display_errors', 1);
ini_set('display_startup_errors', 1);
error_reporting(E_ALL);

// Buffer all upcoming output...
ob_start();

// Send your response.
// echo "Here be response";
http_response_code(200);

// Get the size of the output.
$size = ob_get_length();

// Disable compression (in case content length is compressed).
header("Content-Encoding: none");

// Set the content length of the response.
header("Content-Length: {$size}");

// Close the connection.
header("Connection: close");

// Flush all output.
ob_end_flush();
ob_flush();
flush();

// Close current session (if it exists).
if(session_id()) session_write_close();

usleep(5000000); // 5 seconds

到这里为止,我正在发送响应 200 并使用 sleep 以便 5 秒内没有处理其他代码,因此它应该始终返回 200 标头,一旦发送响应,我正在处理结果

超出此范围的代码应该与问题——只是匹配各种条件来保存数据,但如果有必要,请告诉我,我会解释逻辑

define('SHOPIFY_APP_SECRET', 'somesecret');

function verify_webhook($data, $hmac_header)
{
  $calculated_hmac = base64_encode(hash_hmac('sha256', $data, SHOPIFY_APP_SECRET, true));
  return hash_equals($hmac_header, $calculated_hmac);
}

$hmac_header = $_SERVER['HTTP_X_SHOPIFY_HMAC_SHA256'];
$data        = file_get_contents('php://input');
$verified    = verify_webhook($data, $hmac_header);

$log_file_data  = 'request_' . date('Y-m-d H:i:s') . '.log';

file_put_contents($log_file_data, "verification webhook \r\n".print_r($verified, true)."\r\n");

if($verified){
    
    include 'ZohoCrmClient.php';
    include 'ShopifyClient.php';

    $zoho_obj    = new ZohoCrmClient();
    $shopify_obj = new ShopifyClient;

    
    // $response = file_get_contents('php://input');
    $response = $data;

    $response = json_decode($response, true);

    // print_r($response); die;

    file_put_contents($log_file_data, "shopify_data \r\n".print_r($response, true)."\r\n", FILE_APPEND);
    // die;

    // check if order already exists
    $order_name = rawurlencode($response['name']);
    // $order_name = rawurlencode('OS-5889');

    $order_name = "Subject:equals:$order_name";

    $exists = $zoho_obj->searchZohoCrmRecord('Sales_Orders', $order_name);

    $tagArr  = explode(", ", $response['customer']['tags']);
                    
    if(in_array('cafe-pending', $tagArr) || in_array('cafe-approved', $tagArr)){
    // print_r($exists); die;

    /*if(empty($exists)){*/
        // echo $response['email'];
        $productInfo    = $response['line_items'];
        $email          = $response['email'];
        $available_prod = [];
        $avail_prod_ids = [];
        $postData       = array();
        $proceed        = 0;

        $postData['Product_Details'] = array();

        foreach($productInfo as $key => $product_info){

            if(!$proceed){
                    
                $proceed = 1;
                // $tagArr  = explode(", ", $response['customer']['tags']);
                
                $lead       = $zoho_obj->searchZohoRecordByEmail('Leads', $email);
                $lead_data  = json_decode($lead);
                
                // print_r($lead_data); 
                
                file_put_contents($log_file_data, "\r\nlead_data \r\n".print_r($lead_data, true)."\r\n", FILE_APPEND);
                
                if(isset($lead_data->data[0]) && !empty($lead_data->data[0])){
                    
                    $recordArray    = array();
                    $recordObject   = array();

                    $recordObject["overwrite"]              = true;
                    $recordObject["notify_lead_owner"]      = true;
                    $recordObject["notify_new_entity_owner"]= true;

                    $recordArray[]          = $recordObject;
                    $requestBody["data"]    = $recordArray;

                    $convert = $zoho_obj->convertLead($lead_data->data[0]->id, $requestBody);

                    $convert = json_decode($convert, true);

                    file_put_contents($log_file_data, "\r\nconvert_data \r\n".print_r($convert, true)."\r\n", FILE_APPEND);

                    // print_r($convert); die;
                    // if(isset($convert['data'][0]) && !empty($convert['data'][0]) && !isset($convert['data'][0]['status'])){
                        
                        $contact_id = isset($convert['data'][0]['Contacts']) ? $convert['data'][0]['Contacts'] : '';
                        $account_id = isset($convert['data'][0]['Accounts']) ? $convert['data'][0]['Accounts'] : '';
                    // }

                    // print_r($convert);
                    
                }else{
                    
                    $account = $zoho_obj->searchZohoRecordByEmail('Accounts', $email);
                    $account = json_decode($account, true);
                    
                    file_put_contents($log_file_data, "\r\naccount_data \r\n".print_r($account, true)."\r\n", FILE_APPEND);
                    // print_r($account); 
                    // echo $account['data'][0]['id'];
                    // die;
                    if(isset($account['data'][0]) && !empty($account['data'][0])){

                        $account_id = $account['data'][0]['id'];
                        
                    }else{

                        // create account
                        $createAccountData = array();
                        
                        $createAccountData[0]['Account_Name']   = $response['customer']['default_address']['company'];
                        $createAccountData[0]['Contact_Name']   = $response['customer']['first_name'];
                        $createAccountData[0]['Last_Name']      = isset($response['customer']['last_name']) && !empty($response['customer']['last_name']) ? $response['customer']['last_name'] : $response['customer']['first_name'];
                        $createAccountData[0]['Phone']          = $response['phone'];
                        $createAccountData[0]['Email']          = $response['email'];
                        $createAccountData[0]['Shopify_Customer_ID'] = (string)$response['customer']['id'];
                        $createAccountData[0]['Account_Type']   = 'Shopify';
                        $createAccountData[0]['Account_Status'] = 'Active';
                        
                        $createAccountArr = array('data' => $createAccountData);
                        
                        $createAccount = $zoho_obj->createZohoCrmRecord('Accounts', $createAccountArr);

                        $createAccount = json_decode($createAccount, true);
                        // print_r($createAccount);
                        
                        file_put_contents($log_file_data, "\r\create_account \r\n".print_r($createAccount, true)."\r\n", FILE_APPEND);
                        
                        $account_id = $createAccount['data'][0]['details']['id'];
                    }

                    // convert to contact
                    $contact = $zoho_obj->searchZohoRecordByEmail('Contacts', $email);

                    $contact = json_decode($contact, true);
                    // print_r($contact);

                    file_put_contents($log_file_data, "\r\ncontact_data \r\n".print_r($contact, true)."\r\n", FILE_APPEND);

                    if(isset($contact['data'][0]) && !empty($contact['data'][0])){

                        $contact_id = $contact['data'][0]['id'];
                    
                    }else{

                        // create contact
                        $createContactData = array();
                        
                        $createContactData[0]['Account_Name']   = $account_id;
                        $createContactData[0]['First_Name']     = $response['customer']['first_name'];
                        $createContactData[0]['Last_Name']      = isset($response['customer']['last_name']) && !empty($response['customer']['last_name']) ? $response['customer']['last_name'] : $response['customer']['first_name'];
                        $createContactData[0]['Phone']          = $response['phone'];
                        $createContactData[0]['Email']          = $response['email'];
                        
                        $createContactArr = array('data' => $createContactData);
                        
                        $createContact = $zoho_obj->createZohoCrmRecord('Contacts', $createContactArr);

                        $createContact = json_decode($createContact, true);
                        // print_r($createContact); 
                        
                        file_put_contents($log_file_data, "\r\create_contact \r\n".print_r($createContact, true)."\r\n", FILE_APPEND);

                        $contact_id = $createContact['data'][0]['details']['id'];
                    }
                }
                // echo $response['billing_address']['city'];
            
                $postData['Account_Name']           = $account_id;
                $postData['Billing_City']           = $response['billing_address']['city'] ?? '';
                $postData['Billing_Code']           = $response['billing_address']['zip'] ?? '';
                $postData['Billing_Country']        = $response['billing_address']['country'] ?? '';
                $postData['Billing_State']          = $response['billing_address']['province'] ?? '';
                $postData['Billing_Street']         = $response['billing_address']['address2'] ?? '';
                // $postData['Carrier']                 = '';
                $postData['Contact_Name']           = $contact_id;
                // $postData['Created_By']              = '';
                $postData['Customer_No']            = !empty($response['customer']['id']) ? (string)$response['customer']['id'] : '';

                $postData['Shipping_City']          = $response['shipping_address']['city'] ?? '';
                $postData['Shipping_Code']          = $response['shipping_address']['zip'] ?? '';
                $postData['Shipping_Country']       = $response['shipping_address']['country'] ?? '';
                $postData['Shipping_State']         = $response['shipping_address']['province'] ?? '';
                $postData['Shipping_Street']        = $response['shipping_address']['address2'] ?? '';
                // $postData['SO_Number']               = '';
                $postData['Status']                 = 'Fulfilled';
                $postData['Subject']                = $response['name'];
                $postData['Discount']               = !empty($response['total_discounts']) ? (float)$response['total_discounts'] : (float)0; 
                $postData['Tax']                    = !empty($response['total_tax']) ? (float)$response['total_tax'] : (float)0;
                $postData['Adjustment']             = !empty($response['total_shipping_price_set']) ? (float)$response['total_shipping_price_set']['shop_money']['amount'] : (float)0;
                // $postData['Terms_and_Conditions']    = '';

                // $postData['shopifyextension__Lead_Name']                 = $contact_id;
                $postData['shopifyextension__Order_Shopify_Id']             = (string)$response['id'];
                $postData['shopifyextension__Shopify_Order_Created_Date']   = $response['created_at'];
                $postData['shopifyextension__Shopify_Fulfillment_Status']   = $response['fulfillment_status'];
                $postData['shopifyextension__Shopify_Financial_Status']     = $response['financial_status'];
                $postData['shopifyextension__Shopify_Reference_Id']         = (string)$response['id'];
                $postData['shopifyextension__Source']                       = 'Shopify';

            } 
            // print_r($product_info);
            // file_put_contents($log_file_data, "product_name \r\n".addcslashes($product_info['name'], '()')."\r\n", FILE_APPEND);
            $productName = $product_name = $product_info['name'];
            $product_name = rawurlencode(addcslashes($product_name, '(),'));

            $product = "Product_Name:equals:$product_name";
            // echo $product; die;
            file_put_contents($log_file_data, "product_name \r\n".$product_name."\r\n", FILE_APPEND);

            $zoho_product_record = $zoho_obj->searchZohoCrmRecord('Products', $product);
            // print_r($zoho_product_record);
            // die;

            $product_record = json_decode($zoho_product_record);
            
            file_put_contents($log_file_data, "\r\nproduct_record \r\n".print_r($product_record, true)."\r\n", FILE_APPEND);
            // die;
            if(isset($product_record->data[0]) && !empty($product_record->data[0])){
            
                $product_id = $product_record->data[0]->id;

                // shopify sku code, product id and shopify variant id should be saved
                if(empty($product_record->data[0]->Product_Code) || empty($product_record->data[0]->Shopify_id) || empty($product_record->data[0]->Shopify_Variant_id) || empty($product_record->data[0]->Product_Active)) {

                    $updateProductData = array();
                            
                    $updateProductData[0]['Product_Code']       = $product_info['sku'];
                    $updateProductData[0]['Product_Active']     = true;
                    $updateProductData[0]['Shopify_id']         = (int)$product_info['id'];
                    $updateProductData[0]['Shopify_Variant_id'] = (int)$product_info['variant_id'];

                    $updateProductArr = array('data' => $updateProductData);
                    
                    $updateProduct = $zoho_obj->updateZohoCrmRecord('Products', $product_id, $updateProductArr);

                    $updateProduct = json_decode($updateProduct, true);
                    // print_r($updateProduct);
                    
                    file_put_contents($log_file_data, "\r\nupdate_product \r\n".print_r($updateProduct, true)."\r\n", FILE_APPEND);

                }
                    
            }else{

                $productData = $shopify_obj->searchRecord('products', $product_info['product_id']);

                file_put_contents($log_file_data, "\r\nproduct_id \r\n".$product_info['product_id']."\r\n", FILE_APPEND);

                $productData = json_decode($productData, true);
                
                file_put_contents($log_file_data, "\r\nproduct_data_shopify \r\n".print_r($productData, true)."\r\n", FILE_APPEND);

                $Vendor_Name = $productData['product']['vendor'];
                $Vendor_Name = rawurlencode(addcslashes($Vendor_Name, '(),'));
                
                $vendor = "Vendor_Name:equals:$Vendor_Name";

                $vendorData = $zoho_obj->searchZohoCrmRecord('Vendors', $vendor);

                $vendorData = json_decode($vendorData, true);

                $vendor_id = '';
                if(isset($vendorData['data'][0]) && !empty($vendorData['data'][0])) {

                    $vendor_id = $vendorData['data'][0]['id'];
                }

                $variantData = $shopify_obj->searchRecord('variants', $product_info['variant_id']);

                $variantData = json_decode($variantData, true);
                
                file_put_contents($log_file_data, "\r\nvariant_data_shopify \r\n".print_r($variantData, true)."\r\n", FILE_APPEND);

                $createProductData = array();
                            
                $createProductData[0]['Product_Name']   = $productName;
                $createProductData[0]['Description']    = $productData['product']['body_html'];
                $createProductData[0]['Product_Active'] = true;
                $createProductData[0]['Product_Category'] = $productData['product']['product_type'];
                $createProductData[0]['Product_Code']   = isset($variantData['variant']['sku']) ? $variantData['variant']['sku'] : $product_info['sku'];
                // $createProductData[0]['Owner']           = 2466207000000114009;
                // $createProductData[0]['Qty_Ordered']     = 'Shopify';
                // $createProductData[0]['Qty_in_Demand'] = 'Active';
                $createProductData[0]['Qty_in_Stock'] = isset($variantData['variant']['inventory_quantity']) ? $variantData['variant']['inventory_quantity'] : $productData['product']['variants'][0]['inventory_quantity'];
                // $createProductData[0]['Reorder_Level'] = 'Active';
                $createProductData[0]['Taxable']    = isset($variantData['variant']['taxable']) ? (bool)$variantData['variant']['taxable'] : (bool)$productData['product']['variants'][0]['taxable'];
                $createProductData[0]['Unit_Price'] = isset($variantData['variant']['price']) ? $variantData['variant']['price'] : $productData['product']['variants'][0]['price'];
                $createProductData[0]['Usage_Unit'] = 'Active';
                $createProductData[0]['Vendor_Name'] = $vendor_id; // lookup
                $createProductData[0]['Shopify_id'] = (int)$productData['product']['id'];
                $createProductData[0]['Shopify_Variant_id'] = isset($variantData['variant']['id']) ? (int)$variantData['variant']['id'] : (int)$productData['product']['variants'][0]['id'];

                $createProductArr = array('data' => $createProductData);
                
                $createProduct = $zoho_obj->createZohoCrmRecord('Products', $createProductArr);

                $createProduct = json_decode($createProduct, true);
                print_r($createProduct);
                
                file_put_contents($log_file_data, "\r\ncreate_product \r\n".print_r($createProduct, true)."\r\n", FILE_APPEND);
                
                $product_id = $createProduct['data'][0]['details']['id'];
            }

            // create product
            $product_details_temp = [];

            $product_details_temp['product']    = $product_id;
            $product_details_temp['list_price'] = (double)$product_info['price']; 
            // $product_details_temp['total']   = (double)$Amount; 
            
            /*
            ** product wise tax and discount **
            $product_details_temp['Tax']        = !empty($product_info['tax_lines']) ? (float)$product_info['tax_lines'][0]['price'] : (float)0; 
            $product_details_temp['Discount']   = !empty($product_info['discount_allocations']) ? (float)$product_info['discount_allocations'][0]['amount'] : (float)0;*/

            $product_details_temp['quantity']   = (double)$product_info['quantity'];
            
            array_push($postData['Product_Details'], $product_details_temp);
            
        }

        file_put_contents($log_file_data, "\r\npost_data \r\n".print_r($postData, true)."\r\n", FILE_APPEND);
        // echo 'here';
        // die;
        if($proceed){

            $zohoData = ['data' => array($postData)];
                
            if(empty($exists)){
                
                $create = $zoho_obj->createZohoCrmRecord('Sales_Orders', $zohoData);
                // print_r($create);

                file_put_contents($log_file_data, "\r\ncreate_data \r\n".$create."\r\n", FILE_APPEND);

            }else{
                
                $exists     = json_decode($exists, true);
                $sales_id   = $exists['data'][0]['id'];
                
                $update = $zoho_obj->updateZohoCrmRecord('Sales_Orders', $sales_id, $zohoData);
                // print_r($update);

                file_put_contents($log_file_data, "\r\nupdate_data \r\n".$update."\r\n", FILE_APPEND);
            }       

        }else{

            // echo 'No products found!';

            file_put_contents($log_file_data, "\r\ncreate_data \r\n".'No products found!'."\r\n", FILE_APPEND);
        }

    }else{

        // echo 'customer tag is not cafe-approved or cafe-pending';
        file_put_contents($log_file_data, "\r\ncustomer tag is not:  \r\n".'cafe-approved or cafe-pending'."\r\n", FILE_APPEND);
    }

}else{
    error_log('Webhook verified: '.var_export($verified, true)); //check error.log to see the result
}

参考-

标签: phpshopifywebhookszoho

解决方案


您的代码看起来一切正常!
通常,shopify 在删除任何 webhook 之前会发送一封电子邮件。你收到邮件了吗?如果你这样做了,我猜问题可能出在你的身上。
在 Hookdeck,我们的基础设施会自动响应任何传入的 webhook 连接,以便稍后处理处理。您还可以使用它来调试 webhook 错误,请在此处查看

我们还有一个 Shopify 平台指南,其中详细介绍了如何使用 shopify webhook,请在此处查看

我希望这些帮助。


推荐阅读