diff --git a/VERSION.txt b/VERSION.txt index 25c801ef90..d18e15c65c 100644 --- a/VERSION.txt +++ b/VERSION.txt @@ -1 +1 @@ -5.3.27 \ No newline at end of file +5.3.29 \ No newline at end of file diff --git a/app/Exceptions/Handler.php b/app/Exceptions/Handler.php index 052a477c2d..afe61dd9e7 100644 --- a/app/Exceptions/Handler.php +++ b/app/Exceptions/Handler.php @@ -52,6 +52,8 @@ class Handler extends ExceptionHandler MaxAttemptsExceededException::class, CommandNotFoundException::class, ValidationException::class, + ModelNotFoundException::class, + NotFoundHttpException::class, ]; /** diff --git a/app/Http/Controllers/ActivityController.php b/app/Http/Controllers/ActivityController.php index e6bf5ad711..221de5c61e 100644 --- a/app/Http/Controllers/ActivityController.php +++ b/app/Http/Controllers/ActivityController.php @@ -15,6 +15,7 @@ use App\Http\Requests\Activity\DownloadHistoricalEntityRequest; use App\Models\Activity; use App\Transformers\ActivityTransformer; use App\Utils\HostedPDF\NinjaPdf; +use App\Utils\Ninja; use App\Utils\PhantomJS\Phantom; use App\Utils\Traits\Pdf\PdfMaker; use Illuminate\Http\JsonResponse; @@ -147,7 +148,12 @@ class ActivityController extends BaseController */ if($backup && $backup->filename && Storage::disk(config('filesystems.default'))->exists($backup->filename)){ //disk - $html_backup = file_get_contents(Storage::disk(config('filesystems.default'))->path($backup->filename)); + + if(Ninja::isHosted()) + $html_backup = file_get_contents(Storage::disk(config('filesystems.default'))->url($backup->filename)); + else + $html_backup = file_get_contents(Storage::disk(config('filesystems.default'))->path($backup->filename)); + } elseif($backup && $backup->html_backup){ //db $html_backup = $backup->html_backup; diff --git a/app/Http/Controllers/Auth/ContactLoginController.php b/app/Http/Controllers/Auth/ContactLoginController.php index b6c64a4d87..3f9d0503f0 100644 --- a/app/Http/Controllers/Auth/ContactLoginController.php +++ b/app/Http/Controllers/Auth/ContactLoginController.php @@ -40,8 +40,17 @@ class ContactLoginController extends Controller // if(Ninja::isHosted() && count(explode('.', request()->getHost())) == 2){ // $company = null; // }else + + $company = false; - if (strpos($request->getHost(), 'invoicing.co') !== false) { + if($request->has('company_key')){ + MultiDB::findAndSetDbByCompanyKey($request->input('company_key')); + + $company = Company::where('company_key', $request->input('company_key'))->first(); + + } + + if (!$company && strpos($request->getHost(), 'invoicing.co') !== false) { $subdomain = explode('.', $request->getHost())[0]; MultiDB::findAndSetDbByDomain(['subdomain' => $subdomain]); @@ -72,8 +81,8 @@ class ContactLoginController extends Controller { Auth::shouldUse('contact'); - if(Ninja::isHosted() && $request->has('db')) - MultiDB::setDb($request->input('db')); + if(Ninja::isHosted() && $request->has('company_key')) + MultiDB::findAndSetDbByCompanyKey($request->input('company_key')); $this->validateLogin($request); // If the class is using the ThrottlesLogins trait, we can automatically throttle diff --git a/app/Http/Controllers/ClientPortal/SwitchCompanyController.php b/app/Http/Controllers/ClientPortal/SwitchCompanyController.php index 2867541476..160c2246ad 100644 --- a/app/Http/Controllers/ClientPortal/SwitchCompanyController.php +++ b/app/Http/Controllers/ClientPortal/SwitchCompanyController.php @@ -27,7 +27,7 @@ class SwitchCompanyController extends Controller ->where('id', $this->transformKeys($contact)) ->first(); - auth()->guard('contact')->user()->login($client_contact, true); + auth()->guard('contact')->login($client_contact, true); return redirect('/client/dashboard'); } diff --git a/app/Http/Controllers/CompanyController.php b/app/Http/Controllers/CompanyController.php index 5ac5ed157a..b83d472977 100644 --- a/app/Http/Controllers/CompanyController.php +++ b/app/Http/Controllers/CompanyController.php @@ -240,7 +240,7 @@ class CompanyController extends BaseController /* * Create token */ - $user_agent = request()->input('token_name') ?: request()->server('HTTP_USER_AGENT'); + $user_agent = request()->has('token_name') ? request()->input('token_name') : request()->server('HTTP_USER_AGENT'); $company_token = CreateCompanyToken::dispatchNow($company, auth()->user(), $user_agent); diff --git a/app/Http/Controllers/PaymentController.php b/app/Http/Controllers/PaymentController.php index e0ab42bdc0..b612c6388a 100644 --- a/app/Http/Controllers/PaymentController.php +++ b/app/Http/Controllers/PaymentController.php @@ -683,8 +683,6 @@ class PaymentController extends BaseController { $payment = $request->payment(); -// nlog($request->all()); - $payment = $payment->refund($request->all()); return $this->itemResponse($payment); diff --git a/app/Http/Requests/RecurringExpense/StoreRecurringExpenseRequest.php b/app/Http/Requests/RecurringExpense/StoreRecurringExpenseRequest.php index 675827b6ca..60abdf57cb 100644 --- a/app/Http/Requests/RecurringExpense/StoreRecurringExpenseRequest.php +++ b/app/Http/Requests/RecurringExpense/StoreRecurringExpenseRequest.php @@ -42,6 +42,9 @@ class StoreRecurringExpenseRequest extends Request $rules['client_id'] = 'bail|sometimes|exists:clients,id,company_id,'.auth()->user()->company()->id; $rules['frequency_id'] = 'required|integer|digits_between:1,12'; + $rules['tax_amount1'] = 'numeric'; + $rules['tax_amount2'] = 'numeric'; + $rules['tax_amount3'] = 'numeric'; return $this->globalRules($rules); } diff --git a/app/Http/Requests/RecurringExpense/UpdateRecurringExpenseRequest.php b/app/Http/Requests/RecurringExpense/UpdateRecurringExpenseRequest.php index c1be81d105..4f03269bf7 100644 --- a/app/Http/Requests/RecurringExpense/UpdateRecurringExpenseRequest.php +++ b/app/Http/Requests/RecurringExpense/UpdateRecurringExpenseRequest.php @@ -43,6 +43,10 @@ class UpdateRecurringExpenseRequest extends Request $rules['number'] = Rule::unique('recurring_expenses')->where('company_id', auth()->user()->company()->id)->ignore($this->recurring_expense->id); } + $rules['tax_amount1'] = 'numeric'; + $rules['tax_amount2'] = 'numeric'; + $rules['tax_amount3'] = 'numeric'; + return $this->globalRules($rules); } diff --git a/app/Http/Requests/TaskStatus/UpdateTaskStatusRequest.php b/app/Http/Requests/TaskStatus/UpdateTaskStatusRequest.php index 817e48d6a3..e7e82f5a11 100644 --- a/app/Http/Requests/TaskStatus/UpdateTaskStatusRequest.php +++ b/app/Http/Requests/TaskStatus/UpdateTaskStatusRequest.php @@ -33,9 +33,10 @@ class UpdateTaskStatusRequest extends Request { $rules = []; - if ($this->input('name')) { - $rules['name'] = Rule::unique('task_statuses')->where('company_id', auth()->user()->company()->id)->ignore($this->task_status->id); - } + // 26/10/2021 we disable this as it prevent updating existing task status meta data where the same name already exists + // if ($this->input('name')) { + // $rules['name'] = Rule::unique('task_statuses')->where('company_id', auth()->user()->company()->id)->ignore($this->task_status->id); + // } return $rules; diff --git a/app/Http/ValidationRules/PaymentAppliedValidAmount.php b/app/Http/ValidationRules/PaymentAppliedValidAmount.php index e3a6e3c7df..292712a1d7 100644 --- a/app/Http/ValidationRules/PaymentAppliedValidAmount.php +++ b/app/Http/ValidationRules/PaymentAppliedValidAmount.php @@ -51,7 +51,7 @@ class PaymentAppliedValidAmount implements Rule $payment_amounts = 0; $invoice_amounts = 0; - $payment_amounts = $payment->amount - $payment->applied; + $payment_amounts = $payment->amount - $payment->refunded - $payment->applied; if (request()->input('credits') && is_array(request()->input('credits'))) { foreach (request()->input('credits') as $credit) { diff --git a/app/Http/ValidationRules/ValidAmount.php b/app/Http/ValidationRules/ValidAmount.php index d2832e83a0..e87cd42399 100644 --- a/app/Http/ValidationRules/ValidAmount.php +++ b/app/Http/ValidationRules/ValidAmount.php @@ -26,7 +26,10 @@ class ValidAmount implements Rule */ public function passes($attribute, $value) { - return trim($value, '-1234567890.,') === ''; + return is_numeric((string)$value); + //return filter_var((string)$value, FILTER_VALIDATE_FLOAT); +// return preg_match('^(?=.)([+-]?([0-9]*)(\.([0-9]+))?)$^', (string)$value); + // return trim($value, '-1234567890.,') === ''; } diff --git a/app/Jobs/Cron/RecurringInvoicesCron.php b/app/Jobs/Cron/RecurringInvoicesCron.php index bff131da88..f30232650a 100644 --- a/app/Jobs/Cron/RecurringInvoicesCron.php +++ b/app/Jobs/Cron/RecurringInvoicesCron.php @@ -71,7 +71,7 @@ class RecurringInvoicesCron SendRecurring::dispatchNow($recurring_invoice, $recurring_invoice->company->db); } catch(\Exception $e){ - nlog("Unable to sending recurring invoice {$recurring_invoice->id}"); + nlog("Unable to sending recurring invoice {$recurring_invoice->id} ". $e->getMessage()); } }); @@ -107,7 +107,7 @@ class RecurringInvoicesCron SendRecurring::dispatchNow($recurring_invoice, $recurring_invoice->company->db); } catch(\Exception $e){ - nlog("Unable to sending recurring invoice {$recurring_invoice->id}"); + nlog("Unable to sending recurring invoice {$recurring_invoice->id} ". $e->getMessage()); } }); diff --git a/app/Jobs/Mail/PaymentFailedMailer.php b/app/Jobs/Mail/PaymentFailedMailer.php index 5512c4b1a9..9d84a74595 100644 --- a/app/Jobs/Mail/PaymentFailedMailer.php +++ b/app/Jobs/Mail/PaymentFailedMailer.php @@ -15,6 +15,7 @@ use App\Jobs\Mail\NinjaMailer; use App\Jobs\Mail\NinjaMailerJob; use App\Jobs\Mail\NinjaMailerObject; use App\Libraries\MultiDB; +use App\Mail\Admin\ClientPaymentFailureObject; use App\Mail\Admin\EntityNotificationMailer; use App\Mail\Admin\PaymentFailureObject; use App\Models\Client; @@ -102,6 +103,24 @@ class PaymentFailedMailer implements ShouldQueue }); //add client payment failures here. + nlog("pre client failure email"); + + if($contact = $this->client->primary_contact()->first()) + { + + nlog("inside failure"); + + $mail_obj = (new ClientPaymentFailureObject($this->client, $this->error, $this->company, $this->payment_hash))->build(); + + $nmo = new NinjaMailerObject; + $nmo->mailable = new NinjaMailer($mail_obj); + $nmo->company = $this->company; + $nmo->to_user = $contact; + $nmo->settings = $settings; + + NinjaMailerJob::dispatch($nmo); + } + } diff --git a/app/Jobs/RecurringInvoice/SendRecurring.php b/app/Jobs/RecurringInvoice/SendRecurring.php index 0aab4e659c..464849ef70 100644 --- a/app/Jobs/RecurringInvoice/SendRecurring.php +++ b/app/Jobs/RecurringInvoice/SendRecurring.php @@ -73,13 +73,14 @@ class SendRecurring implements ShouldQueue $invoice->date = now()->format('Y-m-d'); $invoice->due_date = $this->recurring_invoice->calculateDueDate(now()->format('Y-m-d')); $invoice->recurring_id = $this->recurring_invoice->id; - + $invoice->saveQuietly(); + if($invoice->client->getSetting('auto_email_invoice')) { $invoice = $invoice->service() ->markSent() ->applyNumber() - // ->createInvitations() //need to only link invitations to those in the recurring invoice + //->createInvitations() //need to only link invitations to those in the recurring invoice ->fillDefaults() ->save(); diff --git a/app/Mail/Admin/ClientPaymentFailureObject.php b/app/Mail/Admin/ClientPaymentFailureObject.php index c18101b2ed..df13ad8a50 100644 --- a/app/Mail/Admin/ClientPaymentFailureObject.php +++ b/app/Mail/Admin/ClientPaymentFailureObject.php @@ -14,7 +14,6 @@ namespace App\Mail\Admin; use App\Models\Invoice; use App\Utils\HtmlEngine; use App\Utils\Ninja; -use App\Utils\Number; use App\Utils\Traits\MakesHash; use Illuminate\Support\Facades\App; use stdClass; @@ -91,7 +90,7 @@ class ClientPaymentFailureObject return ctrans( 'texts.notification_invoice_payment_failed_subject', - ['invoice' => $this->client->present()->name()] + ['invoice' => implode(",", $this->invoices->pluck('number')->toArray())] ); } @@ -110,7 +109,7 @@ class ClientPaymentFailureObject ] ), 'greeting' => ctrans('texts.email_salutation', ['name' => $this->client->present()->name]), - 'message' => $this->error, + 'message' => ctrans('texts.client_payment_failure_body', ['invoice' => implode(",", $this->invoices->pluck('number')->toArray()), 'amount' => $this->getAmount()]), 'signature' => $signature, 'logo' => $this->company->present()->logo(), 'settings' => $this->client->getMergedSettings(), diff --git a/app/Models/ClientContact.php b/app/Models/ClientContact.php index 05f1c7392b..9607bb2436 100644 --- a/app/Models/ClientContact.php +++ b/app/Models/ClientContact.php @@ -92,7 +92,7 @@ class ClientContact extends Authenticatable implements HasLocalePreference 'custom_value4', 'email', 'is_primary', - // 'client_id', + 'send_email', ]; /** diff --git a/app/Models/Gateway.php b/app/Models/Gateway.php index 1b52c96527..1f60070b0a 100644 --- a/app/Models/Gateway.php +++ b/app/Models/Gateway.php @@ -145,7 +145,9 @@ class Gateway extends StaticModel GatewayType::GIROPAY => ['refund' => true, 'token_billing' => true, 'webhooks' => ['source.chargeable', 'charge.succeeded']], GatewayType::EPS => ['refund' => true, 'token_billing' => true, 'webhooks' => ['source.chargeable', 'charge.succeeded']], GatewayType::BANCONTACT => ['refund' => true, 'token_billing' => true, 'webhooks' => ['source.chargeable', 'charge.succeeded']], + GatewayType::BECS => ['refund' => true, 'token_billing' => true, 'webhooks' => ['source.chargeable', 'charge.succeeded']], GatewayType::IDEAL => ['refund' => true, 'token_billing' => true, 'webhooks' => ['source.chargeable', 'charge.succeeded']], + GatewayType::ACSS => ['refund' => true, 'token_billing' => true, 'webhooks' => ['source.chargeable', 'charge.succeeded']], ]; break; case 57: diff --git a/app/Models/GatewayType.php b/app/Models/GatewayType.php index e7b5160b81..d6c51bc4e7 100644 --- a/app/Models/GatewayType.php +++ b/app/Models/GatewayType.php @@ -84,7 +84,7 @@ class GatewayType extends StaticModel case self::EPS: return ctrans('texts.eps'); case self::BECS: - return ctrans('tets.becs'); + return ctrans('texts.becs'); case self::ACSS: return ctrans('texts.acss'); case self::DIRECT_DEBIT: diff --git a/app/PaymentDrivers/BaseDriver.php b/app/PaymentDrivers/BaseDriver.php index e1b0e65fee..397583bd6e 100644 --- a/app/PaymentDrivers/BaseDriver.php +++ b/app/PaymentDrivers/BaseDriver.php @@ -221,6 +221,19 @@ class BaseDriver extends AbstractPaymentDriver { $this->confirmGatewayFee(); + /*Never create a payment with a duplicate transaction reference*/ + if(array_key_exists('transaction_reference', $data)){ + + $_payment = Payment::where('transaction_reference', $data['transaction_reference']) + ->where('client_id', $this->client->id) + ->first(); + + if($_payment) + return $_payment; + + } + + $payment = PaymentFactory::create($this->client->company->id, $this->client->user->id); $payment->client_id = $this->client->id; $payment->company_gateway_id = $this->company_gateway->id; diff --git a/app/PaymentDrivers/Braintree/ACH.php b/app/PaymentDrivers/Braintree/ACH.php index 25cd07e2cc..de109c54cb 100644 --- a/app/PaymentDrivers/Braintree/ACH.php +++ b/app/PaymentDrivers/Braintree/ACH.php @@ -13,7 +13,6 @@ namespace App\PaymentDrivers\Braintree; use App\Exceptions\PaymentFailed; use App\Http\Requests\ClientPortal\Payments\PaymentResponseRequest; -use App\Http\Requests\Request; use App\Jobs\Util\SystemLogger; use App\Models\ClientGatewayToken; use App\Models\GatewayType; @@ -23,6 +22,7 @@ use App\Models\SystemLog; use App\PaymentDrivers\BraintreePaymentDriver; use App\PaymentDrivers\Common\MethodInterface; use App\Utils\Traits\MakesHash; +use Illuminate\Http\Request; class ACH implements MethodInterface { diff --git a/app/PaymentDrivers/BraintreePaymentDriver.php b/app/PaymentDrivers/BraintreePaymentDriver.php index d360bdf1f8..6dfcf1a80d 100644 --- a/app/PaymentDrivers/BraintreePaymentDriver.php +++ b/app/PaymentDrivers/BraintreePaymentDriver.php @@ -12,8 +12,6 @@ namespace App\PaymentDrivers; - -use App\Http\Requests\ClientPortal\Payments\PaymentResponseRequest; use App\Jobs\Util\SystemLogger; use App\Models\ClientGatewayToken; use App\Models\GatewayType; @@ -27,7 +25,6 @@ use App\PaymentDrivers\Braintree\CreditCard; use App\PaymentDrivers\Braintree\PayPal; use Braintree\Gateway; use Exception; -use Illuminate\Http\Request; class BraintreePaymentDriver extends BaseDriver { @@ -40,7 +37,7 @@ class BraintreePaymentDriver extends BaseDriver /** * @var Gateway; */ - public $gateway; + public Gateway $gateway; public static $methods = [ GatewayType::CREDIT_CARD => CreditCard::class, @@ -118,8 +115,7 @@ class BraintreePaymentDriver extends BaseDriver ]); if ($result->success) { - - $address = $this->gateway->address()->create([ + $address = $this->gateway->address()->create([ 'customerId' => $result->customer->id, 'firstName' => $this->client->present()->name, 'streetAddress' => $this->client->address1, @@ -135,12 +131,9 @@ class BraintreePaymentDriver extends BaseDriver { $this->init(); - try{ - + try { $response = $this->gateway->transaction()->refund($payment->transaction_reference, $amount); - } catch (Exception $e) { - $data = [ 'transaction_reference' => null, 'transaction_response' => json_encode($e->getMessage()), @@ -154,24 +147,19 @@ class BraintreePaymentDriver extends BaseDriver return $data; } - if($response->success) - { - + if ($response->success) { $data = [ - 'transaction_reference' => $response->id, + 'transaction_reference' => $payment->transaction_reference, 'transaction_response' => json_encode($response), - 'success' => (bool)$response->success, - 'description' => $response->status, + 'success' => (bool) $response->success, + 'description' => ctrans('texts.plan_refunded'), 'code' => 0, ]; SystemLogger::dispatch(['server_response' => $response, 'data' => $data], SystemLog::CATEGORY_GATEWAY_RESPONSE, SystemLog::EVENT_GATEWAY_SUCCESS, SystemLog::TYPE_BRAINTREE, $this->client, $this->client->company); return $data; - - } - else{ - + } else { $error = $response->errors->deepAll()[0]; $data = [ @@ -185,7 +173,6 @@ class BraintreePaymentDriver extends BaseDriver SystemLogger::dispatch(['server_response' => $response, 'data' => $data], SystemLog::CATEGORY_GATEWAY_RESPONSE, SystemLog::EVENT_GATEWAY_FAILURE, SystemLog::TYPE_BRAINTREE, $this->client, $this->client->company); return $data; - } } diff --git a/app/PaymentDrivers/CheckoutCom/CreditCard.php b/app/PaymentDrivers/CheckoutCom/CreditCard.php index 317153749a..cd00111dc8 100644 --- a/app/PaymentDrivers/CheckoutCom/CreditCard.php +++ b/app/PaymentDrivers/CheckoutCom/CreditCard.php @@ -14,7 +14,7 @@ namespace App\PaymentDrivers\CheckoutCom; use App\Exceptions\PaymentFailed; use App\Http\Requests\ClientPortal\Payments\PaymentResponseRequest; -use App\Http\Requests\Request; +use Illuminate\Http\Request; use App\Models\ClientGatewayToken; use App\Models\GatewayType; use App\PaymentDrivers\CheckoutComPaymentDriver; @@ -112,7 +112,7 @@ class CreditCard implements MethodInterface $data['currency'] = $this->checkout->client->getCurrencyCode(); $data['value'] = $this->checkout->convertToCheckoutAmount($data['total']['amount_with_fee'], $this->checkout->client->getCurrencyCode()); $data['raw_value'] = $data['total']['amount_with_fee']; - $data['customer_email'] = $this->checkout->client->present()->email; + $data['customer_email'] = $this->checkout->client->present()->email(); return render('gateways.checkout.credit_card.pay', $data); } @@ -173,6 +173,10 @@ class CreditCard implements MethodInterface $payment = new Payment($method, $this->checkout->payment_hash->data->currency); $payment->amount = $this->checkout->payment_hash->data->value; $payment->reference = $this->checkout->getDescription(); + $payment->customer = [ + 'name' => $this->checkout->client->present()->name() , + 'email' => $this->checkout->client->present()->email(), + ]; $this->checkout->payment_hash->data = array_merge((array)$this->checkout->payment_hash->data, ['checkout_payment_ref' => $payment]); $this->checkout->payment_hash->save(); diff --git a/app/PaymentDrivers/CheckoutCom/Utilities.php b/app/PaymentDrivers/CheckoutCom/Utilities.php index 9790a5ca8d..ca4c544d75 100644 --- a/app/PaymentDrivers/CheckoutCom/Utilities.php +++ b/app/PaymentDrivers/CheckoutCom/Utilities.php @@ -84,8 +84,7 @@ trait Utilities public function processUnsuccessfulPayment(Payment $_payment, $throw_exception = true) { - - $this->getParent()->sendFailureMail($_payment->status . " " . $_payment->response_summary); + $this->getParent()->sendFailureMail($_payment->status . " " . optional($_payment)->response_summary); $message = [ 'server_response' => $_payment, @@ -102,7 +101,7 @@ trait Utilities ); if ($throw_exception) { - throw new PaymentFailed($_payment->status . " " . $_payment->response_summary, $_payment->http_code); + throw new PaymentFailed($_payment->status . " " . optional($_payment)->response_summary, $_payment->http_code); } } diff --git a/app/PaymentDrivers/CheckoutComPaymentDriver.php b/app/PaymentDrivers/CheckoutComPaymentDriver.php index 1cb3443c01..d7937fac43 100644 --- a/app/PaymentDrivers/CheckoutComPaymentDriver.php +++ b/app/PaymentDrivers/CheckoutComPaymentDriver.php @@ -338,7 +338,9 @@ class CheckoutComPaymentDriver extends BaseDriver $this->setPaymentHash($request->getPaymentHash()); try { - $payment = $this->gateway->payments()->details($request->query('cko-session-id')); + $payment = $this->gateway->payments()->details( + $request->query('cko-session-id') + ); if ($payment->approved) { return $this->processSuccessfulPayment($payment); diff --git a/app/PaymentDrivers/Common/MethodInterface.php b/app/PaymentDrivers/Common/MethodInterface.php index 0c839d602c..2febf2c2f0 100644 --- a/app/PaymentDrivers/Common/MethodInterface.php +++ b/app/PaymentDrivers/Common/MethodInterface.php @@ -12,7 +12,7 @@ namespace App\PaymentDrivers\Common; use App\Http\Requests\ClientPortal\Payments\PaymentResponseRequest; -use App\Http\Requests\Request; +use Illuminate\Http\Request; interface MethodInterface { diff --git a/app/PaymentDrivers/GoCardless/ACH.php b/app/PaymentDrivers/GoCardless/ACH.php index 1242cc022b..e620db4d56 100644 --- a/app/PaymentDrivers/GoCardless/ACH.php +++ b/app/PaymentDrivers/GoCardless/ACH.php @@ -14,7 +14,7 @@ namespace App\PaymentDrivers\GoCardless; use App\Exceptions\PaymentFailed; use App\Http\Requests\ClientPortal\Payments\PaymentResponseRequest; -use App\Http\Requests\Request; +use Illuminate\Http\Request; use App\Jobs\Util\SystemLogger; use App\Models\ClientGatewayToken; use App\Models\GatewayType; diff --git a/app/PaymentDrivers/GoCardless/DirectDebit.php b/app/PaymentDrivers/GoCardless/DirectDebit.php index 0507c38f63..5b9207ad12 100644 --- a/app/PaymentDrivers/GoCardless/DirectDebit.php +++ b/app/PaymentDrivers/GoCardless/DirectDebit.php @@ -14,7 +14,7 @@ namespace App\PaymentDrivers\GoCardless; use App\Exceptions\PaymentFailed; use App\Http\Requests\ClientPortal\Payments\PaymentResponseRequest; -use App\Http\Requests\Request; +use Illuminate\Http\Request; use App\Jobs\Mail\PaymentFailureMailer; use App\Jobs\Util\SystemLogger; use App\Models\ClientGatewayToken; diff --git a/app/PaymentDrivers/GoCardless/SEPA.php b/app/PaymentDrivers/GoCardless/SEPA.php index a215b975ed..9eef98e8fd 100644 --- a/app/PaymentDrivers/GoCardless/SEPA.php +++ b/app/PaymentDrivers/GoCardless/SEPA.php @@ -14,7 +14,7 @@ namespace App\PaymentDrivers\GoCardless; use App\Exceptions\PaymentFailed; use App\Http\Requests\ClientPortal\Payments\PaymentResponseRequest; -use App\Http\Requests\Request; +use Illuminate\Http\Request; use App\Jobs\Util\SystemLogger; use App\Models\ClientGatewayToken; use App\Models\GatewayType; diff --git a/app/PaymentDrivers/Mollie/Bancontact.php b/app/PaymentDrivers/Mollie/Bancontact.php index d8a0eab788..45df88520e 100644 --- a/app/PaymentDrivers/Mollie/Bancontact.php +++ b/app/PaymentDrivers/Mollie/Bancontact.php @@ -13,7 +13,7 @@ namespace App\PaymentDrivers\Mollie; use App\Exceptions\PaymentFailed; -use App\Http\Requests\Request; +use Illuminate\Http\Request; use App\Http\Requests\ClientPortal\Payments\PaymentResponseRequest; use App\Jobs\Util\SystemLogger; use App\Models\GatewayType; diff --git a/app/PaymentDrivers/Mollie/BankTransfer.php b/app/PaymentDrivers/Mollie/BankTransfer.php index 3002d201ca..04e65996cb 100644 --- a/app/PaymentDrivers/Mollie/BankTransfer.php +++ b/app/PaymentDrivers/Mollie/BankTransfer.php @@ -14,7 +14,7 @@ namespace App\PaymentDrivers\Mollie; use App\Exceptions\PaymentFailed; use App\Http\Requests\ClientPortal\Payments\PaymentResponseRequest; -use App\Http\Requests\Request; +use Illuminate\Http\Request; use App\Jobs\Util\SystemLogger; use App\Models\GatewayType; use App\Models\Payment; diff --git a/app/PaymentDrivers/Mollie/IDEAL.php b/app/PaymentDrivers/Mollie/IDEAL.php index 20ac61b3ce..185cfe758e 100644 --- a/app/PaymentDrivers/Mollie/IDEAL.php +++ b/app/PaymentDrivers/Mollie/IDEAL.php @@ -14,7 +14,7 @@ namespace App\PaymentDrivers\Mollie; use App\Exceptions\PaymentFailed; use App\Http\Requests\ClientPortal\Payments\PaymentResponseRequest; -use App\Http\Requests\Request; +use Illuminate\Http\Request; use App\Jobs\Util\SystemLogger; use App\Models\GatewayType; use App\Models\Payment; diff --git a/app/PaymentDrivers/Mollie/KBC.php b/app/PaymentDrivers/Mollie/KBC.php index d608a62b89..1bb575d1bd 100644 --- a/app/PaymentDrivers/Mollie/KBC.php +++ b/app/PaymentDrivers/Mollie/KBC.php @@ -13,7 +13,7 @@ namespace App\PaymentDrivers\Mollie; use App\Exceptions\PaymentFailed; -use App\Http\Requests\Request; +use Illuminate\Http\Request; use App\Http\Requests\ClientPortal\Payments\PaymentResponseRequest; use App\Jobs\Util\SystemLogger; use App\Models\GatewayType; diff --git a/app/PaymentDrivers/PayPalExpressPaymentDriver.php b/app/PaymentDrivers/PayPalExpressPaymentDriver.php index 2ee33668b8..43b2a6a1ad 100644 --- a/app/PaymentDrivers/PayPalExpressPaymentDriver.php +++ b/app/PaymentDrivers/PayPalExpressPaymentDriver.php @@ -93,7 +93,7 @@ class PayPalExpressPaymentDriver extends BaseDriver return $response->redirect(); } - $this->sendFailureMail($response->getData()); + $this->sendFailureMail($response->getMessage()); $message = [ 'server_response' => $response->getMessage(), diff --git a/app/PaymentDrivers/Razorpay/Hosted.php b/app/PaymentDrivers/Razorpay/Hosted.php index 657cd4d5d7..1eb45072aa 100644 --- a/app/PaymentDrivers/Razorpay/Hosted.php +++ b/app/PaymentDrivers/Razorpay/Hosted.php @@ -15,7 +15,7 @@ namespace App\PaymentDrivers\Razorpay; use App\Exceptions\PaymentFailed; use App\Http\Requests\ClientPortal\Payments\PaymentResponseRequest; -use App\Http\Requests\Request; +use Illuminate\Http\Request; use App\Jobs\Util\SystemLogger; use App\Models\GatewayType; use App\Models\Payment; diff --git a/app/PaymentDrivers/Square/CreditCard.php b/app/PaymentDrivers/Square/CreditCard.php index 47867fa3b3..01696fd431 100644 --- a/app/PaymentDrivers/Square/CreditCard.php +++ b/app/PaymentDrivers/Square/CreditCard.php @@ -13,16 +13,20 @@ namespace App\PaymentDrivers\Square; use App\Http\Requests\ClientPortal\Payments\PaymentResponseRequest; +use Illuminate\Http\Request; use App\Models\ClientGatewayToken; use App\Models\GatewayType; use App\Models\Payment; use App\Models\PaymentType; +use App\PaymentDrivers\Common\MethodInterface; use App\PaymentDrivers\SquarePaymentDriver; use App\Utils\Traits\MakesHash; +use Illuminate\Http\RedirectResponse; use Illuminate\Support\Str; +use Illuminate\View\View; use Square\Http\ApiResponse; -class CreditCard +class CreditCard implements MethodInterface { use MakesHash; @@ -34,90 +38,27 @@ class CreditCard $this->square_driver->init(); } - public function authorizeView($data) + /** + * Authorization page for credit card. + * + * @param array $data + * @return View + */ + public function authorizeView($data): View { $data['gateway'] = $this->square_driver; return render('gateways.square.credit_card.authorize', $data); } - public function authorizeResponse($request) + /** + * Handle authorization for credit card. + * + * @param Request $request + * @return RedirectResponse + */ + public function authorizeResponse($request): RedirectResponse { - /* Step one - process a $1 payment - but don't complete it*/ - $payment = false; - - $amount_money = new \Square\Models\Money(); - $amount_money->setAmount(100); //amount in cents - $amount_money->setCurrency($this->square_driver->client->currency()->code); - - $body = new \Square\Models\CreatePaymentRequest( - $request->sourceId, - Str::random(32), - $amount_money - ); - - $body->setAutocomplete(false); - $body->setLocationId($this->square_driver->company_gateway->getConfigField('locationId')); - $body->setReferenceId(Str::random(16)); - - $api_response = $this->square_driver->square->getPaymentsApi()->createPayment($body); - - if ($api_response->isSuccess()) { - $result = $api_response->getBody(); - $payment = json_decode($result); - } else { - $errors = $api_response->getErrors(); - return $this->processUnsuccessfulPayment($errors); - } - - - /* Step 3 create the card */ - $card = new \Square\Models\Card(); - $card->setCardholderName($this->square_driver->client->present()->name()); - // $card->setBillingAddress($billing_address); - $card->setCustomerId($this->findOrCreateClient()); - $card->setReferenceId(Str::random(8)); - - $body = new \Square\Models\CreateCardRequest( - Str::random(32), - $payment->payment->id, - $card - ); - - $api_response = $this->square_driver - ->square - ->getCardsApi() - ->createCard($body); - - $card = false; - - if ($api_response->isSuccess()) { - $card = $api_response->getBody(); - $card = json_decode($card); - } else { - $errors = $api_response->getErrors(); - - return $this->processUnsuccessfulPayment($errors); - } - - /* Create the token in Invoice Ninja*/ - $cgt = []; - $cgt['token'] = $card->card->id; - $cgt['payment_method_id'] = GatewayType::CREDIT_CARD; - - $payment_meta = new \stdClass; - $payment_meta->exp_month = $card->card->exp_month; - $payment_meta->exp_year = $card->card->exp_year; - $payment_meta->brand = $card->card->card_brand; - $payment_meta->last4 = $card->card->last_4; - $payment_meta->type = GatewayType::CREDIT_CARD; - - $cgt['payment_meta'] = $payment_meta; - - $token = $this->square_driver->storeGatewayToken($cgt, [ - 'gateway_customer_reference' => $this->findOrCreateClient(), - ]); - return redirect()->route('client.payment_methods.index'); } @@ -170,8 +111,9 @@ class CreditCard $body->setLocationId($this->square_driver->company_gateway->getConfigField('locationId')); $body->setReferenceId(Str::random(16)); - if($request->has('verificationToken') && $request->input('verificationToken')) + if ($request->has('verificationToken') && $request->input('verificationToken')) { $body->setVerificationToken($request->input('verificationToken')); + } if ($request->shouldUseToken()) { $body->setCustomerId($cgt->gateway_customer_reference); @@ -181,66 +123,12 @@ class CreditCard $response = $this->square_driver->square->getPaymentsApi()->createPayment($body); if ($response->isSuccess()) { - if ($request->shouldStoreToken()) { - $this->storePaymentMethod($response); - } - return $this->processSuccessfulPayment($response); } return $this->processUnsuccessfulPayment($response); } - private function storePaymentMethod(ApiResponse $response) - { - $payment = \json_decode($response->getBody()); - - $billing_address = new \Square\Models\Address(); - $billing_address->setAddressLine1($this->square_driver->client->address1); - $billing_address->setAddressLine2($this->square_driver->client->address2); - $billing_address->setLocality($this->square_driver->client->city); - $billing_address->setAdministrativeDistrictLevel1($this->square_driver->client->state); - $billing_address->setPostalCode($this->square_driver->client->postal_code); - $billing_address->setCountry($this->square_driver->client->country->iso_3166_2); - - $card = new \Square\Models\Card(); - $card->setCardholderName($this->square_driver->client->present()->first_name(). " " .$this->square_driver->client->present()->last_name()); - $card->setCustomerId($this->findOrCreateClient()); - $card->setReferenceId(Str::random(8)); - $card->setBillingAddress($billing_address); - - $body = new \Square\Models\CreateCardRequest(Str::random(32), $payment->payment->id, $card); - - /** @var ApiResponse */ - $api_response = $this->square_driver - ->square - ->getCardsApi() - ->createCard($body); - - if (!$api_response->isSuccess()) { - return $this->processUnsuccessfulPayment($api_response); - } - - $card = \json_decode($api_response->getBody()); - - $cgt = []; - $cgt['token'] = $card->card->id; - $cgt['payment_method_id'] = GatewayType::CREDIT_CARD; - - $payment_meta = new \stdClass; - $payment_meta->exp_month = $card->card->exp_month; - $payment_meta->exp_year = $card->card->exp_year; - $payment_meta->brand = $card->card->card_brand; - $payment_meta->last4 = $card->card->last_4; - $payment_meta->type = GatewayType::CREDIT_CARD; - - $cgt['payment_meta'] = $payment_meta; - - $this->square_driver->storeGatewayToken($cgt, [ - 'gateway_customer_reference' => $this->findOrCreateClient(), - ]); - } - private function processSuccessfulPayment(ApiResponse $response) { $body = json_decode($response->getBody()); @@ -301,9 +189,9 @@ class CreditCard $customers = $api_response->getBody(); $customers = json_decode($customers); - if(count(array($api_response->getBody(),1)) == 0) + if (count([$api_response->getBody(),1]) == 0) { $customers = false; - + } } else { $errors = $api_response->getErrors(); } diff --git a/app/PaymentDrivers/Stripe/BECS.php b/app/PaymentDrivers/Stripe/BECS.php index 8a9007a0e1..a0942c9972 100644 --- a/app/PaymentDrivers/Stripe/BECS.php +++ b/app/PaymentDrivers/Stripe/BECS.php @@ -141,8 +141,8 @@ class BECS $method = $this->stripe->getStripePaymentMethod($intent->payment_method); $payment_meta = new \stdClass; - $payment_meta->brand = (string) \sprintf('%s (%s)', $method->sepa_debit->bank_code, ctrans('texts.becs')); - $payment_meta->last4 = (string) $method->sepa_debit->last4; + $payment_meta->brand = (string) \sprintf('%s (%s)', $method->au_becs_debit->bank_code, ctrans('texts.becs')); + $payment_meta->last4 = (string) $method->au_becs_debit->last4; $payment_meta->state = 'authorized'; $payment_meta->type = GatewayType::BECS; diff --git a/app/PaymentDrivers/StripePaymentDriver.php b/app/PaymentDrivers/StripePaymentDriver.php index 93cc87f8cd..6ae31452ba 100644 --- a/app/PaymentDrivers/StripePaymentDriver.php +++ b/app/PaymentDrivers/StripePaymentDriver.php @@ -208,7 +208,7 @@ class StripePaymentDriver extends BaseDriver && $this->client->currency() && ($this->client->currency()->code == 'AUD') && isset($this->client->country) - && in_array($this->client->country->iso_3166_3, ["AUS", "DEU"])) + && in_array($this->client->country->iso_3166_3, ['AUS'])) $types[] = GatewayType::BECS; if ($this->client diff --git a/app/PaymentDrivers/WePayPaymentDriver.php b/app/PaymentDrivers/WePayPaymentDriver.php index 27c60e570b..9624a329cf 100644 --- a/app/PaymentDrivers/WePayPaymentDriver.php +++ b/app/PaymentDrivers/WePayPaymentDriver.php @@ -185,7 +185,7 @@ class WePayPaymentDriver extends BaseDriver } if (! isset($objectType)) { - throw new Exception('Could not find object id parameter'); + throw new \Exception('Could not find object id parameter'); } if ($objectType == 'credit_card') { diff --git a/app/Repositories/BaseRepository.php b/app/Repositories/BaseRepository.php index 2f62dbc6cc..cf37b1d3f1 100644 --- a/app/Repositories/BaseRepository.php +++ b/app/Repositories/BaseRepository.php @@ -113,25 +113,26 @@ class BaseRepository * @param $action * * @return int + * @deprecated - this doesn't appear to be used anywhere? */ - public function bulk($ids, $action) - { - if (! $ids) { - return 0; - } + // public function bulk($ids, $action) + // { + // if (! $ids) { + // return 0; + // } - $ids = $this->transformKeys($ids); + // $ids = $this->transformKeys($ids); - $entities = $this->findByPublicIdsWithTrashed($ids); + // $entities = $this->findByPublicIdsWithTrashed($ids); - foreach ($entities as $entity) { - if (auth()->user()->can('edit', $entity)) { - $this->$action($entity); - } - } + // foreach ($entities as $entity) { + // if (auth()->user()->can('edit', $entity)) { + // $this->$action($entity); + // } + // } - return count($entities); - } + // return count($entities); + // } /* Returns an invoice if defined as a key in the $resource array*/ public function getInvitation($invitation, $resource) diff --git a/app/Repositories/ClientRepository.php b/app/Repositories/ClientRepository.php index 8dda9f5c69..4765256cde 100644 --- a/app/Repositories/ClientRepository.php +++ b/app/Repositories/ClientRepository.php @@ -65,7 +65,7 @@ class ClientRepository extends BaseRepository $client->fill($data); $client->save(); - if (!isset($client->number) || empty($client->number)) { + if (!isset($client->number) || empty($client->number) || strlen($client->number) == 0) { $client->number = $this->getNextClientNumber($client); } diff --git a/app/Services/Invoice/InvoiceService.php b/app/Services/Invoice/InvoiceService.php index 162923cee0..45d0ab893a 100644 --- a/app/Services/Invoice/InvoiceService.php +++ b/app/Services/Invoice/InvoiceService.php @@ -134,9 +134,9 @@ class InvoiceService * * @return InvoiceService Parent class object */ - public function updateBalance($balance_adjustment) + public function updateBalance($balance_adjustment, bool $is_draft = false) { - $this->invoice = (new UpdateBalance($this->invoice, $balance_adjustment))->run(); + $this->invoice = (new UpdateBalance($this->invoice, $balance_adjustment, $is_draft))->run(); if ((int)$this->invoice->balance == 0) { $this->invoice->next_send_date = null; @@ -339,6 +339,10 @@ class InvoiceService public function removeUnpaidGatewayFees() { + //return early if type three does not exist. + if(!collect($this->invoice->line_items)->contains('type_id', 3)) + return $this; + $this->invoice->line_items = collect($this->invoice->line_items) ->reject(function ($item) { return $item->type_id == '3'; diff --git a/app/Services/Invoice/MarkSent.php b/app/Services/Invoice/MarkSent.php index fbf874f955..8fe2f2e87a 100644 --- a/app/Services/Invoice/MarkSent.php +++ b/app/Services/Invoice/MarkSent.php @@ -33,7 +33,7 @@ class MarkSent extends AbstractService { /* Return immediately if status is not draft */ - if ($this->invoice->fresh()->status_id != Invoice::STATUS_DRAFT) { + if ($this->invoice && $this->invoice->fresh()->status_id != Invoice::STATUS_DRAFT) { return $this->invoice; } @@ -47,7 +47,7 @@ class MarkSent extends AbstractService ->service() ->applyNumber() ->setDueDate() - ->updateBalance($this->invoice->amount) + ->updateBalance($this->invoice->amount, true) ->deletePdf() ->setReminder() ->save(); diff --git a/app/Services/Invoice/UpdateBalance.php b/app/Services/Invoice/UpdateBalance.php index 9a95391abb..0aab1c2e8c 100644 --- a/app/Services/Invoice/UpdateBalance.php +++ b/app/Services/Invoice/UpdateBalance.php @@ -20,10 +20,13 @@ class UpdateBalance extends AbstractService public $balance_adjustment; - public function __construct($invoice, $balance_adjustment) + private $is_draft; + + public function __construct($invoice, $balance_adjustment, bool $is_draft) { $this->invoice = $invoice; $this->balance_adjustment = $balance_adjustment; + $this->is_draft = $is_draft; } public function run() @@ -34,7 +37,7 @@ class UpdateBalance extends AbstractService $this->invoice->balance += floatval($this->balance_adjustment); - if ($this->invoice->balance == 0) { + if ($this->invoice->balance == 0 && !$this->is_draft) { $this->invoice->status_id = Invoice::STATUS_PAID; } diff --git a/app/Services/Payment/DeletePayment.php b/app/Services/Payment/DeletePayment.php index b486180550..626327f803 100644 --- a/app/Services/Payment/DeletePayment.php +++ b/app/Services/Payment/DeletePayment.php @@ -115,15 +115,22 @@ class DeletePayment ->updatePaidToDate($net_deletable * -1) ->save(); - // $paymentable_invoice->client - // ->service() - // ->updatePaidToDate($net_deletable * -1) - // ->save(); + } }); } + else { + /* If there are no invoices - then we need to still adjust the total client->paid_to_date amount*/ + + $this->payment + ->client + ->service() + ->updatePaidToDate(($this->payment->amount - $this->payment->applied)*-1) + ->save(); + + } return $this; } diff --git a/app/Services/Payment/RefundPayment.php b/app/Services/Payment/RefundPayment.php index 2b44eae951..0dfa6fa355 100644 --- a/app/Services/Payment/RefundPayment.php +++ b/app/Services/Payment/RefundPayment.php @@ -267,9 +267,17 @@ class RefundPayment // $this->credit_note->ledger()->updateCreditBalance($adjustment_amount, $ledger_string); $client = $this->payment->client->fresh(); - //$client->service()->updatePaidToDate(-1 * $this->total_refund)->save(); + $client->service()->updatePaidToDate(-1 * $refunded_invoice['amount'])->save(); } + else{ + //if we are refunding and no payments have been tagged, then we need to decrement the client->paid_to_date by the total refund amount. + + $client = $this->payment->client->fresh(); + + $client->service()->updatePaidToDate(-1 * $this->total_refund)->save(); + + } return $this; } diff --git a/config/ninja.php b/config/ninja.php index a265c17de7..19c4c6da37 100644 --- a/config/ninja.php +++ b/config/ninja.php @@ -14,8 +14,8 @@ return [ 'require_https' => env('REQUIRE_HTTPS', true), 'app_url' => rtrim(env('APP_URL', ''), '/'), 'app_domain' => env('APP_DOMAIN', 'invoicing.co'), - 'app_version' => '5.3.27', - 'app_tag' => '5.3.27', + 'app_version' => '5.3.29', + 'app_tag' => '5.3.29', 'minimum_client_version' => '5.0.16', 'terms_version' => '1.0.1', 'api_secret' => env('API_SECRET', ''), diff --git a/public/js/clients/payments/square-credit-card.js b/public/js/clients/payments/square-credit-card.js index 215fa587ec..b6753383cd 100644 --- a/public/js/clients/payments/square-credit-card.js +++ b/public/js/clients/payments/square-credit-card.js @@ -1,2 +1,2 @@ /*! For license information please see square-credit-card.js.LICENSE.txt */ -!function(t){var e={};function n(r){if(e[r])return e[r].exports;var o=e[r]={i:r,l:!1,exports:{}};return t[r].call(o.exports,o,o.exports,n),o.l=!0,o.exports}n.m=t,n.c=e,n.d=function(t,e,r){n.o(t,e)||Object.defineProperty(t,e,{enumerable:!0,get:r})},n.r=function(t){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(t,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(t,"__esModule",{value:!0})},n.t=function(t,e){if(1&e&&(t=n(t)),8&e)return t;if(4&e&&"object"==typeof t&&t&&t.__esModule)return t;var r=Object.create(null);if(n.r(r),Object.defineProperty(r,"default",{enumerable:!0,value:t}),2&e&&"string"!=typeof t)for(var o in t)n.d(r,o,function(e){return t[e]}.bind(null,o));return r},n.n=function(t){var e=t&&t.__esModule?function(){return t.default}:function(){return t};return n.d(e,"a",e),e},n.o=function(t,e){return Object.prototype.hasOwnProperty.call(t,e)},n.p="/",n(n.s=25)}({25:function(t,e,n){t.exports=n("flnV")},flnV:function(t,e,n){"use strict";n.r(e);var r=n("o0o1"),o=n.n(r);function a(t,e,n,r,o,a,i){try{var c=t[a](i),u=c.value}catch(t){return void n(t)}c.done?e(u):Promise.resolve(u).then(r,o)}function i(t){return function(){var e=this,n=arguments;return new Promise((function(r,o){var i=t.apply(e,n);function c(t){a(i,r,o,c,u,"next",t)}function u(t){a(i,r,o,c,u,"throw",t)}c(void 0)}))}}function c(t,e){for(var n=0;n=0;--o){var a=this.tryEntries[o],i=a.completion;if("root"===a.tryLoc)return r("end");if(a.tryLoc<=this.prev){var c=n.call(a,"catchLoc"),u=n.call(a,"finallyLoc");if(c&&u){if(this.prev=0;--r){var o=this.tryEntries[r];if(o.tryLoc<=this.prev&&n.call(o,"finallyLoc")&&this.prev=0;--e){var n=this.tryEntries[e];if(n.finallyLoc===t)return this.complete(n.completion,n.afterLoc),x(n),l}},catch:function(t){for(var e=this.tryEntries.length-1;e>=0;--e){var n=this.tryEntries[e];if(n.tryLoc===t){var r=n.completion;if("throw"===r.type){var o=r.arg;x(n)}return o}}throw new Error("illegal catch attempt")},delegateYield:function(t,e,n){return this.delegate={iterator:L(t),resultName:e,nextLoc:n},"next"===this.method&&(this.arg=void 0),l}},t}(t.exports);try{regeneratorRuntime=r}catch(t){Function("r","regeneratorRuntime = r")(r)}},o0o1:function(t,e,n){t.exports=n("ls82")}}); \ No newline at end of file +!function(t){var e={};function n(r){if(e[r])return e[r].exports;var o=e[r]={i:r,l:!1,exports:{}};return t[r].call(o.exports,o,o.exports,n),o.l=!0,o.exports}n.m=t,n.c=e,n.d=function(t,e,r){n.o(t,e)||Object.defineProperty(t,e,{enumerable:!0,get:r})},n.r=function(t){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(t,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(t,"__esModule",{value:!0})},n.t=function(t,e){if(1&e&&(t=n(t)),8&e)return t;if(4&e&&"object"==typeof t&&t&&t.__esModule)return t;var r=Object.create(null);if(n.r(r),Object.defineProperty(r,"default",{enumerable:!0,value:t}),2&e&&"string"!=typeof t)for(var o in t)n.d(r,o,function(e){return t[e]}.bind(null,o));return r},n.n=function(t){var e=t&&t.__esModule?function(){return t.default}:function(){return t};return n.d(e,"a",e),e},n.o=function(t,e){return Object.prototype.hasOwnProperty.call(t,e)},n.p="/",n(n.s=25)}({25:function(t,e,n){t.exports=n("flnV")},flnV:function(t,e,n){"use strict";n.r(e);var r=n("o0o1"),o=n.n(r);function a(t,e,n,r,o,a,i){try{var c=t[a](i),u=c.value}catch(t){return void n(t)}c.done?e(u):Promise.resolve(u).then(r,o)}function i(t){return function(){var e=this,n=arguments;return new Promise((function(r,o){var i=t.apply(e,n);function c(t){a(i,r,o,c,u,"next",t)}function u(t){a(i,r,o,c,u,"throw",t)}c(void 0)}))}}function c(t,e){for(var n=0;n=0;--o){var a=this.tryEntries[o],i=a.completion;if("root"===a.tryLoc)return r("end");if(a.tryLoc<=this.prev){var c=n.call(a,"catchLoc"),u=n.call(a,"finallyLoc");if(c&&u){if(this.prev=0;--r){var o=this.tryEntries[r];if(o.tryLoc<=this.prev&&n.call(o,"finallyLoc")&&this.prev=0;--e){var n=this.tryEntries[e];if(n.finallyLoc===t)return this.complete(n.completion,n.afterLoc),E(n),l}},catch:function(t){for(var e=this.tryEntries.length-1;e>=0;--e){var n=this.tryEntries[e];if(n.tryLoc===t){var r=n.completion;if("throw"===r.type){var o=r.arg;E(n)}return o}}throw new Error("illegal catch attempt")},delegateYield:function(t,e,n){return this.delegate={iterator:L(t),resultName:e,nextLoc:n},"next"===this.method&&(this.arg=void 0),l}},t}(t.exports);try{regeneratorRuntime=r}catch(t){Function("r","regeneratorRuntime = r")(r)}},o0o1:function(t,e,n){t.exports=n("ls82")}}); \ No newline at end of file diff --git a/public/mix-manifest.json b/public/mix-manifest.json index 1d81c0bd04..d0bd4c9365 100755 --- a/public/mix-manifest.json +++ b/public/mix-manifest.json @@ -1,6 +1,6 @@ { - "/js/app.js": "/js/app.js?id=019831a9b0c0aff43c7f", - "/css/app.css": "/css/app.css?id=df1ea83ea621533ac837", + "/js/app.js": "/js/app.js?id=696e8203d5e8e7cf5ff5", + "/css/app.css": "/css/app.css?id=f7f7b35aa3f417a3eca3", "/js/clients/invoices/action-selectors.js": "/js/clients/invoices/action-selectors.js?id=a09bb529b8e1826f13b4", "/js/clients/invoices/payment.js": "/js/clients/invoices/payment.js?id=8ce8955ba775ea5f47d1", "/js/clients/linkify-urls.js": "/js/clients/linkify-urls.js?id=0dc8c34010d09195d2f7", @@ -17,7 +17,7 @@ "/js/clients/payments/mollie-credit-card.js": "/js/clients/payments/mollie-credit-card.js?id=73b66e88e2daabcd6549", "/js/clients/payments/paytrace-credit-card.js": "/js/clients/payments/paytrace-credit-card.js?id=c2b5f7831e1a46dd5fb2", "/js/clients/payments/razorpay-aio.js": "/js/clients/payments/razorpay-aio.js?id=817ab3b2b94ee37b14eb", - "/js/clients/payments/square-credit-card.js": "/js/clients/payments/square-credit-card.js?id=070c86b293b532c5a56c", + "/js/clients/payments/square-credit-card.js": "/js/clients/payments/square-credit-card.js?id=13ea3ff41d9417ef0140", "/js/clients/payments/stripe-ach.js": "/js/clients/payments/stripe-ach.js?id=81c2623fc1e5769b51c7", "/js/clients/payments/stripe-acss.js": "/js/clients/payments/stripe-acss.js?id=4a85142c085723991d28", "/js/clients/payments/stripe-alipay.js": "/js/clients/payments/stripe-alipay.js?id=665ddf663500767f1a17", @@ -36,6 +36,6 @@ "/js/clients/shared/multiple-downloads.js": "/js/clients/shared/multiple-downloads.js?id=5c35d28cf0a3286e7c45", "/js/clients/shared/pdf.js": "/js/clients/shared/pdf.js?id=2a99d83305ba87bfa6cc", "/js/clients/statements/view.js": "/js/clients/statements/view.js?id=ca3ec4cea0de824f3a36", - "/js/setup/setup.js": "/js/setup/setup.js?id=03ea88a737e59eb2bd5a", + "/js/setup/setup.js": "/js/setup/setup.js?id=8d454e7090f119552a6c", "/css/card-js.min.css": "/css/card-js.min.css?id=62afeb675235451543ad" } diff --git a/resources/js/clients/payments/square-credit-card.js b/resources/js/clients/payments/square-credit-card.js index 011a4c63e8..cceaacc5a7 100644 --- a/resources/js/clients/payments/square-credit-card.js +++ b/resources/js/clients/payments/square-credit-card.js @@ -43,57 +43,39 @@ class SquareCreditCard { } } - // , - // function(err,verification) { - // if (err == null) { - // console.log("no error"); - // console.log(verification); - // verificationToken = verificationResults.token; - - // } - - // console.log(err); - - // die("verify buyer"); - // } - - async completePaymentWithoutToken(e) { document.getElementById('errors').hidden = true; e.target.parentElement.disabled = true; let result = await this.card.tokenize(); - console.log("square token = " + result.token); - /* SCA */ - let verificationToken; + let verificationToken; - try { - const verificationDetails = { - amount: document.querySelector('meta[name=amount]').content, - billingContact: JSON.parse(document.querySelector('meta[name=square_contact]').content), - currencyCode: document.querySelector('meta[name=currencyCode]').content, - intent: 'CHARGE' - }; - - console.log(verificationDetails); + try { + const verificationDetails = { + amount: document.querySelector('meta[name=amount]').content, + billingContact: JSON.parse( + document.querySelector('meta[name=square_contact]').content + ), + currencyCode: document.querySelector('meta[name=currencyCode]') + .content, + intent: 'CHARGE', + }; const verificationResults = await this.payments.verifyBuyer( - result.token, - verificationDetails + result.token, + verificationDetails ); verificationToken = verificationResults.token; - } - catch(typeError){ - console.log(typeError); + } catch (typeError) { + e.target.parentElement.disabled = true } - console.debug('Verification Token:', verificationToken); - - document.querySelector('input[name="verificationToken"]').value = - verificationToken; + document.querySelector( + 'input[name="verificationToken"]' + ).value = verificationToken; if (result.status === 'OK') { document.getElementById('sourceId').value = result.token; @@ -125,23 +107,20 @@ class SquareCreditCard { /* SCA */ async verifyBuyer(token) { - - console.log("in verify buyer"); - const verificationDetails = { - amount: document.querySelector('meta[name=amount]').content, - billingContact: document.querySelector('meta[name=square_contact]').content, - currencyCode: document.querySelector('meta[name=currencyCode]').content, - intent: 'CHARGE' + amount: document.querySelector('meta[name=amount]').content, + billingContact: document.querySelector('meta[name=square_contact]') + .content, + currencyCode: document.querySelector('meta[name=currencyCode]') + .content, + intent: 'CHARGE', }; const verificationResults = await this.payments.verifyBuyer( - token, - verificationDetails + token, + verificationDetails ); - console.log(" verification toke = " + verificationResults.token); - return verificationResults.token; } diff --git a/resources/lang/en/texts.php b/resources/lang/en/texts.php index 441e738269..e730257a29 100644 --- a/resources/lang/en/texts.php +++ b/resources/lang/en/texts.php @@ -1400,7 +1400,7 @@ $LANG = array( 'more_options' => 'More options', 'credit_card' => 'Credit Card', 'bank_transfer' => 'Bank Transfer', - 'no_transaction_reference' => 'We did not recieve a payment transaction reference from the gateway.', + 'no_transaction_reference' => 'We did not receive a payment transaction reference from the gateway.', 'use_bank_on_file' => 'Use Bank on File', 'auto_bill_email_message' => 'This invoice will automatically be billed to the payment method on file on the due date.', 'bitcoin' => 'Bitcoin', @@ -4328,13 +4328,14 @@ $LANG = array( 'giropay_law' => 'By entering your Customer information (such as name, sort code and account number) you (the Customer) agree that this information is given voluntarily.', 'eps' => 'EPS', 'becs' => 'BECS Direct Debit', - 'becs_mandate' => 'By providing your bank account details, you agree to this Direct Debit Request and the Direct Debit Request service agreement, and authorise Stripe Payments Australia Pty Ltd ACN 160 180 343 Direct Debit User ID number 507156 (“Stripe”) to debit your account through the Bulk Electronic Clearing System (BECS) on behalf of :company (the “Merchant”) for any amounts separately communicated to you by the Merchant. You certify that you are either an account holder or an authorised signatory on the account listed above.', + 'becs_mandate' => 'By providing your bank account details, you agree to this Direct Debit Request and the Direct Debit Request service agreement, and authorise Stripe Payments Australia Pty Ltd ACN 160 180 343 Direct Debit User ID number 507156 (“Stripe”) to debit your account through the Bulk Electronic Clearing System (BECS) on behalf of :company (the “Merchant”) for any amounts separately communicated to you by the Merchant. You certify that you are either an account holder or an authorised signatory on the account listed above.', 'you_need_to_accept_the_terms_before_proceeding' => 'You need to accept the terms before proceeding.', 'direct_debit' => 'Direct Debit', 'clone_to_expense' => 'Clone to expense', 'checkout' => 'Checkout', 'acss' => 'Pre-authorized debit payments', - 'invalid_amount' => 'Invalid amount. Number/Decimal values only.' + 'invalid_amount' => 'Invalid amount. Number/Decimal values only.', + 'client_payment_failure_body' => 'Payment for Invoice :invoice for amount :amount failed.', ); return $LANG; diff --git a/resources/views/portal/ninja2020/gateways/square/credit_card/authorize.blade.php b/resources/views/portal/ninja2020/gateways/square/credit_card/authorize.blade.php index 5278f6c32e..b0eecc44cb 100644 --- a/resources/views/portal/ninja2020/gateways/square/credit_card/authorize.blade.php +++ b/resources/views/portal/ninja2020/gateways/square/credit_card/authorize.blade.php @@ -1,37 +1,7 @@ -@extends('portal.ninja2020.layout.payments', ['gateway_title' => ctrans('texts.payment_type_credit_card'), 'card_title' -=> ctrans('texts.payment_type_credit_card')]) - -@section('gateway_head') - - - -@endsection +@extends('portal.ninja2020.layout.payments', ['gateway_title' => ctrans('texts.credit_card'), 'card_title' => ctrans('texts.credit_card')]) @section('gateway_content') -
- @csrf - -
- - - @component('portal.ninja2020.components.general.card-element-single') -
-
- @endcomponent - - @component('portal.ninja2020.gateways.includes.pay_now', ['id' => 'authorize-card']) - {{ ctrans('texts.add_payment_method') }} + {{ __('texts.payment_method_cannot_be_preauthorized') }} @endcomponent @endsection - -@section('gateway_footer') - @if ($gateway->company_gateway->getConfigField('testMode')) - - @else - - @endif - - -@endsection diff --git a/resources/views/portal/ninja2020/gateways/stripe/becs/becs_debit.blade.php b/resources/views/portal/ninja2020/gateways/stripe/becs/becs_debit.blade.php index cd41c59d29..c808818e0c 100644 --- a/resources/views/portal/ninja2020/gateways/stripe/becs/becs_debit.blade.php +++ b/resources/views/portal/ninja2020/gateways/stripe/becs/becs_debit.blade.php @@ -12,17 +12,20 @@ -