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 @@