Your webhook is failing

Solved

Your webhook is failing

shingekinokyoji
Excursionist
20 1 2

I keep getting an email that my webhook is failing. Also, I see in https://partners.shopify.com/ webhook metrics that there is a 100% failed delivery rate. After some research I encountered the following https://shopify.dev/apps/webhooks/configuration/https#respond-to-a-webhook. I tried responding to the webhook/Shopify in PHP but it's not working. Should I provide the code that I use for the webhook?

Any help would be greatly appreciated. 

Accepted Solution (1)

shingekinokyoji
Excursionist
20 1 2

This is an accepted solution.

I was able to solve the problem.

After looking at the PHP snippet provided here https://shopify.dev/apps/webhooks/configuration/https#respond-to-a-webhook I noticed that I had my code laid out differently. I reorganized the code to be in line with the snippet in the link above. And I got back a 200 response rather than a 500 response. 

Old Version/Layout of Code

 

<?php

header("HTTP/1.1 200 OK");

include("../includes/config.php");

define('SHOPIFY_APP_SECRET', 'shpss_xxxxxxxxxxxxxxxxxxxxxxxxxxx'); 

header("HTTP/1.1 200 OK");

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);
  
  header("HTTP/1.1 200 OK");
  http_response_code(200);
}

$response = '';

header("HTTP/1.1 200 OK");
http_response_code(200);

$hmac_header = $_SERVER['HTTP_X_SHOPIFY_HMAC_SHA256'];

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

echo header("HTTP/1.1 200 OK");
echo http_response_code(200);


$data_json = json_decode( $data, true );

$verified = verify_webhook($data, $hmac_header);


if( $verified == true ) {

    $response = $data_json;
    echo header("HTTP/1.1 200 OK");
    echo http_response_code(200);

} else {

  $response = 'The request is not from Shopify ⚠️';

}

$shop_domain = $_SERVER['HTTP_X_SHOPIFY_SHOP_DOMAIN'];

$log = fopen( $shop_domain . ".json", "w") or die("Cannot open or create this file😭");

$fwrite = fwrite( $log, json_encode($response) );

    
 // Prepare an insert statement
$sql = "INSERT INTO shopify_orders (shopify_id, app_id, checkout_id, checkout_token, confirmed, contact_email, created_at,currency, current_total_price, gateway,first_name,last_name,fulfillable_quantity, product_name, shopify_shop) VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)";
 
if($stmt = $con->prepare($sql)){

    // Bind variables to the prepared statement as parameters
    $stmt->bind_param("sssssssssssssss", $shopify_id_variable,$app_id_variable, $checkout_id_variable, $checkout_token_variable,$confirmed_variable, $contact_email_variable,$created_at_variable,$currency_variable,$current_total_price_variable,$gateway_variable,$first_name_variable,$last_name_variable, $fulfillable_quantity_variable, $product_name_variable, $vendor_variable);    
    
    /* Set the parameters values and execute the statement to insert a row */
    $shopify_id_variable = $data_json['id'];
    $app_id_variable = $data_json['app_id'];
    $checkout_id_variable = $data_json['checkout_id'];    
    $checkout_token_variable = $data_json['checkout_token'];
    $confirmed_variable = $data_json['confirmed'];
    $contact_email_variable = $data_json['contact_email'];
    $created_at_variable = $data_json['created_at'];
    $currency_variable = $data_json['currency'];
    $current_total_price_variable = $data_json['current_total_price'];
    $gateway_variable = $data_json['gateway'];
    $first_name_variable = $data_json['billing_address']['first_name'];
    $last_name_variable = $data_json['billing_address']['last_name'];
    
    $line_items = [];
    foreach($data_json["line_items"] as $item) {
             $line_items["quantity"] = $item["fulfillable_quantity"];
             $line_items["product_name"] = $item["name"];
             $line_items["vendor"] = $item["vendor"];
         }
         
    $fulfillable_quantity_variable = $line_items["quantity"];   
    $product_name_variable = $line_items["product_name"];     
    $vendor_variable = $line_items["vendor"];           
     
         
    $stmt->execute();
    
    header("HTTP/1.1 200 OK");
    
    // // Close statement
    // $stmt->close();
     
    // // Close connection
    // $con->close();
    
    $last_insert_id = $con->insert_id;

    include("checkout_order_email.php");


    }else{
        error_log('Response: '. "ERROR: Could not prepare query: $sql. " . $con->error); //check error.log to see the result
    }

            
?>

 

 

New Version/Layout of Code

This returns a 200 response in https://partners.shopify.com/ webhook metrics delivery logs.

 

<?php

define('SHOPIFY_APP_SECRET', 'shpss_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx'); 

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);

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

if($verified) {
    
    http_response_code(200);
    
    $response = $data_json;
    
    $shop_domain = $_SERVER['HTTP_X_SHOPIFY_SHOP_DOMAIN'];

    $log = fopen( $shop_domain . ".json", "w") or die("Cannot open or create this file😭");
    
    $fwrite = fwrite( $log, json_encode($response) );
    
    

include("../includes/config.php");

$data_json = json_decode( $data, true );
    
 // Prepare an insert statement
$sql = "INSERT INTO shopify_orders (shopify_id, app_id, checkout_id, checkout_token, confirmed, contact_email, created_at,currency, current_total_price, gateway,first_name,last_name,fulfillable_quantity, product_name, shopify_shop) VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)";
 
if($stmt = $con->prepare($sql)){

    // Bind variables to the prepared statement as parameters
    $stmt->bind_param("sssssssssssssss", $shopify_id_variable,$app_id_variable, $checkout_id_variable, $checkout_token_variable,$confirmed_variable, $contact_email_variable,$created_at_variable,$currency_variable,$current_total_price_variable,$gateway_variable,$first_name_variable,$last_name_variable, $fulfillable_quantity_variable, $product_name_variable, $vendor_variable);    
    
    /* Set the parameters values and execute the statement to insert a row */
    $shopify_id_variable = $data_json['id'];
    $app_id_variable = $data_json['app_id'];
    $checkout_id_variable = $data_json['checkout_id'];    
    $checkout_token_variable = $data_json['checkout_token'];
    $confirmed_variable = $data_json['confirmed'];
    $contact_email_variable = $data_json['contact_email'];
    $created_at_variable = $data_json['created_at'];
    $currency_variable = $data_json['currency'];
    $current_total_price_variable = $data_json['current_total_price'];
    $gateway_variable = $data_json['gateway'];
    $first_name_variable = $data_json['billing_address']['first_name'];
    $last_name_variable = $data_json['billing_address']['last_name'];
    
    $line_items = [];
    foreach($data_json["line_items"] as $item) {
             $line_items["quantity"] = $item["fulfillable_quantity"];
             $line_items["product_name"] = $item["name"];
             $line_items["vendor"] = $item["vendor"];
         }
         
    $fulfillable_quantity_variable = $line_items["quantity"];   
    $product_name_variable = $line_items["product_name"];     
    $vendor_variable = $line_items["vendor"];           
     
         
    $stmt->execute();

    }else{
        error_log('Response: '. "ERROR: Could not prepare query: $sql. " . $con->error); //check error.log to see the result
    }
    
} else {

  $response = 'The request is not from Shopify ⚠️';
  
  $shop_domain = $_SERVER['HTTP_X_SHOPIFY_SHOP_DOMAIN'];
  
  $log = fopen( $shop_domain . ".json", "w") or die("Cannot open or create this file😭");
    
  $fwrite = fwrite( $log, json_encode($response) );

}

?>

 

 

 

 

 

Successful Webhook.PNGWebhook Delivery Log - One Success and Many Failures.PNG

View solution in original post

Reply 1 (1)

shingekinokyoji
Excursionist
20 1 2

This is an accepted solution.

I was able to solve the problem.

After looking at the PHP snippet provided here https://shopify.dev/apps/webhooks/configuration/https#respond-to-a-webhook I noticed that I had my code laid out differently. I reorganized the code to be in line with the snippet in the link above. And I got back a 200 response rather than a 500 response. 

Old Version/Layout of Code

 

<?php

header("HTTP/1.1 200 OK");

include("../includes/config.php");

define('SHOPIFY_APP_SECRET', 'shpss_xxxxxxxxxxxxxxxxxxxxxxxxxxx'); 

header("HTTP/1.1 200 OK");

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);
  
  header("HTTP/1.1 200 OK");
  http_response_code(200);
}

$response = '';

header("HTTP/1.1 200 OK");
http_response_code(200);

$hmac_header = $_SERVER['HTTP_X_SHOPIFY_HMAC_SHA256'];

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

echo header("HTTP/1.1 200 OK");
echo http_response_code(200);


$data_json = json_decode( $data, true );

$verified = verify_webhook($data, $hmac_header);


if( $verified == true ) {

    $response = $data_json;
    echo header("HTTP/1.1 200 OK");
    echo http_response_code(200);

} else {

  $response = 'The request is not from Shopify ⚠️';

}

$shop_domain = $_SERVER['HTTP_X_SHOPIFY_SHOP_DOMAIN'];

$log = fopen( $shop_domain . ".json", "w") or die("Cannot open or create this file😭");

$fwrite = fwrite( $log, json_encode($response) );

    
 // Prepare an insert statement
$sql = "INSERT INTO shopify_orders (shopify_id, app_id, checkout_id, checkout_token, confirmed, contact_email, created_at,currency, current_total_price, gateway,first_name,last_name,fulfillable_quantity, product_name, shopify_shop) VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)";
 
if($stmt = $con->prepare($sql)){

    // Bind variables to the prepared statement as parameters
    $stmt->bind_param("sssssssssssssss", $shopify_id_variable,$app_id_variable, $checkout_id_variable, $checkout_token_variable,$confirmed_variable, $contact_email_variable,$created_at_variable,$currency_variable,$current_total_price_variable,$gateway_variable,$first_name_variable,$last_name_variable, $fulfillable_quantity_variable, $product_name_variable, $vendor_variable);    
    
    /* Set the parameters values and execute the statement to insert a row */
    $shopify_id_variable = $data_json['id'];
    $app_id_variable = $data_json['app_id'];
    $checkout_id_variable = $data_json['checkout_id'];    
    $checkout_token_variable = $data_json['checkout_token'];
    $confirmed_variable = $data_json['confirmed'];
    $contact_email_variable = $data_json['contact_email'];
    $created_at_variable = $data_json['created_at'];
    $currency_variable = $data_json['currency'];
    $current_total_price_variable = $data_json['current_total_price'];
    $gateway_variable = $data_json['gateway'];
    $first_name_variable = $data_json['billing_address']['first_name'];
    $last_name_variable = $data_json['billing_address']['last_name'];
    
    $line_items = [];
    foreach($data_json["line_items"] as $item) {
             $line_items["quantity"] = $item["fulfillable_quantity"];
             $line_items["product_name"] = $item["name"];
             $line_items["vendor"] = $item["vendor"];
         }
         
    $fulfillable_quantity_variable = $line_items["quantity"];   
    $product_name_variable = $line_items["product_name"];     
    $vendor_variable = $line_items["vendor"];           
     
         
    $stmt->execute();
    
    header("HTTP/1.1 200 OK");
    
    // // Close statement
    // $stmt->close();
     
    // // Close connection
    // $con->close();
    
    $last_insert_id = $con->insert_id;

    include("checkout_order_email.php");


    }else{
        error_log('Response: '. "ERROR: Could not prepare query: $sql. " . $con->error); //check error.log to see the result
    }

            
?>

 

 

New Version/Layout of Code

This returns a 200 response in https://partners.shopify.com/ webhook metrics delivery logs.

 

<?php

define('SHOPIFY_APP_SECRET', 'shpss_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx'); 

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);

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

if($verified) {
    
    http_response_code(200);
    
    $response = $data_json;
    
    $shop_domain = $_SERVER['HTTP_X_SHOPIFY_SHOP_DOMAIN'];

    $log = fopen( $shop_domain . ".json", "w") or die("Cannot open or create this file😭");
    
    $fwrite = fwrite( $log, json_encode($response) );
    
    

include("../includes/config.php");

$data_json = json_decode( $data, true );
    
 // Prepare an insert statement
$sql = "INSERT INTO shopify_orders (shopify_id, app_id, checkout_id, checkout_token, confirmed, contact_email, created_at,currency, current_total_price, gateway,first_name,last_name,fulfillable_quantity, product_name, shopify_shop) VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)";
 
if($stmt = $con->prepare($sql)){

    // Bind variables to the prepared statement as parameters
    $stmt->bind_param("sssssssssssssss", $shopify_id_variable,$app_id_variable, $checkout_id_variable, $checkout_token_variable,$confirmed_variable, $contact_email_variable,$created_at_variable,$currency_variable,$current_total_price_variable,$gateway_variable,$first_name_variable,$last_name_variable, $fulfillable_quantity_variable, $product_name_variable, $vendor_variable);    
    
    /* Set the parameters values and execute the statement to insert a row */
    $shopify_id_variable = $data_json['id'];
    $app_id_variable = $data_json['app_id'];
    $checkout_id_variable = $data_json['checkout_id'];    
    $checkout_token_variable = $data_json['checkout_token'];
    $confirmed_variable = $data_json['confirmed'];
    $contact_email_variable = $data_json['contact_email'];
    $created_at_variable = $data_json['created_at'];
    $currency_variable = $data_json['currency'];
    $current_total_price_variable = $data_json['current_total_price'];
    $gateway_variable = $data_json['gateway'];
    $first_name_variable = $data_json['billing_address']['first_name'];
    $last_name_variable = $data_json['billing_address']['last_name'];
    
    $line_items = [];
    foreach($data_json["line_items"] as $item) {
             $line_items["quantity"] = $item["fulfillable_quantity"];
             $line_items["product_name"] = $item["name"];
             $line_items["vendor"] = $item["vendor"];
         }
         
    $fulfillable_quantity_variable = $line_items["quantity"];   
    $product_name_variable = $line_items["product_name"];     
    $vendor_variable = $line_items["vendor"];           
     
         
    $stmt->execute();

    }else{
        error_log('Response: '. "ERROR: Could not prepare query: $sql. " . $con->error); //check error.log to see the result
    }
    
} else {

  $response = 'The request is not from Shopify ⚠️';
  
  $shop_domain = $_SERVER['HTTP_X_SHOPIFY_SHOP_DOMAIN'];
  
  $log = fopen( $shop_domain . ".json", "w") or die("Cannot open or create this file😭");
    
  $fwrite = fwrite( $log, json_encode($response) );

}

?>

 

 

 

 

 

Successful Webhook.PNGWebhook Delivery Log - One Success and Many Failures.PNG