简体   繁体   中英

Shopify webhook keeps deleting

I am using a webhook to store the data in Zoho CRM from Shopify using webhook on order-fulfillment(can be interpreted as saving data in the database from Shopify, if you don't know what Zoho CRM is), but for some reason, it gets deleted every 3-4 days.
According to the docs, I need to verify the webhook and send a response 200 within 5 seconds, or else it is interpreted as an error. If the webhook doesn't receive success response, it tries 19 more times and then deletes the webhook. I am fulfilling all of these steps and even then my webhook is deleted. What am I doing wrong and how can I solve this?

Following is my code(I am using PHP for this)-

<?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

Up until here, I am sending the response 200 and using sleep so that no other code is processed for 5 seconds, so it should always return 200 header, once the response is sent, I am processing the result

Code beyond this should be irrelevelant to the question -- Just matching various conditions to save data but if it is necessary, let me know, I will explain the logic

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
}

Reference -

Everything looks fine with your code!
Typically, shopify sends an email before deleting any webhooks. Did you get an email? If you did I guess the problem might be from your end.
At Hookdeck, Our infra responds automatically responds to any incoming webhook connections,so can handle processing later on. You can also use it to debug webhook erros, check it out here

We also have a Shopify Platform guide that details working with shopify webhooks, check it out here .

I hope these help.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM