From b28d76d491e06d138a157ac261ee67c72e9f62d3 Mon Sep 17 00:00:00 2001 From: David Bomba Date: Fri, 1 Oct 2021 08:55:35 +1000 Subject: [PATCH 1/2] Minor fixes --- app/Http/Controllers/CompanyController.php | 2 +- app/Http/Controllers/SubdomainController.php | 1 + app/Models/Account.php | 2 +- app/Services/Quote/TriggeredActions.php | 4 ++++ 4 files changed, 7 insertions(+), 2 deletions(-) diff --git a/app/Http/Controllers/CompanyController.php b/app/Http/Controllers/CompanyController.php index c40b349d5b21..5ac5ed157a78 100644 --- a/app/Http/Controllers/CompanyController.php +++ b/app/Http/Controllers/CompanyController.php @@ -500,7 +500,7 @@ class CompanyController extends BaseController $account->delete(); if(Ninja::isHosted()) - \Modules\Admin\Jobs\Account\NinjaDeletedAccount::dispatch($account_key); + \Modules\Admin\Jobs\Account\NinjaDeletedAccount::dispatch($account_key, $request->all()); LightLogs::create(new AccountDeleted()) ->increment() diff --git a/app/Http/Controllers/SubdomainController.php b/app/Http/Controllers/SubdomainController.php index 6a25f795608d..153c12b91d60 100644 --- a/app/Http/Controllers/SubdomainController.php +++ b/app/Http/Controllers/SubdomainController.php @@ -30,6 +30,7 @@ class SubdomainController extends BaseController 'invoiceninja', 'cname', 'sandbox', + 'stage', ]; public function __construct() diff --git a/app/Models/Account.php b/app/Models/Account.php index d7a9f2d6ce08..2884c6aca8dd 100644 --- a/app/Models/Account.php +++ b/app/Models/Account.php @@ -407,7 +407,7 @@ class Account extends BaseModel } } catch(\Exception $e){ - \Sentry\captureMessage("I encountered an error with email quotas - defaulting to SEND"); + \Sentry\captureMessage("I encountered an error with email quotas for account {$this->key} - defaulting to SEND"); } return false; diff --git a/app/Services/Quote/TriggeredActions.php b/app/Services/Quote/TriggeredActions.php index 055d2216df89..e1ec9a37a00f 100644 --- a/app/Services/Quote/TriggeredActions.php +++ b/app/Services/Quote/TriggeredActions.php @@ -45,6 +45,10 @@ class TriggeredActions extends AbstractService $this->quote = $this->quote->service()->markSent()->save(); } + if ($this->request->has('convert') && $this->request->input('convert') == 'true') { + $this->quote = $this->quote->service()->convert()->save(); + } + return $this->quote; } From 04226eb827c2913cf77e23b0e7894e3f8734013b Mon Sep 17 00:00:00 2001 From: David Bomba Date: Fri, 1 Oct 2021 12:57:34 +1000 Subject: [PATCH 2/2] Fixes for token billing with stripe bank transfers --- app/PaymentDrivers/Stripe/ACH.php | 63 +++++++++++++++++++++- app/PaymentDrivers/Stripe/Charge.php | 5 ++ app/PaymentDrivers/StripePaymentDriver.php | 4 +- 3 files changed, 70 insertions(+), 2 deletions(-) diff --git a/app/PaymentDrivers/Stripe/ACH.php b/app/PaymentDrivers/Stripe/ACH.php index 5af1cbf05ab2..e2e3c8941108 100644 --- a/app/PaymentDrivers/Stripe/ACH.php +++ b/app/PaymentDrivers/Stripe/ACH.php @@ -22,7 +22,9 @@ use App\Jobs\Util\SystemLogger; use App\Mail\Gateways\ACHVerificationNotification; use App\Models\ClientGatewayToken; use App\Models\GatewayType; +use App\Models\Invoice; use App\Models\Payment; +use App\Models\PaymentHash; use App\Models\PaymentType; use App\Models\SystemLog; use App\PaymentDrivers\StripePaymentDriver; @@ -145,6 +147,62 @@ class ACH return render('gateways.stripe.ach.pay', $data); } + public function tokenBilling(ClientGatewayToken $cgt, PaymentHash $payment_hash) + { + + $amount = array_sum(array_column($payment_hash->invoices(), 'amount')) + $payment_hash->fee_total; + $invoice = Invoice::whereIn('id', $this->transformKeys(array_column($payment_hash->invoices(), 'invoice_id'))) + ->withTrashed() + ->first(); + + if ($invoice) { + $description = "Invoice {$invoice->number} for {$amount} for client {$this->stripe->client->present()->name()}"; + } else { + $description = "Payment with no invoice for amount {$amount} for client {$this->stripe->client->present()->name()}"; + } + + $this->stripe->init(); + + $response = null; + + try { + + $state = [ + 'gateway_type_id' => GatewayType::BANK_TRANSFER, + 'amount' => $this->stripe->convertToStripeAmount($amount, $this->stripe->client->currency()->precision, $this->stripe->client->currency()), + 'currency' => $this->stripe->client->getCurrencyCode(), + 'customer' => $cgt->gateway_customer_reference, + 'source' => $cgt->token, + ]; + + $state['charge'] = \Stripe\Charge::create([ + 'amount' => $state['amount'], + 'currency' => $state['currency'], + 'customer' => $state['customer'], + 'source' => $state['source'], + 'description' => $description, + ], $this->stripe->stripe_connect_auth); + + + $payment_hash->data = array_merge((array)$payment_hash->data, $state); + $payment_hash->save(); + + if ($state['charge']->status === 'pending' && is_null($state['charge']->failure_message)) { + return $this->processPendingPayment($state, false); + } + + return $this->processUnsuccessfulPayment($state); + } catch (Exception $e) { + if ($e instanceof CardException) { + return redirect()->route('client.payment_methods.verification', ['payment_method' => $source->hashed_id, 'method' => GatewayType::BANK_TRANSFER]); + } + + throw new PaymentFailed($e->getMessage(), $e->getCode()); + } + + + + } public function paymentResponse($request) { @@ -201,7 +259,7 @@ class ACH } } - public function processPendingPayment($state) + public function processPendingPayment($state, $client_present = true) { $this->stripe->init(); @@ -224,6 +282,9 @@ class ACH $this->stripe->client->company, ); + if(!$client_present) + return $payment; + return redirect()->route('client.payments.show', ['payment' => $this->stripe->encodePrimaryKey($payment->id)]); } diff --git a/app/PaymentDrivers/Stripe/Charge.php b/app/PaymentDrivers/Stripe/Charge.php index 6a238aa61f94..57c1a1bcf7b2 100644 --- a/app/PaymentDrivers/Stripe/Charge.php +++ b/app/PaymentDrivers/Stripe/Charge.php @@ -15,11 +15,13 @@ namespace App\PaymentDrivers\Stripe; use App\Events\Payment\PaymentWasCreated; use App\Jobs\Util\SystemLogger; use App\Models\ClientGatewayToken; +use App\Models\GatewayType; use App\Models\Invoice; use App\Models\PaymentHash; use App\Models\PaymentType; use App\Models\SystemLog; use App\PaymentDrivers\StripePaymentDriver; +use App\PaymentDrivers\Stripe\ACH; use App\Utils\Ninja; use App\Utils\Traits\MakesHash; use Stripe\Exception\ApiConnectionException; @@ -51,6 +53,9 @@ class Charge */ public function tokenBilling(ClientGatewayToken $cgt, PaymentHash $payment_hash) { + if($cgt->gateway_type_id == GatewayType::BANK_TRANSFER) + return (new ACH($this->stripe))->tokenBilling($cgt, $payment_hash); + nlog(" DB = ".$this->stripe->client->company->db); $amount = array_sum(array_column($payment_hash->invoices(), 'amount')) + $payment_hash->fee_total; $invoice = Invoice::whereIn('id', $this->transformKeys(array_column($payment_hash->invoices(), 'invoice_id')))->withTrashed()->first(); diff --git a/app/PaymentDrivers/StripePaymentDriver.php b/app/PaymentDrivers/StripePaymentDriver.php index 122735c05ef0..62537689beb7 100644 --- a/app/PaymentDrivers/StripePaymentDriver.php +++ b/app/PaymentDrivers/StripePaymentDriver.php @@ -314,7 +314,9 @@ class StripePaymentDriver extends BaseDriver $this->init(); - $client_gateway_token = ClientGatewayToken::whereClientId($this->client->id)->whereCompanyGatewayId($this->company_gateway->id)->first(); + $client_gateway_token = ClientGatewayToken::whereClientId($this->client->id) + ->whereCompanyGatewayId($this->company_gateway->id) + ->first(); //Search by customer reference if ($client_gateway_token && $client_gateway_token->gateway_customer_reference) {