diff --git a/app/Console/Commands/CheckData.php b/app/Console/Commands/CheckData.php index 9452fd6edf4c..8b0505e9e346 100644 --- a/app/Console/Commands/CheckData.php +++ b/app/Console/Commands/CheckData.php @@ -78,6 +78,10 @@ class CheckData extends Command protected $isValid = true; + protected $wrong_paid_to_dates = 0; + + protected $wrong_balances = 0; + public function handle() { $database_connection = $this->option('database') ? $this->option('database') : 'Connected to Default DB'; @@ -305,10 +309,10 @@ class CheckData extends Command private function checkPaidToDates() { - $wrong_paid_to_dates = 0; + $this->wrong_paid_to_dates = 0; $credit_total_applied = 0; - Client::withTrashed()->where('is_deleted', 0)->cursor()->each(function ($client) use ($wrong_paid_to_dates, $credit_total_applied) { + Client::withTrashed()->where('is_deleted', 0)->cursor()->each(function ($client) use ($credit_total_applied) { $total_invoice_payments = 0; foreach ($client->invoices()->where('is_deleted', false)->where('status_id', '>', 1)->get() as $invoice) { @@ -330,7 +334,7 @@ class CheckData extends Command if (round($total_invoice_payments, 2) != round($client->paid_to_date, 2)) { - $wrong_paid_to_dates++; + $this->wrong_paid_to_dates++; $this->logMessage($client->present()->name.' id = # '.$client->id." - Paid to date does not match Client Paid To Date = {$client->paid_to_date} - Invoice Payments = {$total_invoice_payments}"); @@ -338,17 +342,16 @@ class CheckData extends Command } }); - $this->logMessage("{$wrong_paid_to_dates} clients with incorrect paid to dates"); + $this->logMessage("{$this->wrong_paid_to_dates} clients with incorrect paid to dates"); } private function checkInvoicePayments() { - $wrong_balances = 0; - $wrong_paid_to_dates = 0; + $this->wrong_balances = 0; - Client::cursor()->where('is_deleted', 0)->each(function ($client) use ($wrong_balances) { + Client::cursor()->where('is_deleted', 0)->each(function ($client) { - $client->invoices->where('is_deleted', false)->whereIn('status_id', '!=', Invoice::STATUS_DRAFT)->each(function ($invoice) use ($wrong_balances, $client) { + $client->invoices->where('is_deleted', false)->whereIn('status_id', '!=', Invoice::STATUS_DRAFT)->each(function ($invoice) use ($client) { $total_amount = $invoice->payments()->whereIn('status_id', [Payment::STATUS_COMPLETED, Payment:: STATUS_PENDING, Payment::STATUS_PARTIALLY_REFUNDED])->get()->sum('pivot.amount'); $total_refund = $invoice->payments()->get()->whereIn('status_id', [Payment::STATUS_COMPLETED, Payment:: STATUS_PENDING, Payment::STATUS_PARTIALLY_REFUNDED])->sum('pivot.refunded'); $total_credit = $invoice->credits()->get()->sum('amount'); @@ -357,7 +360,7 @@ class CheckData extends Command $calculated_paid_amount = $invoice->amount - $invoice->balance - $total_credit; if ((string)$total_paid != (string)($invoice->amount - $invoice->balance - $total_credit)) { - $wrong_balances++; + $this->wrong_balances++; $this->logMessage($client->present()->name.' - '.$client->id." - Total Amount = {$total_amount} != Calculated Total = {$calculated_paid_amount} - Total Refund = {$total_refund} Total credit = {$total_credit}"); @@ -367,13 +370,13 @@ class CheckData extends Command }); - $this->logMessage("{$wrong_balances} clients with incorrect invoice balances"); + $this->logMessage("{$this->wrong_balances} clients with incorrect invoice balances"); } private function checkClientBalances() { - $wrong_balances = 0; - $wrong_paid_to_dates = 0; + $this->wrong_balances = 0; + $this->wrong_paid_to_dates = 0; foreach (Client::cursor()->where('is_deleted', 0) as $client) { //$invoice_balance = $client->invoices->where('is_deleted', false)->where('status_id', '>', 1)->sum('balance'); @@ -387,14 +390,14 @@ class CheckData extends Command $ledger = CompanyLedger::where('client_id', $client->id)->orderBy('id', 'DESC')->first(); if ($ledger && (string) $invoice_balance != (string) $client->balance) { - $wrong_paid_to_dates++; + $this->wrong_paid_to_dates++; $this->logMessage($client->present()->name.' - '.$client->id." - calculated client balances do not match Invoice Balances = {$invoice_balance} - Client Balance = ".rtrim($client->balance, '0'). " Ledger balance = {$ledger->balance}"); $this->isValid = false; } } - $this->logMessage("{$wrong_paid_to_dates} clients with incorrect client balances"); + $this->logMessage("{$this->wrong_paid_to_dates} clients with incorrect client balances"); } //fix for client balances = @@ -406,8 +409,8 @@ class CheckData extends Command private function checkInvoiceBalances() { - $wrong_balances = 0; - $wrong_paid_to_dates = 0; + $this->wrong_balances = 0; + $this->wrong_paid_to_dates = 0; foreach (Client::where('is_deleted', 0)->cursor() as $client) { $invoice_balance = $client->invoices()->where('is_deleted', false)->where('status_id', '>', 1)->get()->sum('balance'); @@ -419,14 +422,14 @@ class CheckData extends Command $ledger = CompanyLedger::where('client_id', $client->id)->orderBy('id', 'DESC')->first(); if ($ledger && number_format($invoice_balance, 4) != number_format($client->balance, 4)) { - $wrong_balances++; + $this->wrong_balances++; $this->logMessage("# {$client->id} " . $client->present()->name.' - '.$client->number." - Balance Failure - Invoice Balances = {$invoice_balance} Client Balance = {$client->balance} Ledger Balance = {$ledger->balance}"); $this->isValid = false; } } - $this->logMessage("{$wrong_balances} clients with incorrect balances"); + $this->logMessage("{$this->wrong_balances} clients with incorrect balances"); } private function checkLogoFiles() diff --git a/app/DataMapper/PaymentMethodMeta.php b/app/DataMapper/PaymentMethodMeta.php index 882ecd8cb828..b970d6af3b51 100644 --- a/app/DataMapper/PaymentMethodMeta.php +++ b/app/DataMapper/PaymentMethodMeta.php @@ -27,4 +27,7 @@ class PaymentMethodMeta /** @var int */ public $type; + + /** @var string */ + public $state; } diff --git a/app/Http/Controllers/Auth/LoginController.php b/app/Http/Controllers/Auth/LoginController.php index 7b07822e3644..ec7899ab6f0e 100644 --- a/app/Http/Controllers/Auth/LoginController.php +++ b/app/Http/Controllers/Auth/LoginController.php @@ -179,8 +179,6 @@ class LoginController extends BaseController $user = $this->guard()->user(); - event(new UserLoggedIn($user, $user->account->default_company, Ninja::eventVars($user->id))); - //2FA if($user->google_2fa_secret && $request->has('one_time_password')) { @@ -226,6 +224,8 @@ class LoginController extends BaseController if(Ninja::isHosted() && !$cu->first()->is_owner && !$user->account->isEnterpriseClient()) return response()->json(['message' => 'Pro / Free accounts only the owner can log in. Please upgrade'], 403); + event(new UserLoggedIn($user, $user->account->default_company, Ninja::eventVars($user->id))); + return $this->timeConstrainedResponse($cu); diff --git a/app/Http/Controllers/BaseController.php b/app/Http/Controllers/BaseController.php index 4e081b33979a..1d7382e01e0a 100644 --- a/app/Http/Controllers/BaseController.php +++ b/app/Http/Controllers/BaseController.php @@ -379,8 +379,6 @@ class BaseController extends Controller 'company.designs'=> function ($query) use ($created_at, $user) { $query->where('created_at', '>=', $created_at)->with('company'); - if(!$user->isAdmin()) - $query->where('designs.user_id', $user->id); }, 'company.documents'=> function ($query) use ($created_at, $user) { $query->where('created_at', '>=', $created_at); @@ -388,22 +386,14 @@ class BaseController extends Controller 'company.groups' => function ($query) use ($created_at, $user) { $query->where('created_at', '>=', $created_at); - if(!$user->isAdmin()) - $query->where('group_settings.user_id', $user->id); }, 'company.payment_terms'=> function ($query) use ($created_at, $user) { $query->where('created_at', '>=', $created_at); - if(!$user->isAdmin()) - $query->where('payment_terms.user_id', $user->id); - }, 'company.tax_rates' => function ($query) use ($created_at, $user) { $query->where('created_at', '>=', $created_at); - if(!$user->isAdmin()) - $query->where('tax_rates.user_id', $user->id); - }, 'company.activities'=> function ($query) use($user) { @@ -519,8 +509,6 @@ class BaseController extends Controller 'company.payment_terms'=> function ($query) use ($created_at, $user) { $query->where('created_at', '>=', $created_at); - if(!$user->isAdmin()) - $query->where('payment_terms.user_id', $user->id); }, 'company.products' => function ($query) use ($created_at, $user) { @@ -561,9 +549,6 @@ class BaseController extends Controller 'company.tax_rates' => function ($query) use ($created_at, $user) { $query->where('created_at', '>=', $created_at); - if(!$user->isAdmin()) - $query->where('tax_rates.user_id', $user->id); - }, 'company.vendors'=> function ($query) use ($created_at, $user) { $query->where('created_at', '>=', $created_at)->with('contacts', 'documents'); @@ -575,9 +560,6 @@ class BaseController extends Controller 'company.expense_categories'=> function ($query) use ($created_at, $user) { $query->where('created_at', '>=', $created_at); - if(!$user->isAdmin()) - $query->where('expense_categories.user_id', $user->id); - }, 'company.task_statuses'=> function ($query) use ($created_at, $user) { $query->where('created_at', '>=', $created_at); diff --git a/app/Http/Controllers/ClientPortal/InvoiceController.php b/app/Http/Controllers/ClientPortal/InvoiceController.php index fd32045565c5..720508bd2bc1 100644 --- a/app/Http/Controllers/ClientPortal/InvoiceController.php +++ b/app/Http/Controllers/ClientPortal/InvoiceController.php @@ -168,7 +168,8 @@ class InvoiceController extends Controller if ($invoices->count() == 1) { $invoice = $invoices->first(); $invitation = $invoice->invitations->first(); - $file = $invoice->pdf_file_path($invitation); + //$file = $invoice->pdf_file_path($invitation); + $file = $invoice->service()->getInvoicePdf(auth()->user()); return response()->download($file, basename($file), ['Cache-Control:' => 'no-cache'])->deleteFileAfterSend(true);; } diff --git a/app/Http/Controllers/ClientPortal/PaymentMethodController.php b/app/Http/Controllers/ClientPortal/PaymentMethodController.php index d922c27d428e..150a3230549d 100644 --- a/app/Http/Controllers/ClientPortal/PaymentMethodController.php +++ b/app/Http/Controllers/ClientPortal/PaymentMethodController.php @@ -51,7 +51,8 @@ class PaymentMethodController extends Controller $gateway = $this->getClientGateway(); $data['gateway'] = $gateway; - + $data['client'] = auth()->user()->client; + return $gateway ->driver(auth()->user()->client) ->setPaymentMethod($request->query('method')) @@ -91,9 +92,9 @@ class PaymentMethodController extends Controller public function verify(ClientGatewayToken $payment_method) { - $gateway = $this->getClientGateway(); - - return $gateway +// $gateway = $this->getClientGateway(); + + return $payment_method->gateway ->driver(auth()->user()->client) ->setPaymentMethod(request()->query('method')) ->verificationView($payment_method); @@ -101,9 +102,9 @@ class PaymentMethodController extends Controller public function processVerification(Request $request, ClientGatewaytoken $payment_method) { - $gateway = $this->getClientGateway(); + // $gateway = $this->getClientGateway(); - return $gateway + return $payment_method->gateway ->driver(auth()->user()->client) ->setPaymentMethod(request()->query('method')) ->processVerification($request, $payment_method); @@ -117,9 +118,9 @@ class PaymentMethodController extends Controller */ public function destroy(ClientGatewayToken $payment_method) { - $gateway = $this->getClientGateway(); + // $gateway = $this->getClientGateway(); - $gateway + $payment_method->gateway ->driver(auth()->user()->client) ->setPaymentMethod(request()->query('method')) ->detach($payment_method); diff --git a/app/Http/Controllers/ClientPortal/QuoteController.php b/app/Http/Controllers/ClientPortal/QuoteController.php index e9b7649935d6..f26b2cefa46b 100644 --- a/app/Http/Controllers/ClientPortal/QuoteController.php +++ b/app/Http/Controllers/ClientPortal/QuoteController.php @@ -7,7 +7,7 @@ * * @copyright Copyright (c) 2021. Invoice Ninja LLC (https://invoiceninja.com) * - * @license https://opensource.org/licenses/AAL + * @license https://www.elastic.co/licensing/elastic-license */ namespace App\Http\Controllers\ClientPortal; diff --git a/app/Http/Controllers/WePayController.php b/app/Http/Controllers/WePayController.php new file mode 100644 index 000000000000..b68bc0b72cfd --- /dev/null +++ b/app/Http/Controllers/WePayController.php @@ -0,0 +1,55 @@ +firstOrFail(); + + $data['user_id'] = $user->id; + $data['company'] = $company; + + $wepay_driver = new WePayPaymentDriver(new CompanyGateway, null, null); + + return $wepay_driver->setup($data); + + } + + public function finished() + { + return render('gateways.wepay.signup.finished'); + } +} diff --git a/app/Http/Livewire/WepaySignup.php b/app/Http/Livewire/WepaySignup.php new file mode 100644 index 000000000000..60590831f052 --- /dev/null +++ b/app/Http/Livewire/WepaySignup.php @@ -0,0 +1,200 @@ + ['required'], + 'last_name' => ['required'], + 'email' => ['required', 'email'], + 'company_name' => ['required'], + 'country' => ['required'], + 'ach' => ['sometimes'], + 'wepay_payment_tos_agree' => ['accepted'], + 'debit_cards' => ['sometimes'], + ]; + + public function mount() + { + MultiDB::setDb($this->company->db); + + $user = User::find($this->user_id); + $this->company = Company::where('company_key', $this->company->company_key)->first(); + + $this->fill([ + 'wepay_payment_tos_agree' => '', + 'ach' => '', + 'country' => 'US', + 'user' => $user, + 'first_name' => $user->first_name, + 'last_name' => $user->last_name, + 'email' => $user->email, + 'company_name' => $this->company->present()->name(), + 'saved' => ctrans('texts.confirm'), + 'terms' => ''.ctrans('texts.terms_of_service').'', + 'privacy_policy' => ''.ctrans('texts.privacy_policy').'', + ]); + } + + public function render() + { + return render('gateways.wepay.signup.wepay-signup'); + } + + public function submit() + { + $data = $this->validate($this->rules); + + //need to create or get a new WePay CompanyGateway + $cg = CompanyGateway::where('gateway_key', '8fdeed552015b3c7b44ed6c8ebd9e992') + ->where('company_id', $this->company->id) + ->firstOrNew(); + + if(!$cg->id) { + + $fees_and_limits = new \stdClass; + $fees_and_limits->{GatewayType::CREDIT_CARD} = new FeesAndLimits; + $fees_and_limits->{GatewayType::BANK_TRANSFER} = new FeesAndLimits; + + $cg = CompanyGatewayFactory::create($this->company->id, $this->user->id); + $cg->gateway_key = '8fdeed552015b3c7b44ed6c8ebd9e992'; + $cg->require_cvv = false; + $cg->require_billing_address = false; + $cg->require_shipping_address = false; + $cg->update_details = false; + $cg->config = encrypt(config('ninja.testvars.checkout')); + $cg->fees_and_limits = $fees_and_limits; + $cg->save(); + + } + + $this->saved = ctrans('texts.processing'); + + $wepay_driver = new WePayPaymentDriver($cg, null, null); + + $wepay = $wepay_driver->init()->wepay; + + $user_details = [ + 'client_id' => config('ninja.wepay.client_id'), + 'client_secret' => config('ninja.wepay.client_secret'), + 'email' => $data['email'], + 'first_name' => $data['first_name'], + 'last_name' => $data['last_name'], + 'original_ip' => request()->ip(), + 'original_device' => request()->server('HTTP_USER_AGENT'), + 'tos_acceptance_time' => time(), + 'redirect_uri' => route('wepay.finished'), + 'scope' => 'manage_accounts,collect_payments,view_user,preapprove_payments,send_money', + ]; + + $wepay_user = $wepay->request('user/register/', $user_details); + + $access_token = $wepay_user->access_token; + + $access_token_expires = $wepay_user->expires_in ? (time() + $wepay_user->expires_in) : null; + + $wepay = new WePay($access_token); + + $account_details = [ + 'name' => $data['company_name'], + 'description' => ctrans('texts.wepay_account_description'), + 'theme_object' => json_decode('{"name":"Invoice Ninja","primary_color":"0b4d78","secondary_color":"0b4d78","background_color":"f8f8f8","button_color":"33b753"}'), + 'callback_uri' => route('payment_webhook', ['company_key' => $this->company->company_key, 'company_gateway_id' => $cg->hashed_id]), + 'rbits' => $this->company->rBits(), + 'country' => $data['country'], + ]; + + if ($data['country'] == 'CA') { + $account_details['currencies'] = ['CAD']; + $account_details['country_options'] = ['debit_opt_in' => boolval($data['debit_cards'])]; + } elseif ($data['country'] == 'GB') { + $account_details['currencies'] = ['GBP']; + } + + $wepay_account = $wepay->request('account/create/', $account_details); + + try { + $wepay->request('user/send_confirmation/', []); + $confirmation_required = true; + } catch (\WePayException $ex) { + if ($ex->getMessage() == 'This access_token is already approved.') { + $confirmation_required = false; + } else { + request()->session()->flash('message', $ex->getMessage()); + } + + nlog("failed in try catch "); + nlog($ex->getMessage()); + } + + $config = [ + 'userId' => $wepay_user->user_id, + 'accessToken' => $access_token, + 'tokenType' => $wepay_user->token_type, + 'tokenExpires' => $access_token_expires, + 'accountId' => $wepay_account->account_id, + 'state' => $wepay_account->state, + 'testMode' => config('ninja.wepay.environment') == 'staging', + 'country' => $data['country'], + ]; + + $cg->setConfig($config); + $cg->save(); + + if ($confirmation_required) { + request()->session()->flash('message', trans('texts.created_wepay_confirmation_required')); + } else { + $update_uri = $wepay->request('/account/get_update_uri', [ + 'account_id' => $wepay_account->account_id, + 'redirect_uri' => config('ninja.app_url'), + ]); + + return redirect($update_uri->uri); + } + + + return redirect()->to('/wepay/finished'); + } + +} diff --git a/app/Http/Requests/ClientPortal/Credits/ShowCreditsRequest.php b/app/Http/Requests/ClientPortal/Credits/ShowCreditsRequest.php index a3b10de1fbd0..2cff1b9014fb 100644 --- a/app/Http/Requests/ClientPortal/Credits/ShowCreditsRequest.php +++ b/app/Http/Requests/ClientPortal/Credits/ShowCreditsRequest.php @@ -7,7 +7,7 @@ * * @copyright Copyright (c) 2021. Invoice Ninja LLC (https://invoiceninja.com) * - * @license https://opensource.org/licenses/AAL + * @license https://www.elastic.co/licensing/elastic-license */ namespace App\Http\Requests\ClientPortal\Credits; diff --git a/app/Http/Requests/ClientPortal/Invoices/ProcessInvoicesInBulkRequest.php b/app/Http/Requests/ClientPortal/Invoices/ProcessInvoicesInBulkRequest.php index 512874a3806a..e3d9ae96b56c 100644 --- a/app/Http/Requests/ClientPortal/Invoices/ProcessInvoicesInBulkRequest.php +++ b/app/Http/Requests/ClientPortal/Invoices/ProcessInvoicesInBulkRequest.php @@ -7,7 +7,7 @@ * * @copyright Copyright (c) 2021. Invoice Ninja LLC (https://invoiceninja.com) * - * @license https://opensource.org/licenses/AAL + * @license https://www.elastic.co/licensing/elastic-license */ namespace App\Http\Requests\ClientPortal\Invoices; diff --git a/app/Http/Requests/ClientPortal/Invoices/ShowInvoicesRequest.php b/app/Http/Requests/ClientPortal/Invoices/ShowInvoicesRequest.php index 8a815d95549c..cf8b13f7a617 100644 --- a/app/Http/Requests/ClientPortal/Invoices/ShowInvoicesRequest.php +++ b/app/Http/Requests/ClientPortal/Invoices/ShowInvoicesRequest.php @@ -7,7 +7,7 @@ * * @copyright Copyright (c) 2021. Invoice Ninja LLC (https://invoiceninja.com) * - * @license https://opensource.org/licenses/AAL + * @license https://www.elastic.co/licensing/elastic-license */ namespace App\Http\Requests\ClientPortal\Invoices; diff --git a/app/Http/Requests/ClientPortal/Quotes/ProcessQuotesInBulkRequest.php b/app/Http/Requests/ClientPortal/Quotes/ProcessQuotesInBulkRequest.php index bfa740e02ff5..0c312549230d 100644 --- a/app/Http/Requests/ClientPortal/Quotes/ProcessQuotesInBulkRequest.php +++ b/app/Http/Requests/ClientPortal/Quotes/ProcessQuotesInBulkRequest.php @@ -7,7 +7,7 @@ * * @copyright Copyright (c) 2021. Invoice Ninja LLC (https://invoiceninja.com) * - * @license https://opensource.org/licenses/AAL + * @license https://www.elastic.co/licensing/elastic-license */ namespace App\Http\Requests\ClientPortal\Quotes; diff --git a/app/Http/Requests/ClientPortal/Quotes/ShowQuoteRequest.php b/app/Http/Requests/ClientPortal/Quotes/ShowQuoteRequest.php index 1690a6c5c8b6..72fe286b064c 100644 --- a/app/Http/Requests/ClientPortal/Quotes/ShowQuoteRequest.php +++ b/app/Http/Requests/ClientPortal/Quotes/ShowQuoteRequest.php @@ -7,7 +7,7 @@ * * @copyright Copyright (c) 2021. Invoice Ninja LLC (https://invoiceninja.com) * - * @license https://opensource.org/licenses/AAL + * @license https://www.elastic.co/licensing/elastic-license */ namespace App\Http\Requests\ClientPortal\Quotes; diff --git a/app/Http/Requests/ClientPortal/Quotes/ShowQuotesRequest.php b/app/Http/Requests/ClientPortal/Quotes/ShowQuotesRequest.php index 6087131e07bd..6e92f66e7694 100644 --- a/app/Http/Requests/ClientPortal/Quotes/ShowQuotesRequest.php +++ b/app/Http/Requests/ClientPortal/Quotes/ShowQuotesRequest.php @@ -7,7 +7,7 @@ * * @copyright Copyright (c) 2021. Invoice Ninja LLC (https://invoiceninja.com) * - * @license https://opensource.org/licenses/AAL + * @license https://www.elastic.co/licensing/elastic-license */ namespace App\Http\Requests\ClientPortal\Quotes; diff --git a/app/Http/Requests/ClientPortal/RecurringInvoices/ShowRecurringInvoicesRequest.php b/app/Http/Requests/ClientPortal/RecurringInvoices/ShowRecurringInvoicesRequest.php index 75b336fef462..eb785596bf1e 100644 --- a/app/Http/Requests/ClientPortal/RecurringInvoices/ShowRecurringInvoicesRequest.php +++ b/app/Http/Requests/ClientPortal/RecurringInvoices/ShowRecurringInvoicesRequest.php @@ -7,7 +7,7 @@ * * @copyright Copyright (c) 2021. Invoice Ninja LLC (https://invoiceninja.com) * - * @license https://opensource.org/licenses/AAL + * @license https://www.elastic.co/licensing/elastic-license */ namespace App\Http\Requests\ClientPortal\RecurringInvoices; diff --git a/app/Http/Requests/ClientPortal/Tasks/ShowTasksRequest.php b/app/Http/Requests/ClientPortal/Tasks/ShowTasksRequest.php index 9217c7e9a8bb..91c9366d2d4e 100644 --- a/app/Http/Requests/ClientPortal/Tasks/ShowTasksRequest.php +++ b/app/Http/Requests/ClientPortal/Tasks/ShowTasksRequest.php @@ -7,7 +7,7 @@ * * @copyright Copyright (c) 2021. Invoice Ninja LLC (https://invoiceninja.com) * - * @license https://opensource.org/licenses/AAL + * @license https://www.elastic.co/licensing/elastic-license */ namespace App\Http\Requests\ClientPortal\Tasks; diff --git a/app/Jobs/Company/CompanyExport.php b/app/Jobs/Company/CompanyExport.php index 71a0d5d7de5d..504c0dc599ac 100644 --- a/app/Jobs/Company/CompanyExport.php +++ b/app/Jobs/Company/CompanyExport.php @@ -484,7 +484,7 @@ class CompanyExport implements ShouldQueue if(!Storage::disk(config('filesystems.default'))->exists($path)) Storage::disk(config('filesystems.default'))->makeDirectory($path, 0775); - + $zip_path = public_path('storage/backups/'.$file_name); $zip = new \ZipArchive(); diff --git a/app/Jobs/Util/Import.php b/app/Jobs/Util/Import.php index 9a489e4d0524..4f45ba9a5959 100644 --- a/app/Jobs/Util/Import.php +++ b/app/Jobs/Util/Import.php @@ -214,12 +214,12 @@ class Import implements ShouldQueue // if(Ninja::isHosted() && array_key_exists('ninja_tokens', $data)) $this->processNinjaTokens($data['ninja_tokens']); + $this->fixData(); + $this->setInitialCompanyLedgerBalances(); // $this->fixClientBalances(); $check_data = CheckCompanyData::dispatchNow($this->company, md5(time())); - - try{ Mail::to($this->user->email, $this->user->name()) @@ -247,6 +247,41 @@ class Import implements ShouldQueue unlink($this->file_path); } + private function fixData() + { + + $this->company->clients()->withTrashed()->where('is_deleted', 0)->cursor()->each(function ($client) { + $total_invoice_payments = 0; + $credit_total_applied = 0; + + foreach ($client->invoices()->where('is_deleted', false)->where('status_id', '>', 1)->get() as $invoice) { + + $total_amount = $invoice->payments()->where('is_deleted', false)->whereIn('status_id', [Payment::STATUS_COMPLETED, Payment:: STATUS_PENDING, Payment::STATUS_PARTIALLY_REFUNDED, Payment::STATUS_REFUNDED])->get()->sum('pivot.amount'); + $total_refund = $invoice->payments()->where('is_deleted', false)->whereIn('status_id', [Payment::STATUS_COMPLETED, Payment:: STATUS_PENDING, Payment::STATUS_PARTIALLY_REFUNDED, Payment::STATUS_REFUNDED])->get()->sum('pivot.refunded'); + + $total_invoice_payments += ($total_amount - $total_refund); + } + + // 10/02/21 + foreach ($client->payments as $payment) { + $credit_total_applied += $payment->paymentables()->where('paymentable_type', App\Models\Credit::class)->get()->sum(\DB::raw('amount')); + } + + if ($credit_total_applied < 0) { + $total_invoice_payments += $credit_total_applied; + } + + + if (round($total_invoice_payments, 2) != round($client->paid_to_date, 2)) { + + $client->paid_to_date = $total_invoice_payments; + $client->save(); + + } + }); + + } + private function setInitialCompanyLedgerBalances() { Client::cursor()->each(function ($client) { @@ -1175,10 +1210,14 @@ class Import implements ShouldQueue if($try_quote && array_key_exists('quotes', $this->ids) ) { - $quote_id = $this->transformId('quotes', $resource['invoice_id']); - $entity = Quote::where('id', $quote_id)->withTrashed()->first(); - $exception = $e; - + try{ + $quote_id = $this->transformId('quotes', $resource['invoice_id']); + $entity = Quote::where('id', $quote_id)->withTrashed()->first(); + } + catch(\Exception $e){ + nlog("i couldn't find the quote document {$resource['invoice_id']}, perhaps it is a quote?"); + nlog($e->getMessage()); + } } if(!$entity) @@ -1642,7 +1681,6 @@ class Import implements ShouldQueue public function exec($method, $url, $data) { - nlog($this->token); $client = new \GuzzleHttp\Client(['headers' => [ diff --git a/app/Mail/MigrationCompleted.php b/app/Mail/MigrationCompleted.php index 9181c1f26838..b7d979f906a4 100644 --- a/app/Mail/MigrationCompleted.php +++ b/app/Mail/MigrationCompleted.php @@ -37,7 +37,8 @@ class MigrationCompleted extends Mailable $data['company'] = $this->company->fresh(); $data['whitelabel'] = $this->company->account->isPaid() ? true : false; $data['check_data'] = $this->check_data; - + $data['logo'] = $this->company->present()->logo(); + $result = $this->from(config('mail.from.address'), config('mail.from.name')) ->view('email.import.completed', $data); diff --git a/app/Mail/SupportMessageSent.php b/app/Mail/SupportMessageSent.php index e8301dfd1d56..7fde45a34e7d 100644 --- a/app/Mail/SupportMessageSent.php +++ b/app/Mail/SupportMessageSent.php @@ -52,12 +52,15 @@ class SupportMessageSent extends Mailable $account = auth()->user()->account; - $plan = $account->plan ?: 'Self Hosted'; + $plan = $account->plan ?: 'Free Self Hosted'; $company = auth()->user()->company(); $user = auth()->user(); - $subject = "Customer MSG {$user->present()->name} - [{$plan} - DB:{$company->db}]"; + if(Ninja::isHosted()) + $subject = "Hosted {$user->present()->name} - [{$plan} - DB:{$company->db}]"; + else + $subject = "Self Host {$user->present()->name} - [{$plan} - DB:{$company->db}]"; return $this->from(config('mail.from.address'), config('mail.from.name')) ->replyTo($user->email, $user->present()->name()) diff --git a/app/Models/Company.php b/app/Models/Company.php index fdb387403f58..bb139f042660 100644 --- a/app/Models/Company.php +++ b/app/Models/Company.php @@ -468,4 +468,39 @@ class Company extends BaseModel { return $this->slack_webhook_url; } + + public function rBits() + { + $user = $this->owner(); + $data = []; + + $data[] = $this->createRBit('business_name', 'user', ['business_name' => $this->present()->name()]); + $data[] = $this->createRBit('industry_code', 'user', ['industry_detail' => $this->industry ? $this->industry->name : '']); + $data[] = $this->createRBit('comment', 'partner_database', ['comment_text' => 'Logo image not present']); + $data[] = $this->createRBit('business_description', 'user', ['business_description' => $this->present()->size()]); + + $data[] = $this->createRBit('person', 'user', ['name' => $user->present()->getFullName()]); + $data[] = $this->createRBit('email', 'user', ['email' => $user->email]); + $data[] = $this->createRBit('phone', 'user', ['phone' => $user->phone]); + $data[] = $this->createRBit('website_uri', 'user', ['uri' => $this->settings->website]); + $data[] = $this->createRBit('external_account', 'partner_database', ['is_partner_account' => 'yes', 'account_type' => 'Invoice Ninja', 'create_time' => time()]); + + return $data; + } + + + private function createRBit($type, $source, $properties) + { + $data = new \stdClass; + $data->receive_time = time(); + $data->type = $type; + $data->source = $source; + $data->properties = new \stdClass; + + foreach ($properties as $key => $val) { + $data->properties->$key = $val; + } + + return $data; + } } diff --git a/app/Models/Gateway.php b/app/Models/Gateway.php index ceb0fc17d8ba..fa95888fb63d 100644 --- a/app/Models/Gateway.php +++ b/app/Models/Gateway.php @@ -95,6 +95,10 @@ class Gateway extends StaticModel case 39: return [GatewayType::CREDIT_CARD => ['refund' => true, 'token_billing' => true]]; //Checkout break; + case 49: + return [GatewayType::CREDIT_CARD => ['refund' => true, 'token_billing' => true], + GatewayType::BANK_TRANSFER => ['refund' => true, 'token_billing' => true]]; //WePay + break; case 50: return [ GatewayType::CREDIT_CARD => ['refund' => true, 'token_billing' => true], diff --git a/app/Models/Payment.php b/app/Models/Payment.php index 62ed6f56c585..531c1f0eb8f2 100644 --- a/app/Models/Payment.php +++ b/app/Models/Payment.php @@ -59,6 +59,8 @@ class Payment extends BaseModel 'date', 'transaction_reference', 'number', + 'exchange_currency_id', + 'exchange_rate', // 'is_manual', 'private_notes', 'custom_value1', diff --git a/app/Models/Presenters/CompanyPresenter.php b/app/Models/Presenters/CompanyPresenter.php index 2ae54399ca29..f5035e32bbf6 100644 --- a/app/Models/Presenters/CompanyPresenter.php +++ b/app/Models/Presenters/CompanyPresenter.php @@ -106,4 +106,8 @@ class CompanyPresenter extends EntityPresenter "SPC\n0200\n1\n{$user_iban}\nK\n{$this->name}\n{$settings->address1}\n{$settings->postal_code} {$settings->city}\n\n\nCH\n\n\n\n\n\n\n\n{$balance_due_raw}\n{$client_currency}\n\n\n\n\n\n\n\nNON\n\n{$invoice_number}\nEPD\n"; } + public function size() + { + return $this->entity->size ? $this->entity->size->name : ''; + } } diff --git a/app/Models/Presenters/InvoicePresenter.php b/app/Models/Presenters/InvoicePresenter.php index 2ed8ee40ee88..91ccd12c0b84 100644 --- a/app/Models/Presenters/InvoicePresenter.php +++ b/app/Models/Presenters/InvoicePresenter.php @@ -41,4 +41,35 @@ class InvoicePresenter extends EntityPresenter return ''; } } + + public function rBits() + { + $properties = new \stdClass(); + $properties->terms_text = $this->terms; + $properties->note = $this->public_notes; + $properties->itemized_receipt = []; + + foreach ($this->line_items as $item) { + $properties->itemized_receipt[] = $this->itemRbits($item); + } + + $data = new stdClass(); + $data->receive_time = time(); + $data->type = 'transaction_details'; + $data->source = 'user'; + $data->properties = $properties; + + return [$data]; + } + + public function itemRbits($item) + { + $data = new stdClass(); + $data->description = $item->notes; + $data->item_price = floatval($item->cost); + $data->quantity = floatval($item->quantity); + $data->amount = round($data->item_price * $data->quantity, 2); + + return $data; + } } diff --git a/app/Models/Presenters/UserPresenter.php b/app/Models/Presenters/UserPresenter.php index 52aded296c55..dd5f079db5ac 100644 --- a/app/Models/Presenters/UserPresenter.php +++ b/app/Models/Presenters/UserPresenter.php @@ -26,4 +26,28 @@ class UserPresenter extends EntityPresenter return $first_name.' '.$last_name; } + + + public function getDisplayName() + { + if ($this->getFullName()) { + return $this->getFullName(); + } elseif ($this->entity->email) { + return $this->entity->email; + } else { + return ctrans('texts.guest'); + } + } + + /** + * @return string + */ + public function getFullName() + { + if ($this->entity->first_name || $this->entity->last_name) { + return $this->entity->first_name.' '.$this->entity->last_name; + } else { + return ''; + } + } } diff --git a/app/Models/SystemLog.php b/app/Models/SystemLog.php index 40e1df580492..ae05a07aec22 100644 --- a/app/Models/SystemLog.php +++ b/app/Models/SystemLog.php @@ -66,6 +66,8 @@ class SystemLog extends Model const TYPE_AUTHORIZE = 305; const TYPE_CUSTOM = 306; const TYPE_BRAINTREE = 307; + const TYPE_WEPAY = 309; + const TYPE_QUOTA_EXCEEDED = 400; const TYPE_UPSTREAM_FAILURE = 401; diff --git a/app/PaymentDrivers/BaseDriver.php b/app/PaymentDrivers/BaseDriver.php index 4404bb2d86e1..a95c4e26ce23 100644 --- a/app/PaymentDrivers/BaseDriver.php +++ b/app/PaymentDrivers/BaseDriver.php @@ -160,6 +160,17 @@ class BaseDriver extends AbstractPaymentDriver { } + /** + * Detaches a payment method from the gateway + * + * @param ClientGatewayToken $token The gateway token + * @return bool boolean response + */ + public function detach(ClientGatewayToken $token) + { + return true; + } + /** * Set the inbound request payment method type for access. * diff --git a/app/PaymentDrivers/Stripe/ACH.php b/app/PaymentDrivers/Stripe/ACH.php index 38046c92f373..fa02cd32e0a9 100644 --- a/app/PaymentDrivers/Stripe/ACH.php +++ b/app/PaymentDrivers/Stripe/ACH.php @@ -167,7 +167,7 @@ class ACH return $this->processUnsuccessfulPayment($state); } catch (Exception $e) { if ($e instanceof CardException) { - return redirect()->route('client.payment_methods.verification', ['id' => ClientGatewayToken::first()->hashed_id, 'method' => GatewayType::BANK_TRANSFER]); + return redirect()->route('client.payment_methods.verification', ['payment_method' => ClientGatewayToken::first()->hashed_id, 'method' => GatewayType::BANK_TRANSFER]); } throw new PaymentFailed($e->getMessage(), $e->getCode()); diff --git a/app/PaymentDrivers/Stripe/Connect/Account.php b/app/PaymentDrivers/Stripe/Connect/Account.php index e924ae77fb51..20517887bf15 100644 --- a/app/PaymentDrivers/Stripe/Connect/Account.php +++ b/app/PaymentDrivers/Stripe/Connect/Account.php @@ -47,164 +47,5 @@ class Account ]); } -/*** If this is a new account (ie there is no account_id in company_gateways.config, the we need to create an account as below. - -/// -// $stripe = new \Stripe\StripeClient( -// 'sk_test_4eC39HqLyjWDarjtT1zdp7dc' -// ); -// $stripe->accounts->create([ -// 'type' => 'standard', -// 'country' => 'US', //if we have it - inject -// 'email' => 'jenny.rosen@example.com', //if we have it - inject -// ]); -/// - - -//response - -//******************* We should store the 'id' as a property in the config with the key `account_id` - -/** - * { - "id": "acct_1032D82eZvKYlo2C", - "object": "account", - "business_profile": { - "mcc": null, - "name": "Stripe.com", - "product_description": null, - "support_address": null, - "support_email": null, - "support_phone": null, - "support_url": null, - "url": null - }, - "capabilities": { - "card_payments": "active", - "transfers": "active" - }, - "charges_enabled": false, - "country": "US", - "default_currency": "usd", - "details_submitted": false, - "email": "site@stripe.com", - "metadata": {}, - "payouts_enabled": false, - "requirements": { - "current_deadline": null, - "currently_due": [ - "business_profile.product_description", - "business_profile.support_phone", - "business_profile.url", - "external_account", - "tos_acceptance.date", - "tos_acceptance.ip" - ], - "disabled_reason": "requirements.past_due", - "errors": [], - "eventually_due": [ - "business_profile.product_description", - "business_profile.support_phone", - "business_profile.url", - "external_account", - "tos_acceptance.date", - "tos_acceptance.ip" - ], - "past_due": [], - "pending_verification": [] - }, - "settings": { - "bacs_debit_payments": {}, - "branding": { - "icon": null, - "logo": null, - "primary_color": null, - "secondary_color": null - }, - "card_issuing": { - "tos_acceptance": { - "date": null, - "ip": null - } - }, - "card_payments": { - "decline_on": { - "avs_failure": true, - "cvc_failure": false - }, - "statement_descriptor_prefix": null - }, - "dashboard": { - "display_name": "Stripe.com", - "timezone": "US/Pacific" - }, - "payments": { - "statement_descriptor": null, - "statement_descriptor_kana": null, - "statement_descriptor_kanji": null - }, - "payouts": { - "debit_negative_balances": true, - "schedule": { - "delay_days": 7, - "interval": "daily" - }, - "statement_descriptor": null - }, - "sepa_debit_payments": {} - }, - "type": "standard" -} - - */ - - -//At this stage we have an account, so we need to generate the account link -//then create the account link - -// now we start the stripe onboarding flow -// https://stripe.com/docs/api/account_links/object -// -/** - * $stripe = new \Stripe\StripeClient( - 'sk_test_4eC39HqLyjWDarjtT1zdp7dc' -); -$stripe->accountLinks->create([ - 'account' => 'acct_1032D82eZvKYlo2C', - 'refresh_url' => 'https://example.com/reauth', - 'return_url' => 'https://example.com/return', - 'type' => 'account_onboarding', -]); - */ - -/** - * Response = - * { - "object": "account_link", - "created": 1618869558, - "expires_at": 1618869858, - "url": "https://connect.stripe.com/setup/s/9BhFaPdfseRF" -} - */ - -//The users account may not be active yet, we need to pull the account back and check for the property `charges_enabled` -// -// - - -// What next? -// -// Now we need to create a superclass of the StripePaymentDriver, i believe the only thing we need to change is the way we initialize the gateway.. - -/** - * -\Stripe\Stripe::setApiKey("{{PLATFORM_SECRET_KEY}}"); <--- platform secret key = Invoice Ninja secret key -\Stripe\Customer::create( - ["email" => "person@example.edu"], - ["stripe_account" => "{{CONNECTED_STRIPE_ACCOUNT_ID}}"] <------ company_gateway.config.account_id -); - - - */ } diff --git a/app/PaymentDrivers/WePay/ACH.php b/app/PaymentDrivers/WePay/ACH.php new file mode 100644 index 000000000000..02dc8aa3f7d1 --- /dev/null +++ b/app/PaymentDrivers/WePay/ACH.php @@ -0,0 +1,265 @@ +wepay_payment_driver = $wepay_payment_driver; + } + + public function authorizeView($data) + { + $data['gateway'] = $this->wepay_payment_driver; + + return render('gateways.wepay.authorize.bank_transfer', $data); + } + + + public function authorizeResponse($request) + { + //https://developer.wepay.com/api/api-calls/credit_card#authorize + $data = $request->all(); + // authorize the credit card + + nlog($data); + /* + '_token' => '1Fk5CRj34up5ntKPvrFyMIAJhDdUNF3boqT3iIN3', + 'company_gateway_id' => '39', + 'payment_method_id' => '1', + 'gateway_response' => NULL, + 'is_default' => NULL, + 'credit_card_id' => '180642154638', + 'q' => '/client/payment_methods', + 'method' => '1', + */ + + $response = $this->wepay_payment_driver->wepay->request('payment_bank/persist', [ + 'client_id' => config('ninja.wepay.client_id'), + 'client_secret' => config('ninja.wepay.client_secret'), + 'payment_bank_id' => (int)$data['bank_account_id'], + ]); + + // display the response + // nlog($response); + + if(in_array($response->state, ['new', 'pending', 'authorized'])){ + + $this->storePaymentMethod($response, GatewayType::BANK_TRANSFER); + + return redirect()->route('client.payment_methods.index'); + + } + + throw new PaymentFailed("There was a problem adding this payment method.", 400); + + /* + { + "payment_bank_id": 12345, + "bank_name": "Wells Fargo", + "account_last_four": "6789", + "state": "authorized" + } + + state options: new, pending, authorized, disabled. + */ + + } + + +/* If the bank transfer token is PENDING - we need to verify!! */ +// + + public function verificationView(ClientGatewayToken $token) + { + $this->wepay_payment_driver->init(); + + $data = [ + 'token' => $token, + 'gateway' => $this->wepay_payment_driver, + ]; + + return render('gateways.wepay.authorize.verify', $data); + } + + /** + { + "client_id": 1234, + "client_secret": "b1fc2f68-4d1f-4a", + "payment_bank_id": 12345, + "type": "microdeposits", + "microdeposits": [ + 8, + 12 + ] + } + */ + public function processVerification(Request $request, ClientGatewayToken $token) + { + $transactions = $request->input('transactions'); + + $transformed_transactions = []; + + foreach($transactions as $transaction) + $transformed_transactions[] = (int)$transaction; + + try { + + $response = $this->wepay_payment_driver->wepay->request('payment_bank/verify', [ + 'client_id' => config('ninja.wepay.client_id'), + 'client_secret' => config('ninja.wepay.client_secret'), + 'payment_bank_id' => $token->token, + 'type' => 'microdeposits', + 'microdeposits' => $transformed_transactions, + ]); + + } + catch(\Exception $e){ + + return redirect()->route('client.payment_methods.verification', ['payment_method' => $token->hashed_id, 'method' => GatewayType::BANK_TRANSFER]) + ->with('error', $e->getMessage()); + + } + /* + { + "payment_bank_id": 12345, + "bank_name": "Wells Fargo", + "account_last_four": "6789", + "state": "authorized" + } + */ + nlog($response); + + //$meta = $token->meta; + if($response->state == "authorized") + { + $meta = $token->meta; + $meta->state = $response->state; + $token->meta; + $token->save(); + + return redirect()->route('client.payment_methods.index'); + + } + else{ + + return redirect()->route('client.payment_methods.verification', ['payment_method' => $token->hashed_id, 'method' => GatewayType::BANK_TRANSFER]) + ->with('error', ctrans('texts.verification_failed')); + } + } + +/////////////////////////////////////////////////////////////////////////////////////// + public function paymentView(array $data) + { + + $data['gateway'] = $this->wepay_payment_driver; + $data['currency'] = $this->wepay_payment_driver->client->getCurrencyCode(); + $data['payment_method_id'] = GatewayType::BANK_TRANSFER; + $data['amount'] = $data['total']['amount_with_fee']; + + return render('gateways.wepay.bank_transfer', $data); + } + + + public function paymentResponse($request) + { + nlog($request->all()); + + $token = ClientGatewayToken::find($this->decodePrimaryKey($request->input('source'))); + $token_meta = $token->meta; + + if($token_meta->state != "authorized") + return redirect()->route('client.payment_methods.verification', ['payment_method' => $token->hashed_id, 'method' => GatewayType::BANK_TRANSFER]); + + $response = $this->wepay_payment_driver->wepay->request('checkout/create', array( + // 'callback_uri' => route('payment_webhook', ['company_key' => $this->wepay_payment_driver->company_gateway->company->company_key, 'company_gateway_id' => $this->wepay_payment_driver->company_gateway->hashed_id]), + 'unique_id' => Str::random(40), + 'account_id' => $this->wepay_payment_driver->company_gateway->getConfigField('accountId'), + 'amount' => $this->wepay_payment_driver->payment_hash->data->amount_with_fee, + 'currency' => $this->wepay_payment_driver->client->getCurrencyCode(), + 'short_description' => 'A vacation home rental', + 'type' => 'goods', + 'payment_method' => array( + 'type' => 'payment_bank', + 'payment_bank' => array( + 'id' => $token->token + ) + ) + )); + + /* Merge all data and store in the payment hash*/ + $state = [ + 'server_response' => $response, + 'payment_hash' => $request->payment_hash, + ]; + + $state = array_merge($state, $request->all()); + $this->wepay_payment_driver->payment_hash->data = array_merge((array) $this->wepay_payment_driver->payment_hash->data, $state); + $this->wepay_payment_driver->payment_hash->save(); + + if(in_array($response->state, ['authorized', 'captured'])){ + //success + nlog("success"); + $payment_status = $response->state == 'authorized' ? Payment::STATUS_COMPLETED : Payment::STATUS_PENDING; + + return $this->processSuccessfulPayment($response, $payment_status, GatewayType::BANK_TRANSFER); + } + + if(in_array($response->state, ['released', 'cancelled', 'failed', 'expired'])){ + //some type of failure + nlog("failure"); + + $payment_status = $response->state == 'cancelled' ? Payment::STATUS_CANCELLED : Payment::STATUS_FAILED; + + $this->processUnSuccessfulPayment($response, $payment_status); + } + + } + + private function storePaymentMethod($response, $payment_method_id) + { + + $payment_meta = new \stdClass; + $payment_meta->exp_month = (string) ''; + $payment_meta->exp_year = (string) ''; + $payment_meta->brand = (string) $response->bank_name; + $payment_meta->last4 = (string) $response->account_last_four; + $payment_meta->type = GatewayType::BANK_TRANSFER; + $payment_meta->state = $response->state; + + $data = [ + 'payment_meta' => $payment_meta, + 'token' => $response->payment_bank_id, + 'payment_method_id' => $payment_method_id, + ]; + + $this->wepay_payment_driver->storeGatewayToken($data); + + } +} diff --git a/app/PaymentDrivers/WePay/CreditCard.php b/app/PaymentDrivers/WePay/CreditCard.php new file mode 100644 index 000000000000..9fa7b0ac0f24 --- /dev/null +++ b/app/PaymentDrivers/WePay/CreditCard.php @@ -0,0 +1,281 @@ +wepay_payment_driver = $wepay_payment_driver; + } + + public function authorizeView($data) + { + $data['gateway'] = $this->wepay_payment_driver; + + return render('gateways.wepay.authorize.authorize', $data); + } + + public function authorizeResponse($request) + { + //https://developer.wepay.com/api/api-calls/credit_card#authorize + $data = $request->all(); + // authorize the credit card + + nlog($data); + /* + '_token' => '1Fk5CRj34up5ntKPvrFyMIAJhDdUNF3boqT3iIN3', + 'company_gateway_id' => '39', + 'payment_method_id' => '1', + 'gateway_response' => NULL, + 'is_default' => NULL, + 'credit_card_id' => '180642154638', + 'q' => '/client/payment_methods', + 'method' => '1', + */ + + $response = $this->wepay_payment_driver->wepay->request('credit_card/authorize', array( + 'client_id' => config('ninja.wepay.client_id'), + 'client_secret' => config('ninja.wepay.client_secret'), + 'credit_card_id' => (int)$data['credit_card_id'], + )); + + // display the response + // nlog($response); + + if(in_array($response->state, ['new', 'authorized'])){ + + $this->storePaymentMethod($response, GatewayType::CREDIT_CARD); + + return redirect()->route('client.payment_methods.index'); + } + + throw new PaymentFailed("There was a problem adding this payment method.", 400); + + /* + [credit_card_id] => 348084962473 + [credit_card_name] => Visa xxxxxx4018 + [state] => authorized + [user_name] => Joey Diaz + [email] => user@example.com + [create_time] => 1623798172 + [expiration_month] => 10 + [expiration_year] => 2023 + [last_four] => 4018 + [input_source] => card_keyed + [virtual_terminal_mode] => none + [card_on_file] => + [recurring] => + [cvv_provided] => 1 + [auto_update] => + */ + + } + + + public function paymentView(array $data) + { + $data['gateway'] = $this->wepay_payment_driver; + $data['description'] = ctrans('texts.invoices') . ': ' . collect($data['invoices'])->pluck('invoice_number'); + + return render('gateways.wepay.credit_card.pay', $data); + } + + public function paymentResponse(PaymentResponseRequest $request) + { + nlog("payment response"); + + //it could be an existing token or a new credit_card_id that needs to be converted into a wepay token + if($request->has('credit_card_id') && $request->input('credit_card_id')) + { + nlog("authorize the card first!"); + + $response = $this->wepay_payment_driver->wepay->request('credit_card/authorize', array( + // 'callback_uri' => route('payment_webhook', ['company_key' => $this->wepay_payment_driver->company_gateway->company->company_key, 'company_gateway_id' => $this->wepay_payment_driver->company_gateway->hashed_id]), + 'client_id' => config('ninja.wepay.client_id'), + 'client_secret' => config('ninja.wepay.client_secret'), + 'credit_card_id' => (int)$request->input('credit_card_id'), + )); + + $credit_card_id = (int)$response->credit_card_id; + + if(in_array($response->state, ['new', 'authorized']) && boolval($request->input('store_card'))){ + + $this->storePaymentMethod($response, GatewayType::CREDIT_CARD); + + } + + } + else { + + $credit_card_id = (int)$request->input('token'); + + } + + // USD, CAD, and GBP. + nlog($request->all()); + // charge the credit card + $response = $this->wepay_payment_driver->wepay->request('checkout/create', array( + // 'callback_uri' => route('payment_webhook', ['company_key' => $this->wepay_payment_driver->company_gateway->company->company_key, 'company_gateway_id' => $this->wepay_payment_driver->company_gateway->hashed_id]), + 'unique_id' => Str::random(40), + 'account_id' => $this->wepay_payment_driver->company_gateway->getConfigField('accountId'), + 'amount' => $this->wepay_payment_driver->payment_hash->data->amount_with_fee, + 'currency' => $this->wepay_payment_driver->client->getCurrencyCode(), + 'short_description' => 'A vacation home rental', + 'type' => 'goods', + 'payment_method' => array( + 'type' => 'credit_card', + 'credit_card' => array( + 'id' => $credit_card_id + ) + ) + )); + + /* Merge all data and store in the payment hash*/ + $state = [ + 'server_response' => $response, + 'payment_hash' => $request->payment_hash, + ]; + + $state = array_merge($state, $request->all()); + $this->wepay_payment_driver->payment_hash->data = array_merge((array) $this->wepay_payment_driver->payment_hash->data, $state); + $this->wepay_payment_driver->payment_hash->save(); + + + if(in_array($response->state, ['authorized', 'captured'])){ + //success + nlog("success"); + $payment_status = $response->state == 'authorized' ? Payment::STATUS_COMPLETED : Payment::STATUS_PENDING; + + return $this->processSuccessfulPayment($response, $payment_status, GatewayType::CREDIT_CARD); + } + + if(in_array($response->state, ['released', 'cancelled', 'failed', 'expired'])){ + //some type of failure + nlog("failure"); + + $payment_status = $response->state == 'cancelled' ? Payment::STATUS_CANCELLED : Payment::STATUS_FAILED; + + $this->processUnSuccessfulPayment($response, $payment_status); + } + + } + +/* +new The checkout was created by the application. This state typically indicates that checkouts created in WePay's hosted checkout flow are waiting for the payer to submit their information. +authorized The payer entered their payment info and confirmed the payment on WePay. WePay has successfully charged the card. +captured The payment has been reserved from the payer. +released The payment has been credited to the payee account. Note that the released state may be active although there are active partial refunds or partial chargebacks. +cancelled The payment has been cancelled by the payer, payee, or application. +refunded The payment was captured and then refunded by the payer, payee, or application. The payment has been debited from the payee account. +charged back The payment has been charged back by the payer and the payment has been debited from the payee account. +failed The payment has failed. +expired Checkouts expire if they remain in the new state for more than 30 minutes (e.g., they have been abandoned). + */ + +/* +https://developer.wepay.com/api/api-calls/checkout +{ + "checkout_id": 649945633, + "account_id": 1548718026, + "type": "donation", + "short_description": "test checkout", + "currency": "USD", + "amount": 20, + "state": "authorized", + "soft_descriptor": "WPY*Wolverine", + "auto_release": true, + "create_time": 1463589958, + "gross": 20.88, + "reference_id": null, + "callback_uri": null, + "long_description": null, + "delivery_type": null, + "initiated_by": "merchant", + "in_review": false, + "fee": { + "app_fee": 0, + "processing_fee": 0.88, + "fee_payer": "payer" + }, + "chargeback": { + "amount_charged_back": 0, + "dispute_uri": null + }, + "refund": { + "amount_refunded": 0, + "refund_reason": null + }, + "payment_method": { + "type": "credit_card", + "credit_card": { + "id": 1684847614, + "data": { + "emv_receipt": null, + "signature_url": null + }, + "auto_release": false + } + }, + "hosted_checkout": null, + "payer": { + "email": "test@example.com", + "name": "Mr Smith", + "home_address": null + }, + "npo_information": null, + "payment_error": null +} + */ + + + private function storePaymentMethod($response, $payment_method_id) + { +nlog("storing card"); + $payment_meta = new \stdClass; + $payment_meta->exp_month = (string) $response->expiration_month; + $payment_meta->exp_year = (string) $response->expiration_year; + $payment_meta->brand = (string) $response->credit_card_name; + $payment_meta->last4 = (string) $response->last_four; + $payment_meta->type = GatewayType::CREDIT_CARD; + + $data = [ + 'payment_meta' => $payment_meta, + 'token' => $response->credit_card_id, + 'payment_method_id' => $payment_method_id, + ]; + + $this->wepay_payment_driver->storeGatewayToken($data); + + } + + + +} + diff --git a/app/PaymentDrivers/WePay/Setup.php b/app/PaymentDrivers/WePay/Setup.php new file mode 100644 index 000000000000..3498751bf5f6 --- /dev/null +++ b/app/PaymentDrivers/WePay/Setup.php @@ -0,0 +1,37 @@ +wepay = $wepay; + } + + public function boot($data) + { + /* + 'user_id', + 'company', + */ + + return render('gateways.wepay.signup.index', $data); + } + +} \ No newline at end of file diff --git a/app/PaymentDrivers/WePay/WePayCommon.php b/app/PaymentDrivers/WePay/WePayCommon.php new file mode 100644 index 000000000000..791ab7b31274 --- /dev/null +++ b/app/PaymentDrivers/WePay/WePayCommon.php @@ -0,0 +1,76 @@ + PaymentType::CREDIT_CARD_OTHER, + 'amount' => $response->amount, + 'transaction_reference' => $response->checkout_id, + 'gateway_type_id' => $gateway_type, + ]; + + $payment = $this->wepay_payment_driver->createPayment($data, $payment_status); + + SystemLogger::dispatch( + ['response' => $this->wepay_payment_driver->payment_hash->data->server_response, 'data' => $data], + SystemLog::CATEGORY_GATEWAY_RESPONSE, + SystemLog::EVENT_GATEWAY_SUCCESS, + SystemLog::TYPE_WEPAY, + $this->wepay_payment_driver->client, + $this->wepay_payment_driver->client->company, + ); + + return redirect()->route('client.payments.show', ['payment' => $this->wepay_payment_driver->encodePrimaryKey($payment->id)]); + } + + private function processUnSuccessfulPayment($response, $payment_status) + { + PaymentFailureMailer::dispatch($this->wepay_payment_driver->client, $response->state, $this->wepay_payment_driver->client->company, $response->amount); + + PaymentFailureMailer::dispatch( + $this->wepay_payment_driver->client, + $response, + $this->wepay_payment_driver->client->company, + $response->gross + ); + + $message = [ + 'server_response' => $response, + 'data' => $this->wepay_payment_driver->payment_hash->data, + ]; + + SystemLogger::dispatch( + $message, + SystemLog::CATEGORY_GATEWAY_RESPONSE, + SystemLog::EVENT_GATEWAY_FAILURE, + SystemLog::TYPE_WEPAY, + $this->wepay_payment_driver->client, + $this->wepay_payment_driver->client->company, + ); + + throw new PaymentFailed('Failed to process the payment.', 500); + } + +} diff --git a/app/PaymentDrivers/WePayPaymentDriver.php b/app/PaymentDrivers/WePayPaymentDriver.php new file mode 100644 index 000000000000..acffce11362b --- /dev/null +++ b/app/PaymentDrivers/WePayPaymentDriver.php @@ -0,0 +1,357 @@ + CreditCard::class, + GatewayType::BANK_TRANSFER => ACH::class, + ]; + + const SYSTEM_LOG_TYPE = SystemLog::TYPE_WEPAY; + + public function init() + { + + if (WePay::getEnvironment() == 'none') { + + if(config('ninja.wepay.environment') == 'staging') + WePay::useStaging(config('ninja.wepay.client_id'), config('ninja.wepay.client_secret')); + else + WePay::useProduction(config('ninja.wepay.client_id'), config('ninja.wepay.client_secret')); + + } + + if ($this->company_gateway) + $this->wepay = new WePay($this->company_gateway->getConfigField('accessToken')); + else + $this->wepay = new WePay(null); + + return $this; + + } + + /** + * Return the gateway types that have been enabled + * + * @return array + */ + public function gatewayTypes(): array + { + $types = []; + + if($this->company_gateway->fees_and_limits->{GatewayType::BANK_TRANSFER}->is_enabled) + $types[] = GatewayType::CREDIT_CARD; + + if($this->company_gateway->fees_and_limits->{GatewayType::BANK_TRANSFER}->is_enabled) + $types[] = GatewayType::BANK_TRANSFER; + + return $types; + } + + /** + * Setup the gateway + * + * @param array $data user_id + company + * @return view + */ + public function setup(array $data) + { + return (new Setup($this))->boot($data); + } + + /** + * Set the payment method + * + * @param int $payment_method_id Alias of GatewayType + */ + public function setPaymentMethod($payment_method_id) + { + $class = self::$methods[$payment_method_id]; + $this->payment_method = new $class($this); + return $this; + } + + public function authorizeView(array $data) + { + $this->init(); + + $data['gateway'] = $this->wepay; + $client = $data['client']; + $contact = $client->primary_contact()->first() ? $client->primary_contact()->first() : $lient->contacts->first(); + $data['contact'] = $contact; + + return $this->payment_method->authorizeView($data); //this is your custom implementation from here + } + + public function authorizeResponse($request) + { + $this->init(); + + return $this->payment_method->authorizeResponse($request); //this is your custom implementation from here + } + + public function verificationView(ClientGatewayToken $cgt) + { + $this->init(); + + return $this->payment_method->verificationView($cgt); + } + + public function processVerification(Request $request, ClientGatewayToken $cgt) + { + $this->init(); + + return $this->payment_method->processVerification($request, $cgt); + } + + public function processPaymentView(array $data) + { + $this->init(); + + return $this->payment_method->paymentView($data); //this is your custom implementation from here + } + + public function processPaymentResponse($request) + { + $this->init(); + + return $this->payment_method->paymentResponse($request); //this is your custom implementation from here + } + + public function tokenBilling(ClientGatewayToken $cgt, PaymentHash $payment_hash) + { + return $this->payment_method->yourTokenBillingImplmentation(); //this is your custom implementation from here + } + + public function processWebhookRequest(PaymentWebhookRequest $request, Payment $payment = null) + { + $this->init(); + + $input = $request->all(); + + $accountId = $this->company_gateway->getConfigField('accountId'); + + foreach (array_keys($input) as $key) { + if ('_id' == substr($key, -3)) { + $objectType = substr($key, 0, -3); + $objectId = $input[$key]; + break; + } + } + + if (! isset($objectType)) { + throw new Exception('Could not find object id parameter'); + } + + if ($objectType == 'credit_card') { + $payment_method = ClientGatewayToken::where('token', $objectId)->first(); + + if (! $paymentMethod) + throw new \Exception('Unknown payment method'); + + $source = $this->wepay->request('credit_card', array( + 'client_id' => config('ninja.wepay.client_id'), + 'client_secret' => config('ninja.wepay.client_secret'), + 'credit_card_id' => (int)$objectId, + )); + + if ($source->state == 'deleted') { + $payment_method->delete(); + } else { + //$this->paymentService->convertPaymentMethodFromWePay($source, null, $paymentMethod)->save(); + } + + return 'Processed successfully'; + } elseif ($objectType == 'account') { + if ($accountId != $objectId) { + throw new \Exception('Unknown account'); + } + + $wepayAccount = $this->wepay->request('account', array( + 'account_id' => (int)$objectId, + )); + + if ($wepayAccount->state == 'deleted') { + $this->company_gateway->delete(); + } else { + $config->state = $wepayAccount->state; + $this->company_gateway->setConfig($config); + $this->company_gateway->save(); + } + + return ['message' => 'Processed successfully']; + } elseif ($objectType == 'checkout') { + $payment = Payment::where('company_id', $this->company_gateway->company_id) + ->where('transaction_reference', '=', $objectId) + ->first(); + + if (! $payment) { + throw new Exception('Unknown payment'); + } + + if ($payment->is_deleted) { + throw new \Exception('Payment is deleted'); + } + + $checkout = $this->wepay->request('checkout', array( + 'checkout_id' => intval($objectId), + )); + + if ($checkout->state == 'captured') { + $payment->status_id = Payment::STATUS_COMPLETED; + $payment->save(); + } elseif ($checkout->state == 'cancelled') { + $payment->service()->deletePayment()->save(); + } elseif ($checkout->state == 'failed') { + $payment->status_id = Payment::STATUS_FAILED; + $payment->save(); + } + + return 'Processed successfully'; + } else { + return 'Ignoring event'; + } + + + + return true; + } + + public function refund(Payment $payment, $amount, $return_client_response = false) + { + + $this->init(); + + $response = $this->wepay->request('checkout/refund', array( + 'checkout_id' => $payment->transaction_reference, + 'refund_reason' => 'Refund', + 'amount' => $amount + )); + + + return [ + 'transaction_reference' => $response->checkout_id, + 'transaction_response' => json_encode($response), + 'success' => $response->state == 'refunded' ? true : false, + 'description' => 'refund', + 'code' => 0, + ]; + + } + + public function detach(ClientGatewayToken $token) + { + /*Bank accounts cannot be deleted - only CC*/ + if($token->gateway_type_id == 2) + return true; + + $this->init(); + + $response = $this->wepay->request('/credit_card/delete', [ + 'client_id' => config('ninja.wepay.client_id'), + 'client_secret' => config('ninja.wepay.client_secret'), + 'credit_card_id' => intval($token->token), + ]); + + if ($response->state == 'deleted') { + return true; + } else { + throw new \Exception(trans('texts.failed_remove_payment_method')); + } + } + + + public function getClientRequiredFields(): array + { + $fields = [ + ['name' => 'client_postal_code', 'label' => ctrans('texts.postal_code'), 'type' => 'text', 'validation' => 'required'], + ['name' => 'contact_email', 'label' => ctrans('texts.email'), 'type' => 'text', 'validation' => 'required'], + ]; + + if ($this->company_gateway->require_client_name) { + $fields[] = ['name' => 'client_name', 'label' => ctrans('texts.client_name'), 'type' => 'text', 'validation' => 'required']; + } + + if ($this->company_gateway->require_client_phone) { + $fields[] = ['name' => 'client_phone', 'label' => ctrans('texts.client_phone'), 'type' => 'tel', 'validation' => 'required']; + } + + if ($this->company_gateway->require_contact_name) { + $fields[] = ['name' => 'contact_first_name', 'label' => ctrans('texts.first_name'), 'type' => 'text', 'validation' => 'required']; + $fields[] = ['name' => 'contact_last_name', 'label' => ctrans('texts.last_name'), 'type' => 'text', 'validation' => 'required']; + } + + if ($this->company_gateway->require_contact_email) { + $fields[] = ['name' => 'contact_email', 'label' => ctrans('texts.email'), 'type' => 'text', 'validation' => 'required,email:rfc']; + } + + if ($this->company_gateway->require_billing_address) { + $fields[] = ['name' => 'client_address_line_1', 'label' => ctrans('texts.address1'), 'type' => 'text', 'validation' => 'required']; +// $fields[] = ['name' => 'client_address_line_2', 'label' => ctrans('texts.address2'), 'type' => 'text', 'validation' => 'nullable']; + $fields[] = ['name' => 'client_city', 'label' => ctrans('texts.city'), 'type' => 'text', 'validation' => 'required']; + $fields[] = ['name' => 'client_state', 'label' => ctrans('texts.state'), 'type' => 'text', 'validation' => 'required']; + $fields[] = ['name' => 'client_country_id', 'label' => ctrans('texts.country'), 'type' => 'text', 'validation' => 'required']; + } + + if ($this->company_gateway->require_shipping_address) { + $fields[] = ['name' => 'client_shipping_address_line_1', 'label' => ctrans('texts.shipping_address1'), 'type' => 'text', 'validation' => 'required']; +// $fields[] = ['name' => 'client_shipping_address_line_2', 'label' => ctrans('texts.shipping_address2'), 'type' => 'text', 'validation' => 'sometimes']; + $fields[] = ['name' => 'client_shipping_city', 'label' => ctrans('texts.shipping_city'), 'type' => 'text', 'validation' => 'required']; + $fields[] = ['name' => 'client_shipping_state', 'label' => ctrans('texts.shipping_state'), 'type' => 'text', 'validation' => 'required']; + $fields[] = ['name' => 'client_shipping_postal_code', 'label' => ctrans('texts.shipping_postal_code'), 'type' => 'text', 'validation' => 'required']; + $fields[] = ['name' => 'client_shipping_country_id', 'label' => ctrans('texts.shipping_country'), 'type' => 'text', 'validation' => 'required']; + } + + return $fields; + } + + + + + + + + +} diff --git a/app/Repositories/BaseRepository.php b/app/Repositories/BaseRepository.php index 46df209e4ea5..51ba726ee75b 100644 --- a/app/Repositories/BaseRepository.php +++ b/app/Repositories/BaseRepository.php @@ -330,8 +330,6 @@ class BaseRepository $model = $model->calc()->getCredit(); - // $model->ledger()->updateCreditBalance(-1*($state['finished_amount'] - $state['starting_amount'])); - if (! $model->design_id) $model->design_id = $this->decodePrimaryKey($client->getSetting('credit_design_id')); @@ -339,12 +337,18 @@ class BaseRepository if ($model instanceof Quote) { + if (! $model->design_id) + $model->design_id = $this->decodePrimaryKey($client->getSetting('quote_design_id')); + $model = $model->calc()->getQuote(); } if ($model instanceof RecurringInvoice) { + if (! $model->design_id) + $model->design_id = $this->decodePrimaryKey($client->getSetting('invoice_design_id')); + $model = $model->calc()->getRecurringInvoice(); } diff --git a/app/Repositories/PaymentRepository.php b/app/Repositories/PaymentRepository.php index 3b456ae1e2cd..e0d881682316 100644 --- a/app/Repositories/PaymentRepository.php +++ b/app/Repositories/PaymentRepository.php @@ -90,6 +90,7 @@ class PaymentRepository extends BaseRepository { $client->service()->updatePaidToDate($_credit_totals)->save(); } } + } /*Fill the payment*/ @@ -184,6 +185,10 @@ class PaymentRepository extends BaseRepository { */ private function processExchangeRates($data, $payment) { + + if(array_key_exists('exchange_rate', $data) && isset($data['exchange_rate'])) + return $payment; + $client = Client::find($data['client_id']); $client_currency = $client->getSetting('currency_id'); diff --git a/app/Utils/Statics.php b/app/Utils/Statics.php index cbdd9dc78a65..513f88366d03 100644 --- a/app/Utils/Statics.php +++ b/app/Utils/Statics.php @@ -70,27 +70,27 @@ class Statics $data = []; foreach (config('ninja.cached_tables') as $name => $class) { + + if (!Cache::has($name)) { - // if (!Cache::has($name)) { - - // // check that the table exists in case the migration is pending - // if (!Schema::hasTable((new $class())->getTable())) { - // continue; - // } - // if ($name == 'payment_terms') { - // $orderBy = 'num_days'; - // } elseif ($name == 'fonts') { - // $orderBy = 'sort_order'; - // } elseif (in_array($name, ['currencies', 'industries', 'languages', 'countries', 'banks'])) { - // $orderBy = 'name'; - // } else { - // $orderBy = 'id'; - // } - // $tableData = $class::orderBy($orderBy)->get(); - // if ($tableData->count()) { - // Cache::forever($name, $tableData); - // } - // } + // check that the table exists in case the migration is pending + if (!Schema::hasTable((new $class())->getTable())) { + continue; + } + if ($name == 'payment_terms') { + $orderBy = 'num_days'; + } elseif ($name == 'fonts') { + $orderBy = 'sort_order'; + } elseif (in_array($name, ['currencies', 'industries', 'languages', 'countries', 'banks'])) { + $orderBy = 'name'; + } else { + $orderBy = 'id'; + } + $tableData = $class::orderBy($orderBy)->get(); + if ($tableData->count()) { + Cache::forever($name, $tableData); + } + } $data[$name] = Cache::get($name); } diff --git a/composer.json b/composer.json index 8d7e80559057..aac5045c9a80 100644 --- a/composer.json +++ b/composer.json @@ -72,6 +72,7 @@ "turbo124/beacon": "^1.0", "turbo124/laravel-gmail": "^5", "webpatser/laravel-countries": "dev-master#75992ad", + "wepay/php-sdk": "^0.3", "wildbit/swiftmailer-postmark": "^3.3" }, "require-dev": { diff --git a/composer.lock b/composer.lock index b1790ead062c..8f7e0b5d340e 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "551d077c3d25c2a962f0c2c270618582", + "content-hash": "013b0357f14c1782315168bc42234b34", "packages": [ { "name": "asm/php-ansible", @@ -159,16 +159,16 @@ }, { "name": "aws/aws-sdk-php", - "version": "3.183.10", + "version": "3.184.2", "source": { "type": "git", "url": "https://github.com/aws/aws-sdk-php.git", - "reference": "3995354f4791f8ca85f5208325cef9065e471f3b" + "reference": "78fe691ab466fecf195209672f6c00c5d4ed219a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/aws/aws-sdk-php/zipball/3995354f4791f8ca85f5208325cef9065e471f3b", - "reference": "3995354f4791f8ca85f5208325cef9065e471f3b", + "url": "https://api.github.com/repos/aws/aws-sdk-php/zipball/78fe691ab466fecf195209672f6c00c5d4ed219a", + "reference": "78fe691ab466fecf195209672f6c00c5d4ed219a", "shasum": "" }, "require": { @@ -243,9 +243,9 @@ "support": { "forum": "https://forums.aws.amazon.com/forum.jspa?forumID=80", "issues": "https://github.com/aws/aws-sdk-php/issues", - "source": "https://github.com/aws/aws-sdk-php/tree/3.183.10" + "source": "https://github.com/aws/aws-sdk-php/tree/3.184.2" }, - "time": "2021-06-01T18:13:35+00:00" + "time": "2021-06-11T18:20:15+00:00" }, { "name": "bacon/bacon-qr-code", @@ -460,16 +460,16 @@ }, { "name": "checkout/checkout-sdk-php", - "version": "1.0.15", + "version": "1.0.16", "source": { "type": "git", "url": "https://github.com/checkout/checkout-sdk-php.git", - "reference": "f73f6478c966968f2f0b9a9525c4bfb9b8e046f1" + "reference": "81c6aa884fb586b8a9456aecf83b639fed205f86" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/checkout/checkout-sdk-php/zipball/f73f6478c966968f2f0b9a9525c4bfb9b8e046f1", - "reference": "f73f6478c966968f2f0b9a9525c4bfb9b8e046f1", + "url": "https://api.github.com/repos/checkout/checkout-sdk-php/zipball/81c6aa884fb586b8a9456aecf83b639fed205f86", + "reference": "81c6aa884fb586b8a9456aecf83b639fed205f86", "shasum": "" }, "require": { @@ -513,9 +513,9 @@ ], "support": { "issues": "https://github.com/checkout/checkout-sdk-php/issues", - "source": "https://github.com/checkout/checkout-sdk-php/tree/1.0.15" + "source": "https://github.com/checkout/checkout-sdk-php/tree/1.0.16" }, - "time": "2021-05-25T07:59:04+00:00" + "time": "2021-06-03T13:52:46+00:00" }, { "name": "cleverit/ubl_invoice", @@ -804,16 +804,16 @@ }, { "name": "composer/ca-bundle", - "version": "1.2.9", + "version": "1.2.10", "source": { "type": "git", "url": "https://github.com/composer/ca-bundle.git", - "reference": "78a0e288fdcebf92aa2318a8d3656168da6ac1a5" + "reference": "9fdb22c2e97a614657716178093cd1da90a64aa8" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/composer/ca-bundle/zipball/78a0e288fdcebf92aa2318a8d3656168da6ac1a5", - "reference": "78a0e288fdcebf92aa2318a8d3656168da6ac1a5", + "url": "https://api.github.com/repos/composer/ca-bundle/zipball/9fdb22c2e97a614657716178093cd1da90a64aa8", + "reference": "9fdb22c2e97a614657716178093cd1da90a64aa8", "shasum": "" }, "require": { @@ -860,7 +860,7 @@ "support": { "irc": "irc://irc.freenode.org/composer", "issues": "https://github.com/composer/ca-bundle/issues", - "source": "https://github.com/composer/ca-bundle/tree/1.2.9" + "source": "https://github.com/composer/ca-bundle/tree/1.2.10" }, "funding": [ { @@ -876,20 +876,20 @@ "type": "tidelift" } ], - "time": "2021-01-12T12:10:35+00:00" + "time": "2021-06-07T13:58:28+00:00" }, { "name": "composer/composer", - "version": "2.0.14", + "version": "2.1.3", "source": { "type": "git", "url": "https://github.com/composer/composer.git", - "reference": "92b2ccbef65292ba9f2004271ef47c7231e2eed5" + "reference": "fc5c4573aafce3a018eb7f1f8f91cea423970f2e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/composer/composer/zipball/92b2ccbef65292ba9f2004271ef47c7231e2eed5", - "reference": "92b2ccbef65292ba9f2004271ef47c7231e2eed5", + "url": "https://api.github.com/repos/composer/composer/zipball/fc5c4573aafce3a018eb7f1f8f91cea423970f2e", + "reference": "fc5c4573aafce3a018eb7f1f8f91cea423970f2e", "shasum": "" }, "require": { @@ -924,7 +924,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "2.0-dev" + "dev-master": "2.1-dev" } }, "autoload": { @@ -958,7 +958,7 @@ "support": { "irc": "irc://irc.freenode.org/composer", "issues": "https://github.com/composer/composer/issues", - "source": "https://github.com/composer/composer/tree/2.0.14" + "source": "https://github.com/composer/composer/tree/2.1.3" }, "funding": [ { @@ -974,7 +974,7 @@ "type": "tidelift" } ], - "time": "2021-05-21T15:03:37+00:00" + "time": "2021-06-09T14:31:20+00:00" }, { "name": "composer/metadata-minifier", @@ -2219,16 +2219,16 @@ }, { "name": "google/apiclient", - "version": "v2.9.1", + "version": "v2.9.2", "source": { "type": "git", "url": "https://github.com/googleapis/google-api-php-client.git", - "reference": "2fb6e702aca5d68203fa737f89f6f774022494c6" + "reference": "e9ef4c26a044b8d39a46bcf296be795fe24a1849" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/googleapis/google-api-php-client/zipball/2fb6e702aca5d68203fa737f89f6f774022494c6", - "reference": "2fb6e702aca5d68203fa737f89f6f774022494c6", + "url": "https://api.github.com/repos/googleapis/google-api-php-client/zipball/e9ef4c26a044b8d39a46bcf296be795fe24a1849", + "reference": "e9ef4c26a044b8d39a46bcf296be795fe24a1849", "shasum": "" }, "require": { @@ -2243,7 +2243,7 @@ }, "require-dev": { "cache/filesystem-adapter": "^0.3.2|^1.1", - "composer/composer": "^1.10", + "composer/composer": "^1.10.22", "dealerdirect/phpcodesniffer-composer-installer": "^0.7", "phpcompatibility/php-compatibility": "^9.2", "phpunit/phpunit": "^5.7||^8.5.13", @@ -2282,29 +2282,29 @@ ], "support": { "issues": "https://github.com/googleapis/google-api-php-client/issues", - "source": "https://github.com/googleapis/google-api-php-client/tree/v2.9.1" + "source": "https://github.com/googleapis/google-api-php-client/tree/v2.9.2" }, - "time": "2021-01-19T17:48:59+00:00" + "time": "2021-06-09T22:15:08+00:00" }, { "name": "google/apiclient-services", - "version": "v0.177.0", + "version": "v0.181.0", "source": { "type": "git", "url": "https://github.com/googleapis/google-api-php-client-services.git", - "reference": "316cbf9b02c575a140d8cbeca48a3ca0070fcd5a" + "reference": "a4ea5fd96887d654d10d446b239e1ff60240e2c1" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/googleapis/google-api-php-client-services/zipball/316cbf9b02c575a140d8cbeca48a3ca0070fcd5a", - "reference": "316cbf9b02c575a140d8cbeca48a3ca0070fcd5a", + "url": "https://api.github.com/repos/googleapis/google-api-php-client-services/zipball/a4ea5fd96887d654d10d446b239e1ff60240e2c1", + "reference": "a4ea5fd96887d654d10d446b239e1ff60240e2c1", "shasum": "" }, "require": { - "php": ">=5.4" + "php": ">=5.6" }, "require-dev": { - "phpunit/phpunit": "^4.8|^5" + "phpunit/phpunit": "^5.7||^8.5.13" }, "type": "library", "autoload": { @@ -2323,9 +2323,9 @@ ], "support": { "issues": "https://github.com/googleapis/google-api-php-client-services/issues", - "source": "https://github.com/googleapis/google-api-php-client-services/tree/v0.177.0" + "source": "https://github.com/googleapis/google-api-php-client-services/tree/v0.181.0" }, - "time": "2021-05-15T11:18:02+00:00" + "time": "2021-06-13T11:20:02+00:00" }, { "name": "google/auth", @@ -3062,16 +3062,16 @@ }, { "name": "laravel/framework", - "version": "v8.44.0", + "version": "v8.46.0", "source": { "type": "git", "url": "https://github.com/laravel/framework.git", - "reference": "7b3b27dc8911ab02a69731af2ba97b5130b2ddb8" + "reference": "a18266c612e0e6aba5e0174b3c873d2d217dccfb" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/laravel/framework/zipball/7b3b27dc8911ab02a69731af2ba97b5130b2ddb8", - "reference": "7b3b27dc8911ab02a69731af2ba97b5130b2ddb8", + "url": "https://api.github.com/repos/laravel/framework/zipball/a18266c612e0e6aba5e0174b3c873d2d217dccfb", + "reference": "a18266c612e0e6aba5e0174b3c873d2d217dccfb", "shasum": "" }, "require": { @@ -3153,7 +3153,7 @@ "orchestra/testbench-core": "^6.8", "pda/pheanstalk": "^4.0", "phpunit/phpunit": "^8.5.8|^9.3.3", - "predis/predis": "^1.1.1", + "predis/predis": "^1.1.2", "symfony/cache": "^5.1.4" }, "suggest": { @@ -3226,7 +3226,7 @@ "issues": "https://github.com/laravel/framework/issues", "source": "https://github.com/laravel/framework" }, - "time": "2021-05-27T16:46:06+00:00" + "time": "2021-06-08T13:36:46+00:00" }, { "name": "laravel/slack-notification-channel", @@ -4067,23 +4067,23 @@ }, { "name": "league/omnipay", - "version": "v3.2.0", + "version": "v3.2.1", "source": { "type": "git", "url": "https://github.com/thephpleague/omnipay.git", - "reference": "0caded2a46f809dc42e350e07e798cc3c45cd47f" + "reference": "38f66a0cc043ed51d6edf7956d6439a2f263501f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/thephpleague/omnipay/zipball/0caded2a46f809dc42e350e07e798cc3c45cd47f", - "reference": "0caded2a46f809dc42e350e07e798cc3c45cd47f", + "url": "https://api.github.com/repos/thephpleague/omnipay/zipball/38f66a0cc043ed51d6edf7956d6439a2f263501f", + "reference": "38f66a0cc043ed51d6edf7956d6439a2f263501f", "shasum": "" }, "require": { "omnipay/common": "^3.1", - "php": "^7.3|^8.0", - "php-http/discovery": "^1.12", - "php-http/guzzle7-adapter": "^0.1" + "php": "^7.2|^8.0", + "php-http/discovery": "^1.14", + "php-http/guzzle7-adapter": "^1" }, "require-dev": { "omnipay/tests": "^3|^4" @@ -4118,7 +4118,7 @@ ], "support": { "issues": "https://github.com/thephpleague/omnipay/issues", - "source": "https://github.com/thephpleague/omnipay/tree/v3.2.0" + "source": "https://github.com/thephpleague/omnipay/tree/v3.2.1" }, "funding": [ { @@ -4126,7 +4126,7 @@ "type": "github" } ], - "time": "2021-06-01T09:16:20+00:00" + "time": "2021-06-05T11:34:12+00:00" }, { "name": "livewire/livewire", @@ -4570,16 +4570,16 @@ }, { "name": "nesbot/carbon", - "version": "2.48.1", + "version": "2.49.0", "source": { "type": "git", "url": "https://github.com/briannesbitt/Carbon.git", - "reference": "8d1f50f1436fb4b05e7127360483dd9c6e73da16" + "reference": "93d9db91c0235c486875d22f1e08b50bdf3e6eee" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/briannesbitt/Carbon/zipball/8d1f50f1436fb4b05e7127360483dd9c6e73da16", - "reference": "8d1f50f1436fb4b05e7127360483dd9c6e73da16", + "url": "https://api.github.com/repos/briannesbitt/Carbon/zipball/93d9db91c0235c486875d22f1e08b50bdf3e6eee", + "reference": "93d9db91c0235c486875d22f1e08b50bdf3e6eee", "shasum": "" }, "require": { @@ -4659,7 +4659,7 @@ "type": "tidelift" } ], - "time": "2021-05-26T22:08:38+00:00" + "time": "2021-06-02T07:31:40+00:00" }, { "name": "nikic/php-parser", @@ -4877,29 +4877,29 @@ }, { "name": "omnipay/common", - "version": "v3.1.0", + "version": "v3.1.2", "source": { "type": "git", "url": "https://github.com/thephpleague/omnipay-common.git", - "reference": "fae2bc97a1b6c808361c5cafc796d380130714c7" + "reference": "5b16387ec5ab1b9ff86bdf0f20415088693b9948" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/thephpleague/omnipay-common/zipball/fae2bc97a1b6c808361c5cafc796d380130714c7", - "reference": "fae2bc97a1b6c808361c5cafc796d380130714c7", + "url": "https://api.github.com/repos/thephpleague/omnipay-common/zipball/5b16387ec5ab1b9ff86bdf0f20415088693b9948", + "reference": "5b16387ec5ab1b9ff86bdf0f20415088693b9948", "shasum": "" }, "require": { "moneyphp/money": "^3.1", - "php": "^7.3|^8", + "php": "^7.2|^8", "php-http/client-implementation": "^1", - "php-http/discovery": "^1.13", - "php-http/guzzle7-adapter": "^0.1", + "php-http/discovery": "^1.14", "php-http/message": "^1.5", "symfony/http-foundation": "^2.1|^3|^4|^5" }, "require-dev": { - "omnipay/tests": "^4", + "omnipay/tests": "^4.1", + "php-http/guzzle7-adapter": "^1", "php-http/mock-client": "^1", "squizlabs/php_codesniffer": "^3.5" }, @@ -4909,7 +4909,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "3.0.x-dev" + "dev-master": "3.1.x-dev" } }, "autoload": { @@ -4957,7 +4957,7 @@ ], "support": { "issues": "https://github.com/thephpleague/omnipay-common/issues", - "source": "https://github.com/thephpleague/omnipay-common/tree/v3.1.0" + "source": "https://github.com/thephpleague/omnipay-common/tree/v3.1.2" }, "funding": [ { @@ -4965,7 +4965,7 @@ "type": "github" } ], - "time": "2021-06-01T08:17:22+00:00" + "time": "2021-06-05T11:36:12+00:00" }, { "name": "omnipay/paypal", @@ -5358,16 +5358,16 @@ }, { "name": "php-http/guzzle7-adapter", - "version": "0.1.1", + "version": "1.0.0", "source": { "type": "git", "url": "https://github.com/php-http/guzzle7-adapter.git", - "reference": "1967de656b9679a2a6a66d0e4e16fa99bbed1ad1" + "reference": "fb075a71dbfa4847cf0c2938c4e5a9c478ef8b01" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/php-http/guzzle7-adapter/zipball/1967de656b9679a2a6a66d0e4e16fa99bbed1ad1", - "reference": "1967de656b9679a2a6a66d0e4e16fa99bbed1ad1", + "url": "https://api.github.com/repos/php-http/guzzle7-adapter/zipball/fb075a71dbfa4847cf0c2938c4e5a9c478ef8b01", + "reference": "fb075a71dbfa4847cf0c2938c4e5a9c478ef8b01", "shasum": "" }, "require": { @@ -5414,9 +5414,9 @@ ], "support": { "issues": "https://github.com/php-http/guzzle7-adapter/issues", - "source": "https://github.com/php-http/guzzle7-adapter/tree/0.1.1" + "source": "https://github.com/php-http/guzzle7-adapter/tree/1.0.0" }, - "time": "2020-10-21T17:30:51+00:00" + "time": "2021-03-09T07:35:15+00:00" }, { "name": "php-http/httplug", @@ -5736,16 +5736,16 @@ }, { "name": "phpseclib/phpseclib", - "version": "3.0.8", + "version": "3.0.9", "source": { "type": "git", "url": "https://github.com/phpseclib/phpseclib.git", - "reference": "d9615a6fb970d9933866ca8b4036ec3407b020b6" + "reference": "a127a5133804ff2f47ae629dd529b129da616ad7" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpseclib/phpseclib/zipball/d9615a6fb970d9933866ca8b4036ec3407b020b6", - "reference": "d9615a6fb970d9933866ca8b4036ec3407b020b6", + "url": "https://api.github.com/repos/phpseclib/phpseclib/zipball/a127a5133804ff2f47ae629dd529b129da616ad7", + "reference": "a127a5133804ff2f47ae629dd529b129da616ad7", "shasum": "" }, "require": { @@ -5827,7 +5827,7 @@ ], "support": { "issues": "https://github.com/phpseclib/phpseclib/issues", - "source": "https://github.com/phpseclib/phpseclib/tree/3.0.8" + "source": "https://github.com/phpseclib/phpseclib/tree/3.0.9" }, "funding": [ { @@ -5843,7 +5843,7 @@ "type": "tidelift" } ], - "time": "2021-04-19T03:20:48+00:00" + "time": "2021-06-14T06:54:45+00:00" }, { "name": "pragmarx/google2fa", @@ -7198,16 +7198,16 @@ }, { "name": "stripe/stripe-php", - "version": "v7.80.0", + "version": "v7.83.0", "source": { "type": "git", "url": "https://github.com/stripe/stripe-php.git", - "reference": "566900968407302f88a925ba731c87c05fe98a7a" + "reference": "bb7244c7334ad8bf30d31bb4972d5aff57df1563" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/stripe/stripe-php/zipball/566900968407302f88a925ba731c87c05fe98a7a", - "reference": "566900968407302f88a925ba731c87c05fe98a7a", + "url": "https://api.github.com/repos/stripe/stripe-php/zipball/bb7244c7334ad8bf30d31bb4972d5aff57df1563", + "reference": "bb7244c7334ad8bf30d31bb4972d5aff57df1563", "shasum": "" }, "require": { @@ -7253,9 +7253,9 @@ ], "support": { "issues": "https://github.com/stripe/stripe-php/issues", - "source": "https://github.com/stripe/stripe-php/tree/v7.80.0" + "source": "https://github.com/stripe/stripe-php/tree/v7.83.0" }, - "time": "2021-05-26T19:10:43+00:00" + "time": "2021-06-07T23:15:45+00:00" }, { "name": "swiftmailer/swiftmailer", @@ -8085,16 +8085,16 @@ }, { "name": "symfony/http-foundation", - "version": "v5.3.0", + "version": "v5.3.1", "source": { "type": "git", "url": "https://github.com/symfony/http-foundation.git", - "reference": "31f25d99b329a1461f42bcef8505b54926a30be6" + "reference": "8827b90cf8806e467124ad476acd15216c2fceb6" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/http-foundation/zipball/31f25d99b329a1461f42bcef8505b54926a30be6", - "reference": "31f25d99b329a1461f42bcef8505b54926a30be6", + "url": "https://api.github.com/repos/symfony/http-foundation/zipball/8827b90cf8806e467124ad476acd15216c2fceb6", + "reference": "8827b90cf8806e467124ad476acd15216c2fceb6", "shasum": "" }, "require": { @@ -8138,7 +8138,7 @@ "description": "Defines an object-oriented layer for the HTTP specification", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/http-foundation/tree/v5.3.0" + "source": "https://github.com/symfony/http-foundation/tree/v5.3.1" }, "funding": [ { @@ -8154,20 +8154,20 @@ "type": "tidelift" } ], - "time": "2021-05-26T17:43:10+00:00" + "time": "2021-06-02T09:32:00+00:00" }, { "name": "symfony/http-kernel", - "version": "v5.3.0", + "version": "v5.3.1", "source": { "type": "git", "url": "https://github.com/symfony/http-kernel.git", - "reference": "f8e8f5391b6909e2f0ba8c12220ab7af3050eb4f" + "reference": "74eb022e3bac36b3d3a897951a98759f2b32b864" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/http-kernel/zipball/f8e8f5391b6909e2f0ba8c12220ab7af3050eb4f", - "reference": "f8e8f5391b6909e2f0ba8c12220ab7af3050eb4f", + "url": "https://api.github.com/repos/symfony/http-kernel/zipball/74eb022e3bac36b3d3a897951a98759f2b32b864", + "reference": "74eb022e3bac36b3d3a897951a98759f2b32b864", "shasum": "" }, "require": { @@ -8250,7 +8250,7 @@ "description": "Provides a structured process for converting a Request into a Response", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/http-kernel/tree/v5.3.0" + "source": "https://github.com/symfony/http-kernel/tree/v5.3.1" }, "funding": [ { @@ -8266,7 +8266,7 @@ "type": "tidelift" } ], - "time": "2021-05-31T10:44:03+00:00" + "time": "2021-06-02T10:07:12+00:00" }, { "name": "symfony/mime", @@ -10355,6 +10355,57 @@ }, "time": "2019-07-12T14:06:05+00:00" }, + { + "name": "wepay/php-sdk", + "version": "0.3.1", + "source": { + "type": "git", + "url": "https://github.com/wepay/PHP-SDK.git", + "reference": "2a89ceb2954d117d082f869d3bfcb7864e6c2a7d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/wepay/PHP-SDK/zipball/2a89ceb2954d117d082f869d3bfcb7864e6c2a7d", + "reference": "2a89ceb2954d117d082f869d3bfcb7864e6c2a7d", + "shasum": "" + }, + "require": { + "ext-curl": "*", + "php": ">=5.3.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "0.2.x-dev" + } + }, + "autoload": { + "classmap": [ + "wepay.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "Apache-2.0" + ], + "authors": [ + { + "name": "WePay", + "email": "api@wepay.com" + } + ], + "description": "WePay APIv2 SDK for PHP", + "keywords": [ + "payment", + "sdk", + "wepay" + ], + "support": { + "issues": "https://github.com/wepay/PHP-SDK/issues", + "source": "https://github.com/wepay/PHP-SDK/tree/master" + }, + "time": "2017-01-21T07:03:26+00:00" + }, { "name": "wildbit/swiftmailer-postmark", "version": "3.3.0", @@ -10693,16 +10744,16 @@ }, { "name": "barryvdh/laravel-debugbar", - "version": "v3.6.0", + "version": "v3.6.1", "source": { "type": "git", "url": "https://github.com/barryvdh/laravel-debugbar.git", - "reference": "bc99f4c52aec0636ecb3aae4576ce84c5773bae2" + "reference": "f6f0f895a33cac801286a74355d146bb5384a5da" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/barryvdh/laravel-debugbar/zipball/bc99f4c52aec0636ecb3aae4576ce84c5773bae2", - "reference": "bc99f4c52aec0636ecb3aae4576ce84c5773bae2", + "url": "https://api.github.com/repos/barryvdh/laravel-debugbar/zipball/f6f0f895a33cac801286a74355d146bb5384a5da", + "reference": "f6f0f895a33cac801286a74355d146bb5384a5da", "shasum": "" }, "require": { @@ -10762,7 +10813,7 @@ ], "support": { "issues": "https://github.com/barryvdh/laravel-debugbar/issues", - "source": "https://github.com/barryvdh/laravel-debugbar/tree/v3.6.0" + "source": "https://github.com/barryvdh/laravel-debugbar/tree/v3.6.1" }, "funding": [ { @@ -10770,7 +10821,7 @@ "type": "github" } ], - "time": "2021-06-01T08:46:17+00:00" + "time": "2021-06-02T06:42:22+00:00" }, { "name": "brianium/paratest", @@ -11263,16 +11314,16 @@ }, { "name": "facade/ignition", - "version": "2.9.0", + "version": "2.10.2", "source": { "type": "git", "url": "https://github.com/facade/ignition.git", - "reference": "e7db3b601ce742568b92648818ef903904d20164" + "reference": "43688227bbf27c43bc1ad83af224f135b6ef0ff4" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/facade/ignition/zipball/e7db3b601ce742568b92648818ef903904d20164", - "reference": "e7db3b601ce742568b92648818ef903904d20164", + "url": "https://api.github.com/repos/facade/ignition/zipball/43688227bbf27c43bc1ad83af224f135b6ef0ff4", + "reference": "43688227bbf27c43bc1ad83af224f135b6ef0ff4", "shasum": "" }, "require": { @@ -11336,7 +11387,7 @@ "issues": "https://github.com/facade/ignition/issues", "source": "https://github.com/facade/ignition" }, - "time": "2021-05-05T06:45:12+00:00" + "time": "2021-06-11T06:57:25+00:00" }, { "name": "facade/ignition-contracts", @@ -11393,20 +11444,20 @@ }, { "name": "felixfbecker/advanced-json-rpc", - "version": "v3.2.0", + "version": "v3.2.1", "source": { "type": "git", "url": "https://github.com/felixfbecker/php-advanced-json-rpc.git", - "reference": "06f0b06043c7438959dbdeed8bb3f699a19be22e" + "reference": "b5f37dbff9a8ad360ca341f3240dc1c168b45447" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/felixfbecker/php-advanced-json-rpc/zipball/06f0b06043c7438959dbdeed8bb3f699a19be22e", - "reference": "06f0b06043c7438959dbdeed8bb3f699a19be22e", + "url": "https://api.github.com/repos/felixfbecker/php-advanced-json-rpc/zipball/b5f37dbff9a8ad360ca341f3240dc1c168b45447", + "reference": "b5f37dbff9a8ad360ca341f3240dc1c168b45447", "shasum": "" }, "require": { - "netresearch/jsonmapper": "^1.0 || ^2.0", + "netresearch/jsonmapper": "^1.0 || ^2.0 || ^3.0 || ^4.0", "php": "^7.1 || ^8.0", "phpdocumentor/reflection-docblock": "^4.3.4 || ^5.0.0" }, @@ -11432,9 +11483,9 @@ "description": "A more advanced JSONRPC implementation", "support": { "issues": "https://github.com/felixfbecker/php-advanced-json-rpc/issues", - "source": "https://github.com/felixfbecker/php-advanced-json-rpc/tree/v3.2.0" + "source": "https://github.com/felixfbecker/php-advanced-json-rpc/tree/v3.2.1" }, - "time": "2021-01-10T17:48:47+00:00" + "time": "2021-06-11T22:34:44+00:00" }, { "name": "felixfbecker/language-server-protocol", @@ -11494,16 +11545,16 @@ }, { "name": "filp/whoops", - "version": "2.12.1", + "version": "2.13.0", "source": { "type": "git", "url": "https://github.com/filp/whoops.git", - "reference": "c13c0be93cff50f88bbd70827d993026821914dd" + "reference": "2edbc73a4687d9085c8f20f398eebade844e8424" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/filp/whoops/zipball/c13c0be93cff50f88bbd70827d993026821914dd", - "reference": "c13c0be93cff50f88bbd70827d993026821914dd", + "url": "https://api.github.com/repos/filp/whoops/zipball/2edbc73a4687d9085c8f20f398eebade844e8424", + "reference": "2edbc73a4687d9085c8f20f398eebade844e8424", "shasum": "" }, "require": { @@ -11553,7 +11604,7 @@ ], "support": { "issues": "https://github.com/filp/whoops/issues", - "source": "https://github.com/filp/whoops/tree/2.12.1" + "source": "https://github.com/filp/whoops/tree/2.13.0" }, "funding": [ { @@ -11561,7 +11612,7 @@ "type": "github" } ], - "time": "2021-04-25T12:00:00+00:00" + "time": "2021-06-04T12:00:00+00:00" }, { "name": "friendsofphp/php-cs-fixer", @@ -11920,16 +11971,16 @@ }, { "name": "netresearch/jsonmapper", - "version": "v2.1.0", + "version": "v4.0.0", "source": { "type": "git", "url": "https://github.com/cweiske/jsonmapper.git", - "reference": "e0f1e33a71587aca81be5cffbb9746510e1fe04e" + "reference": "8bbc021a8edb2e4a7ea2f8ad4fa9ec9dce2fcb8d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/cweiske/jsonmapper/zipball/e0f1e33a71587aca81be5cffbb9746510e1fe04e", - "reference": "e0f1e33a71587aca81be5cffbb9746510e1fe04e", + "url": "https://api.github.com/repos/cweiske/jsonmapper/zipball/8bbc021a8edb2e4a7ea2f8ad4fa9ec9dce2fcb8d", + "reference": "8bbc021a8edb2e4a7ea2f8ad4fa9ec9dce2fcb8d", "shasum": "" }, "require": { @@ -11937,10 +11988,10 @@ "ext-pcre": "*", "ext-reflection": "*", "ext-spl": "*", - "php": ">=5.6" + "php": ">=7.1" }, "require-dev": { - "phpunit/phpunit": "~4.8.35 || ~5.7 || ~6.4 || ~7.0", + "phpunit/phpunit": "~7.5 || ~8.0 || ~9.0", "squizlabs/php_codesniffer": "~3.5" }, "type": "library", @@ -11965,9 +12016,9 @@ "support": { "email": "cweiske@cweiske.de", "issues": "https://github.com/cweiske/jsonmapper/issues", - "source": "https://github.com/cweiske/jsonmapper/tree/master" + "source": "https://github.com/cweiske/jsonmapper/tree/v4.0.0" }, - "time": "2020-04-16T18:48:43+00:00" + "time": "2020-12-01T19:48:11+00:00" }, { "name": "nunomaduro/collision", @@ -12821,16 +12872,16 @@ }, { "name": "phpunit/phpunit", - "version": "9.5.4", + "version": "9.5.5", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/phpunit.git", - "reference": "c73c6737305e779771147af66c96ca6a7ed8a741" + "reference": "89ff45ea9d70e35522fb6654a2ebc221158de276" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/c73c6737305e779771147af66c96ca6a7ed8a741", - "reference": "c73c6737305e779771147af66c96ca6a7ed8a741", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/89ff45ea9d70e35522fb6654a2ebc221158de276", + "reference": "89ff45ea9d70e35522fb6654a2ebc221158de276", "shasum": "" }, "require": { @@ -12860,7 +12911,7 @@ "sebastian/global-state": "^5.0.1", "sebastian/object-enumerator": "^4.0.3", "sebastian/resource-operations": "^3.0.3", - "sebastian/type": "^2.3", + "sebastian/type": "^2.3.2", "sebastian/version": "^3.0.2" }, "require-dev": { @@ -12908,7 +12959,7 @@ ], "support": { "issues": "https://github.com/sebastianbergmann/phpunit/issues", - "source": "https://github.com/sebastianbergmann/phpunit/tree/9.5.4" + "source": "https://github.com/sebastianbergmann/phpunit/tree/9.5.5" }, "funding": [ { @@ -12920,7 +12971,7 @@ "type": "github" } ], - "time": "2021-03-23T07:16:29+00:00" + "time": "2021-06-05T04:49:07+00:00" }, { "name": "sebastian/cli-parser", @@ -13428,16 +13479,16 @@ }, { "name": "sebastian/global-state", - "version": "5.0.2", + "version": "5.0.3", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/global-state.git", - "reference": "a90ccbddffa067b51f574dea6eb25d5680839455" + "reference": "23bd5951f7ff26f12d4e3242864df3e08dec4e49" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/a90ccbddffa067b51f574dea6eb25d5680839455", - "reference": "a90ccbddffa067b51f574dea6eb25d5680839455", + "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/23bd5951f7ff26f12d4e3242864df3e08dec4e49", + "reference": "23bd5951f7ff26f12d4e3242864df3e08dec4e49", "shasum": "" }, "require": { @@ -13480,7 +13531,7 @@ ], "support": { "issues": "https://github.com/sebastianbergmann/global-state/issues", - "source": "https://github.com/sebastianbergmann/global-state/tree/5.0.2" + "source": "https://github.com/sebastianbergmann/global-state/tree/5.0.3" }, "funding": [ { @@ -13488,7 +13539,7 @@ "type": "github" } ], - "time": "2020-10-26T15:55:19+00:00" + "time": "2021-06-11T13:31:12+00:00" }, { "name": "sebastian/lines-of-code", @@ -13779,16 +13830,16 @@ }, { "name": "sebastian/type", - "version": "2.3.1", + "version": "2.3.2", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/type.git", - "reference": "81cd61ab7bbf2de744aba0ea61fae32f721df3d2" + "reference": "0d1c587401514d17e8f9258a27e23527cb1b06c1" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/type/zipball/81cd61ab7bbf2de744aba0ea61fae32f721df3d2", - "reference": "81cd61ab7bbf2de744aba0ea61fae32f721df3d2", + "url": "https://api.github.com/repos/sebastianbergmann/type/zipball/0d1c587401514d17e8f9258a27e23527cb1b06c1", + "reference": "0d1c587401514d17e8f9258a27e23527cb1b06c1", "shasum": "" }, "require": { @@ -13823,7 +13874,7 @@ "homepage": "https://github.com/sebastianbergmann/type", "support": { "issues": "https://github.com/sebastianbergmann/type/issues", - "source": "https://github.com/sebastianbergmann/type/tree/2.3.1" + "source": "https://github.com/sebastianbergmann/type/tree/2.3.2" }, "funding": [ { @@ -13831,7 +13882,7 @@ "type": "github" } ], - "time": "2020-10-26T13:18:59+00:00" + "time": "2021-06-04T13:02:07+00:00" }, { "name": "sebastian/version", @@ -13888,16 +13939,16 @@ }, { "name": "swagger-api/swagger-ui", - "version": "v3.49.0", + "version": "v3.50.0", "source": { "type": "git", "url": "https://github.com/swagger-api/swagger-ui.git", - "reference": "bbfa31beae18df5118dfcdfec257bd64dc8f61a2" + "reference": "91858cc811d3cddb45ef604365e2c88cd96e4ca0" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/swagger-api/swagger-ui/zipball/bbfa31beae18df5118dfcdfec257bd64dc8f61a2", - "reference": "bbfa31beae18df5118dfcdfec257bd64dc8f61a2", + "url": "https://api.github.com/repos/swagger-api/swagger-ui/zipball/91858cc811d3cddb45ef604365e2c88cd96e4ca0", + "reference": "91858cc811d3cddb45ef604365e2c88cd96e4ca0", "shasum": "" }, "type": "library", @@ -13943,9 +13994,9 @@ ], "support": { "issues": "https://github.com/swagger-api/swagger-ui/issues", - "source": "https://github.com/swagger-api/swagger-ui/tree/v3.49.0" + "source": "https://github.com/swagger-api/swagger-ui/tree/v3.50.0" }, - "time": "2021-05-19T21:54:39+00:00" + "time": "2021-06-03T21:00:28+00:00" }, { "name": "symfony/debug", diff --git a/config/ninja.php b/config/ninja.php index 3456aa043c5c..6aa1b314de97 100644 --- a/config/ninja.php +++ b/config/ninja.php @@ -148,6 +148,11 @@ return [ 'disable_auto_update' => env('DISABLE_AUTO_UPDATE', false), 'invoiceninja_hosted_pdf_generation' => env('NINJA_HOSTED_PDF', false), 'ninja_stripe_key' => env('NINJA_STRIPE_KEY', null), + 'wepay' => [ + 'environment' => env('WEPAY_ENVIRONMENT', 'stage'), + 'client_id' => env('WEPAY_CLIENT_ID', ''), + 'client_secret' => env('WEPAY_CLIENT_SECRET',''), + ], 'ninja_stripe_publishable_key' => env('NINJA_PUBLISHABLE_KEY', null), 'ninja_stripe_client_id' => env('NINJA_STRIPE_CLIENT_ID', null), 'ninja_default_company_id' => env('NINJA_COMPANY_ID', null), diff --git a/database/migrations/2021_05_05_014713_activate_we_pay.php b/database/migrations/2021_05_05_014713_activate_we_pay.php new file mode 100644 index 000000000000..bfd1d96815f8 --- /dev/null +++ b/database/migrations/2021_05_05_014713_activate_we_pay.php @@ -0,0 +1,31 @@ +=1 && Ninja::isHosted()) + Gateway::whereIn('id', [49])->update(['visible' => true]); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + // + } +} diff --git a/database/seeders/PaymentLibrariesSeeder.php b/database/seeders/PaymentLibrariesSeeder.php index e184cad80404..b9ff0f84146f 100644 --- a/database/seeders/PaymentLibrariesSeeder.php +++ b/database/seeders/PaymentLibrariesSeeder.php @@ -101,8 +101,9 @@ class PaymentLibrariesSeeder extends Seeder if (Ninja::isHosted()) { Gateway::whereIn('id', [20])->update(['visible' => 0]); Gateway::whereIn('id', [56])->update(['visible' => 1]); + Gateway::whereIn('id', [49])->update(['visible' => 1]); } - + Gateway::all()->each(function ($gateway) { $gateway->site_url = $gateway->getHelp(); $gateway->save(); diff --git a/public/images/wepay.svg b/public/images/wepay.svg new file mode 100644 index 000000000000..25f541e8c251 --- /dev/null +++ b/public/images/wepay.svg @@ -0,0 +1,383 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/resources/lang/en/texts.php b/resources/lang/en/texts.php index d333442c5667..070975170120 100644 --- a/resources/lang/en/texts.php +++ b/resources/lang/en/texts.php @@ -4267,6 +4267,7 @@ $LANG = array( 'company_import_failure_subject' => 'Error importing :company', 'company_import_failure_body' => 'There was an error importing the company data, the error message was:', 'recurring_invoice_due_date' => 'Due Date', + 'amount_cents' => 'Amount in pennies,pence or cents', ); return $LANG; diff --git a/resources/views/portal/ninja2020/gateways/stripe/ach/verify.blade.php b/resources/views/portal/ninja2020/gateways/stripe/ach/verify.blade.php index 9cdcf2803c4e..e173a2dd84a9 100644 --- a/resources/views/portal/ninja2020/gateways/stripe/ach/verify.blade.php +++ b/resources/views/portal/ninja2020/gateways/stripe/ach/verify.blade.php @@ -10,11 +10,11 @@ - @component('portal.ninja2020.components.general.card-element', ['title' => '#1 ' . ctrans('texts.amount')]) + @component('portal.ninja2020.components.general.card-element', ['title' => '#1 ' . ctrans('texts.amount_cents')]) @endcomponent - @component('portal.ninja2020.components.general.card-element', ['title' => '#2 ' . ctrans('texts.amount')]) + @component('portal.ninja2020.components.general.card-element', ['title' => '#2 ' . ctrans('texts.amount_cents')]) @endcomponent diff --git a/resources/views/portal/ninja2020/gateways/wepay/authorize/authorize.blade.php b/resources/views/portal/ninja2020/gateways/wepay/authorize/authorize.blade.php new file mode 100644 index 000000000000..8be02b9c9b17 --- /dev/null +++ b/resources/views/portal/ninja2020/gateways/wepay/authorize/authorize.blade.php @@ -0,0 +1,150 @@ +@extends('portal.ninja2020.layout.payments', ['gateway_title' => ctrans('texts.credit_card'), 'card_title' => ctrans('texts.credit_card')]) + +@section('gateway_head') + + + + + + + +@endsection + +@section('gateway_content') +
+ @csrf + + + + + + +
+ + @if(!Request::isSecure()) +

{{ ctrans('texts.https_required') }}

+ @endif + + + + @component('portal.ninja2020.components.general.card-element', ['title' => ctrans('texts.method')]) + {{ ctrans('texts.credit_card') }} + @endcomponent + + @include('portal.ninja2020.gateways.wepay.includes.credit_card') + + @component('portal.ninja2020.gateways.includes.pay_now', ['id' => 'card_button']) + {{ ctrans('texts.add_payment_method') }} + @endcomponent +@endsection + +@section('gateway_footer') + + + + +@endsection \ No newline at end of file diff --git a/resources/views/portal/ninja2020/gateways/wepay/authorize/bank_transfer.blade.php b/resources/views/portal/ninja2020/gateways/wepay/authorize/bank_transfer.blade.php new file mode 100644 index 000000000000..d1f837fec634 --- /dev/null +++ b/resources/views/portal/ninja2020/gateways/wepay/authorize/bank_transfer.blade.php @@ -0,0 +1,71 @@ +@extends('portal.ninja2020.layout.payments', ['gateway_title' => ctrans('texts.credit_card'), 'card_title' => ctrans('texts.bank_transfer')]) + +@section('gateway_head') + +@endsection + +@section('gateway_content') +
+ @csrf + + + + + +
+ + + +@endsection + +@section('gateway_footer') + + + + + +@endsection \ No newline at end of file diff --git a/resources/views/portal/ninja2020/gateways/wepay/authorize/verify.blade.php b/resources/views/portal/ninja2020/gateways/wepay/authorize/verify.blade.php new file mode 100644 index 000000000000..8087eb3b6ce2 --- /dev/null +++ b/resources/views/portal/ninja2020/gateways/wepay/authorize/verify.blade.php @@ -0,0 +1,24 @@ +@extends('portal.ninja2020.layout.payments', ['gateway_title' => 'ACH (Verification)', 'card_title' => 'ACH (Verification)']) + +@section('gateway_content') + @if(session()->has('error')) +
{{ session('error') }}
+ @endif + +
+ @csrf + + + @component('portal.ninja2020.components.general.card-element', ['title' => '#1 ' . ctrans('texts.amount_cents')]) + + @endcomponent + + @component('portal.ninja2020.components.general.card-element', ['title' => '#2 ' . ctrans('texts.amount_cents')]) + + @endcomponent + + @component('portal.ninja2020.gateways.includes.pay_now', ['type' => 'submit']) + {{ ctrans('texts.complete_verification')}} + @endcomponent +
+@endsection diff --git a/resources/views/portal/ninja2020/gateways/wepay/bank_transfer.blade.php b/resources/views/portal/ninja2020/gateways/wepay/bank_transfer.blade.php new file mode 100644 index 000000000000..3c77a2519dfa --- /dev/null +++ b/resources/views/portal/ninja2020/gateways/wepay/bank_transfer.blade.php @@ -0,0 +1,57 @@ +@extends('portal.ninja2020.layout.payments', ['gateway_title' => 'ACH', 'card_title' => 'ACH']) + +@section('gateway_content') + @if(count($tokens) > 0) + + + @include('portal.ninja2020.gateways.includes.payment_details') + +
+ @csrf + + + + + + +
+ + @component('portal.ninja2020.components.general.card-element', ['title' => ctrans('texts.pay_with')]) + @if(count($tokens) > 0) + @foreach($tokens as $token) + + @endforeach + @endisset + @endcomponent + + @else + @component('portal.ninja2020.components.general.card-element-single', ['title' => 'ACH', 'show_title' => false]) + {{ ctrans('texts.bank_account_not_linked') }} + {{ ctrans('texts.add_payment_method') }} + @endcomponent + @endif + + @include('portal.ninja2020.gateways.includes.pay_now') +@endsection + +@push('footer') + +@endpush diff --git a/resources/views/portal/ninja2020/gateways/wepay/credit_card/pay.blade.php b/resources/views/portal/ninja2020/gateways/wepay/credit_card/pay.blade.php new file mode 100644 index 000000000000..8994199d07ea --- /dev/null +++ b/resources/views/portal/ninja2020/gateways/wepay/credit_card/pay.blade.php @@ -0,0 +1,249 @@ +@extends('portal.ninja2020.layout.payments', ['gateway_title' => ctrans('texts.credit_card'), 'card_title' => ctrans('texts.credit_card')]) + +@section('gateway_head') + + + +@endsection + +@section('gateway_content') +
+ @csrf + + + + + + + + + +
+ + + + @component('portal.ninja2020.components.general.card-element', ['title' => ctrans('texts.payment_type')]) + {{ ctrans('texts.credit_card') }} + @endcomponent + + @include('portal.ninja2020.gateways.includes.payment_details') + + @component('portal.ninja2020.components.general.card-element', ['title' => ctrans('texts.pay_with')]) + @if(count($tokens) > 0) + @foreach($tokens as $token) + + @endforeach + @endisset + + + @endcomponent + + @include('portal.ninja2020.gateways.includes.save_card') + + @include('portal.ninja2020.gateways.wepay.includes.credit_card') + + @include('portal.ninja2020.gateways.includes.pay_now') +@endsection + +@section('gateway_footer') + + + +@endsection diff --git a/resources/views/portal/ninja2020/gateways/wepay/includes/credit_card.blade.php b/resources/views/portal/ninja2020/gateways/wepay/includes/credit_card.blade.php new file mode 100644 index 000000000000..94c621a6f4f3 --- /dev/null +++ b/resources/views/portal/ninja2020/gateways/wepay/includes/credit_card.blade.php @@ -0,0 +1,12 @@ +
+
+ + + + + +
+ +
+
diff --git a/resources/views/portal/ninja2020/gateways/wepay/signup/finished.blade.php b/resources/views/portal/ninja2020/gateways/wepay/signup/finished.blade.php new file mode 100644 index 000000000000..c0c67077a6d1 --- /dev/null +++ b/resources/views/portal/ninja2020/gateways/wepay/signup/finished.blade.php @@ -0,0 +1,24 @@ +@extends('portal.ninja2020.layout.clean', ['custom_body_class' => 'bg-gray-50']) +@section('meta_title', ctrans('texts.sign_up_with_wepay')) + +@section('body') +
+ We Pay +
+ +
+

Wepay setup complete:

+
+ +
+ @if(isset($message)) + {{ $message ?? '' }} + @endif +
+ +@endsection + +@push('footer') + +@endpush diff --git a/resources/views/portal/ninja2020/gateways/wepay/signup/index.blade.php b/resources/views/portal/ninja2020/gateways/wepay/signup/index.blade.php new file mode 100644 index 000000000000..9c30c242083c --- /dev/null +++ b/resources/views/portal/ninja2020/gateways/wepay/signup/index.blade.php @@ -0,0 +1,15 @@ +@extends('portal.ninja2020.layout.clean', ['custom_body_class' => 'bg-gray-50']) +@section('meta_title', ctrans('texts.sign_up_with_wepay')) + +@section('body') +
+ We Pay +
+ + @livewire('wepay-signup', ['user_id' => $user_id, 'company' => $company]) +@endsection + +@push('footer') + +@endpush diff --git a/resources/views/portal/ninja2020/gateways/wepay/signup/wepay-signup.blade.php b/resources/views/portal/ninja2020/gateways/wepay/signup/wepay-signup.blade.php new file mode 100644 index 000000000000..2c122944aa2c --- /dev/null +++ b/resources/views/portal/ninja2020/gateways/wepay/signup/wepay-signup.blade.php @@ -0,0 +1,285 @@ +
+ +
+ @csrf + @method('POST') +
+
+
+
+ + + @error('first_name') +
+ {{ $message }} +
+ @enderror +
+ +
+ + + @error('last_name') +
+ {{ $message }} +
+ @enderror +
+ +
+ + + @error('email') +
+ {{ $message }} +
+ @enderror +
+ +
+ + + @error('company_name') +
+ {{ $message }} +
+ @enderror +
+ +
+ + +
+ + {{ ctrans('texts.country_United States') }} +
+ +
+ + {{ ctrans('texts.country_Canada') }} +
+ +
+ + {{ ctrans('texts.country_United Kingdom') }} +
+ +
+ + @if($country == 'CA') +
+ + +
+ + {{ ctrans('texts.accept_debit_cards') }} +
+
+ @endif + + + @if($country == 'US') +
+ +
+ + {{ ctrans('texts.enable_ach')}} +
+
+ @endif + +
+ +
+ + {!! ctrans('texts.wepay_payment_tos_agree', ['terms' => $terms, 'privacy_policy' => $privacy_policy]) !!} +
+ @error('wepay_payment_tos_agree') +
+ {{ $message }} +
+ @enderror +
+ +
+ {{ ctrans('texts.standard_fees_apply')}} +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ Fees Disclosure Box +
+

Payment Card Type

+ (These are the most common domestically issued card types + and processing methods. They do not represent all the + possible fees and variations that are charged to the + merchants.) +
+

Processing Method: Card Not Present

+ (Means that the card/device was not + electronically read. Generally, the card + information is manually key-entered, e.g. online + payment) +
+ Visa Consumer Credit + + 2.9% + CA$0.30 +
+ Visa Infinite + + 2.9% + CA$0.30 +
+ Visa Infinite Privilege + + 2.9% + CA$0.30 +
+ Visa Business + + 2.9% + CA$0.30 +
+ Visa Business Premium + + 2.9% + CA$0.30 +
+ Visa Corporate + + 2.9% + CA$0.30 +
+ Visa Prepaid + + 2.9% + CA$0.30 +
+ Visa Debit + + 2.9% + CA$0.30 +
+ MasterCard Consumer Credit + + 2.9% + CA$0.30 +
+ MasterCard World + + 2.9% + CA$0.30 +
+ MasterCard World Elite + + 2.9% + CA$0.30 +
+ MasterCard Business/Corporate + + 2.9% + CA$0.30 +
+ MasterCard Debit + + 2.9% + CA$0.30 +
+ MasterCard Prepaid + + 2.9% + CA$0.30 +
+ American Express + + 2.9% + CA$0.30 +
+ Other Fees Disclosure Box + +
+ Chargeback + + CA$15.00 +
+
+ + +
+
+ +
+ +
+
+
+
diff --git a/routes/client.php b/routes/client.php index 5b3a5aacf6d6..53e5e2626ad0 100644 --- a/routes/client.php +++ b/routes/client.php @@ -80,6 +80,7 @@ Route::group(['middleware' => ['auth:contact', 'locale', 'check_client_existence Route::post('upload', 'ClientPortal\UploadController')->name('upload.store'); Route::get('logout', 'Auth\ContactLoginController@logout')->name('logout'); + }); Route::get('client/subscriptions/{subscription}/purchase', 'ClientPortal\SubscriptionPurchaseController@index')->name('client.subscription.purchase')->middleware('domain_db'); diff --git a/routes/web.php b/routes/web.php index 715f8d5d5ead..3468a99ebbd9 100644 --- a/routes/web.php +++ b/routes/web.php @@ -20,6 +20,9 @@ Route::post('password/email', 'Auth\ForgotPasswordController@sendResetLinkEmail' Route::get('password/reset/{token}', 'Auth\ResetPasswordController@showResetForm')->middleware(['domain_db','email_db'])->name('password.reset'); Route::post('password/reset', 'Auth\ResetPasswordController@reset')->middleware('email_db')->name('password.update'); +Route::get('wepay/signup/{token}', 'WePayController@signup')->name('wepay.signup'); +Route::get('wepay/finished', 'WePayController@finished')->name('wepay.finished'); + /* * Social authentication */