mirror of
https://github.com/standardebooks/web.git
synced 2025-07-14 10:31:59 -04:00
Add system to retrieve and manage donations in a local database
This commit is contained in:
parent
79c531aacb
commit
70a80d0e02
46 changed files with 782 additions and 910 deletions
|
@ -21,14 +21,14 @@ try{
|
|||
throw new Exceptions\WebhookException('Expected HTTP POST.');
|
||||
}
|
||||
|
||||
$post = file_get_contents('php://input') ?: '';
|
||||
$post = file_get_contents('php://input');
|
||||
|
||||
// Validate the GitHub secret.
|
||||
$splitHash = explode('=', $_SERVER['HTTP_X_HUB_SIGNATURE']);
|
||||
$hashAlgorithm = $splitHash[0];
|
||||
$hash = $splitHash[1];
|
||||
|
||||
if(!hash_equals($hash, hash_hmac($hashAlgorithm, $post, preg_replace("/[\r\n]/ius", '', file_get_contents(GITHUB_SECRET_FILE_PATH) ?: '') ?? ''))){
|
||||
if(!hash_equals($hash, hash_hmac($hashAlgorithm, $post, preg_replace("/[\r\n]/ius", '', file_get_contents(GITHUB_SECRET_FILE_PATH))))){
|
||||
throw new Exceptions\InvalidCredentialsException();
|
||||
}
|
||||
|
||||
|
|
|
@ -11,7 +11,7 @@ use function Safe\substr;
|
|||
$log = new Log(POSTMARK_WEBHOOK_LOG_FILE_PATH);
|
||||
|
||||
try{
|
||||
$smtpUsername = trim(file_get_contents(POSTMARK_SECRET_FILE_PATH)) ?: '';
|
||||
$smtpUsername = trim(file_get_contents(POSTMARK_SECRET_FILE_PATH));
|
||||
|
||||
$log->Write('Received Postmark webhook.');
|
||||
|
||||
|
@ -19,14 +19,14 @@ try{
|
|||
throw new Exceptions\WebhookException('Expected HTTP POST.');
|
||||
}
|
||||
|
||||
$apiKey = trim(file_get_contents(SITE_ROOT . '/config/secrets/webhooks@postmarkapp.com')) ?: '';
|
||||
$apiKey = trim(file_get_contents(SITE_ROOT . '/config/secrets/webhooks@postmarkapp.com'));
|
||||
|
||||
// Ensure this webhook actually came from Postmark
|
||||
if($apiKey != ($_SERVER['HTTP_X_SE_KEY'] ?? '')){
|
||||
throw new Exceptions\InvalidCredentialsException();
|
||||
}
|
||||
|
||||
$post = json_decode(file_get_contents('php://input') ?: '');
|
||||
$post = json_decode(file_get_contents('php://input'));
|
||||
|
||||
if(!$post || !property_exists($post, 'RecordType')){
|
||||
throw new Exceptions\WebhookException('Couldn\'t understand HTTP request.', $post);
|
||||
|
|
82
www/webhooks/zoho.php
Normal file
82
www/webhooks/zoho.php
Normal file
|
@ -0,0 +1,82 @@
|
|||
<?
|
||||
require_once('Core.php');
|
||||
|
||||
use function Safe\file_get_contents;
|
||||
use function Safe\preg_match;
|
||||
use function Safe\preg_replace;
|
||||
use function Safe\json_decode;
|
||||
|
||||
$log = new Log(ZOHO_WEBHOOK_LOG_FILE_PATH);
|
||||
|
||||
try{
|
||||
$log->Write('Received Zoho webhook.');
|
||||
|
||||
if($_SERVER['REQUEST_METHOD'] != 'POST'){
|
||||
throw new Exceptions\WebhookException('Expected HTTP POST.');
|
||||
}
|
||||
|
||||
$post = file_get_contents('php://input');
|
||||
|
||||
// Validate the Zoho secret.
|
||||
if(!hash_equals($_SERVER['HTTP_X_HOOK_SIGNATURE'], base64_encode(hash_hmac('sha256', $post, preg_replace("/[\r\n]/ius", '', file_get_contents(ZOHO_SECRET_FILE_PATH)), true)))){
|
||||
throw new Exceptions\InvalidCredentialsException();
|
||||
}
|
||||
|
||||
$data = json_decode($post);
|
||||
|
||||
if($data->fromAddress == 'support@fracturedatlas.org' && strpos($data->subject, 'NOTICE:') !== false){
|
||||
$log->Write('Processing new donation.');
|
||||
|
||||
// Get the donation ID
|
||||
preg_match('/Donation ID: ([0-9a-f\-]+)/us', $data->html, $matches);
|
||||
if(sizeof($matches) == 2){
|
||||
$transactionId = $matches[1];
|
||||
|
||||
// FA has a bug where some anonymous donations can't be found in their search form,
|
||||
// so we aren't able to get them programatically later. Therefore, store anonymous donations right now
|
||||
// instead of queueing them for later retrieval.
|
||||
if(preg_match('/Donor: Anonymous/u', $data->html) === 1){
|
||||
$payment = new Payment();
|
||||
$payment->ChannelId = PAYMENT_CHANNEL_FA;
|
||||
$payment->TransactionId = $transactionId;
|
||||
$payment->IsRecurring = stripos($data->subject, 'recurring') !== false;
|
||||
preg_match('/Amount: \$([\d\.]+)/u', $data->html, $matches);
|
||||
if(sizeof($matches) == 2){
|
||||
$payment->Amount = $matches[1];
|
||||
$payment->Fee = $payment->Amount - ($payment->Amount / 1.087);
|
||||
}
|
||||
$payment->Create();
|
||||
}
|
||||
else{
|
||||
Db::Query('insert into PendingPayments (Timestamp, ChannelId, TransactionId) values (utc_timestamp(), ?, ?);', [PAYMENT_CHANNEL_FA, $transactionId]);
|
||||
}
|
||||
|
||||
$log->Write('Donation ID: ' . $transactionId);
|
||||
}
|
||||
else{
|
||||
throw new Exceptions\WebhookException('Couldn\'t find donation ID.');
|
||||
}
|
||||
}
|
||||
|
||||
$log->Write('Event processed.');
|
||||
|
||||
// "Success, no content"
|
||||
http_response_code(204);
|
||||
}
|
||||
catch(Exceptions\InvalidCredentialsException $ex){
|
||||
// "Forbidden"
|
||||
$log->Write('Couldn\'t validate POST data.');
|
||||
http_response_code(403);
|
||||
}
|
||||
catch(Exceptions\WebhookException $ex){
|
||||
// Uh oh, something went wrong!
|
||||
// Log detailed error and debugging information locally.
|
||||
$log->Write('Webhook failed! Error: ' . $ex->getMessage());
|
||||
$log->Write('Webhook POST data: ' . $ex->PostData);
|
||||
|
||||
// Print less details to the client.
|
||||
print($ex->getMessage());
|
||||
|
||||
// "Client error"
|
||||
http_response_code(400);
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue