From 6088a3617529e46ad2f04f98b8305ff7f38233f9 Mon Sep 17 00:00:00 2001 From: Hillel Coren Date: Mon, 26 Sep 2016 12:33:30 +0300 Subject: [PATCH] Support for custom gateway --- .../Controllers/AccountGatewayController.php | 14 +++-- .../Controllers/ClientPortalController.php | 11 +++- app/Http/routes.php | 2 + app/Models/Gateway.php | 21 +++++++- .../Datatables/AccountGatewayDatatable.php | 52 ++++++++++++++----- .../PaymentDrivers/BasePaymentDriver.php | 13 ++++- .../PaymentDrivers/CustomPaymentDriver.php | 12 +++++ database/seeds/CurrenciesSeeder.php | 1 + database/seeds/GatewayTypesSeeder.php | 1 + database/seeds/PaymentLibrariesSeeder.php | 16 +++--- resources/lang/en/texts.php | 1 + .../views/accounts/account_gateway.blade.php | 2 + .../templates_and_reminders.blade.php | 4 +- resources/views/invoices/view.blade.php | 28 +++++++++- 14 files changed, 145 insertions(+), 33 deletions(-) create mode 100644 app/Ninja/PaymentDrivers/CustomPaymentDriver.php diff --git a/app/Http/Controllers/AccountGatewayController.php b/app/Http/Controllers/AccountGatewayController.php index d0ce1b6f62..30fbd3a11b 100644 --- a/app/Http/Controllers/AccountGatewayController.php +++ b/app/Http/Controllers/AccountGatewayController.php @@ -48,8 +48,10 @@ class AccountGatewayController extends BaseController $accountGateway = AccountGateway::scope($publicId)->firstOrFail(); $config = $accountGateway->getConfig(); - foreach ($config as $field => $value) { - $config->$field = str_repeat('*', strlen($value)); + if ($accountGateway->gateway_id != GATEWAY_CUSTOM) { + foreach ($config as $field => $value) { + $config->$field = str_repeat('*', strlen($value)); + } } $data = self::getViewModel($accountGateway); @@ -100,7 +102,7 @@ class AccountGatewayController extends BaseController if ($otherProviders) { $availableGatewaysIds = $account->availableGatewaysIds(); - $data['primaryGateways'] = Gateway::primary($availableGatewaysIds)->orderBy('name', 'desc')->get(); + $data['primaryGateways'] = Gateway::primary($availableGatewaysIds)->orderBy('sort_order')->get(); $data['secondaryGateways'] = Gateway::secondary($availableGatewaysIds)->orderBy('name')->get(); $data['hiddenFields'] = Gateway::$hiddenFields; @@ -132,7 +134,9 @@ class AccountGatewayController extends BaseController foreach ($gateways as $gateway) { $fields = $gateway->getFields(); - asort($fields); + if ( ! $gateway->isCustom()) { + asort($fields); + } $gateway->fields = $gateway->id == GATEWAY_WEPAY ? [] : $fields; if ($accountGateway && $accountGateway->gateway_id == $gateway->id) { $accountGateway->fields = $gateway->fields; @@ -247,6 +251,8 @@ class AccountGatewayController extends BaseController } if (!$value && ($field == 'testMode' || $field == 'developerMode')) { // do nothing + } elseif ($gatewayId == GATEWAY_CUSTOM && $field == 'text') { + $config->$field = strip_tags($value); } else { $config->$field = $value; } diff --git a/app/Http/Controllers/ClientPortalController.php b/app/Http/Controllers/ClientPortalController.php index 96a3ec2835..ca7f94414f 100644 --- a/app/Http/Controllers/ClientPortalController.php +++ b/app/Http/Controllers/ClientPortalController.php @@ -104,7 +104,9 @@ class ClientPortalController extends BaseController $paymentURL = ''; if (count($paymentTypes) == 1) { $paymentURL = $paymentTypes[0]['url']; - if (!$account->isGatewayConfigured(GATEWAY_PAYPAL_EXPRESS)) { + if ($paymentTypes[0]['gatewayTypeId'] == GATEWAY_TYPE_CUSTOM) { + // do nothing + } elseif (!$account->isGatewayConfigured(GATEWAY_PAYPAL_EXPRESS)) { $paymentURL = URL::to($paymentURL); } } @@ -143,7 +145,12 @@ class ClientPortalController extends BaseController ]; } - + if ($accountGateway = $account->getGatewayByType(GATEWAY_TYPE_CUSTOM)) { + $data += [ + 'customGatewayName' => $accountGateway->getConfigField('name'), + 'customGatewayText' => $accountGateway->getConfigField('text'), + ]; + } if($account->hasFeature(FEATURE_DOCUMENTS) && $this->canCreateZip()){ $zipDocs = $this->getInvoiceZipDocuments($invoice, $size); diff --git a/app/Http/routes.php b/app/Http/routes.php index 095e627f53..bf67e1682a 100644 --- a/app/Http/routes.php +++ b/app/Http/routes.php @@ -605,6 +605,7 @@ if (!defined('CONTACT_EMAIL')) { define('GATEWAY_CYBERSOURCE', 49); define('GATEWAY_WEPAY', 60); define('GATEWAY_BRAINTREE', 61); + define('GATEWAY_CUSTOM', 62); // The customer exists, but only as a local concept // The remote gateway doesn't understand the concept of customers @@ -713,6 +714,7 @@ if (!defined('CONTACT_EMAIL')) { define('GATEWAY_TYPE_PAYPAL', 3); define('GATEWAY_TYPE_BITCOIN', 4); define('GATEWAY_TYPE_DWOLLA', 5); + define('GATEWAY_TYPE_CUSTOM', 6); define('GATEWAY_TYPE_TOKEN', 'token'); define('REMINDER1', 'reminder1'); diff --git a/app/Models/Gateway.php b/app/Models/Gateway.php index c13065c73e..6f7c42d90c 100644 --- a/app/Models/Gateway.php +++ b/app/Models/Gateway.php @@ -14,6 +14,12 @@ class Gateway extends Eloquent */ public $timestamps = true; + protected $fillable = [ + 'provider', + 'is_offsite', + 'sort_order', + ]; + /** * @var array */ @@ -39,6 +45,7 @@ class Gateway extends Eloquent GATEWAY_BRAINTREE, GATEWAY_AUTHORIZE_NET, GATEWAY_MOLLIE, + GATEWAY_CUSTOM, ]; // allow adding these gateway if another gateway @@ -174,6 +181,18 @@ class Gateway extends Eloquent */ public function getFields() { - return Omnipay::create($this->provider)->getDefaultParameters(); + if ($this->isCustom()) { + return [ + 'name' => '', + 'text' => '', + ]; + } else { + return Omnipay::create($this->provider)->getDefaultParameters(); + } + } + + public function isCustom() + { + return $this->id === GATEWAY_CUSTOM; } } diff --git a/app/Ninja/Datatables/AccountGatewayDatatable.php b/app/Ninja/Datatables/AccountGatewayDatatable.php index f4f56c2511..e7a4be2558 100644 --- a/app/Ninja/Datatables/AccountGatewayDatatable.php +++ b/app/Ninja/Datatables/AccountGatewayDatatable.php @@ -10,6 +10,8 @@ use App\Models\AccountGateway; class AccountGatewayDatatable extends EntityDatatable { + private static $accountGateways; + public $entityType = ENTITY_ACCOUNT_GATEWAY; public function columns() @@ -20,10 +22,14 @@ class AccountGatewayDatatable extends EntityDatatable function ($model) { if ($model->deleted_at) { return $model->name; + } elseif ($model->gateway_id == GATEWAY_CUSTOM) { + $accountGateway = $this->getAccountGateway($model->id); + $name = $accountGateway->getConfigField('name') . ' [' . trans('texts.custom') . ']'; + return link_to("gateways/{$model->public_id}/edit", $name)->toHtml(); } elseif ($model->gateway_id != GATEWAY_WEPAY) { return link_to("gateways/{$model->public_id}/edit", $model->name)->toHtml(); } else { - $accountGateway = AccountGateway::find($model->id); + $accountGateway = $this->getAccountGateway($model->id); $config = $accountGateway->getConfig(); $endpoint = WEPAY_ENVIRONMENT == WEPAY_STAGE ? 'https://stage.wepay.com/' : 'https://www.wepay.com/'; $wepayAccountId = $config->accountId; @@ -53,10 +59,14 @@ class AccountGatewayDatatable extends EntityDatatable [ 'limit', function ($model) { - $accountGateway = AccountGateway::find($model->id); - $paymentDriver = $accountGateway->paymentDriver(); - $gatewayTypes = $paymentDriver->gatewayTypes(); - $gatewayTypes = array_diff($gatewayTypes, array(GATEWAY_TYPE_TOKEN)); + if ($model->gateway_id == GATEWAY_CUSTOM) { + $gatewayTypes = [GATEWAY_TYPE_CUSTOM]; + } else { + $accountGateway = $this->getAccountGateway($model->id); + $paymentDriver = $accountGateway->paymentDriver(); + $gatewayTypes = $paymentDriver->gatewayTypes(); + $gatewayTypes = array_diff($gatewayTypes, array(GATEWAY_TYPE_TOKEN)); + } $html = ''; foreach ($gatewayTypes as $gatewayTypeId) { @@ -123,7 +133,7 @@ class AccountGatewayDatatable extends EntityDatatable ], [ uctrans('texts.manage_account'), function ($model) { - $accountGateway = AccountGateway::find($model->id); + $accountGateway = $this->getAccountGateway($model->id); $endpoint = WEPAY_ENVIRONMENT == WEPAY_STAGE ? 'https://stage.wepay.com/' : 'https://www.wepay.com/'; return [ 'url' => $endpoint.'account/'.$accountGateway->getConfig()->accountId, @@ -148,20 +158,25 @@ class AccountGatewayDatatable extends EntityDatatable $actions[] = [ trans('texts.set_limits', ['gateway_type' => $gatewayType->name]), function () use ($gatewayType) { - $accountGatewaySettings = AccountGatewaySettings::scope()->where('account_gateway_settings.gateway_type_id', - '=', $gatewayType->id)->first(); + $accountGatewaySettings = AccountGatewaySettings::scope() + ->where('account_gateway_settings.gateway_type_id', '=', $gatewayType->id) + ->first(); $min = $accountGatewaySettings && $accountGatewaySettings->min_limit !== null ? $accountGatewaySettings->min_limit : 'null'; $max = $accountGatewaySettings && $accountGatewaySettings->max_limit !== null ? $accountGatewaySettings->max_limit : 'null'; - return "javascript:showLimitsModal('{$gatewayType->name}',{$gatewayType->id},$min,$max)"; + return "javascript:showLimitsModal('{$gatewayType->name}', {$gatewayType->id}, $min, $max)"; }, function ($model) use ($gatewayType) { // Only show this action if the given gateway supports this gateway type - $accountGateway = AccountGateway::find($model->id); - $paymentDriver = $accountGateway->paymentDriver(); - $gatewayTypes = $paymentDriver->gatewayTypes(); + if ($model->gateway_id == GATEWAY_CUSTOM) { + return $gatewayType->id == GATEWAY_TYPE_CUSTOM; + } else { + $accountGateway = $this->getAccountGateway($model->id); + $paymentDriver = $accountGateway->paymentDriver(); + $gatewayTypes = $paymentDriver->gatewayTypes(); - return in_array($gatewayType->id, $gatewayTypes); + return in_array($gatewayType->id, $gatewayTypes); + } } ]; } @@ -169,4 +184,15 @@ class AccountGatewayDatatable extends EntityDatatable return $actions; } + private function getAccountGateway($id) + { + if (isset(static::$accountGateways[$id])) { + return static::$accountGateways[$id]; + } + + static::$accountGateways[$id] = AccountGateway::find($id); + + return static::$accountGateways[$id]; + } + } diff --git a/app/Ninja/PaymentDrivers/BasePaymentDriver.php b/app/Ninja/PaymentDrivers/BasePaymentDriver.php index dc4d4e0ff3..948aec1f98 100644 --- a/app/Ninja/PaymentDrivers/BasePaymentDriver.php +++ b/app/Ninja/PaymentDrivers/BasePaymentDriver.php @@ -818,9 +818,18 @@ class BasePaymentDriver $gatewayTypeAlias = GatewayType::getAliasFromId($gatewayTypeId); + if ($gatewayTypeId == GATEWAY_TYPE_CUSTOM) { + $url = "javascript:showCustomModal();"; + $label = $this->accountGateway->getConfigField('name'); + } else { + $url = $this->paymentUrl($gatewayTypeAlias); + $label = trans("texts.{$gatewayTypeAlias}"); + } + $links[] = [ - 'url' => $this->paymentUrl($gatewayTypeAlias), - 'label' => trans("texts.{$gatewayTypeAlias}") + 'gatewayTypeId' => $gatewayTypeId, + 'url' => $url, + 'label' => $label, ]; } diff --git a/app/Ninja/PaymentDrivers/CustomPaymentDriver.php b/app/Ninja/PaymentDrivers/CustomPaymentDriver.php new file mode 100644 index 0000000000..1dcbc7095b --- /dev/null +++ b/app/Ninja/PaymentDrivers/CustomPaymentDriver.php @@ -0,0 +1,12 @@ + 'Pakistani Rupee', 'code' => 'PKR', 'symbol' => 'Rs ', 'precision' => '0', 'thousand_separator' => ',', 'decimal_separator' => '.'], ['name' => 'Polish Zloty', 'code' => 'PLN', 'symbol' => 'zł', 'precision' => '2', 'thousand_separator' => ' ', 'decimal_separator' => ',', 'swap_currency_symbol' => true], ['name' => 'Sri Lankan Rupee', 'code' => 'LKR', 'symbol' => 'LKR', 'precision' => '2', 'thousand_separator' => ',', 'decimal_separator' => '.', 'swap_currency_symbol' => true], + //['name' => 'Bahraini Dinar', 'code' => 'BHD', 'symbol' => '', 'precision' => '2', 'thousand_separator' => ',', 'decimal_separator' => '.'], ]; foreach ($currencies as $currency) { diff --git a/database/seeds/GatewayTypesSeeder.php b/database/seeds/GatewayTypesSeeder.php index d97eef5ca2..dc556e89fd 100644 --- a/database/seeds/GatewayTypesSeeder.php +++ b/database/seeds/GatewayTypesSeeder.php @@ -15,6 +15,7 @@ class GatewayTypesSeeder extends Seeder ['alias' => 'paypal', 'name' => 'PayPal'], ['alias' => 'bitcoin', 'name' => 'Bitcoin'], ['alias' => 'dwolla', 'name' => 'Dwolla'], + ['alias' => 'custom', 'name' => 'Custom'], ]; foreach ($gateway_types as $gateway_type) { diff --git a/database/seeds/PaymentLibrariesSeeder.php b/database/seeds/PaymentLibrariesSeeder.php index e7884e422d..42dda31400 100644 --- a/database/seeds/PaymentLibrariesSeeder.php +++ b/database/seeds/PaymentLibrariesSeeder.php @@ -15,7 +15,7 @@ class PaymentLibrariesSeeder extends Seeder Eloquent::unguard(); $gateways = [ - ['name' => 'Authorize.Net AIM', 'provider' => 'AuthorizeNet_AIM'], + ['name' => 'Authorize.Net AIM', 'provider' => 'AuthorizeNet_AIM', 'sort_order' => 3], ['name' => 'Authorize.Net SIM', 'provider' => 'AuthorizeNet_SIM', 'payment_library_id' => 2], ['name' => 'CardSave', 'provider' => 'CardSave'], ['name' => 'Eway Rapid', 'provider' => 'Eway_RapidShared', 'is_offsite' => true], @@ -23,7 +23,7 @@ class PaymentLibrariesSeeder extends Seeder ['name' => 'GoCardless', 'provider' => 'GoCardless', 'is_offsite' => true], ['name' => 'Migs ThreeParty', 'provider' => 'Migs_ThreeParty'], ['name' => 'Migs TwoParty', 'provider' => 'Migs_TwoParty'], - ['name' => 'Mollie', 'provider' => 'Mollie', 'is_offsite' => true], + ['name' => 'Mollie', 'provider' => 'Mollie', 'is_offsite' => true, 'sort_order' => 6], ['name' => 'MultiSafepay', 'provider' => 'MultiSafepay'], ['name' => 'Netaxept', 'provider' => 'Netaxept'], ['name' => 'NetBanx', 'provider' => 'NetBanx'], @@ -37,7 +37,7 @@ class PaymentLibrariesSeeder extends Seeder ['name' => 'SagePay Direct', 'provider' => 'SagePay_Direct'], ['name' => 'SagePay Server', 'provider' => 'SagePay_Server'], ['name' => 'SecurePay DirectPost', 'provider' => 'SecurePay_DirectPost'], - ['name' => 'Stripe', 'provider' => 'Stripe'], + ['name' => 'Stripe', 'provider' => 'Stripe', 'sort_order' => 1], ['name' => 'TargetPay Direct eBanking', 'provider' => 'TargetPay_Directebanking'], ['name' => 'TargetPay Ideal', 'provider' => 'TargetPay_Ideal'], ['name' => 'TargetPay Mr Cash', 'provider' => 'TargetPay_Mrcash'], @@ -56,8 +56,8 @@ class PaymentLibrariesSeeder extends Seeder ['name' => 'Realex', 'provider' => 'Realex_Remote'], ['name' => 'Sisow', 'provider' => 'Sisow'], ['name' => 'Skrill', 'provider' => 'Skrill'], - ['name' => 'BitPay', 'provider' => 'BitPay', 'is_offsite' => true], - ['name' => 'Dwolla', 'provider' => 'Dwolla', 'is_offsite' => true], + ['name' => 'BitPay', 'provider' => 'BitPay', 'is_offsite' => true, 'sort_order' => 5], + ['name' => 'Dwolla', 'provider' => 'Dwolla', 'is_offsite' => true, 'sort_order' => 4], ['name' => 'AGMS', 'provider' => 'Agms'], ['name' => 'Barclays', 'provider' => 'BarclaysEpdq\Essential'], ['name' => 'Cardgate', 'provider' => 'Cardgate'], @@ -75,14 +75,14 @@ class PaymentLibrariesSeeder extends Seeder ['name' => 'SecPay', 'provider' => 'SecPay'], ['name' => 'WeChat Express', 'provider' => 'WeChat_Express'], ['name' => 'WePay', 'provider' => 'WePay', 'is_offsite' => false], - ['name' => 'Braintree', 'provider' => 'Braintree'], + ['name' => 'Braintree', 'provider' => 'Braintree', 'sort_order' => 2], + ['name' => 'Custom', 'provider' => 'Custom', 'is_offsite' => true, 'sort_order' => 7], ]; foreach ($gateways as $gateway) { $record = Gateway::where('name', '=', $gateway['name'])->first(); if ($record) { - $record->provider = $gateway['provider']; - $record->is_offsite = isset($gateway['is_offsite']) ? boolval($gateway['is_offsite']) : false; + $record->fill($gateway); $record->save(); } else { Gateway::create($gateway); diff --git a/resources/lang/en/texts.php b/resources/lang/en/texts.php index e737a1aed1..7bcf889243 100644 --- a/resources/lang/en/texts.php +++ b/resources/lang/en/texts.php @@ -2141,6 +2141,7 @@ $LANG = array( 'invoice_error' => 'There was an error saving your invoice.', 'enable_recurring' => 'Enable Recurring', 'disable_recurring' => 'Disable Recurring', + 'text' => 'Text', ); diff --git a/resources/views/accounts/account_gateway.blade.php b/resources/views/accounts/account_gateway.blade.php index a6a1efe616..cc0aa0c0df 100644 --- a/resources/views/accounts/account_gateway.blade.php +++ b/resources/views/accounts/account_gateway.blade.php @@ -80,6 +80,8 @@ {!! Former::checkbox($gateway->id.'_'.$field)->label(ucwords(Utils::toSpaceCase($field)))->text('Enable')->value('true') !!} @elseif ($field == 'username' || $field == 'password') {!! Former::text($gateway->id.'_'.$field)->label('API '. ucfirst(Utils::toSpaceCase($field))) !!} + @elseif ($gateway->isCustom() && $field == 'text') + {!! Former::textarea($gateway->id.'_'.$field)->label(trans('texts.text'))->rows(6) !!} @else {!! Former::text($gateway->id.'_'.$field)->label($gateway->id == GATEWAY_STRIPE ? trans('texts.secret_key') : ucwords(Utils::toSpaceCase($field))) !!} @endif diff --git a/resources/views/accounts/templates_and_reminders.blade.php b/resources/views/accounts/templates_and_reminders.blade.php index cdfc7ee4eb..aeb49da332 100644 --- a/resources/views/accounts/templates_and_reminders.blade.php +++ b/resources/views/accounts/templates_and_reminders.blade.php @@ -153,8 +153,8 @@ @if (count($account->account_gateways) > 1) @foreach (\App\Models\Gateway::$gatewayTypes as $type) @if ($account->getGatewayByType($type)) -
  • ${{ Utils::toCamelCase($type) }}Link
  • -
  • ${{ Utils::toCamelCase($type) }}Button
  • +
  • ${{ Utils::toCamelCase(\App\Models\GatewayType::getAliasFromId($type)) }}Link
  • +
  • ${{ Utils::toCamelCase(\App\Models\GatewayType::getAliasFromId($type)) }}Button
  • @endif @endforeach @endif diff --git a/resources/views/invoices/view.blade.php b/resources/views/invoices/view.blade.php index 445ff65650..52005cb4ad 100644 --- a/resources/views/invoices/view.blade.php +++ b/resources/views/invoices/view.blade.php @@ -109,7 +109,7 @@ {!! Button::normal(trans('texts.download_pdf'))->withAttributes(['onclick' => 'onDownloadClick()'])->large() !!}   @if (count($paymentTypes) > 1) {!! DropdownButton::success(trans('texts.pay_now'))->withContents($paymentTypes)->large() !!} - @else + @elseif (count($paymentTypes) == 1) {{ trans('texts.pay_now') }} @endif @else @@ -199,6 +199,10 @@ doc.save(fileName + '-' + invoice.invoice_number + '.pdf'); } + function showCustomModal() { + $('#customGatewayModal').modal('show'); + } + @include('invoices.pdf', ['account' => $invoice->client->account, 'viewPDF' => true]) @@ -206,4 +210,26 @@

     

    + + + @if (isset($customGatewayName)) + + @endif @stop