mirror of
				https://github.com/invoiceninja/invoiceninja.git
				synced 2025-10-31 11:17:34 -04:00 
			
		
		
		
	Update payment methods for Stripe
This commit is contained in:
		
							parent
							
								
									6f06e3b268
								
							
						
					
					
						commit
						0347ca00f5
					
				
							
								
								
									
										35
									
								
								app/Http/Controllers/StripeController.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										35
									
								
								app/Http/Controllers/StripeController.php
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,35 @@ | ||||
| <?php | ||||
| 
 | ||||
| /** | ||||
|  * Invoice Ninja (https://invoiceninja.com). | ||||
|  * | ||||
|  * @link https://github.com/invoiceninja/invoiceninja source repository | ||||
|  * | ||||
|  * @copyright Copyright (c) 2021. Invoice Ninja LLC (https://invoiceninja.com) | ||||
|  * | ||||
|  * @license https://opensource.org/licenses/AAL | ||||
|  */ | ||||
| 
 | ||||
| namespace App\Http\Controllers; | ||||
| 
 | ||||
| use App\Jobs\Util\StripeUpdatePaymentMethods; | ||||
| 
 | ||||
| class StripeController extends BaseController | ||||
| { | ||||
| 
 | ||||
| 	public function update() | ||||
| 	{ | ||||
| 		if(auth()->user()->isAdmin()) | ||||
| 		{ | ||||
| 
 | ||||
| 			StripeUpdatePaymentMethods::dispatch(auth()->user()->getCompany()); | ||||
| 
 | ||||
| 			return response()->json(['message' => 'Processing'], 403); | ||||
| 
 | ||||
| 		} | ||||
| 
 | ||||
| 		 | ||||
| 		return response()->json(['message' => 'Unauthorized'], 403); | ||||
| 	} | ||||
| 
 | ||||
| } | ||||
							
								
								
									
										68
									
								
								app/Jobs/Util/StripeUpdatePaymentMethods.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										68
									
								
								app/Jobs/Util/StripeUpdatePaymentMethods.php
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,68 @@ | ||||
| <?php | ||||
| /** | ||||
|  * Invoice Ninja (https://invoiceninja.com). | ||||
|  * | ||||
|  * @link https://github.com/invoiceninja/invoiceninja source repository | ||||
|  * | ||||
|  * @copyright Copyright (c) 2021. Invoice Ninja LLC (https://invoiceninja.com) | ||||
|  * | ||||
|  * @license https://opensource.org/licenses/AAL | ||||
|  */ | ||||
| namespace App\Jobs\Util; | ||||
| 
 | ||||
| use App\Libraries\MultiDB; | ||||
| use App\Models\Client; | ||||
| use App\Models\CompanyGateway; | ||||
| use Illuminate\Bus\Queueable; | ||||
| use Illuminate\Contracts\Queue\ShouldQueue; | ||||
| use Illuminate\Foundation\Bus\Dispatchable; | ||||
| use Illuminate\Queue\InteractsWithQueue; | ||||
| use Illuminate\Queue\SerializesModels; | ||||
| 
 | ||||
| 
 | ||||
| class StripeUpdatePaymentMethods implements ShouldQueue | ||||
| { | ||||
|     use Dispatchable, InteractsWithQueue, Queueable, SerializesModels; | ||||
| 
 | ||||
|     public $company; | ||||
| 
 | ||||
|     private $stripe_keys = ['d14dd26a47cecc30fdd65700bfb67b34', 'd14dd26a37cecc30fdd65700bfb55b23']; | ||||
|     /** | ||||
|      * Create a new job instance. | ||||
|      * | ||||
|      * @param $event_id | ||||
|      * @param $entity | ||||
|      */ | ||||
|     public function __construct($company) | ||||
|     { | ||||
|         $this->company = $company; | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Execute the job. | ||||
|      * | ||||
|      * @return bool | ||||
|      */ | ||||
|     public function handle() | ||||
|     { | ||||
| 
 | ||||
|     	MultiDB::setDb($this->company->db); | ||||
| 
 | ||||
|     	$cgs = CompanyGateway::where('company_id', $this->company->id) | ||||
|     						->whereIn('gateway_key', $this->stripe_keys) | ||||
|     						->get(); | ||||
| 
 | ||||
| 		$cgs->each(function ($company_gateway){ | ||||
| 
 | ||||
| 			$company_gateway->driver(new Client)->updateAllPaymentMethods(); | ||||
| 
 | ||||
| 		}); | ||||
| 
 | ||||
|     } | ||||
| 
 | ||||
|     public function failed($exception) | ||||
|     { | ||||
|     	nlog("Stripe update payment methods exception"); | ||||
|         nlog($exception->getMessage()); | ||||
|     } | ||||
| } | ||||
							
								
								
									
										168
									
								
								app/PaymentDrivers/Stripe/UpdatePaymentMethods.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										168
									
								
								app/PaymentDrivers/Stripe/UpdatePaymentMethods.php
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,168 @@ | ||||
| <?php | ||||
| 
 | ||||
| /** | ||||
|  * Invoice Ninja (https://invoiceninja.com). | ||||
|  * | ||||
|  * @link https://github.com/invoiceninja/invoiceninja source repository | ||||
|  * | ||||
|  * @copyright Copyright (c) 2021. Invoice Ninja LLC (https://invoiceninja.com) | ||||
|  * | ||||
|  * @license https://opensource.org/licenses/AAL | ||||
|  */ | ||||
| 
 | ||||
| namespace App\PaymentDrivers\Stripe; | ||||
| 
 | ||||
| use App\Factory\ClientGatewayTokenFactory; | ||||
| use App\Models\ClientGatewayToken; | ||||
| use App\Models\GatewayType; | ||||
| use App\PaymentDrivers\StripePaymentDriver; | ||||
| use App\Utils\Traits\MakesHash; | ||||
| use Stripe\Customer; | ||||
| use Stripe\PaymentMethod; | ||||
| 
 | ||||
| class UpdatePaymentMethods | ||||
| { | ||||
|     use MakesHash; | ||||
| 
 | ||||
|     /** @var StripePaymentDriver */ | ||||
|     public $stripe; | ||||
| 
 | ||||
|     public function __construct(StripePaymentDriver $stripe) | ||||
|     { | ||||
|         $this->stripe = $stripe; | ||||
|     } | ||||
| 
 | ||||
|     public function run() | ||||
|     { | ||||
|         $this->stripe->init(); | ||||
| 
 | ||||
|         $this->stripe | ||||
|              ->company_gateway | ||||
|              ->client_gateway_tokens | ||||
|              ->each(function ($token){ | ||||
| 
 | ||||
|                 $card_methods = PaymentMethod::all([ | ||||
|                     'customer' => $token->gateway_customer_reference, | ||||
|                     'type' => 'card', | ||||
|                     ], | ||||
|                      $this->stripe->stripe_connect_auth); | ||||
| 
 | ||||
|                 foreach($card_methods as $method)  | ||||
|                 { | ||||
|                     $this->addOrUpdateCard($method, $token, GatewayType::CREDIT_CARD); | ||||
|                 } | ||||
| 
 | ||||
|                 $alipay_methods = PaymentMethod::all([ | ||||
|                     'customer' => $token->gateway_customer_reference, | ||||
|                     'type' => 'alipay', | ||||
|                     ], | ||||
|                      $this->stripe->stripe_connect_auth); | ||||
| 
 | ||||
|                 foreach($alipay_methods as $method)  | ||||
|                 { | ||||
|                     $this->addOrUpdateCard($method, $token, GatewayType::ALIPAY); | ||||
|                 } | ||||
| 
 | ||||
|                 $sofort_methods = PaymentMethod::all([ | ||||
|                     'customer' => $token->gateway_customer_reference, | ||||
|                     'type' => 'sofort', | ||||
|                     ], | ||||
|                      $this->stripe->stripe_connect_auth); | ||||
| 
 | ||||
|                 foreach($alipay_methods as $method)  | ||||
|                 { | ||||
|                     $this->addOrUpdateCard($method, $token, GatewayType::SOFORT); | ||||
|                 } | ||||
| 
 | ||||
|                 $bank_accounts = Customer::allSources( | ||||
|                     $token->gateway_customer_reference, | ||||
|                     ['object' => 'bank_account', 'limit' => 300] | ||||
|                 ); | ||||
| 
 | ||||
|                 foreach($bank_accounts as $bank_account) | ||||
|                 { | ||||
|                     $this->addOrUpdateBankAccount($bank_account, $token); | ||||
|                 } | ||||
| 
 | ||||
|         }); | ||||
| 
 | ||||
|     } | ||||
| 
 | ||||
|     private function addOrUpdateBankAccount($bank_account, ClientGatewayToken $token) | ||||
|     { | ||||
|         $token_exists = ClientGatewayToken::where([ | ||||
|             'gateway_customer_reference' => $token->gateway_customer_reference, | ||||
|             'token' => $bank_account->id, | ||||
|         ])->exists(); | ||||
| 
 | ||||
|         /* Already exists return */ | ||||
|         if($token_exists) | ||||
|             return; | ||||
| 
 | ||||
|         $cgt = ClientGatewayTokenFactory::create($token->company_id); | ||||
|         $cgt->client_id = $token->client_id; | ||||
|         $cgt->token = $bank_account->id; | ||||
|         $cgt->gateway_customer_reference = $token->gateway_customer_reference; | ||||
|         $cgt->company_gateway_id = $token->company_gateway_id; | ||||
|         $cgt->gateway_type_id = GatewayType::BANK_TRANSFER | ||||
|         $cgt->meta = new \stdClass; | ||||
|         $cgt->routing_number = $bank_account->routing_number; | ||||
|         $cgt->save(); | ||||
| 
 | ||||
|     } | ||||
| 
 | ||||
|     private function addOrUpdateCard(PaymentMethod $method, ClientGatewayToken $token, GatewayType $type_id) | ||||
|     { | ||||
|          | ||||
|         $token_exists = ClientGatewayToken::where([ | ||||
|             'gateway_customer_reference' => $token->gateway_customer_reference, | ||||
|             'token' => $method->id, | ||||
|         ])->exists(); | ||||
| 
 | ||||
|         /* Already exists return */ | ||||
|         if($token_exists) | ||||
|             return; | ||||
| 
 | ||||
|         /* Ignore Expired cards */ | ||||
|         if($method->card->exp_year <= date('Y') && $method->card->exp_month < date('m')) | ||||
|             return; | ||||
| 
 | ||||
|         $cgt = ClientGatewayTokenFactory::create($token->company_id); | ||||
|         $cgt->client_id = $token->client_id; | ||||
|         $cgt->token = $method->id; | ||||
|         $cgt->gateway_customer_reference = $token->gateway_customer_reference; | ||||
|         $cgt->company_gateway_id = $token->company_gateway_id; | ||||
|         $cgt->gateway_type_id = $type_id; | ||||
|         $cgt->meta = $this->buildPaymentMethodMeta($method, $type_id); | ||||
|         $cgt->save(); | ||||
| 
 | ||||
|     } | ||||
| 
 | ||||
|     private function buildPaymentMethodMeta(PaymentMethod $method, GatewayType $type_id) | ||||
|     { | ||||
| 
 | ||||
|         switch ($type_id) { | ||||
|             case GatewayType::CREDIT_CARD: | ||||
| 
 | ||||
|                 $payment_meta = new \stdClass; | ||||
|                 $payment_meta->exp_month = (string) $method->card->exp_month; | ||||
|                 $payment_meta->exp_year = (string) $method->card->exp_year; | ||||
|                 $payment_meta->brand = (string) $method->card->brand; | ||||
|                 $payment_meta->last4 = (string) $method->card->last4; | ||||
|                 $payment_meta->type = GatewayType::CREDIT_CARD; | ||||
|                 return $payment_meta; | ||||
| 
 | ||||
|                 break; | ||||
|              | ||||
|             case GatewayType::ALIPAY: | ||||
|             case GatewayType::SOFORT: | ||||
| 
 | ||||
|                 return new \stdClass; | ||||
| 
 | ||||
|             default: | ||||
|                  | ||||
| 
 | ||||
|                 break; | ||||
|         } | ||||
|     } | ||||
| } | ||||
| @ -26,6 +26,7 @@ use App\PaymentDrivers\Stripe\Alipay; | ||||
| use App\PaymentDrivers\Stripe\Charge; | ||||
| use App\PaymentDrivers\Stripe\CreditCard; | ||||
| use App\PaymentDrivers\Stripe\SOFORT; | ||||
| use App\PaymentDrivers\Stripe\UpdatePaymentMethods; | ||||
| use App\PaymentDrivers\Stripe\Utilities; | ||||
| use App\Utils\Traits\MakesHash; | ||||
| use Exception; | ||||
| @ -493,4 +494,29 @@ class StripePaymentDriver extends BaseDriver | ||||
| 
 | ||||
|         return Account::all(); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Pull all client payment methods and update | ||||
|      * the respective tokens in the system. | ||||
|      *      | ||||
|      */ | ||||
|     public function updateAllPaymentMethods() | ||||
|     { | ||||
|         return (new UpdatePaymentMethods($this))->run(); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Imports stripe customers and their payment methods | ||||
|      * Matches users in the system based on the $match_on_record  | ||||
|      * ie. email | ||||
|      *      | ||||
|      * Phone | ||||
|      * Email | ||||
|      */ | ||||
|     public function importAndUpdateCustomers() | ||||
|     { | ||||
| 
 | ||||
|         //match clients based on the gateway_customer_reference column
 | ||||
| 
 | ||||
|     } | ||||
| } | ||||
|  | ||||
| @ -183,6 +183,8 @@ Route::group(['middleware' => ['api_db', 'token_auth', 'locale'], 'prefix' => 'a | ||||
|     // Route::post('hooks', 'SubscriptionController@subscribe')->name('hooks.subscribe');
 | ||||
|     // Route::delete('hooks/{subscription_id}', 'SubscriptionController@unsubscribe')->name('hooks.unsubscribe');
 | ||||
| 
 | ||||
|     Route::post('stripe/update_payment_methods', 'StripeController@update')->middleware('password_protected')->name('stripe.update'); | ||||
| 
 | ||||
|     Route::resource('subscriptions', 'SubscriptionController'); | ||||
|     Route::post('subscriptions/bulk', 'SubscriptionController@bulk')->name('subscriptions.bulk'); | ||||
| 
 | ||||
| @ -193,9 +195,7 @@ Route::match(['get', 'post'], 'payment_webhook/{company_key}/{company_gateway_id | ||||
|     ->name('payment_webhook'); | ||||
| 
 | ||||
| Route::post('api/v1/postmark_webhook', 'PostMarkController@webhook'); | ||||
| 
 | ||||
| Route::get('token_hash_router', 'OneTimeTokenController@router'); | ||||
| 
 | ||||
| Route::get('webcron', 'WebCronController@index'); | ||||
| 
 | ||||
| Route::fallback('BaseController@notFound'); | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user