diff --git a/VERSION.txt b/VERSION.txt index 25c801ef900e..d18e15c65c8b 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 052a477c2da2..afe61dd9e7f1 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 e6bf5ad711e6..221de5c61e75 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 b6c64a4d87d2..3f9d0503f0ca 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 2867541476d6..160c2246ad05 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 5ac5ed157a78..b83d472977f0 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 e0ab42bdc038..b612c6388aa5 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 675827b6cada..60abdf57cba8 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 c1be81d1053a..4f03269bf77e 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 817e48d6a3e4..e7e82f5a1187 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 e3a6e3c7dfa5..292712a1d738 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 d2832e83a046..e87cd4239977 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 bff131da8838..f30232650a3e 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 5512c4b1a986..9d84a7459502 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 0aab4e659cbd..464849ef70d8 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 c18101b2edae..df13ad8a5049 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 05f1c7392b86..9607bb24361f 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 1b52c9652726..1f60070b0acb 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 e7b5160b816a..d6c51bc4e7f1 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 e1b0e65fee77..397583bd6e43 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 25cd07e2cc4d..de109c54cbff 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 d360bdf1f819..6dfcf1a80d8a 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 317153749afa..cd00111dc892 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 9790a5ca8d2d..ca4c544d75b4 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 1cb3443c014f..d7937fac43ff 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 0c839d602cdd..2febf2c2f030 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 1242cc022b6a..e620db4d56ba 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 0507c38f6324..5b9207ad1205 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 a215b975ed41..9eef98e8fde7 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 d8a0eab78807..45df88520e27 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 3002d201ca3e..04e65996cbc2 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 20ac61b3cebe..185cfe758e9c 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 d608a62b89ca..1bb575d1bdd1 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 2ee33668b8d7..43b2a6a1ad4a 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 657cd4d5d76e..1eb45072aa5b 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 47867fa3b379..01696fd43178 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 8a9007a0e1c3..a0942c997202 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 93cc87f8cd85..6ae31452ba21 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 27c60e570b84..9624a329cf03 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 2f62dbc6ccf3..cf37b1d3f141 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 8dda9f5c692e..4765256cde03 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 162923cee0c9..45d0ab893a13 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 fbf874f9558b..8fe2f2e87a49 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 9a95391abbf5..0aab1c2e8c69 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 b486180550ca..626327f803a7 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 2b44eae951e8..0dfa6fa355eb 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 a265c17de77f..19c4c6da37ea 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 215fa587ec23..b6753383cd7d 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 1d81c0bd044c..d0bd4c936593 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 011a4c63e84f..cceaacc5a7f3 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 441e7382691c..e730257a298d 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 5278f6c32e44..b0eecc44cb5e 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 cd41c59d29e6..c808818e0cc8 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 @@ -