From e5fb3546433eeac299da5be9401569be8f78e7bb Mon Sep 17 00:00:00 2001 From: Joshua Dwire Date: Thu, 28 Apr 2016 16:38:01 -0400 Subject: [PATCH] Support configuring Stripe for ACH and Plaid --- .../Controllers/AccountGatewayController.php | 41 ++++++++++++++++ app/Http/routes.php | 1 + app/Models/AccountGateway.php | 48 +++++++++++++++++++ app/Models/Gateway.php | 5 +- resources/lang/en/texts.php | 15 +++++- .../views/accounts/account_gateway.blade.php | 48 ++++++++++++++++++- 6 files changed, 155 insertions(+), 3 deletions(-) diff --git a/app/Http/Controllers/AccountGatewayController.php b/app/Http/Controllers/AccountGatewayController.php index 0bc730129fe1..08b2d1355f80 100644 --- a/app/Http/Controllers/AccountGatewayController.php +++ b/app/Http/Controllers/AccountGatewayController.php @@ -86,6 +86,7 @@ class AccountGatewayController extends BaseController ->where('id', '!=', GATEWAY_BITPAY) ->where('id', '!=', GATEWAY_GOCARDLESS) ->where('id', '!=', GATEWAY_DWOLLA) + ->where('id', '!=', GATEWAY_STRIPE) ->orderBy('name')->get(); $data['hiddenFields'] = Gateway::$hiddenFields; @@ -104,6 +105,18 @@ class AccountGatewayController extends BaseController $paymentTypes = []; foreach (Gateway::$paymentTypes as $type) { if ($accountGateway || !$account->getGatewayByType($type)) { + if ($type == PAYMENT_TYPE_CREDIT_CARD && $account->getGatewayByType(PAYMENT_TYPE_STRIPE)) { + // Stripe is already handling credit card payments + continue; + } + + if ($type == PAYMENT_TYPE_DIRECT_DEBIT && $stripeGateway = $account->getGatewayByType(PAYMENT_TYPE_STRIPE)) { + if (!empty($stripeGateway->getConfig()->enableAch)) { + // Stripe is already handling ACH payments + continue; + } + } + $paymentTypes[$type] = trans('texts.'.strtolower($type)); if ($type == PAYMENT_TYPE_BITCOIN) { @@ -185,6 +198,8 @@ class AccountGatewayController extends BaseController $gatewayId = GATEWAY_GOCARDLESS; } elseif ($paymentType == PAYMENT_TYPE_DWOLLA) { $gatewayId = GATEWAY_DWOLLA; + } elseif ($paymentType == PAYMENT_TYPE_STRIPE) { + $gatewayId = GATEWAY_STRIPE; } if (!$gatewayId) { @@ -204,6 +219,7 @@ class AccountGatewayController extends BaseController // do nothing - we're unable to acceptance test with StripeJS } else { $rules['publishable_key'] = 'required'; + $rules['enable_ach'] = 'boolean'; } } @@ -259,6 +275,31 @@ class AccountGatewayController extends BaseController $config->publishableKey = $oldConfig->publishableKey; } + $plaidClientId = Input::get('plaid_client_id'); + if ($plaidClientId = str_replace('*', '', $plaidClientId)) { + $config->plaidClientId = $plaidClientId; + } elseif ($oldConfig && property_exists($oldConfig, 'plaidClientId')) { + $config->plaidClientId = $oldConfig->plaidClientId; + } + + $plaidSecret = Input::get('plaid_secret'); + if ($plaidSecret = str_replace('*', '', $plaidSecret)) { + $config->plaidSecret = $plaidSecret; + } elseif ($oldConfig && property_exists($oldConfig, 'plaidSecret')) { + $config->plaidSecret = $oldConfig->plaidSecret; + } + + $plaidPublicKey = Input::get('plaid_public_key'); + if ($plaidPublicKey = str_replace('*', '', $plaidPublicKey)) { + $config->plaidPublicKey = $plaidPublicKey; + } elseif ($oldConfig && property_exists($oldConfig, 'plaidPublicKey')) { + $config->plaidPublicKey = $oldConfig->plaidPublicKey; + } + + if ($gatewayId == GATEWAY_STRIPE) { + $config->enableAch = boolval(Input::get('enable_ach')); + } + $cardCount = 0; if ($creditcards) { foreach ($creditcards as $card => $value) { diff --git a/app/Http/routes.php b/app/Http/routes.php index 7c3759aa8ef4..d6cd8f497aec 100644 --- a/app/Http/routes.php +++ b/app/Http/routes.php @@ -632,6 +632,7 @@ if (!defined('CONTACT_EMAIL')) { define('PAYMENT_TYPE_SWITCH', 23); define('PAYMENT_TYPE_PAYPAL', 'PAYMENT_TYPE_PAYPAL'); + define('PAYMENT_TYPE_STRIPE', 'PAYMENT_TYPE_STRIPE'); define('PAYMENT_TYPE_CREDIT_CARD', 'PAYMENT_TYPE_CREDIT_CARD'); define('PAYMENT_TYPE_DIRECT_DEBIT', 'PAYMENT_TYPE_DIRECT_DEBIT'); define('PAYMENT_TYPE_BITCOIN', 'PAYMENT_TYPE_BITCOIN'); diff --git a/app/Models/AccountGateway.php b/app/Models/AccountGateway.php index 5e951285349e..6236f1c15b57 100644 --- a/app/Models/AccountGateway.php +++ b/app/Models/AccountGateway.php @@ -71,5 +71,53 @@ class AccountGateway extends EntityModel return $this->getConfigField('publishableKey'); } + + public function getAchEnabled() + { + return !empty($this->getConfigField('enableAch')); + } + + public function getPlaidSecret() + { + if ( ! $this->isGateway(GATEWAY_STRIPE)) { + return false; + } + + return $this->getConfigField('plaidSecret'); + } + + public function getPlaidClientId() + { + if ( ! $this->isGateway(GATEWAY_STRIPE)) { + return false; + } + + return $this->getConfigField('plaidClientId'); + } + + public function getPlaidPublicKey() + { + if ( ! $this->isGateway(GATEWAY_STRIPE)) { + return false; + } + + return $this->getConfigField('plaidPublicKey'); + } + + public function getPlaidEnabled() + { + return !empty($this->getPlaidClientId()) && $this->getAchEnabled(); + } + + public function getPlaidEnvironment() + { + if (!$this->getPlaidClientId()) { + return null; + } + + $stripe_key = $this->getPublishableStripeKey(); + + return substr(trim($stripe_key), 0, 8) == 'sk_test_' ? 'tartan' : 'production'; + } } diff --git a/app/Models/Gateway.php b/app/Models/Gateway.php index 681e8315c512..ec84eab8fb18 100644 --- a/app/Models/Gateway.php +++ b/app/Models/Gateway.php @@ -9,6 +9,7 @@ class Gateway extends Eloquent public $timestamps = true; public static $paymentTypes = [ + PAYMENT_TYPE_STRIPE, PAYMENT_TYPE_CREDIT_CARD, PAYMENT_TYPE_PAYPAL, PAYMENT_TYPE_BITCOIN, @@ -97,8 +98,10 @@ class Gateway extends Eloquent return PAYMENT_TYPE_BITCOIN; } else if ($gatewayId == GATEWAY_DWOLLA) { return PAYMENT_TYPE_DWOLLA; - }else if ($gatewayId == GATEWAY_GOCARDLESS) { + } else if ($gatewayId == GATEWAY_GOCARDLESS) { return PAYMENT_TYPE_DIRECT_DEBIT; + } else if ($gatewayId == GATEWAY_STRIPE) { + return PAYMENT_TYPE_STRIPE; } else { return PAYMENT_TYPE_CREDIT_CARD; } diff --git a/resources/lang/en/texts.php b/resources/lang/en/texts.php index f96dd990b818..467e836a2820 100644 --- a/resources/lang/en/texts.php +++ b/resources/lang/en/texts.php @@ -502,7 +502,7 @@ $LANG = array( 'resend_confirmation' => 'Resend confirmation email', 'confirmation_resent' => 'The confirmation email was resent', 'gateway_help_42' => ':link to sign up for BitPay.
Note: use a Legacy API Key, not an API token.', - 'payment_type_credit_card' => 'Credit Card', + 'payment_type_credit_card' => 'Other Providers', 'payment_type_paypal' => 'PayPal', 'payment_type_bitcoin' => 'Bitcoin', 'knowledge_base' => 'Knowledge Base', @@ -1205,6 +1205,19 @@ $LANG = array( 'card_solo' => 'Solo', 'card_switch' => 'Switch', 'card_visacard' => 'Visa', + + 'payment_type_stripe' => 'Stripe', + 'ach' => 'ACH', + 'enable_ach' => 'Enable ACH', + 'stripe_ach_help' => 'ACH support must also be enabled at Stripe.', + 'stripe_ach_disabled' => 'Another gateway is already configured for direct debit.', + + 'plaid' => 'Plaid', + 'client_id' => 'Client Id', + 'secret' => 'Secret', + 'public_key' => 'Public Key', + 'plaid_optional' => '(optional)', + 'plaid_environment_help' => 'When a Stripe test key is given, Plaid\'s development environement (tartan) will be used.', ); return $LANG; diff --git a/resources/views/accounts/account_gateway.blade.php b/resources/views/accounts/account_gateway.blade.php index b321239024b9..469a11090374 100644 --- a/resources/views/accounts/account_gateway.blade.php +++ b/resources/views/accounts/account_gateway.blade.php @@ -22,6 +22,10 @@ {!! Former::populateField('show_address', intval($accountGateway->show_address)) !!} {!! Former::populateField('update_address', intval($accountGateway->update_address)) !!} {!! Former::populateField('publishable_key', $accountGateway->getPublishableStripeKey() ? str_repeat('*', strlen($accountGateway->getPublishableStripeKey())) : '') !!} + {!! Former::populateField('enable_ach', $accountGateway->getAchEnabled() ? '1' : null) !!} + {!! Former::populateField('plaid_client_id', $accountGateway->getPlaidClientId() ? str_repeat('*', strlen($accountGateway->getPlaidClientId())) : '') !!} + {!! Former::populateField('plaid_secret', $accountGateway->getPlaidSecret() ? str_repeat('*', strlen($accountGateway->getPlaidSecret())) : '') !!} + {!! Former::populateField('plaid_public_key', $accountGateway->getPlaidPublicKey() ? str_repeat('*', strlen($accountGateway->getPlaidPublicKey())) : '') !!} @if ($config) @foreach ($accountGateway->fields as $field => $junk) @@ -45,7 +49,7 @@ {!! Former::select('gateway_id') ->dataClass('gateway-dropdown') - ->addGroupClass('gateway-option') + ->addGroupClass('gateway-option gateway-choice') ->fromQuery($selectGateways, 'name', 'id') ->onchange('setFieldsShown()') !!} @@ -110,6 +114,34 @@ ->class('creditcard-types') ->addGroupClass('gateway-option') !!} +
+ + @if ($account->getGatewayByType(PAYMENT_TYPE_DIRECT_DEBIT)) + {!! Former::checkbox('enable_ach') + ->label(trans('texts.ach')) + ->text(trans('texts.enable_ach')) + ->value(null) + ->disabled(true) + ->help(trans('texts.stripe_ach_disabled')) !!} + @else + {!! Former::checkbox('enable_ach') + ->label(trans('texts.ach')) + ->text(trans('texts.enable_ach')) + ->help(trans('texts.stripe_ach_help')) !!} +
+
+
+

{{trans('texts.plaid')}}

+
{{trans('texts.plaid_optional')}}
+
+
+ {!! Former::text('plaid_client_id')->label(trans('texts.client_id')) !!} + {!! Former::text('plaid_secret')->label(trans('texts.secret')) !!} + {!! Former::text('plaid_public_key')->label(trans('texts.public_key')) + ->help(trans('texts.plaid_environment_help')) !!} +
+ @endif +
@@ -128,9 +160,11 @@ var val = $('#payment_type_id').val(); if (val == 'PAYMENT_TYPE_CREDIT_CARD') { $('.gateway-option').show(); + $('.stripe-ach').hide(); setFieldsShown(); } else { $('.gateway-option').hide(); + $('.stripe-ach').hide(); if (val == 'PAYMENT_TYPE_PAYPAL') { setFieldsShown({{ GATEWAY_PAYPAL_EXPRESS }}); @@ -138,6 +172,10 @@ setFieldsShown({{ GATEWAY_DWOLLA }}); } else if (val == 'PAYMENT_TYPE_DIRECT_DEBIT') { setFieldsShown({{ GATEWAY_GOCARDLESS }}); + } else if (val == 'PAYMENT_TYPE_STRIPE') { + $('.gateway-option:not(.gateway-choice)').show(); + $('.stripe-ach').show(); + setFieldsShown({{ GATEWAY_STRIPE }}); } else { setFieldsShown({{ GATEWAY_BITPAY }}); } @@ -171,14 +209,22 @@ } } + function enablePlaidSettings() { + var visible = $('#enable_ach').is(':checked'); + $('.stripe-plaid').toggle(visible); + } + $(function() { setPaymentType(); + enablePlaidSettings(); @if ($accountGateway) $('.payment-type-option').hide(); @endif $('#show_address').change(enableUpdateAddress); enableUpdateAddress(); + + $('#enable_ach').change(enablePlaidSettings) })