/** * @param $user * @param $amount * @return void */ private function setupNewMember(User $user, $amount) { //At this point the day of the month hasn't been set for the user, set it now $user->updateSubscription('paypal', Carbon::now()->day); //if this is blank then the user hasn't been setup yet $subCharge = $this->subscriptionChargeRepository->createCharge($user->id, Carbon::now(), $amount); }
/** * The bill has been cancelled or failed, update the user records to compensate * * @param $existingPayment */ private function handleFailedCancelledBill(Payment $existingPayment) { if ($existingPayment->reason == 'subscription') { //If the payment is a subscription payment then we need to take action and warn the user $user = $existingPayment->user()->first(); $user->status = 'suspended'; //Rollback the users subscription expiry date or set it to today $expiryDate = \BB\Helpers\MembershipPayments::lastUserPaymentExpires($user->id); if ($expiryDate) { $user->subscription_expires = $expiryDate; } else { $user->subscription_expires = new Carbon(); } $user->save(); //Update the subscription charge to reflect the payment failure $subCharge = $this->subscriptionChargeRepository->getById($existingPayment->reference); if ($subCharge) { $this->subscriptionChargeRepository->paymentFailed($subCharge->id); } } elseif ($existingPayment->reason == 'induction') { //We still need to collect the payment from the user } elseif ($existingPayment->reason == 'box-deposit') { } elseif ($existingPayment->reason == 'key-deposit') { } }
private function updateSubPayment($paymentId, $userId, $status) { $payment = $this->paymentRepository->getById($paymentId); $subCharge = $this->subscriptionChargeRepository->findCharge($userId); if (!$subCharge) { \Log::warning('Subscription payment without a sub charge. Payment ID:' . $paymentId); return; } //The sub charge record id gets saved onto the payment if (empty($payment->reference)) { $payment->reference = $subCharge->id; $payment->save(); } else { if ($payment->reference != $subCharge->id) { throw new PaymentException('Attempting to update sub charge (' . $subCharge->id . ') but payment (' . $payment->id . ') doesn\'t match. Sub charge has an existing reference on it.'); } } if ($status == 'paid') { $this->subscriptionChargeRepository->markChargeAsPaid($subCharge->id); } else { if ($status == 'pending') { $this->subscriptionChargeRepository->markChargeAsProcessing($subCharge->id); } } //The amount isn't stored on the sub charge record until its paid or processing if ($payment->amount != $subCharge->amount) { $this->subscriptionChargeRepository->updateAmount($subCharge->id, $payment->amount); } }
/** * The member has left, disable their account and cancel any out stand sub charge records * The payment day is also cleared so when they start again the payment is charge happens at restart time * * @param $userId */ public function memberLeft($userId) { $user = $this->getById($userId); $user->active = false; $user->status = 'left'; $user->payment_day = ''; $user->save(); $this->subscriptionChargeRepository->cancelOutstandingCharges($userId); }
/** * Bill members based on the sub charges that are due */ public function billMembers() { $subCharges = $this->subscriptionChargeRepository->getDue(); foreach ($subCharges as $charge) { if ($charge->user->payment_method == 'gocardless-variable') { //Look the the previous attempts - there may be multiple failures $existingPayments = $this->paymentRepository->getPaymentsByReference($charge->id); if ($existingPayments->count() > 0) { //We will let the user retry the payment if it fails continue; } $bill = $this->goCardless->newBill($charge->user->subscription_id, $charge->user->monthly_subscription, $this->goCardless->getNameFromReason('subscription')); if ($bill) { $this->paymentRepository->recordSubscriptionPayment($charge->user->id, 'gocardless-variable', $bill->id, $bill->amount, $bill->status, $bill->gocardless_fees, $charge->id); } } } }
/** * Bill members based on the sub charges that are due */ public function billMembers() { $subCharges = $this->subscriptionChargeRepository->getDue(); //Check each of the due charges, if they have previous attempted payments ignore them // we don't want to retry failed payments as for DD's this will generate bank charges $subCharges->reject(function ($charge) { return $this->paymentRepository->getPaymentsByReference($charge->id)->count() > 0; }); //Filter the list into two gocardless and balance subscriptions $goCardlessUsers = $subCharges->filter(function ($charge) { return $charge->user->payment_method == 'gocardless-variable'; }); $balanceUsers = $subCharges->filter(function ($charge) { return $charge->user->payment_method == 'balance'; }); //Charge the balance users foreach ($balanceUsers as $charge) { if ($charge->user->monthly_subscription * 100 > $charge->user->cash_balance) { //user doesn't have enough money //If they have a secondary payment method of gocardless try that if ($charge->user->secondary_payment_method == 'gocardless-variable') { //Add the charge to the gocardless list for processing $goCardlessUsers->push($charge); event(new SubscriptionPayment\InsufficientFundsTryingDirectDebit($charge->user->id, $charge->id)); } else { event(new SubscriptionPayment\FailedInsufficientFunds($charge->user->id, $charge->id)); } continue; } $this->paymentRepository->recordSubscriptionPayment($charge->user->id, 'balance', '', $charge->user->monthly_subscription, 'paid', 0, $charge->id); event(new MemberBalanceChanged($charge->user->id)); } //Charge the gocardless users foreach ($goCardlessUsers as $charge) { $bill = $this->goCardless->newBill($charge->user->subscription_id, $charge->user->monthly_subscription, $this->goCardless->getNameFromReason('subscription')); if ($bill) { $this->paymentRepository->recordSubscriptionPayment($charge->user->id, 'gocardless-variable', $bill->id, $bill->amount, $bill->status, $bill->gocardless_fees, $charge->id); } } }
/** * Display the specified resource. * * @param int $id * @return Response */ public function show($id) { $user = User::findWithPermission($id); $inductions = $this->equipmentRepository->getRequiresInduction(); $userInductions = $user->inductions()->get(); foreach ($inductions as $i => $induction) { $inductions[$i]->userInduction = false; foreach ($userInductions as $userInduction) { if ($userInduction->key == $induction->induction_category) { $inductions[$i]->userInduction = $userInduction; } } } //get pending address if any $newAddress = $this->addressRepository->getNewUserAddress($id); //Get the member subscription payments $subscriptionCharges = $this->subscriptionChargeRepository->getMemberChargesPaginated($id); return \View::make('account.show')->with('user', $user)->with('inductions', $inductions)->with('newAddress', $newAddress)->with('subscriptionCharges', $subscriptionCharges); }
public function listCharges() { $charges = $this->subscriptionChargeRepository->getChargesPaginated(); return \View::make('payments.sub-charges')->with('charges', $charges); }
/** * Store a newly created resource in storage. * * @return Response */ public function store() { $spreadsheetPath = \Input::file('statement')->getRealPath(); $testProcess = \Request::get('test'); if ($testProcess) { $testProcess = true; echo "Test Mode - no payment records are being created<br /><br />"; } else { $testProcess = false; echo "Live Mode - Payments have been created<br /><br />"; } $reader = new SpreadsheetReader($spreadsheetPath); $reader->ChangeSheet(0); $stringMatchUsers = User::active()->where('import_match_string', '!=', '')->get(); $users = User::active()->get(); echo '<br />' . PHP_EOL; echo '<table width="100%">'; foreach ($reader as $i => $row) { echo "<tr>"; $subPayment = false; $balancePayment = false; $paymentReference = null; //print_r($row); //If the payment isn't a credit then we don't care about it //if (($row[1] != 'CR') && ($row[1]) != 'BP') if ($row[1] != 'CR') { continue; } if (strpos(strtoupper($row[2]), 'GC C1 BUILDBRIGHTO') !== false) { continue; } if (strpos(strtoupper($row[2]), 'STRIPE TRANSFER') !== false) { continue; } if (strpos(strtoupper($row[2]), 'EVENTBRITE') !== false) { continue; } $date = new \Carbon\Carbon($row[0]); echo "<td>" . $date->format('d/m/y') . '</td>'; //echo "<td>".$row[1].'</td>'; if (strpos(strtoupper($row[2]), 'SUB') !== false) { $subPayment = true; } elseif (strpos($row[2], 'MEMBERSHIP') !== false) { $subPayment = true; } elseif (strpos($row[2], '-BALANCE-') !== false) { $balancePayment = true; $descriptionParts = explode('-BALANCE-', $row[2]); if (is_array($descriptionParts) && count($descriptionParts) > 1) { $paymentReference = strtolower($descriptionParts[1]); } } if ($subPayment) { echo '<td>SUB</td>'; $reasonString = 'subscription'; } elseif ($balancePayment) { echo '<td>Balance</td>'; $reasonString = 'balance'; } else { echo '<td></td>'; $reasonString = 'unknown'; } $matchedUser = false; $paymentDescription = strtolower($row[2]); //Try matching against specific match strings first foreach ($stringMatchUsers as $user) { if (strpos($paymentDescription, strtolower($user->import_match_string)) !== false) { $matchedUser = $user; break; } } //If there was no match do a general surname match if (!$matchedUser) { foreach ($users as $user) { if (strpos($paymentDescription, strtolower($user->family_name)) !== false) { $matchedUser = $user; break; } } } if ($matchedUser) { echo '<td>' . $matchedUser->name . '</td>'; if ($subPayment) { $subCharge = $this->subscriptionChargeRepository->findCharge($matchedUser->id, $date); if ($subCharge) { echo '<td>Subscription Payment</td>'; } else { echo '<td style="background-color: #ff8c14;">Unknown: Recording as balance top up</td>'; $subPayment = false; $reasonString = 'balance'; } } } else { echo '<td style="background-color: #F00;">Unknown</td><td></td>'; } echo '<td>' . $row[2] . '</td>'; //echo '<td>'.$row[3].'</td>'; echo '<td>' . $row[4] . '</td>'; echo "</tr>"; if (!$testProcess && $matchedUser) { if ($subPayment) { if (isset($subCharge) && $subCharge) { $paymentReference = $subCharge->id; $this->subscriptionChargeRepository->markChargeAsPaid($subCharge->id, $date, $row[4]); } } Payment::create(['created_at' => $date, 'reason' => $reasonString, 'source' => 'standing-order', 'user_id' => $matchedUser->id, 'amount' => $row[4], 'fee' => 0, 'amount_minus_fee' => $row[4], 'status' => 'paid', 'reference' => $paymentReference]); if ($subPayment) { if ($matchedUser->payment_method == 'standing-order') { $matchedUser->monthly_subscription = $row[4]; } $matchedUser->save(); } } } echo "</table>"; exit; }