Files
wticreatorstudio/Modules/WTIALaCarte/Http/Controllers/PaypalWebhookController.php
T
2024-02-12 22:54:20 -05:00

198 lines
7.5 KiB
PHP

<?php
namespace Modules\WTIALaCarte\Http\Controllers;
use Illuminate\Http\Request;
use Illuminate\Routing\Controller;
use Modules\WTIALaCarte\Entities\Alacarte;
use Modules\WTIALaCarte\Entities\AlacarteOrder;
use Modules\WTIALaCarte\Entities\AlacarteOrderItem;
use Modules\Subscription\Entities\SubscriptionCoupon;
use Modules\Subscription\Entities\SubscriptionCouponRedemption;
use Modules\Subscription\Entities\UserCredit;
use Modules\Subscription\Entities\UserCreditHistory;
use Modules\WTIALaCarte\Services\PaypalService;
use Modules\Customer\Services\CustomerService;
use Carbon\Carbon;
use Stripe;
use Exception;
use Log;
class PaypalWebhookController extends Controller
{
protected $paypal;
protected $customerService;
public function __construct(CustomerService $customerService){
$this->paypal = new PaypalService();
$this->customerService = $customerService;
}
protected function isValidWebhook()
{
// get request headers
$headers = apache_request_headers();
Log::info($headers);
// get http payload
$body = file_get_contents('php://input');
$webhook_id = '6V2767039S933004S'; //live
$data =
$headers['PAYPAL-TRANSMISSION-ID'] . '|' .
$headers['PAYPAL-TRANSMISSION-TIME'] . '|' .
$webhook_id . '|' . crc32($body);
// load certificate and extract public key
$pubKey = openssl_pkey_get_public(file_get_contents($headers['PAYPAL-CERT-URL']));
$key = openssl_pkey_get_details($pubKey)['key'];
// verify data against provided signature
$result = openssl_verify(
$data,
base64_decode($headers['PAYPAL-TRANSMISSION-SIG']),
$key,
'sha256WithRSAEncryption'
);
if ($result == 1) {
// webhook notification is verified
Log::info('webhook verified');
return true;
} elseif ($result == 0) {
// webhook notification is NOT verified
Log::info('webhook not verified');
return false;
} else {
// there was an error verifying this
Log::info('webhook verification error');
return false;
}
}
public function webhook(Request $request) {
// Verify that the webhook is authentic
if (!$this->isValidWebhook()) {
Log::error('Received invalid webhook');
return response('Invalid webhook', 400);
exit();
}
// Get the webhook data from the request
$webhookData = $request->all();
$event_type = $webhookData["event_type"];
Log::info($webhookData);
if($event_type == 'CHECKOUT.ORDER.APPROVED'){
try {
$total = 0;
$user_id = null;
$coupon_id = null;
foreach ($webhookData['resource']['purchase_units'] as $key => $purchase_unit) {
$total += (float) $purchase_unit['amount']['value'];
$custom_data = json_decode($purchase_unit['custom_id']);
$user_id = $custom_data->user_id;
if(isset($custom_data->coupon_id)){
$coupon_id = $custom_data->coupon_id;
}
}
$alacarte_order = AlacarteOrder::create([
'order_number' => rand(11, 99).date('ymdhis'),
'user_id' => $user_id,
'paypal_order_id' => $webhookData['resource']['id'],
'total' => $total * 100,
'status' => 'waiting for payment'
]);
if($coupon_id != null){
$coupon = SubscriptionCoupon::find((int)$coupon_id);
if($coupon){
$coupon_redemption = new SubscriptionCouponRedemption;
$coupon_redemption->subscription_coupon_id = $coupon->id;
$coupon_redemption->customer_id = $alacarte_order->user_id;
$coupon_redemption->alacarte_order_id = $alacarte_order->id;
$coupon_redemption->save();
}
}
$user_credits = UserCredit::firstOrCreate(['user_id' => $user_id]);
$captureResponse = $this->paypal->capturePayment($webhookData['resource']['id']);
if($captureResponse->status == 'COMPLETED'){
$alacarte_order->status = 'paid';
$alacarte_order->save();
Log::info($captureResponse->purchase_units);
foreach ($captureResponse->purchase_units as $key => $purchase_unit) {
$alacarte = Alacarte::with('category')->where('id',(int)$purchase_unit->reference_id)->first();
if($alacarte){
$capture_data = $purchase_unit->payments->captures[0];
$custom_data = json_decode($capture_data->custom_id);
$quantity = $custom_data->quantity;
$discount = $custom_data->discount;
$total_price = $capture_data->amount->value;
$alacarte_order->items()->create([
'alacarte_id' => $alacarte->id,
'price' => ($total_price / $quantity) + $discount,
'quantity' => $quantity,
'discount' => ($discount * $quantity) * 100,
'total' => $total_price * 100,
]);
if($capture_data->status == 'COMPLETED'){
Log::info('Updating user credits');
$before_credits = $this->customerService->credits($user_credits->user_id);
$user_credits->alacarte_credits = $user_credits->alacarte_credits + ($alacarte->credits * $quantity);
$user_credits->save();
$after_credits = $this->customerService->credits($user_credits->user_id);
$user_credits_history = new UserCreditHistory;
$user_credits_history->user_id = $user_credits->user_id;
$user_credits_history->subscription_credits_from = $before_credits['total_available_credits']['subscription'];
$user_credits_history->subscription_credits_to = $after_credits['total_available_credits']['subscription'];
$user_credits_history->alacarte_credits_from = $before_credits['total_available_credits']['alacarte'];;
$user_credits_history->alacarte_credits_to = $after_credits['total_available_credits']['alacarte'];
$user_credits_history->details = 'Added '.$quantity.'X '.$alacarte->name;
$user_credits_history->save();
}
}
}
} else {
Log::info('Capture Payment Failed');
}
} catch(\Exception $e) {
Log::info($e->getMessage());
http_response_code(400);
exit();
}
} else {
Log::info($webhookData);
}
}
}