From f42777b1f549a45b4f692b35588ff1cf8686d627 Mon Sep 17 00:00:00 2001 From: Hillel Coren Date: Wed, 4 Mar 2015 00:14:44 +0200 Subject: [PATCH] Added support for an additional payment gateway (paypal + credit card) --- app/controllers/AccountController.php | 191 +----------- app/controllers/AccountGatewayController.php | 294 +++++++++++++++++++ app/controllers/InvoiceController.php | 7 +- app/controllers/PaymentController.php | 42 ++- app/lang/da/texts.php | 10 + app/lang/de/texts.php | 10 + app/lang/en/texts.php | 10 + app/lang/es/texts.php | 10 + app/lang/fr/texts.php | 10 + app/lang/it/texts.php | 10 + app/lang/lt/texts.php | 10 + app/lang/nl/texts.php | 12 +- app/lang/pt_BR/texts.php | 10 + app/models/Account.php | 15 + app/models/AccountGateway.php | 4 + app/models/Client.php | 4 +- app/routes.php | 11 +- app/views/accounts/account_gateway.blade.php | 153 ++++++++++ app/views/accounts/nav.blade.php | 5 +- app/views/accounts/nav_advanced.blade.php | 4 +- app/views/accounts/payments.blade.php | 178 +++-------- app/views/accounts/product.blade.php | 2 +- app/views/accounts/token.blade.php | 3 +- app/views/clients/show.blade.php | 4 + app/views/invoices/view.blade.php | 9 +- app/views/users/edit.blade.php | 5 +- 26 files changed, 675 insertions(+), 348 deletions(-) create mode 100755 app/controllers/AccountGatewayController.php create mode 100644 app/views/accounts/account_gateway.blade.php diff --git a/app/controllers/AccountController.php b/app/controllers/AccountController.php index 2fb4e0e39dc7..6036a93b3753 100755 --- a/app/controllers/AccountController.php +++ b/app/controllers/AccountController.php @@ -97,7 +97,6 @@ class AccountController extends \BaseController public function getSearchData() { $data = $this->accountRepo->getSearchData(); - return Response::json($data); } @@ -119,94 +118,16 @@ class AccountController extends \BaseController return View::make('accounts.details', $data); } elseif ($section == ACCOUNT_PAYMENTS) { - $account = Account::with('account_gateways')->findOrFail(Auth::user()->account_id); - $accountGateway = null; - $config = null; - $configFields = null; - $selectedCards = 0; - if (count($account->account_gateways) > 0) { - $accountGateway = $account->account_gateways[0]; - $config = $accountGateway->config; - $selectedCards = $accountGateway->accepted_credit_cards; - - $configFields = json_decode($config); - - foreach ($configFields as $configField => $value) { - $configFields->$configField = str_repeat('*', strlen($value)); - } + $account = Auth::user()->account; + $account->load('account_gateways'); + $count = count($account->account_gateways); + + if ($count == 0) { + return Redirect::to('gateways/create'); } else { - $accountGateway = AccountGateway::createNew(); - $accountGateway->gateway_id = GATEWAY_MOOLAH; + return View::make('accounts.payments', ['showAdd' => $count < 2]); } - - $recommendedGateways = Gateway::remember(DEFAULT_QUERY_CACHE) - ->where('recommended', '=', '1') - ->orderBy('sort_order') - ->get(); - $recommendedGatewayArray = array(); - - foreach ($recommendedGateways as $recommendedGateway) { - $arrayItem = array( - 'value' => $recommendedGateway->id, - 'other' => 'false', - 'data-imageUrl' => asset($recommendedGateway->getLogoUrl()), - 'data-siteUrl' => $recommendedGateway->site_url, - ); - $recommendedGatewayArray[$recommendedGateway->name] = $arrayItem; - } - - $creditCardsArray = unserialize(CREDIT_CARDS); - $creditCards = []; - foreach ($creditCardsArray as $card => $name) { - if ($selectedCards > 0 && ($selectedCards & $card) == $card) { - $creditCards[$name['text']] = ['value' => $card, 'data-imageUrl' => asset($name['card']), 'checked' => 'checked']; - } else { - $creditCards[$name['text']] = ['value' => $card, 'data-imageUrl' => asset($name['card'])]; - } - } - - $otherItem = array( - 'value' => 1000000, - 'other' => 'true', - 'data-imageUrl' => '', - 'data-siteUrl' => '', - ); - $recommendedGatewayArray['Other Options'] = $otherItem; - - $gateways = Gateway::remember(DEFAULT_QUERY_CACHE)->where('payment_library_id', '=', 1)->orderBy('name')->get(); - - foreach ($gateways as $gateway) { - $paymentLibrary = $gateway->paymentlibrary; - - $gateway->fields = $gateway->getFields(); - - if ($accountGateway && $accountGateway->gateway_id == $gateway->id) { - $accountGateway->fields = $gateway->fields; - } - } - - $tokenBillingOptions = []; - for ($i=1; $i<=4; $i++) { - $tokenBillingOptions[$i] = trans("texts.token_billing_{$i}"); - } - - $data = [ - 'account' => $account, - 'accountGateway' => $accountGateway, - 'config' => $configFields, - 'gateways' => $gateways, - 'dropdownGateways' => Gateway::remember(DEFAULT_QUERY_CACHE) - ->where('recommended', '=', '0') - ->where('payment_library_id', '=', 1) - ->orderBy('name') - ->get(), - 'recommendedGateways' => $recommendedGatewayArray, - 'creditCardTypes' => $creditCards, - 'tokenBillingOptions' => $tokenBillingOptions, - ]; - - return View::make('accounts.payments', $data); } elseif ($section == ACCOUNT_NOTIFICATIONS) { $data = [ 'account' => Account::with('users')->findOrFail(Auth::user()->account_id), @@ -272,8 +193,6 @@ class AccountController extends \BaseController { if ($section == ACCOUNT_DETAILS) { return AccountController::saveDetails(); - } elseif ($section == ACCOUNT_PAYMENTS) { - return AccountController::savePayments(); } elseif ($section == ACCOUNT_IMPORT_EXPORT) { return AccountController::importFile(); } elseif ($section == ACCOUNT_MAP) { @@ -614,102 +533,6 @@ class AccountController extends \BaseController return Redirect::to('company/notifications'); } - private function savePayments() - { - $rules = array(); - $recommendedId = Input::get('recommendedGateway_id'); - - if ($gatewayId = $recommendedId == 1000000 ? Input::get('gateway_id') : $recommendedId) { - $gateway = Gateway::findOrFail($gatewayId); - - $paymentLibrary = $gateway->paymentlibrary; - - $fields = $gateway->getFields(); - - foreach ($fields as $field => $details) { - if (!in_array($field, ['testMode', 'developerMode', 'headerImageUrl', 'solutionType', 'landingPage', 'brandName', 'logoImageUrl', 'borderColor'])) { - if (strtolower($gateway->name) == 'beanstream') { - if (in_array($field, ['merchant_id', 'passCode'])) { - $rules[$gateway->id.'_'.$field] = 'required'; - } - } else { - $rules[$gateway->id.'_'.$field] = 'required'; - } - } - } - } - - $creditcards = Input::get('creditCardTypes'); - $validator = Validator::make(Input::all(), $rules); - - if ($validator->fails()) { - return Redirect::to('company/payments') - ->withErrors($validator) - ->withInput(); - } else { - $account = Account::with('account_gateways')->findOrFail(Auth::user()->account_id); - - if ($gatewayId) { - $accountGateway = AccountGateway::createNew(); - $accountGateway->gateway_id = $gatewayId; - $isMasked = false; - - $config = new stdClass(); - foreach ($fields as $field => $details) { - $value = trim(Input::get($gateway->id.'_'.$field)); - - if ($value && $value === str_repeat('*', strlen($value))) { - $isMasked = true; - } - - $config->$field = $value; - } - - $cardCount = 0; - if ($creditcards) { - foreach ($creditcards as $card => $value) { - $cardCount += intval($value); - } - } - - // check if a gateway is already configured - $currentGateway = false; - if (count($account->account_gateways)) { - $currentGateway = $account->account_gateways[0]; - } - - // if the values haven't changed don't update the config - if ($isMasked && $currentGateway) { - $currentGateway->accepted_credit_cards = $cardCount; - $currentGateway->save(); - // if there's an existing config for this gateway update it - } elseif (!$isMasked && $currentGateway && $currentGateway->gateway_id == $gatewayId) { - $currentGateway->accepted_credit_cards = $cardCount; - $currentGateway->config = json_encode($config); - $currentGateway->save(); - // otherwise, create a new gateway config - } else { - $accountGateway->config = json_encode($config); - $accountGateway->accepted_credit_cards = $cardCount; - - $account->account_gateways()->delete(); - $account->account_gateways()->save($accountGateway); - } - - if (Input::get('token_billing_type_id')) { - $account->token_billing_type_id = Input::get('token_billing_type_id'); - $account->save(); - } - - Session::flash('message', trans('texts.updated_settings')); - } else { - Session::flash('error', trans('validation.required', ['attribute' => 'gateway'])); - } - - return Redirect::to('company/payments'); - } - } - private function saveDetails() { $rules = array( diff --git a/app/controllers/AccountGatewayController.php b/app/controllers/AccountGatewayController.php new file mode 100755 index 000000000000..21b1aad7497e --- /dev/null +++ b/app/controllers/AccountGatewayController.php @@ -0,0 +1,294 @@ +join('gateways', 'gateways.id', '=', 'account_gateways.gateway_id') + ->where('account_gateways.deleted_at', '=', null) + ->where('account_gateways.account_id', '=', \Auth::user()->account_id) + ->select('account_gateways.public_id', 'gateways.name', 'account_gateways.deleted_at'); + + return Datatable::query($query) + ->addColumn('name', function ($model) { return link_to('gateways/'.$model->public_id.'/edit', $model->name); }) + ->addColumn('dropdown', function ($model) { + $actions = ''; + + return $actions; + }) + ->orderColumns(['name']) + ->make(); + } + + public function edit($publicId) + { + $accountGateway = AccountGateway::scope($publicId)->firstOrFail(); + $config = $accountGateway->config; + $selectedCards = $accountGateway->accepted_credit_cards; + + $configFields = json_decode($config); + + foreach ($configFields as $configField => $value) { + $configFields->$configField = str_repeat('*', strlen($value)); + } + + $data = self::getViewModel($accountGateway); + $data['url'] = 'gateways/'.$publicId; + $data['method'] = 'PUT'; + $data['title'] = trans('texts.edit_gateway') . ' - ' . $accountGateway->gateway->name; + $data['config'] = $configFields; + + return View::make('accounts.account_gateway', $data); + } + + public function update($publicId) + { + return $this->save($publicId); + } + + public function store() + { + return $this->save(); + } + + /** + * Displays the form for account creation + * + */ + public function create() + { + $data = self::getViewModel(); + $data['url'] = 'gateways'; + $data['method'] = 'POST'; + $data['title'] = trans('texts.add_gateway'); + + return View::make('accounts.account_gateway', $data); + } + + private function getViewModel($accountGateway = false) + { + $selectedCards = $accountGateway ? $accountGateway->accepted_credit_cards : 0; + $account = Auth::user()->account; + + $recommendedGateways = Gateway::remember(DEFAULT_QUERY_CACHE) + ->where('recommended', '=', '1') + ->orderBy('sort_order') + ->get(); + $recommendedGatewayArray = array(); + + foreach ($recommendedGateways as $recommendedGateway) { + $arrayItem = array( + 'value' => $recommendedGateway->id, + 'other' => 'false', + 'data-imageUrl' => asset($recommendedGateway->getLogoUrl()), + 'data-siteUrl' => $recommendedGateway->site_url, + ); + $recommendedGatewayArray[$recommendedGateway->name] = $arrayItem; + } + + $creditCardsArray = unserialize(CREDIT_CARDS); + $creditCards = []; + foreach ($creditCardsArray as $card => $name) { + if ($selectedCards > 0 && ($selectedCards & $card) == $card) { + $creditCards[$name['text']] = ['value' => $card, 'data-imageUrl' => asset($name['card']), 'checked' => 'checked']; + } else { + $creditCards[$name['text']] = ['value' => $card, 'data-imageUrl' => asset($name['card'])]; + } + } + + $otherItem = array( + 'value' => 1000000, + 'other' => 'true', + 'data-imageUrl' => '', + 'data-siteUrl' => '', + ); + $recommendedGatewayArray['Other Options'] = $otherItem; + + $account->load('account_gateways'); + $currentGateways = $account->account_gateways; + $gateways = Gateway::where('payment_library_id', '=', 1)->orderBy('name'); + $onlyPayPal = false; + if (!$accountGateway) { + if (count($currentGateways) > 0) { + $currentGateway = $currentGateways[0]; + if ($currentGateway->isPayPal()) { + $gateways->where('id', '!=', GATEWAY_PAYPAL_EXPRESS) + ->where('id', '!=', GATEWAY_PAYPAL_PRO); + } else { + $gateways->where('id', '>=', GATEWAY_PAYPAL_EXPRESS) + ->where('id', '<=', GATEWAY_PAYPAL_PRO); + $onlyPayPal = true; + } + } + } + $gateways = $gateways->get(); + + foreach ($gateways as $gateway) { + $paymentLibrary = $gateway->paymentlibrary; + $gateway->fields = $gateway->getFields(); + + if ($accountGateway && $accountGateway->gateway_id == $gateway->id) { + $accountGateway->fields = $gateway->fields; + } + } + + $tokenBillingOptions = []; + for ($i=1; $i<=4; $i++) { + $tokenBillingOptions[$i] = trans("texts.token_billing_{$i}"); + } + + return [ + 'account' => $account, + 'accountGateway' => $accountGateway, + 'config' => false, + 'gateways' => $gateways, + 'recommendedGateways' => $recommendedGatewayArray, + 'creditCardTypes' => $creditCards, + 'tokenBillingOptions' => $tokenBillingOptions, + 'showBreadcrumbs' => false, + 'onlyPayPal' => $onlyPayPal, + 'countGateways' => count($currentGateways) + ]; + } + + public function delete() + { + $accountGatewayPublicId = Input::get('accountGatewayPublicId'); + $gateway = AccountGateway::scope($accountGatewayPublicId)->firstOrFail(); + + $gateway->delete(); + + Session::flash('message', trans('texts.deleted_gateway')); + + return Redirect::to('company/payments'); + } + + /** + * Stores new account + * + */ + public function save($accountGatewayPublicId = false) + { + $rules = array(); + $recommendedId = Input::get('recommendedGateway_id'); + + $gatewayId = ($recommendedId == 1000000 ? Input::get('gateway_id') : $recommendedId); + + if (!$gatewayId) { + Session::flash('error', trans('validation.required', ['attribute' => 'gateway'])); + return Redirect::to('gateways/create') + ->withInput(); + } + + $gateway = Gateway::findOrFail($gatewayId); + $paymentLibrary = $gateway->paymentlibrary; + $fields = $gateway->getFields(); + + foreach ($fields as $field => $details) { + if (!in_array($field, ['testMode', 'developerMode', 'headerImageUrl', 'solutionType', 'landingPage', 'brandName', 'logoImageUrl', 'borderColor'])) { + if (strtolower($gateway->name) == 'beanstream') { + if (in_array($field, ['merchant_id', 'passCode'])) { + $rules[$gateway->id.'_'.$field] = 'required'; + } + } else { + $rules[$gateway->id.'_'.$field] = 'required'; + } + } + } + + $creditcards = Input::get('creditCardTypes'); + $validator = Validator::make(Input::all(), $rules); + + if ($validator->fails()) { + return Redirect::to('gateways/create') + ->withErrors($validator) + ->withInput(); + } else { + $account = Account::with('account_gateways')->findOrFail(Auth::user()->account_id); + + if ($accountGatewayPublicId) { + $accountGateway = AccountGateway::scope($accountGatewayPublicId)->firstOrFail(); + } else { + $accountGateway = AccountGateway::createNew(); + $accountGateway->gateway_id = $gatewayId; + } + + $isMasked = false; + + $config = new stdClass(); + foreach ($fields as $field => $details) { + $value = trim(Input::get($gateway->id.'_'.$field)); + + if ($value && $value === str_repeat('*', strlen($value))) { + $isMasked = true; + } + + $config->$field = $value; + } + + $cardCount = 0; + if ($creditcards) { + foreach ($creditcards as $card => $value) { + $cardCount += intval($value); + } + } + + // if the values haven't changed don't update the config + if ($isMasked && $accountGatewayPublicId) { + $accountGateway->accepted_credit_cards = $cardCount; + $accountGateway->save(); + // if there's an existing config for this gateway update it + } elseif (!$isMasked && $accountGatewayPublicId && $accountGateway->gateway_id == $gatewayId) { + $accountGateway->accepted_credit_cards = $cardCount; + $accountGateway->config = json_encode($config); + $accountGateway->save(); + // otherwise, create a new gateway config + } else { + $accountGateway->config = json_encode($config); + $accountGateway->accepted_credit_cards = $cardCount; + $account->account_gateways()->save($accountGateway); + } + + if (Input::get('token_billing_type_id')) { + $account->token_billing_type_id = Input::get('token_billing_type_id'); + $account->save(); + } + + if ($accountGatewayPublicId) { + $message = trans('texts.updated_gateway'); + } else { + $message = trans('texts.created_gateway'); + } + + Session::flash('message', $message); + + return Redirect::to('company/payments'); + } + } + +} \ No newline at end of file diff --git a/app/controllers/InvoiceController.php b/app/controllers/InvoiceController.php index e41dfd98775f..dabbb0c00c10 100755 --- a/app/controllers/InvoiceController.php +++ b/app/controllers/InvoiceController.php @@ -167,8 +167,8 @@ class InvoiceController extends \BaseController $invoice->invoice_date = Utils::fromSqlDate($invoice->invoice_date); $invoice->due_date = Utils::fromSqlDate($invoice->due_date); - $invoice->is_pro = $client->account->isPro(); - + $invoice->is_pro = $client->account->isPro(); + $contact = $invitation->contact; $contact->setVisible([ 'first_name', @@ -184,7 +184,8 @@ class InvoiceController extends \BaseController 'invitation' => $invitation, 'invoiceLabels' => $client->account->getInvoiceLabels(), 'contact' => $contact, - 'hasToken' => $client->getGatewayToken() + 'hasToken' => $client->getGatewayToken(), + 'countGateways' => AccountGateway::scope()->count(), ); return View::make('invoices.view', $data); diff --git a/app/controllers/PaymentController.php b/app/controllers/PaymentController.php index f94a93a3fcf6..196a81052563 100755 --- a/app/controllers/PaymentController.php +++ b/app/controllers/PaymentController.php @@ -226,7 +226,7 @@ class PaymentController extends \BaseController private function getPaymentDetails($invoice, $input = null) { $key = $invoice->invoice_number.'_details'; - $gateway = $invoice->client->account->account_gateways[0]->gateway; + $gateway = $invoice->client->account->getGatewayByType(Session::get('payment_type'))->gateway; $paymentLibrary = $gateway->paymentlibrary; $currencyCode = $invoice->client->currency ? $invoice->client->currency->code : ($invoice->account->currency ? $invoice->account->currency->code : 'USD'); @@ -301,10 +301,26 @@ class PaymentController extends \BaseController if (Input::get('use_token') == 'true') { return self::do_payment($invitationKey, false, true); } - // For PayPal Express we redirect straight to their site - $invitation = Invitation::with('invoice.client.account', 'invoice.client.account.account_gateways.gateway')->where('invitation_key', '=', $invitationKey)->firstOrFail(); - $account = $invitation->invoice->client->account; - if ($account->isGatewayConfigured(GATEWAY_PAYPAL_EXPRESS)) { + + if (Input::has('use_paypal')) { + Session::put('payment_type', Input::get('use_paypal') == 'true' ? PAYMENT_TYPE_PAYPAL : PAYMENT_TYPE_CREDIT_CARD); + } else { + Session::put('payment_type', PAYMENT_TYPE_ANY); + } + Session::save(); + + // For PayPal we redirect straight to their site + $usePayPal = false; + if ($usePayPal = Input::get('use_paypal')) { + $usePayPal = $usePayPal == 'true'; + } else { + $invitation = Invitation::with('invoice.client.account', 'invoice.client.account.account_gateways.gateway')->where('invitation_key', '=', $invitationKey)->firstOrFail(); + $account = $invitation->invoice->client->account; + if ($account->isGatewayConfigured(GATEWAY_PAYPAL_EXPRESS)) { + $usePayPal = true; + } + } + if ($usePayPal) { if (Session::has('error')) { Session::reflash(); return Redirect::to('view/'.$invitationKey); @@ -316,8 +332,8 @@ class PaymentController extends \BaseController $invitation = Invitation::with('invoice.invoice_items', 'invoice.client.currency', 'invoice.client.account.account_gateways.gateway')->where('invitation_key', '=', $invitationKey)->firstOrFail(); $invoice = $invitation->invoice; $client = $invoice->client; - $accountGateway = $invoice->client->account->account_gateways[0]; - $gateway = $invoice->client->account->account_gateways[0]->gateway; + $accountGateway = $invoice->client->account->getGatewayByType(Session::get('payment_type')); + $gateway = $invoice->client->account->getGatewayByType(Session::get('payment_type'))->gateway; $paymentLibrary = $gateway->paymentlibrary; $acceptedCreditCardTypes = $accountGateway->getCreditcardTypes(); @@ -363,7 +379,7 @@ class PaymentController extends \BaseController $account = $this->accountRepo->getNinjaAccount(); $account->load('account_gateways.gateway'); - $accountGateway = $account->account_gateways[0]; + $accountGateway = $account->getGatewayByType(Session::get('payment_type')); $gateway = $accountGateway->gateway; $paymentLibrary = $gateway->paymentlibrary; $acceptedCreditCardTypes = $accountGateway->getCreditcardTypes(); @@ -415,7 +431,7 @@ class PaymentController extends \BaseController $account = $this->accountRepo->getNinjaAccount(); $account->load('account_gateways.gateway'); - $accountGateway = $account->account_gateways[0]; + $accountGateway = $account->getGatewayByType(PAYMENT_TYPE_CREDIT_CARD); try { $affiliate = Affiliate::find(Session::get('affiliate_id')); @@ -527,7 +543,7 @@ class PaymentController extends \BaseController $invoice = $invitation->invoice; $client = $invoice->client; $account = $client->account; - $accountGateway = $account->account_gateways[0]; + $accountGateway = $account->getGatewayByType(Session::get('payment_type')); $paymentLibrary = $accountGateway->gateway->paymentlibrary; if ($onSite) { @@ -542,7 +558,7 @@ class PaymentController extends \BaseController try { if ($paymentLibrary->id == PAYMENT_LIBRARY_OMNIPAY) { $gateway = self::createGateway($accountGateway); - $details = self::getPaymentDetails($invoice, $useToken ? false : Input::all()); + $details = self::getPaymentDetails($invoice, $useToken || !$onSite ? false : Input::all()); if ($accountGateway->gateway_id == GATEWAY_STRIPE) { if ($useToken) { @@ -644,7 +660,7 @@ class PaymentController extends \BaseController private function createPayment($invitation, $ref, $payerId = null) { $invoice = $invitation->invoice; - $accountGateway = $invoice->client->account->account_gateways[0]; + $accountGateway = $invoice->client->account->getGatewayByType(Session::get('payment_type')); if ($invoice->account->account_key == NINJA_ACCOUNT_KEY) { $account = Account::find($invoice->client->public_id); @@ -681,7 +697,7 @@ class PaymentController extends \BaseController $invitation = Invitation::with('invoice.client.currency', 'invoice.client.account.account_gateways.gateway')->where('transaction_reference', '=', $token)->firstOrFail(); $invoice = $invitation->invoice; - $accountGateway = $invoice->client->account->account_gateways[0]; + $accountGateway = $invoice->client->account->getGatewayByType(Session::get('payment_type')); $gateway = self::createGateway($accountGateway); try { diff --git a/app/lang/da/texts.php b/app/lang/da/texts.php index c9bb24e2dbf7..23612c3fe0ac 100644 --- a/app/lang/da/texts.php +++ b/app/lang/da/texts.php @@ -549,6 +549,16 @@ return array( 'edit_token' => 'Edit Token', 'delete_token' => 'Delete Token', 'token' => 'Token', + + 'add_gateway' => 'Add Gateway', + 'delete_gateway' => 'Delete Gateway', + 'edit_gateway' => 'Edit Gateway', + 'updated_gateway' => 'Successfully updated gateway', + 'created_gateway' => 'Successfully created gateway', + 'deleted_gateway' => 'Successfully deleted gateway', + 'pay_with_paypal' => 'PayPal', + 'pay_with_card' => 'Credit card', + ); diff --git a/app/lang/de/texts.php b/app/lang/de/texts.php index 9b625600c51f..2a5a2f668283 100644 --- a/app/lang/de/texts.php +++ b/app/lang/de/texts.php @@ -539,6 +539,16 @@ return array( 'edit_token' => 'Edit Token', 'delete_token' => 'Delete Token', 'token' => 'Token', + + 'add_gateway' => 'Add Gateway', + 'delete_gateway' => 'Delete Gateway', + 'edit_gateway' => 'Edit Gateway', + 'updated_gateway' => 'Successfully updated gateway', + 'created_gateway' => 'Successfully created gateway', + 'deleted_gateway' => 'Successfully deleted gateway', + 'pay_with_paypal' => 'PayPal', + 'pay_with_card' => 'Credit card', + ); diff --git a/app/lang/en/texts.php b/app/lang/en/texts.php index f15f14e5e85c..646154ebdf80 100644 --- a/app/lang/en/texts.php +++ b/app/lang/en/texts.php @@ -548,4 +548,14 @@ return array( 'delete_token' => 'Delete Token', 'token' => 'Token', + 'add_gateway' => 'Add Gateway', + 'delete_gateway' => 'Delete Gateway', + 'edit_gateway' => 'Edit Gateway', + 'updated_gateway' => 'Successfully updated gateway', + 'created_gateway' => 'Successfully created gateway', + 'deleted_gateway' => 'Successfully deleted gateway', + 'pay_with_paypal' => 'PayPal', + 'pay_with_card' => 'Credit card', + + ); diff --git a/app/lang/es/texts.php b/app/lang/es/texts.php index 76aac6f70da1..c13074f2d8f8 100644 --- a/app/lang/es/texts.php +++ b/app/lang/es/texts.php @@ -520,4 +520,14 @@ return array( 'delete_token' => 'Delete Token', 'token' => 'Token', + 'add_gateway' => 'Add Gateway', + 'delete_gateway' => 'Delete Gateway', + 'edit_gateway' => 'Edit Gateway', + 'updated_gateway' => 'Successfully updated gateway', + 'created_gateway' => 'Successfully created gateway', + 'deleted_gateway' => 'Successfully deleted gateway', + 'pay_with_paypal' => 'PayPal', + 'pay_with_card' => 'Credit card', + + ); \ No newline at end of file diff --git a/app/lang/fr/texts.php b/app/lang/fr/texts.php index 3ca233cf043c..40d55c761fce 100644 --- a/app/lang/fr/texts.php +++ b/app/lang/fr/texts.php @@ -541,4 +541,14 @@ return array( 'delete_token' => 'Delete Token', 'token' => 'Token', + 'add_gateway' => 'Add Gateway', + 'delete_gateway' => 'Delete Gateway', + 'edit_gateway' => 'Edit Gateway', + 'updated_gateway' => 'Successfully updated gateway', + 'created_gateway' => 'Successfully created gateway', + 'deleted_gateway' => 'Successfully deleted gateway', + 'pay_with_paypal' => 'PayPal', + 'pay_with_card' => 'Credit card', + + ); \ No newline at end of file diff --git a/app/lang/it/texts.php b/app/lang/it/texts.php index 7fa241629f23..30032642df30 100644 --- a/app/lang/it/texts.php +++ b/app/lang/it/texts.php @@ -542,5 +542,15 @@ return array( 'edit_token' => 'Edit Token', 'delete_token' => 'Delete Token', 'token' => 'Token', + + 'add_gateway' => 'Add Gateway', + 'delete_gateway' => 'Delete Gateway', + 'edit_gateway' => 'Edit Gateway', + 'updated_gateway' => 'Successfully updated gateway', + 'created_gateway' => 'Successfully created gateway', + 'deleted_gateway' => 'Successfully deleted gateway', + 'pay_with_paypal' => 'PayPal', + 'pay_with_card' => 'Credit card', + ); diff --git a/app/lang/lt/texts.php b/app/lang/lt/texts.php index d0985358a938..0707cbc6f934 100644 --- a/app/lang/lt/texts.php +++ b/app/lang/lt/texts.php @@ -550,6 +550,16 @@ return array( 'edit_token' => 'Edit Token', 'delete_token' => 'Delete Token', 'token' => 'Token', + + 'add_gateway' => 'Add Gateway', + 'delete_gateway' => 'Delete Gateway', + 'edit_gateway' => 'Edit Gateway', + 'updated_gateway' => 'Successfully updated gateway', + 'created_gateway' => 'Successfully created gateway', + 'deleted_gateway' => 'Successfully deleted gateway', + 'pay_with_paypal' => 'PayPal', + 'pay_with_card' => 'Credit card', + ); diff --git a/app/lang/nl/texts.php b/app/lang/nl/texts.php index e9f4e7d5abc8..36a7027cc966 100644 --- a/app/lang/nl/texts.php +++ b/app/lang/nl/texts.php @@ -543,6 +543,16 @@ return array( 'edit_token' => 'Edit Token', 'delete_token' => 'Delete Token', 'token' => 'Token', - + + 'add_gateway' => 'Add Gateway', + 'delete_gateway' => 'Delete Gateway', + 'edit_gateway' => 'Edit Gateway', + 'updated_gateway' => 'Successfully updated gateway', + 'created_gateway' => 'Successfully created gateway', + 'deleted_gateway' => 'Successfully deleted gateway', + 'pay_with_paypal' => 'PayPal', + 'pay_with_card' => 'Credit card', + + ); \ No newline at end of file diff --git a/app/lang/pt_BR/texts.php b/app/lang/pt_BR/texts.php index 079721e4d925..531f8a3e94a8 100644 --- a/app/lang/pt_BR/texts.php +++ b/app/lang/pt_BR/texts.php @@ -531,5 +531,15 @@ return array( 'delete_token' => 'Delete Token', 'token' => 'Token', + 'add_gateway' => 'Add Gateway', + 'delete_gateway' => 'Delete Gateway', + 'edit_gateway' => 'Edit Gateway', + 'updated_gateway' => 'Successfully updated gateway', + 'created_gateway' => 'Successfully created gateway', + 'deleted_gateway' => 'Successfully deleted gateway', + 'pay_with_paypal' => 'PayPal', + 'pay_with_card' => 'Credit card', + + ); diff --git a/app/models/Account.php b/app/models/Account.php index caaa03c12689..bbe026266a64 100755 --- a/app/models/Account.php +++ b/app/models/Account.php @@ -96,6 +96,21 @@ class Account extends Eloquent } } + public function getGatewayByType($type = PAYMENT_TYPE_ANY) + { + foreach ($this->account_gateways as $gateway) { + if ($type == PAYMENT_TYPE_ANY) { + return $gateway; + } elseif ($gateway->isPayPal() && $type == PAYMENT_TYPE_PAYPAL) { + return $gateway; + } elseif (!$gateway->isPayPal() && $type == PAYMENT_TYPE_CREDIT_CARD) { + return $gateway; + } + } + + return false; + } + public function getGatewayConfig($gatewayId) { foreach ($this->account_gateways as $gateway) { diff --git a/app/models/AccountGateway.php b/app/models/AccountGateway.php index 39ebd7a8be3b..e66a599cba97 100755 --- a/app/models/AccountGateway.php +++ b/app/models/AccountGateway.php @@ -20,4 +20,8 @@ class AccountGateway extends EntityModel return $arrayOfImages; } + + public function isPayPal() { + return $this->gateway_id == GATEWAY_PAYPAL_EXPRESS || $this->gateway_id == GATEWAY_PAYPAL_PRO; + } } diff --git a/app/models/Client.php b/app/models/Client.php index 70d0c7a3b7df..df723de8fc77 100755 --- a/app/models/Client.php +++ b/app/models/Client.php @@ -229,9 +229,9 @@ class Client extends EntityModel return false; } - $accountGateway = $this->account->account_gateways[0]; + $accountGateway = $this->account->getGatewayConfig(GATEWAY_STRIPE); - if ($accountGateway->gateway_id != GATEWAY_STRIPE) { + if (!$accountGateway) { return false; } diff --git a/app/routes.php b/app/routes.php index 377407cc6ec0..8b1641314e28 100755 --- a/app/routes.php +++ b/app/routes.php @@ -102,6 +102,10 @@ Route::group(array('before' => 'auth'), function() { Route::post('remove_logo', 'AccountController@removeLogo'); Route::post('account/go_pro', 'AccountController@enableProPlan'); + Route::resource('gateways', 'AccountGatewayController'); + Route::get('api/gateways', array('as'=>'api.gateways', 'uses'=>'AccountGatewayController@getDatatable')); + Route::post('gateways/delete', 'AccountGatewayController@delete'); + Route::resource('clients', 'ClientController'); Route::get('api/clients', array('as'=>'api.clients', 'uses'=>'ClientController@getDatatable')); Route::get('api/activities/{client_id?}', array('as'=>'api.activities', 'uses'=>'ActivityController@getDatatable')); @@ -277,6 +281,7 @@ define('PAYMENT_LIBRARY_PHP_PAYMENTS', 2); define('GATEWAY_AUTHORIZE_NET', 1); define('GATEWAY_AUTHORIZE_NET_SIM', 2); define('GATEWAY_PAYPAL_EXPRESS', 17); +define('GATEWAY_PAYPAL_PRO', 18); define('GATEWAY_STRIPE', 23); define('GATEWAY_TWO_CHECKOUT', 27); define('GATEWAY_BEANSTREAM', 29); @@ -322,6 +327,10 @@ define('TOKEN_BILLING_OPT_IN', 2); define('TOKEN_BILLING_OPT_OUT', 3); define('TOKEN_BILLING_ALWAYS', 4); +define('PAYMENT_TYPE_PAYPAL', 'PAYMENT_TYPE_PAYPAL'); +define('PAYMENT_TYPE_CREDIT_CARD', 'PAYMENT_TYPE_CREDIT_CARD'); +define('PAYMENT_TYPE_ANY', 'PAYMENT_TYPE_ANY'); + /* define('GATEWAY_AMAZON', 30); define('GATEWAY_BLUEPAY', 31); @@ -347,7 +356,7 @@ define('CREDIT_CARDS', serialize($creditCards)); HTML::macro('nav_link', function($url, $text, $url2 = '', $extra = '') { - $class = ( Request::is($url) || Request::is($url.'/*') || Request::is($url2) ) ? ' class="active"' : ''; + $class = ( Request::is($url) || Request::is($url.'/*') || Request::is($url2.'/*') ) ? ' class="active"' : ''; $title = ucwords(trans("texts.$text")) . Utils::getProLabel($text); return ''.$title.''; }); diff --git a/app/views/accounts/account_gateway.blade.php b/app/views/accounts/account_gateway.blade.php new file mode 100644 index 000000000000..9aa605664798 --- /dev/null +++ b/app/views/accounts/account_gateway.blade.php @@ -0,0 +1,153 @@ +@extends('accounts.nav') + +@section('content') + @parent + + {{ Former::open($url)->method($method)->rule()->addClass('col-md-8 col-md-offset-2 warn-on-exit') }} + {{ Former::populate($account) }} + + {{ Former::legend($title) }} + + @if ($accountGateway) + {{ Former::populateField('gateway_id', $accountGateway->gateway_id) }} + {{ Former::populateField('recommendedGateway_id', $accountGateway->gateway_id) }} + @if ($config) + @foreach ($accountGateway->fields as $field => $junk) + @if (in_array($field, ['solutionType', 'landingPage', 'headerImageUrl', 'brandName'])) + {{-- do nothing --}} + @elseif (isset($config->$field)) + {{ Former::populateField($accountGateway->gateway_id.'_'.$field, $config->$field) }} + @endif + @endforeach + @endif + @endif + +
+ {{ Former::checkboxes('creditCardTypes[]')->label('Accepted Credit Cards') + ->checkboxes($creditCardTypes)->class('creditcard-types') + }} +
+ +

 

+ +

+
+ {{ Former::radios('recommendedGateway_id')->label('Recommended Gateway') + ->radios($recommendedGateways)->class('recommended-gateway') + }} +
+ + {{ Former::select('gateway_id')->label('Select Gateway')->addOption('', '') + ->dataClass('gateway-dropdown') + ->fromQuery($gateways, 'name', 'id') + ->onchange('setFieldsShown()'); }} +
+ + @foreach ($gateways as $gateway) + + + + @endforeach + +

 

+ + {{ Former::actions( + Button::lg_success_submit('Save')->append_with_icon('floppy-disk'), + $countGateways > 0 ? Button::lg_default_link('company/payments', 'Cancel')->append_with_icon('remove-circle') : false + )}} + {{ Former::close() }} + + + + +@stop \ No newline at end of file diff --git a/app/views/accounts/nav.blade.php b/app/views/accounts/nav.blade.php index 66fca0dcc43b..1aec91d426a5 100755 --- a/app/views/accounts/nav.blade.php +++ b/app/views/accounts/nav.blade.php @@ -4,13 +4,12 @@

- -
+

 

@stop \ No newline at end of file diff --git a/app/views/accounts/nav_advanced.blade.php b/app/views/accounts/nav_advanced.blade.php index 99ea2abf8eb6..7c344f575419 100644 --- a/app/views/accounts/nav_advanced.blade.php +++ b/app/views/accounts/nav_advanced.blade.php @@ -4,8 +4,8 @@ {{ HTML::nav_link('company/advanced_settings/email_templates', 'email_templates') }} {{ HTML::nav_link('company/advanced_settings/data_visualizations', 'data_visualizations') }} {{ HTML::nav_link('company/advanced_settings/chart_builder', 'chart_builder') }} - {{ HTML::nav_link('company/advanced_settings/user_management', 'users') }} - {{ HTML::nav_link('company/advanced_settings/token_management', 'tokens') }} + {{ HTML::nav_link('company/advanced_settings/user_management', 'users', 'users') }} + {{ HTML::nav_link('company/advanced_settings/token_management', 'tokens', 'tokens') }}

 

diff --git a/app/views/accounts/payments.blade.php b/app/views/accounts/payments.blade.php index a47ba1ce2cab..abb07a11c787 100755 --- a/app/views/accounts/payments.blade.php +++ b/app/views/accounts/payments.blade.php @@ -3,146 +3,58 @@ @section('content') @parent - {{ Former::open()->rule()->addClass('col-md-8 col-md-offset-2 warn-on-exit') }} - {{ Former::populate($account) }} + {{ Former::open('gateways/delete')->addClass('user-form') }} + {{ Former::legend('online_payments') }} - {{ Former::legend('Payment Gateway') }} - - @if ($accountGateway) - {{ Former::populateField('gateway_id', $accountGateway->gateway_id) }} - {{ Former::populateField('recommendedGateway_id', $accountGateway->gateway_id) }} - @if ($config) - @foreach ($accountGateway->fields as $field => $junk) - @if (in_array($field, ['solutionType', 'landingPage', 'headerImageUrl', 'brandName'])) - {{-- do nothing --}} - @elseif (isset($config->$field)) - {{ Former::populateField($accountGateway->gateway_id.'_'.$field, $config->$field) }} - @endif - @endforeach - @endif - @endif - -
- {{ Former::checkboxes('creditCardTypes[]')->label('Accepted Credit Cards') - ->checkboxes($creditCardTypes)->class('creditcard-types') - }} -
- -

 

- -

- {{ Former::radios('recommendedGateway_id')->label('Recommended Gateway') - ->radios($recommendedGateways)->class('recommended-gateway') - }} -
- - {{ Former::select('gateway_id')->label('Select Gateway')->addOption('', '') - ->dataClass('gateway-dropdown') - ->fromQuery($dropdownGateways, 'name', 'id') - ->onchange('setFieldsShown()'); }} - - @foreach ($gateways as $gateway) - - - - @endforeach - -

 

- - {{ Former::actions( Button::lg_success_submit('Save')->append_with_icon('floppy-disk') ) }} - {{ Former::close() }} +

+ {{ Former::text('accountGatewayPublicId') }} +
+ {{ Former::close() }} - + $('#accountGatewayPublicId').val(id); + $('form.user-form').submit(); + } + @stop \ No newline at end of file diff --git a/app/views/accounts/product.blade.php b/app/views/accounts/product.blade.php index c6acabecf0e2..9fe08652c237 100644 --- a/app/views/accounts/product.blade.php +++ b/app/views/accounts/product.blade.php @@ -21,7 +21,7 @@ {{ Former::actions( Button::lg_success_submit(trans('texts.save'))->append_with_icon('floppy-disk'), - Button::lg_default_link('company/products', 'Cancel')->append_with_icon('remove-circle') + Button::lg_default_link('company/products', trans('texts.cancel'))->append_with_icon('remove-circle') ) }} {{ Former::close() }} diff --git a/app/views/accounts/token.blade.php b/app/views/accounts/token.blade.php index ac8649079f92..ace566e9dbf3 100644 --- a/app/views/accounts/token.blade.php +++ b/app/views/accounts/token.blade.php @@ -2,6 +2,7 @@ @section('content') @parent + @include('accounts.nav_advanced') {{ Former::open($url)->method($method)->addClass('col-md-8 col-md-offset-2 warn-on-exit')->rules(array( 'name' => 'required', @@ -21,7 +22,7 @@ {{ Former::actions( Button::lg_success_submit(trans('texts.save'))->append_with_icon('floppy-disk'), - Button::lg_default_link('company/advanced_settings/token_management', 'Cancel')->append_with_icon('remove-circle') + Button::lg_default_link('company/advanced_settings/token_management', trans('texts.cancel'))->append_with_icon('remove-circle') ) }} {{ Former::close() }} diff --git a/app/views/clients/show.blade.php b/app/views/clients/show.blade.php index eb30c8a3e84a..c162d2939052 100755 --- a/app/views/clients/show.blade.php +++ b/app/views/clients/show.blade.php @@ -10,6 +10,10 @@ {{ Former::text('id')->value($client->public_id) }} + @if ($gatewayLink) + {{ Button::link($gatewayLink, trans('texts.view_in_stripe'), ['target' => '_blank']) }} + @endif + @if ($client->trashed()) {{ Button::primary(trans('texts.restore_client'), ['onclick' => 'onRestoreClick()']) }} @else diff --git a/app/views/invoices/view.blade.php b/app/views/invoices/view.blade.php index 84adacbe7316..6f53dba4a4c8 100755 --- a/app/views/invoices/view.blade.php +++ b/app/views/invoices/view.blade.php @@ -30,8 +30,13 @@ {{ Button::normal(trans('texts.download_pdf'), array('onclick' => 'onDownloadClick()', 'class' => 'btn-lg')) }}   @if ($hasToken) {{ DropdownButton::success_lg(trans('texts.pay_now'), [ - ['url' => URL::to("payment/{$invitation->invitation_key}?use_token=true"), 'label' => trans('texts.use_card_on_file')], - ['url' => URL::to('payment/' . $invitation->invitation_key), 'label' => trans('texts.edit_payment_details')] + ['url' => URL::to("payment/{$invitation->invitation_key}?use_token=true&use_paypal=false"), 'label' => trans('texts.use_card_on_file')], + ['url' => URL::to("payment/{$invitation->invitation_key}?use_paypal=false"), 'label' => trans('texts.edit_payment_details')] + ])->addClass('btn-lg') }} + @elseif ($countGateways == 2) + {{ DropdownButton::success_lg(trans('texts.pay_now'), [ + ['url' => URL::to("payment/{$invitation->invitation_key}?use_paypal=true"), 'label' => trans('texts.pay_with_paypal')], + ['url' => URL::to("payment/{$invitation->invitation_key}?use_paypal=false"), 'label' => trans('texts.pay_with_card')] ])->addClass('btn-lg') }} @else {{ Button::success_link(URL::to('payment/' . $invitation->invitation_key), trans('texts.pay_now'), array('class' => 'btn-lg')) }} diff --git a/app/views/users/edit.blade.php b/app/views/users/edit.blade.php index 74a07e1b2027..c88f4b43370f 100644 --- a/app/views/users/edit.blade.php +++ b/app/views/users/edit.blade.php @@ -2,6 +2,7 @@ @section('content') @parent + @include('accounts.nav_advanced') {{ Former::open($url)->method($method)->addClass('col-md-8 col-md-offset-2 warn-on-exit')->rules(array( 'first_name' => 'required', @@ -21,8 +22,8 @@ {{ Former::actions( Button::lg_success_submit(trans($user && $user->confirmed ? 'texts.save' : 'texts.send_invite'))->append_with_icon($user && $user->confirmed ? 'floppy-disk' : 'send'), - Button::lg_default_link('company/advanced_settings/user_management', 'Cancel')->append_with_icon('remove-circle') - ) }} + Button::lg_default_link('company/advanced_settings/user_management', trans('texts.cancel'))->append_with_icon('remove-circle') + )}} {{ Former::close() }}