/**
  * Start the creation of a new gocardless payment
  *   Details get posted into this method and the redirected to gocardless
  * @param $userId
  * @throws \BB\Exceptions\AuthenticationException
  * @throws \BB\Exceptions\FormValidationException
  * @throws \BB\Exceptions\NotImplementedException
  */
 public function store($userId)
 {
     User::findWithPermission($userId);
     $requestData = \Request::only(['reason', 'amount', 'return_path', 'stripeToken', 'ref']);
     $stripeToken = $requestData['stripeToken'];
     $amount = $requestData['amount'];
     $reason = $requestData['reason'];
     $returnPath = $requestData['return_path'];
     $ref = $requestData['ref'];
     try {
         $charge = Stripe_Charge::create(array("amount" => $amount, "currency" => "gbp", "card" => $stripeToken, "description" => $reason));
     } catch (\Exception $e) {
         \Log::error($e);
         if (\Request::wantsJson()) {
             return \Response::json(['error' => 'There was an error confirming your payment'], 400);
         }
         \Notification::error("There was an error confirming your payment");
         return \Redirect::to($returnPath);
     }
     //Replace the amount with the one from the charge, this prevents issues with variable tempering
     $amount = $charge->amount / 100;
     //Stripe don't provide us with the fee so this should be OK
     $fee = $amount * 0.024 + 0.2;
     $this->paymentRepository->recordPayment($reason, $userId, 'stripe', $charge->id, $amount, 'paid', $fee, $ref);
     if (\Request::wantsJson()) {
         return \Response::json(['message' => 'Payment made']);
     }
     \Notification::success("Payment made");
     return \Redirect::to($returnPath);
 }
 /**
  * Start the creation of a new balance payment
  *   Details get posted into this method
  * @param $userId
  * @throws \BB\Exceptions\AuthenticationException
  * @throws \BB\Exceptions\FormValidationException
  * @throws \BB\Exceptions\NotImplementedException
  */
 public function store($userId)
 {
     $user = User::findWithPermission($userId);
     $this->bbCredit->setUserId($user->id);
     $requestData = \Request::only(['reason', 'amount', 'return_path', 'ref']);
     $amount = $requestData['amount'] * 1 / 100;
     $reason = $requestData['reason'];
     $returnPath = $requestData['return_path'];
     $ref = $requestData['ref'];
     //Can the users balance go below 0
     $minimumBalance = $this->bbCredit->acceptableNegativeBalance($reason);
     //What is the users balance
     $userBalance = $this->bbCredit->getBalance();
     //With this payment will the users balance go to low?
     if ($userBalance - $amount < $minimumBalance) {
         if (\Request::wantsJson()) {
             return \Response::json(['error' => 'You don\'t have the money for this'], 400);
         }
         \Notification::error("You don't have the money for this");
         return \Redirect::to($returnPath);
     }
     //Everything looks gooc, create the payment
     $this->paymentRepository->recordPayment($reason, $userId, 'balance', '', $amount, 'paid', 0, $ref);
     //Update the users cached balance
     $this->bbCredit->recalculate();
     if (\Request::wantsJson()) {
         return \Response::json(['message' => 'Payment made']);
     }
     \Notification::success("Payment made");
     return \Redirect::to($returnPath);
 }
 public function handle()
 {
     $data = \Request::only(['device', 'tag', 'service']);
     try {
         $keyFob = $this->keyFobAccess->lookupKeyFob($data['tag']);
     } catch (\Exception $e) {
         \Log::debug(json_encode($data));
         return \Response::make('Not found', 404);
     }
     $user = $keyFob->user()->first();
     $this->paymentRepository->recordPayment($data['service'], $user->id, 'balance', null, 0.05, 'paid', 0, $data['device']);
     event(new MemberActivity($keyFob, $data['service']));
     return \Response::make('OK', 201);
 }
 /**
  * Remove cash from the users balance
  *
  * @param $userId
  * @return mixed
  * @throws \BB\Exceptions\AuthenticationException
  * @throws \BB\Exceptions\InvalidDataException
  */
 public function destroy($userId)
 {
     $user = User::findWithPermission($userId);
     $this->bbCredit->setUserId($userId);
     $amount = \Request::get('amount');
     $returnPath = \Request::get('return_path');
     $ref = \Request::get('ref');
     $minimumBalance = $this->bbCredit->acceptableNegativeBalance('withdrawal');
     if ($user->cash_balance + $minimumBalance * 100 < $amount * 100) {
         \Notification::error("Not enough money");
         return \Redirect::to($returnPath);
     }
     $this->paymentRepository->recordPayment('withdrawal', $userId, 'balance', '', $amount, 'paid', 0, $ref);
     $this->bbCredit->recalculate();
     \Notification::success("Payment recorded");
     return \Redirect::to($returnPath);
 }
 public function receiveNotification()
 {
     $ipnMessage = new \PayPal\IPN\PPIPNMessage('', PayPalConfig::getConfig());
     if (!$ipnMessage->validate()) {
         \Log::error("Invalid IPN");
     }
     $ipnData = $ipnMessage->getRawData();
     if (isset($ipnData['txn_type']) && $ipnData['txn_type'] == 'subscr_payment') {
         if ($ipnData['payment_status'] != 'Completed') {
             \Log::error("PayPal IPN: Received unknown payment status for sub payment: \"" . $ipnData['payment_status'] . "\" Email: " . $ipnData['payer_email']);
             return;
         }
         $user = User::where('email', $ipnData['payer_email'])->first();
         if (!$user) {
             $user = User::where('secondary_email', $ipnData['payer_email'])->first();
         }
         if (!$user) {
             //\Log::error("PayPal IPN Received for unknown email " . $ipnData['payer_email']);
             $paymentId = $this->paymentRepository->recordPayment('donation', 0, 'paypal', $ipnData['txn_id'], $ipnData['mc_gross'], 'paid', $ipnData['mc_fee'], $ipnData['payer_email']);
             event(new \BB\Events\UnknownPayPalPaymentReceived($paymentId, $ipnData['payer_email']));
             return;
         }
         //It looks like the user might be joining again
         if ($user->status == 'left') {
             $user->rejoin();
         }
         //If its a new user set them up by creating the first sub charge record and setting the payment day
         if ($user->status == 'setting-up') {
             $this->setupNewMember($user, $ipnData['mc_gross']);
         }
         //Record the subscription payment, this will automatically deal with locating the sub charge and updating that
         $this->paymentRepository->recordSubscriptionPayment($user->id, 'paypal', $ipnData['txn_id'], $ipnData['mc_gross'], 'paid', $ipnData['mc_fee']);
     } elseif (isset($ipnData['txn_type']) && $ipnData['txn_type'] == 'subscr_cancel') {
         $user = User::where('email', $ipnData['payer_email'])->first();
         if ($user) {
             //The user may have already changed to another method, only cancel if its still paypal
             if ($user->payment_method == 'paypal') {
                 $user->cancelSubscription();
             }
             //@TODO: Deal with any open sub payment records
         }
     }
 }
 public function calculatePendingFees()
 {
     $records = $this->equipmentLogRepository->getFinishedUnbilledRecords();
     foreach ($records as $record) {
         $equipment = $this->equipmentRepository->findBySlug($record->device);
         if ($equipment->hasUsageCharge()) {
             $feePerSecond = $this->costPerSecond($equipment->usageCost);
             //How may seconds was the device in use
             $secondsActive = $record->finished->diffInSeconds($record->started);
             //Charges are for a minimum of 15 minutes
             $secondsActive = $this->roundUpSecondsActive($secondsActive);
             $incurredFee = $this->sessionFee($feePerSecond, $secondsActive);
             //If the reason is empty then its not a special case and should be billed
             if (empty($record->reason)) {
                 //Create a payment against the user
                 $this->paymentRepository->recordPayment('equipment-fee', $record->user_id, 'balance', '', $incurredFee, 'paid', 0, $record->id . ':' . $record->device);
             }
         }
         //Mark this log as being billed and complete
         $record->billed = true;
         $record->save();
     }
 }
 /**
  * Process a direct debit payment when we have a preauth
  *
  * @param $amount
  * @param $reason
  * @param User $user
  * @param $ref
  * @param $returnPath
  * @return mixed
  */
 private function handleBill($amount, $reason, $user, $ref, $returnPath)
 {
     $bill = $this->goCardless->newBill($user->subscription_id, $amount, $this->goCardless->getNameFromReason($reason));
     if ($bill) {
         //Store the payment
         $fee = $bill->amount - $bill->amount_minus_fees;
         $paymentSourceId = $bill->id;
         $amount = $bill->amount;
         $status = $bill->status;
         //The record payment process will make the necessary record updates
         $this->paymentRepository->recordPayment($reason, $user->id, 'gocardless-variable', $paymentSourceId, $amount, $status, $fee, $ref);
         if (\Request::wantsJson()) {
             return \Response::json(['message' => 'The payment was submitted successfully']);
         }
         \Notification::success("The payment was submitted successfully");
     } else {
         //something went wrong - we still have the pre auth though
         if (\Request::wantsJson()) {
             return \Response::json(['error' => 'There was a problem charging your account'], 400);
         }
         \Notification::error("There was a problem charging your account");
     }
     return \Redirect::to($returnPath);
 }
 /**
  * Handle the event.
  *
  * @param  ExpenseWasApproved  $event
  * @return void
  */
 public function handle(ExpenseWasApproved $event)
 {
     $this->paymentRepository->recordPayment('balance', $event->expense->user_id, 'reimbursement', $event->expense->id, $event->expense->amount / 100);
 }