TheMonk300
TheMonk300

Reputation: 3

PHP Webhook - x-www-form-urlencode parse

I am trying to build a kofi webhook parser and the data it sends is like this

data: {
"message_id":"3a1fac0c-f960-4506-a60e-824979a74e74",
"kofi_transaction_id":"0a1fac0c-f960-4506-a60e-824979a74e71",
"timestamp":"2022-08-21T13:04:30Z",
"type":"Donation",
"from_name":"Ko-fi Team",
"message":"Good luck with the integration!",
"amount":"3.00",
"currency":"USD",
"url":"https://ko-fi.com"
"is_subscription_payment":false
"is_first_subscription_payment":false}

The data is sent with a content type of application/x-www-form-urlencoded. A field named 'data' contains the payment infomation as a JSON string (as per the website information).

I have a php script to try and obtain the data

parse_str(file_get_contents("php://input"), $data);
//$data = (object)$data;
$data = json_decode(json_encode($data), true);
var_dump($data);

error_log($data->{'message_id'});

I cannot seem to get the value of message_id.

POSTMAN returns

array(12) {
  ["data"]=>
  string(2) " {"
  [""message_id""]=>
  string(39) ""3a1fac0c-f960-4506-a60e-824979a74e74","
  [""kofi_transaction_id""]=>
  string(39) ""0a1fac0c-f960-4506-a60e-824979a74e71","
  [""timestamp""]=>
  string(23) ""2022-08-21T13:04:30Z","
  [""type""]=>
  string(11) ""Donation","
  [""from_name""]=>
  string(13) ""Ko-fi Team","
  [""message""]=>
  string(34) ""Good luck with the integration!","
  [""amount""]=>
  string(7) ""3.00","
  [""currency""]=>
  string(6) ""USD","
  [""url""]=>
  string(19) ""https://ko-fi.com""
  [""is_subscription_payment""]=>
  string(5) "false"
  [""is_first_subscription_payment""]=>
  string(6) "false}"
}

I am not convinced the data being sent by postman is accurate though, it formats it weirdly.

Please can someone help me with what I am doing wrong? I basically want to receive the data and pull values from the data received which I am going to push in to a database.

Upvotes: 0

Views: 1849

Answers (3)

Kai
Kai

Reputation: 1

I've tried Kim Hallberg's code. Although it works fine with the webhook test messages, it won't work with real Ko-fi donations because of an ampersand in the "url" parameter, messing up parsing the data with parse_str.

I ended up writing my own code that works fine, although I'm getting rid of the initial data= part with the substr function:

// Get the input, remove the initial "data=" part, decode the url, and convert to a JSON object
$data = json_decode(urldecode(substr(file_get_contents("php://input"), 5)));

// Check the verification code, replace the verification code with your own!
if ($data->verification_token != '9a1121c4-bd1c-11ed-afa1-0242ac120002') {
    // If the verification token is not valid, set the response code to 403 Forbidden, and terminate the code execution.
    http_response_code(403);
    exit(1);
}

// Do what you need to do with the data
// Example: dump $data to file
ob_start();
var_dump($data);
file_put_contents('kofi_data_dump.txt', ob_get_clean());

Upvotes: 0

Kim Hallberg
Kim Hallberg

Reputation: 1265

Ko-fi sends urlencoded form data, meaning you have to use urldecode to decode that incoming string before you can parse it and decode the json object.

parse_str(urldecode(file_get_contents("php://input")), $input);

$webhook = json_decode($input['data']);

var_dump($webhook->message_id);

Upvotes: 2

Shlomtzion
Shlomtzion

Reputation: 718

You understand ofcourse that you cannot view the incoming data - you need to save it somewhere ... in the next example I am saving the json received to a txt file to see if is even being received.

Try to do this:

$webhookContent = '';

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

error_log($webhookContent);
$webhookContent = str_replace("'", "", $webhookContent);

$WebHookArray = json_decode($webhookContent,true);

$newFile = fopen("someFile.txt","w");
fwrite($newFile,$webhookContent . "\n");
fclose($newFile);

This will save the data to a file localy (if it doesn't create - create it and just for testing give it 777 permissions so it will save the data in there....)

Take that json and decode it online or via php json_decode($json,true); <- don't forget the ,true ... and see if it becomes a standard array that you can grab the "message_id" from.

if everything there appears to be right ... in a json format... than replace the $webhookContent with $WebHookArray['message_id'] - json_decoded already.

Upvotes: 0

Related Questions