From 1524447cd494aa2f405e9b24b4b32dc1b63cc3ac Mon Sep 17 00:00:00 2001 From: Joshua Dwire Date: Sat, 14 May 2016 22:22:06 -0400 Subject: [PATCH] WePay fixes; support account updater --- .env.example | 10 +++- .../Controllers/AccountGatewayController.php | 2 +- app/Http/Controllers/PaymentController.php | 46 +++++++++++++++++++ app/Http/routes.php | 1 + app/Services/PaymentService.php | 15 ++++-- .../views/accounts/account_gateway.blade.php | 2 +- .../payments/tokenization_wepay.blade.php | 14 +++++- 7 files changed, 81 insertions(+), 9 deletions(-) diff --git a/.env.example b/.env.example index 41ce2039f7e5..dd797f50d0ec 100644 --- a/.env.example +++ b/.env.example @@ -67,4 +67,12 @@ API_SECRET=password #MAX_DOCUMENT_SIZE # KB #MAX_EMAIL_DOCUMENTS_SIZE # Total KB #MAX_ZIP_DOCUMENTS_SIZE # Total KB (uncompressed) -#DOCUMENT_PREVIEW_SIZE # Pixels \ No newline at end of file +#DOCUMENT_PREVIEW_SIZE # Pixels + +WEPAY_CLIENT_ID= +WEPAY_CLIENT_SECRET= +WEPAY_AUTO_UPDATE=true # Requires permission from WePay +WEPAY_ENVIRONMENT=production # production or stage + +# See https://www.wepay.com/developer/reference/structures#theme +WEPAY_THEME={"name":"Invoice Ninja","primary_color":"0b4d78","secondary_color":"0b4d78","background_color":"f8f8f8","button_color":"33b753"}')); \ No newline at end of file diff --git a/app/Http/Controllers/AccountGatewayController.php b/app/Http/Controllers/AccountGatewayController.php index 9a12ca11c5f9..34a378379d21 100644 --- a/app/Http/Controllers/AccountGatewayController.php +++ b/app/Http/Controllers/AccountGatewayController.php @@ -393,7 +393,7 @@ class AccountGatewayController extends BaseController 'original_device' => \Request::server('HTTP_USER_AGENT'), 'tos_acceptance_time' => time(), 'redirect_uri' => URL::to('gateways'), - 'callback_uri' => URL::to('https://sometechie.ngrok.io/paymenthook/'.$account->account_key.'/'.GATEWAY_WEPAY), + 'callback_uri' => URL::to(env('WEBHOOK_PREFIX','').'paymenthook/'.$account->account_key.'/'.GATEWAY_WEPAY), 'scope' => 'manage_accounts,collect_payments,view_user,preapprove_payments,send_money', )); diff --git a/app/Http/Controllers/PaymentController.php b/app/Http/Controllers/PaymentController.php index e14a9cb9cd69..c30436cd3a80 100644 --- a/app/Http/Controllers/PaymentController.php +++ b/app/Http/Controllers/PaymentController.php @@ -790,6 +790,8 @@ class PaymentController extends BaseController switch($gatewayId) { case GATEWAY_STRIPE: return $this->handleStripeWebhook($accountGateway); + case GATEWAY_WEPAY: + return $this->handleWePayWebhook($accountGateway); default: return response()->json([ 'message' => 'Unsupported gateway', @@ -797,6 +799,50 @@ class PaymentController extends BaseController } } + protected function handleWePayWebhook($accountGateway) { + $data = Input::all(); + $accountId = $accountGateway->account_id; + + foreach (array_keys($data) as $key) { + if ('_id' == substr($key, -3)) { + $objectType = substr($key, 0, -3); + $objectId = $data[$key]; + break; + } + } + + if (!isset($objectType)) { + return response()->json([ + 'message' => 'Could not find object id parameter', + ], 400); + } + + if ($objectType == 'credit_card') { + $paymentMethod = PaymentMethod::scope(false, $accountId)->where('source_reference', '=', $objectId)->first(); + + if (!$paymentMethod) { + return array('message' => 'Unknown payment method'); + } + + $wepay = \Utils::setupWePay($accountGateway); + $source = $wepay->request('credit_card', array( + 'client_id' => WEPAY_CLIENT_ID, + 'client_secret' => WEPAY_CLIENT_SECRET, + 'credit_card_id' => intval($objectId), + )); + + if ($source->state == 'deleted') { + $paymentMethod->delete(); + } else { + $this->paymentService->convertPaymentMethodFromWePay($source, null, $paymentMethod)->save(); + } + + return array('message' => 'Processed successfully'); + } else { + return array('message' => 'Ignoring event'); + } + } + protected function handleStripeWebhook($accountGateway) { $eventId = Input::get('id'); $eventType= Input::get('type'); diff --git a/app/Http/routes.php b/app/Http/routes.php index 3a02960d8005..4f362a3c6df6 100644 --- a/app/Http/routes.php +++ b/app/Http/routes.php @@ -756,6 +756,7 @@ if (!defined('CONTACT_EMAIL')) { define('WEPAY_STAGE', 'stage'); define('WEPAY_CLIENT_ID', env('WEPAY_CLIENT_ID')); define('WEPAY_CLIENT_SECRET', env('WEPAY_CLIENT_SECRET')); + define('WEPAY_AUTO_UPDATE', env('WEPAY_AUTO_UPDATE', false)); define('WEPAY_ENVIRONMENT', env('WEPAY_ENVIRONMENT', WEPAY_PRODUCTION)); define('WEPAY_THEME', env('WEPAY_THEME','{"name":"Invoice Ninja","primary_color":"0b4d78","secondary_color":"0b4d78","background_color":"f8f8f8","button_color":"33b753"}')); diff --git a/app/Services/PaymentService.php b/app/Services/PaymentService.php index 626366a469cd..11d9cda41e9f 100644 --- a/app/Services/PaymentService.php +++ b/app/Services/PaymentService.php @@ -278,7 +278,7 @@ class PaymentService extends BaseService $wepay->request('/credit_card/delete', [ 'client_id' => WEPAY_CLIENT_ID, 'client_secret' => WEPAY_CLIENT_SECRET, - 'credit_card_id' => $paymentMethod->source_reference, + 'credit_card_id' => intval($paymentMethod->source_reference), ]); } catch (\WePayException $ex){ return $ex->getMessage(); @@ -401,14 +401,21 @@ class PaymentService extends BaseService $wepay->request('credit_card/authorize', array( 'client_id' => WEPAY_CLIENT_ID, 'client_secret' => WEPAY_CLIENT_SECRET, - 'credit_card_id' => $details['token'], + 'credit_card_id' => intval($details['token']), )); - // Get the card details + // Update the callback uri and get the card details + $wepay->request('credit_card/modify', array( + 'client_id' => WEPAY_CLIENT_ID, + 'client_secret' => WEPAY_CLIENT_SECRET, + 'credit_card_id' => intval($details['token']), + 'auto_update' => WEPAY_AUTO_UPDATE, + 'callback_uri' => URL::to(env('WEBHOOK_PREFIX','').'paymenthook/'.$client->account->account_key.'/'.GATEWAY_WEPAY), + )); $tokenResponse = $wepay->request('credit_card', array( 'client_id' => WEPAY_CLIENT_ID, 'client_secret' => WEPAY_CLIENT_SECRET, - 'credit_card_id' => $details['token'], + 'credit_card_id' => intval($details['token']), )); $customerReference = CUSTOMER_REFERENCE_LOCAL; diff --git a/resources/views/accounts/account_gateway.blade.php b/resources/views/accounts/account_gateway.blade.php index 4bcbc1cc0fb6..155ef6579f69 100644 --- a/resources/views/accounts/account_gateway.blade.php +++ b/resources/views/accounts/account_gateway.blade.php @@ -104,7 +104,7 @@
- +
{!! trans('texts.stripe_webhook_help', [ 'link'=>''.trans('texts.stripe_webhook_help_link_text').'' ]) !!}
diff --git a/resources/views/payments/tokenization_wepay.blade.php b/resources/views/payments/tokenization_wepay.blade.php index 4f130d69e01b..5d41cfc9fc69 100644 --- a/resources/views/payments/tokenization_wepay.blade.php +++ b/resources/views/payments/tokenization_wepay.blade.php @@ -3,6 +3,7 @@ $(function() { var countries = {!! $countries->pluck('iso_3166_2','id') !!}; WePay.set_endpoint('{{ WEPAY_ENVIRONMENT }}'); + var $form = $('.payment-form'); $('.payment-form').submit(function(event) { var data = { client_id: {{ WEPAY_CLIENT_ID }}, @@ -27,9 +28,11 @@ } // Not including state/province, since WePay wants 2-letter codes and users enter the full name - var response = WePay.credit_card.create(data, function(response) { - var $form = $('.payment-form'); + // Disable the submit button to prevent repeated clicks + $form.find('button').prop('disabled', true); + $('#js-error-message').hide(); + var response = WePay.credit_card.create(data, function(response) { if (response.error) { // Show the errors on the form var error = response.error_description; @@ -45,6 +48,13 @@ } }); + if (response.error) { + // Show the errors on the form + var error = response.error_description; + $form.find('button').prop('disabled', false); + $('#js-error-message').text(error).fadeIn(); + } + // Prevent the form from submitting with the default action return false; });