Braintree webhooks, GET & POST configuration - php

I am trying to use webhooks to send emails about whether subscriptions were successfully charged or not. I use bt_challenge code to successfully register the webhook on Braintree's dashboard:
if(isset($_GET["bt_challenge"])) {
echo(Braintree_WebhookNotification::verify($_GET["bt_challenge"]));
}
However, when I use the subscription information from $webhook notification:
if(isset($_POST["bt_signature"]) && isset($_POST["bt_payload"])) {
$webhookNotification = Braintree_WebhookNotification::parse(
$_POST["bt_signature"], $_POST["bt_payload"]
);
}
I don't get an email sent. Furthermore, when I try to re-register the webhook from the Braintree dashboard, it won't recognize it with this second snippet of code in the file. Are both of these snippets meant to be in the same file? This part is unclear to me.
Following these two snippets, I have my phpmailer code, which is properly configured and sends a email when the script is called not via webhook. The phpmailer code is not contained within the "if" statement of either of these first two code blocks.

Related

What does this email from SendGrid is refering to in PHP API?

a few days a go we received a email from sendgrid stating they are going to change some behaviors in their API, I've done research but I have not found concretly what they are refering to, currently we are using the PHP API, and atleast for the 2) I think we are OK as we use SendGrid classes to build the emails
Check your code that uses the mail send endpoint and ensure that the
“enable” parameter is included under the filter when applicable.
What do you need to do?
To avoid disruption to your mail send service, please be sure to make
the following actions before August 10, 2021
Check your code that uses the mail send endpoint and ensure that the
“enable” parameter is included under the filter when applicable.
Check your mail send header to ensure that you are using just one
X-SMTPAPI header and address header of the same kind. Remove multiple
headers of the same kind, so you have only 1 header of the same kind.
For example, if you are currently using multiple “from” headers, you
should modify your code so that you have a single “from” header.
Check your code to ensure that you are not applying any
personalization block substitution to your custom argument fields.
But what about the third item? we have substitions of following fashion: $mail->personalization[0]->addSubstitution('%url%', $link);
But I havent found anything like a "block sustitution in custom arguments"
And the first item also worries me, I haven't found anything like that neither, so I'm afraid that perhaps there is something that the PHP API does behind the scenes.
This a example of the code we use.
$sendgrid = new SendGrid(env('SENDGRID_APIKEY'));
$from_m = new SendGrid\Email(null, $from);
$to_m = new SendGrid\Email(null, $from);
$content = new SendGrid\Content("text/html", $body);
$mail = new SendGrid\Mail($from_m, '.', $to_m, $content);
$mail->personalization[0]->addBcc($tos);
$mail->personalization[0]->setSubject($subject);
$mail->personalization[0]->addSubstitution('%MemberName%', $name);
$mail->personalization[0]->addSubstitution('%url%', $hash_url);
$mail->setTemplateId($template_id);
$sendgrid->client->mail()->send()->post($mail);
We are using sendgrid/sendgrid: ~6.2
Twilio SendGrid developer evangelist here.
From my reading of your code and the guidelines you've been sent, you should be ok.
You don't appear to be using anything that needs to be enabled via the API, though you can check all the mail_settings and tracking_settings in the API reference here.
As you are using the library and calling the API you don't appear to be sending any extra headers.
You don't seem to be using any custom arguments, so you aren't applying any substitutions to them.
I do recommend that you upgrade your PHP helper library to version 7 from 6. That will ensure that the underlying library is also using the API in the most up to date manner.

Cannot Verify Shopify Webhook

I have setup a webhook in shopify via settings > notifications > webhooks and entered a heroku app URL. My heroku app is in php and I run the verification function found here: https://shopify.dev/tutorials/manage-webhooks and when I open my app I get a blank response. I am not sure if this is something I am doing wrong on my heroku app, or if I am missing something. The goal here is to grab the json data after the event I have selected is ran, then to send that data to via third party api. But to start I just want to be able to verify that my heroku app is receiving the payload. Is there more I need to add to my php file in order to verify? (php noob here). Below is the code I am running in my php file, and yes I am using my shared secret found in the webhooks section.
<?php
define('SHOPIFY_APP_SECRET', 'my_shared_secret');
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 I am not mistaken you cannot test webhooks that way as the admin does not use your API key as it has no idea who you are when in the admin. So if you have a heroku App and it has an API key, use that API key to first off establish the webhook, verify you created it with the API, and then sit around and test your actual endpoint with Shopify Admin itself. That is how it works AFAIK.
The other verification in the admin is mickey mouse and meant to just throw data at any old endpoint with no validation.

Create a webhook programmatically in wordpress/woocommerce

i'm making a Plugin to make a integration of one ERP to Woocommerce and i'm thinking about using the web hooks for that integration, the problem create the web hooks when the plugin is activated for the first time, and not oblige people to create the woocommerce webhooks manually and configure them. i googled and tried several things but looks like no one works, also tried make a sql query, but don't worked.
i tried this:
function createWebhook($userID,$topic,$secret,$deliveryURL,$status)
{
$webhook = new WC_Webhook();
$webhook->set_user_id($userID); // User ID used while generating the webhook payload.
$webhook->set_topic( $topic ); // Event used to trigger a webhook.
$webhook->set_secret( $secret ); // Secret to validate webhook when received.
$webhook->set_delivery_url( $deliveryURL ); // URL where webhook should be sent.
$webhook->set_status( $status ); // Webhook status.
$save = $webhook->save();
return $save;
}
from this thread
without sucess, getting a lot of errors.
Anyway, thanks for the help. and i hope you'r ale in safety and with good health!
You are missing the webhook name
Add $webhook->set_name('Webhook Name');

PHP verify Paypal webhook signature

I'm having trouble trying to verify paypal webhook signatures with PHP. Using the new V2 of paypals APIs I am receiving the paypal webhook on my page.
However I can not seem to successfully validate the signature.
From the link HERE I got some sample webhook validation PHP code from paypal.
I can not get it working, I don't know where I am supposed to get bootstrap.php from in the paypal code. The paypal information seems incomplete or half baked. Paypal seems to be terrible to set-up compared to Stripe.
Has anyone got experience of validating paypal webhook signatures with PHP when using V2 of the paypal APIs ?
Well I have come to the conclusion that the Paypal developer information is rather poor, it is scatted all over the place, on multiple different pages and sites. The examples they give on the paypal developer website HERE are not a complete picture of what is required to validate a webhook signature. Stripe developer documentation is much better formatted and concise.
Installing Paypal Checkout V2 SDK does not give you the necessary development tools to validate paypal webhook signatures i.e. you can process payments and receive webhooks but you can not validate the webhook signatures....I know stupid. Tip do not download the SDK directly as you will not include the required autoload.php file. Use composer to install Paypal Checkout V2 SDK so that you get the autoload.php file.
Once you are to a point that you can process payments and receive webhooks form paypal you need to install the another SKD called Paypal Rest API SDK. Again use composer to install the SDK so that you get a autoload.php file which you will need.
When you install Paypal Rest API SDK amazingly you will still be missing files that are required to validate the payapl webhook signatures. I can find no mention of these anywhere on the paypal developer website.
bootstrap.php & common.php
Thanks to #Grumpy I got some samples provided on github HERE
Note you will probably need to modify the samples a bit in order to get them working with your website. Tip set the logger to false and save yourself some bother if you don't have the necessary access permissions to write.
Once you have bootstrap.php & common.php files created you can write the code for your webhook endpoint page i.e. the page that paypal sends the webhook to. I have included my PHP code below for how to validate and then process the paypal webhook. Tip in the below code you need to specify the webhook ID, each webhook that you create in paypal has a unique ID. Also when you are testing you can not use webhook simulator as this will fail validation, you can make manually a payment with your sandbox account details which will trigger a webhook payment event.
Paypal sure don't make it easy, their documentation is all over the place compared to Stripe. The Paypal webhooks can sometimes take several minutes to arrive after a payment is made, very frustrating when trying to debug. Also it's a bit ridiculous that they have a webhook simulator on the paypal developer website that can not be used to validate signatures...if stripe can do it why can't paypal.
<?php
//get the webhook payload
$requestBody = file_get_contents('php://input');
//check if webhook payload has data
if($requestBody) {
//request body is set
} else {
//request body is not set
exit();
}
use \PayPal\Api\VerifyWebhookSignature;
use \PayPal\Api\WebhookEvent;
$apiContext = require __DIR__ . '/bootstrap.php';
//Receive HTTP headers that you received from PayPal webhook.
$headers = getallheaders();
//need header keys to be UPPERCASE
$headers = array_change_key_case($headers, CASE_UPPER);
/*
example header paypal signature content for webhook, these values are recieved as an array, we then need to use this data to verify the payload
CONTENT-LENGTH : 1376
CORRELATION-ID : 6db85170269e7
USER-AGENT : PayPal/AUHD-214.0-54377828
CONTENT-TYPE: application/json
PAYPAL-AUTH-ALGO : SHA256withRSA
PAYPAL-CERT-URL : https://api.paypal.com/v1/notifications/certs/CERT-360caa42-fca2a784-5edc0ebc
PAYPAL-AUTH-VERSION : v2
PAYPAL-TRANSMISSION-SIG : Hc2lsDedYdSjOM4/t3T/ioAVQqFPNVB/AY/EyPNlavXk5WYUfnAmt9dyEP6neAPOjFHiVkXMK+JlLODbr6dalw6i26aFQdsPXqGl38Mafuu9elPE74qgsqNferUFgHi9QFXL+UZCNYcb4mvlDePXZIIAPbB0gOuFGOdEv2uqNwTCSAa/D8aguv1/51FWb3RkytFuVwXK/XNfIEy2oJCpDs8dgtYAZeojH8qO6IAwchdSpttMods5YfNBzT7oCoxO80hncVorBtjj1zQrkoynEB9WNNN9ytepNCkT8l29fQ4Sx/WRndm/PESCqxqmRoYJoiSosxYU3bZP7QTtILDykQ==
PAYPAL-TRANSMISSION-TIME : 2020-04-05T14:40:43Z
PAYPAL-TRANSMISSION-ID : 6dec99b0-774b-11ea-b306-c3ed128f0c4b
*/
//if any of the relevant paypal signature headers are not set exit()
if(
(!array_key_exists('PAYPAL-AUTH-ALGO', $headers)) ||
(!array_key_exists('PAYPAL-TRANSMISSION-ID', $headers)) ||
(!array_key_exists('PAYPAL-CERT-URL', $headers)) ||
(!array_key_exists('PAYPAL-TRANSMISSION-SIG', $headers)) ||
(!array_key_exists('PAYPAL-TRANSMISSION-TIME', $headers))
)
{
exit();
}
//specify the ID for the webhook that you have set up on the paypal developer website, each web hook that you create has a unique ID
$webhookID = "ENTER_YOUR_WEBHOOK_ID_HERE";
//start paypal webhook signature validation
$signatureVerification = new VerifyWebhookSignature();
$signatureVerification->setAuthAlgo($headers['PAYPAL-AUTH-ALGO']);
$signatureVerification->setTransmissionId($headers['PAYPAL-TRANSMISSION-ID']);
$signatureVerification->setCertUrl($headers['PAYPAL-CERT-URL']);
$signatureVerification->setWebhookId($webhookID);
$signatureVerification->setTransmissionSig($headers['PAYPAL-TRANSMISSION-SIG']);
$signatureVerification->setTransmissionTime($headers['PAYPAL-TRANSMISSION-TIME']);
$signatureVerification->setRequestBody($requestBody);
$request = clone $signatureVerification;
try {
$output = $signatureVerification->post($apiContext);
} catch (Exception $ex) {
//error during signature validation, capture error and exit
ResultPrinter::printError("Validate Received Webhook Event", "WebhookEvent", null, $request->toJSON(), $ex);
exit(1);
}
$sigVerificationResult = $output->getVerificationStatus();
// $sigVerificationResult is a string and will either be "SUCCESS" or "FAILURE"
//if not webhook signature failed validation exit
if($sigVerificationResult != "SUCCESS"){
exit();
}
else if($sigVerificationResult == "SUCCESS"){
//paypay webhook signature is valid
//proceed to process webhook payload
//decode raw request body
$requestBodyDecode = json_decode($requestBody);
//pull whatever info required from decoded request body, some examples below
$paymentSystemID = $requestBodyDecode->id;
$eventType = $requestBodyDecode->event_type;
//do something with info captured from the webhook payload
}
This seems to work with php 8.1:
if (openssl_verify(
data: implode(separator: '|', array: [
$httpPayPalTransmissionId,
$httpPayPalTransmissionTime,
$webhookID,
crc32(string: $rawRequestBody),
]),
signature: base64_decode(string: $httpPayPalTransmissionSignature),
public_key: openssl_pkey_get_public(public_key: file_get_contents(filename: $cachedHttpPayPalCertUrl)),
algorithm: 'sha256WithRSAEncryption'
) === 1) {
die('OK');
} else {
die('FAILED');
}

SendGrid Web API bounced email header response

I am sending emails via SendGrid with this inside the x-smtpapi header
$json_string = array(
'unique_args' => array (
'email_id' => 1
)
);
It all seems to send okay, inside SendGrid I can view the "email_id" in the Email activity under Unique Args.
However when I try to use the API to look at this email, I cannot find a way to actually get these unique arguments from the API.
I am using this to try and get the headers returned with the bounced emails.
$request = 'https://api.sendgrid.com/api/bounces.get.json&api_user=username&api_key=password'
All I get is just the email addresses that have bounced, not the header information (the unique arguments)
I want to know, is it possible to get the unique arguments from the API. I have read it multiple times to no avail.
I hope this makes sense.
Thanks
At present there's no way request to lookup specific events by unique_arg with the Web API.
However, the SendGrid Event Webhook will give you granular data on each event, such as a bounce as it happens. The Event Webhook POSTs data to your server every time an action is taken upon an email (e.g. open, click, bounce).
Once you receive it, you're responsible for storing this, although it's not a typical API it gives very specific data on events which you can then compile and rehash however you like.
To get started using the webhook, you'll do something like the following, and have SendGrid POST to the following script:
<?php
$data = file_get_contents("php://input");
$events = json_decode($data, true);
foreach ($events as $event) {
// Here, you now have each event and can process them how you like
process_event($event);
}
[Taken from the SendGrid Webhook Code Example]

Categories