Gumroad Webhooks Response - php

I came across a great checkout solution called Gumroad. What I am trying to do is use their webhook functionality.
I have a Wordpress site, that when the user buys a product I will generate a user account based on their email.
With webhooks, they send a POST request to my endpoint which I have defined as www.mysite.com/gumroad. In here is where I want to grab the email address, then I will create the account and generate a password. What Gumroad expects me to return as stated on the page linked above is :
→ return an HTTP status code of 200
→ have a text/plain content type
→ contain only a URL (in the body)
I have no idea how to do this or what the code should look like.
Here is what I have so far and I know this isn't working but I can't figure out what exactly to do.
<?php
/* Template Name: Gumroad Test */
$email = $_POST['email'];
if( isset($email) ){
header("HTTP/1.1 200 OK");
echo "<h1>WEBHOOK WORKING</h1>";
}
?>

You only need to echo your full url instead of "<h1>WEBHOOK WORKING</h1>";
echo "http://www.example.com/sell";

Related

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

PHP incoming webhook handling

I have a 3rd party website that has webhooks that send to a specific url. I set it up to send to a blank page on my site (example: www.mysite.com/webhook.php)
I have a var_dump set up in the webhook.php that should display any information in the post or get.. I am new to webhooks and might just not understand how they work. I assume that i can have var_dump($_POST) in my php file to display an array of the HTTP request that is coming to my site.
I cannot see any requests on my site from the hook after sending test data.. any ideas?
I would do this to test the webhook.
<?php
$fWrite = fopen("log.txt","a");
$wrote = fwrite($fWrite, var_dump($_POST));
fclose($fWrite);
?>
This will return var_dump data in log.txt file, since as rickdenhaan said 36 mins ago, your current webhook.php return data to the webhook not your view.
You may need to create log.txt manually if you don't have right on directory (755)
I'm currently working with a payment API that use webhook. Webhook send data to X url then do action and return code to webhook. so webhook.php is the place where my order if ispaid or not is proceed or not... here what I did:
if ($payment->isPaid() == TRUE)
{
/*
* At this point you'd probably want to start the process of delivering the product to the customer.
*/
$con->query("UPDATE orders SET bankno = '$bankno', status = 'paid' WHERE ordertr = '$ids'");
}
elseif ($payment->isOpen() == FALSE)
{
/*
* The payment isn't paid and isn't open anymore. We can assume it was aborted.
*/
$con->query("UPDATE orders SET bankno = '$bankno', status = 'closed' WHERE ordertr = '$ids'");
}
So if order paid mark as paid in database if not mark as closed. This show webhook usage. Doing action according to what the webhook data send.
here is how i get content sent to my app:
$varname = json_decode(file_get_contents('php://input'));
well my content are JSON encoded, but I think this would be fine:
$varname = file_get_contents('php://input');

Braintree webhooks, GET & POST configuration

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.

Issue while integrating SMS gateway in PHP

In my PHP project I want to integrate SMS gateway.
I have integrated HSPSMS SMS gateway.
They have given one API for this,but unfortunately I am unable to call this in proper way. I have called API after user successfully registered to site for sending SMS to user regarding same to notify he had successfully registered. Currently I am sending SMS for same but API's can send response back for SMS delivery(Successfully SMS sent or not in a JSON format).
Here is a problem- I am unable to caught the return response of SMS gateway,so it causes the Response is showing on user/Web Page.
It is a problematic for user.
For calling SMS gateway I have used PHP Header function like:
header("Location:URL of SMS Gateway");
My Code as Bellow,
<?php
include("otherpages/connection.php");
if(isset($_POST['submit1'])) {
$mname=$_POST['mname'];
$cdate=$_POST['cdate'];
$maddress1=$_POST['maddress'];
$mschool=$_POST['mschool'];
$mkendra=$_POST['centrename'];
$mmobile=$_POST['mmobile'];
$user=$_POST['user'];
$pass=$_POST['pass'];
$approved="0";
$qr="insert into tempregistration values('','$cdate','$mname','$maddress1','$mschool','$mschool','$mkendra','$mmobile','$user','$pass','$approved')";
// Code for Registration SMS
$url = 'http://sms.hspsms.com/sendSMS?username=#USERNAME#&message=Dear User,You Have Succeffully Registered to ABC.com ,Thanks&sendername=HSPSMS&smstype=PROMO&numbers=9503808004&apikey=#APIKey#';
header("Location:$url");
?>
Please help me on same or guide where I am doing right or wrong?
Any help will be appreciable.
You're sending the user's browser to the API, what you want to do is have PHP make the request and then tell the user if it was successful or not.
You may be able to use get_file_contents, but curl will give you more control.
You should have a function that will send the request to the API and return a success/failure and then display a message to the user.
Something like this (untested):
if(isset($_POST['submit1'])) {
$mname=$_POST['mname'];
$cdate=$_POST['cdate'];
$maddress1=$_POST['maddress'];
$mschool=$_POST['mschool'];
$mkendra=$_POST['centrename'];
$mmobile=$_POST['mmobile'];
$user=$_POST['user'];
$pass=$_POST['pass'];
$approved="0";
$qr="insert into tempregistration values('',
'$cdate','$mname','$maddress1','$mschool',
'$mschool','$mkendra','$mmobile','$user','$pass','$approved')";
//update to encode parameters which contain spaces
$message = urlencode('Dear User, You have successfully registered ...');
// other parametes might also contain spaces ...
$username = urlencode('#USERNAME');
$sendername = urlencode('HSPSMS');
//etc
$url = 'http://sms.hspsms.com/sendSMS?username='.$username
.'&message='.$message
.'&sendername='.$sendername
.'&smstype=PROMO&numbers=9503808004&apikey=#APIKey#';
if ($result = do_api_call($url)){
echo "SMS API returned:<br>";
echo $result;//for debugging
}else {
echo "Failure"
}
}
...
function do_api_call($url){
//this is very simplistic code to get you going ...
//use curl instead for more control
return file_get_contents($url);
}

Google in-app payments: howto to handle Google's postback JWT

Maybe its a stupid question but I'm not an advanced programmer. I've
have successfully setup In-App payments for my app but it only works
without using a postback url.
I've Google'd around many hours trying to tackle this myself without
success. Hopefully anybody could help me out. I've included the script
handling the post data which does obviously something wrong.. This is what Google says:
Your server must send a 200 OK response for each HTTP POST message
that Google sends to your postback URL. To send this response, your
server must:
Decode the JWT that's specified in the jwt parameter of the POST
message. Check to make sure that the order is OK. Get the value of the
JWT's "orderId" field. Send a 200 OK response that has only one thing
in the body: the "orderId" value you got in step 3.
This is what I wrote but as far as I can see there is no way to test it (how can I simulate a post from Google?).
require_once 'include/jwt.php'; // including luciferous jwt library
$encoded_jwt = $_POST['jwt'];
$decoded_jwt = JWT::decode($encoded_jwt, "fdNAbAdfkCDakJQBdViErg");
$decoded_jwt_array = (array) $decoded_jwt;
$orderId = $decoded_jwt_array['response']['orderId'];
header("HTTP/1.0 200 OK");
echo $orderId;
Any help would be much appreciated. Thanks Tim
I had this same problem a year later and solved it with the following code:
require_once 'include/jwt.php'; // including luciferous jwt library
$encoded_jwt = $_POST['jwt'];
$decodedJWT = JWT::decode($jwt, $sellerSecret);
// get orderId
$orderId = $decodedJWT->response->orderId;
header("HTTP/1.0 200 OK");
echo $orderId;
Google Wallet's In App Purchase documentation is relatively new, and lacking on the callback side. This code works both sandbox and production side, just make sure you use your own seller secret.
Set Sandbox Postback URL in your Google Wallet setting to a test page, then log the requests to that page. You will see a JWT. Use it for test.

Categories