mirror of
				https://github.com/invoiceninja/invoiceninja.git
				synced 2025-11-03 22:07:33 -05:00 
			
		
		
		
	Merge pull request #5487 from beganovich/v5-2004-stripe-connect
(v5) Stripe Connect
This commit is contained in:
		
						commit
						24e17ff6f7
					
				@ -68,19 +68,18 @@ class OneTimeTokenController extends BaseController
 | 
				
			|||||||
     */
 | 
					     */
 | 
				
			||||||
    public function create(OneTimeTokenRequest $request)
 | 
					    public function create(OneTimeTokenRequest $request)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
 | 
					 | 
				
			||||||
        $hash = Str::random(64);
 | 
					        $hash = Str::random(64);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $data = [
 | 
					        $data = [
 | 
				
			||||||
            'user_id' => auth()->user()->id,
 | 
					            'user_id' => auth()->user()->id,
 | 
				
			||||||
            'company_key'=> auth()->user()->company()->company_key,
 | 
					            'company_key'=> auth()->user()->company->company_key,
 | 
				
			||||||
            'context' => $request->input('context'),
 | 
					            'context' => $request->input('context'),
 | 
				
			||||||
        ];
 | 
					        ];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        Cache::put( $hash, $data, 3600);
 | 
					        Cache::put( $hash, $data, 3600);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        return response()->json(['hash' => $hash], 200);
 | 
					        return response()->json(['hash' => $hash], 200);
 | 
				
			||||||
    
 | 
					
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public function router(OneTimeRouterRequest $request)
 | 
					    public function router(OneTimeRouterRequest $request)
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										45
									
								
								app/Http/Controllers/StripeConnectController.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										45
									
								
								app/Http/Controllers/StripeConnectController.php
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,45 @@
 | 
				
			|||||||
 | 
					<?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\Http\Requests\StripeConnect\InitializeStripeConnectRequest;
 | 
				
			||||||
 | 
					use App\Models\CompanyGateway;
 | 
				
			||||||
 | 
					use App\PaymentDrivers\Stripe\Connect\Account;
 | 
				
			||||||
 | 
					use Stripe\Exception\ApiErrorException;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class StripeConnectController extends BaseController
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Initialize Stripe Connect flow.
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @param string $token One-time token
 | 
				
			||||||
 | 
					     * @throws ApiErrorException
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public function initialize(InitializeStripeConnectRequest $request, string $token)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					//        $request->getTokenContent();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $data = [
 | 
				
			||||||
 | 
					            'email' => 'user@example.com',
 | 
				
			||||||
 | 
					            'country' => 'US',
 | 
				
			||||||
 | 
					        ];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $account = Account::create($data);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $link = Account::link($account->id);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // Store account->id into company_gateways.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return redirect($link['url']);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@ -0,0 +1,55 @@
 | 
				
			|||||||
 | 
					<?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\Requests\StripeConnect;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					use Illuminate\Foundation\Http\FormRequest;
 | 
				
			||||||
 | 
					use Illuminate\Support\Facades\Cache;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class InitializeStripeConnectRequest extends FormRequest
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Determine if the user is authorized to make this request.
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @return bool
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public function authorize(): bool
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        return true;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Get the validation rules that apply to the request.
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @return array
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public function rules(): array
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        return [
 | 
				
			||||||
 | 
					            //
 | 
				
			||||||
 | 
					        ];
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Resolve one-time token instance.
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @return mixed
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public function getTokenContent()
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        $data = Cache::get($this->input('token'));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        abort_if(!$data, 404);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return $data;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@ -12,24 +12,40 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
namespace App\PaymentDrivers\Stripe\Connect;
 | 
					namespace App\PaymentDrivers\Stripe\Connect;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
use App\Exceptions\PaymentFailed;
 | 
					 | 
				
			||||||
use App\Http\Requests\Request;
 | 
					 | 
				
			||||||
use App\Jobs\Mail\PaymentFailureMailer;
 | 
					 | 
				
			||||||
use App\Jobs\Util\SystemLogger;
 | 
					 | 
				
			||||||
use App\Models\ClientGatewayToken;
 | 
					 | 
				
			||||||
use App\Models\GatewayType;
 | 
					 | 
				
			||||||
use App\Models\Payment;
 | 
					 | 
				
			||||||
use App\Models\PaymentType;
 | 
					 | 
				
			||||||
use App\Models\SystemLog;
 | 
					 | 
				
			||||||
use App\PaymentDrivers\StripePaymentDriver;
 | 
					 | 
				
			||||||
use App\Utils\Traits\MakesHash;
 | 
					 | 
				
			||||||
use Exception;
 | 
					 | 
				
			||||||
use Stripe\Customer;
 | 
					 | 
				
			||||||
use Stripe\Exception\CardException;
 | 
					 | 
				
			||||||
use Stripe\Exception\InvalidRequestException;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
class Account
 | 
					class Account
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * @throws \Stripe\Exception\ApiErrorException
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public static function create(array $payload): \Stripe\Account
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        $stripe = new \Stripe\StripeClient(
 | 
				
			||||||
 | 
					            config('ninja.stripe_private_key')
 | 
				
			||||||
 | 
					        );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return $stripe->accounts->create([
 | 
				
			||||||
 | 
					            'type' => 'standard',
 | 
				
			||||||
 | 
					            'country' => $payload['country'],
 | 
				
			||||||
 | 
					            'email' => $payload['email'],
 | 
				
			||||||
 | 
					        ]);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * @throws \Stripe\Exception\ApiErrorException
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public static function link(string $account_id): \Stripe\AccountLink
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        $stripe = new \Stripe\StripeClient(
 | 
				
			||||||
 | 
					            config('ninja.stripe_private_key')
 | 
				
			||||||
 | 
					        );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return $stripe->accountLinks->create([
 | 
				
			||||||
 | 
					            'account' => $account_id,
 | 
				
			||||||
 | 
					            'refresh_url' => 'http://localhost:8080/stripe_connect/reauth',
 | 
				
			||||||
 | 
					            'return_url' => 'http://localhost:8080/stripe_connect/return',
 | 
				
			||||||
 | 
					            'type' => 'account_onboarding',
 | 
				
			||||||
 | 
					        ]);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/*** If this is a new account (ie there is no account_id in company_gateways.config, the we need to create an account as below.
 | 
					/*** If this is a new account (ie there is no account_id in company_gateways.config, the we need to create an account as below.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -148,7 +164,7 @@ class Account
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
// now we start the stripe onboarding flow
 | 
					// now we start the stripe onboarding flow
 | 
				
			||||||
// https://stripe.com/docs/api/account_links/object
 | 
					// https://stripe.com/docs/api/account_links/object
 | 
				
			||||||
// 
 | 
					//
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 * $stripe = new \Stripe\StripeClient(
 | 
					 * $stripe = new \Stripe\StripeClient(
 | 
				
			||||||
  'sk_test_4eC39HqLyjWDarjtT1zdp7dc'
 | 
					  'sk_test_4eC39HqLyjWDarjtT1zdp7dc'
 | 
				
			||||||
@ -162,7 +178,7 @@ $stripe->accountLinks->create([
 | 
				
			|||||||
 */
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 * Response = 
 | 
					 * Response =
 | 
				
			||||||
 * {
 | 
					 * {
 | 
				
			||||||
  "object": "account_link",
 | 
					  "object": "account_link",
 | 
				
			||||||
  "created": 1618869558,
 | 
					  "created": 1618869558,
 | 
				
			||||||
@ -177,11 +193,11 @@ $stripe->accountLinks->create([
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// What next?
 | 
					// What next?
 | 
				
			||||||
// 
 | 
					//
 | 
				
			||||||
// Now we need to create a superclass of the StripePaymentDriver, i believe the only thing we need to change is the way we initialize the gateway..
 | 
					// Now we need to create a superclass of the StripePaymentDriver, i believe the only thing we need to change is the way we initialize the gateway..
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 * 
 | 
					 *
 | 
				
			||||||
\Stripe\Stripe::setApiKey("{{PLATFORM_SECRET_KEY}}"); <--- platform secret key  = Invoice Ninja secret key
 | 
					\Stripe\Stripe::setApiKey("{{PLATFORM_SECRET_KEY}}"); <--- platform secret key  = Invoice Ninja secret key
 | 
				
			||||||
\Stripe\Customer::create(
 | 
					\Stripe\Customer::create(
 | 
				
			||||||
  ["email" => "person@example.edu"],
 | 
					  ["email" => "person@example.edu"],
 | 
				
			||||||
@ -191,4 +207,4 @@ $stripe->accountLinks->create([
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -147,5 +147,5 @@ return [
 | 
				
			|||||||
    'webcron_secret' => env('WEBCRON_SECRET', false),
 | 
					    'webcron_secret' => env('WEBCRON_SECRET', false),
 | 
				
			||||||
    'disable_auto_update' => env('DISABLE_AUTO_UPDATE', false),
 | 
					    'disable_auto_update' => env('DISABLE_AUTO_UPDATE', false),
 | 
				
			||||||
    'invoiceninja_hosted_pdf_generation' => env('NINJA_HOSTED_PDF', false),
 | 
					    'invoiceninja_hosted_pdf_generation' => env('NINJA_HOSTED_PDF', false),
 | 
				
			||||||
    'ninja_stripe_key' => env('NINJA_STRIPE_KEY', false),
 | 
					    'stripe_private_key' => env('STRIPE_PRIVATE_KEY', null),
 | 
				
			||||||
];
 | 
					];
 | 
				
			||||||
 | 
				
			|||||||
@ -29,12 +29,10 @@ class StripeConnectGateway extends Migration
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        Gateway::create($gateway);
 | 
					        Gateway::create($gateway);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if(Ninja::isNinja())
 | 
					        if (Ninja::isNinja()) {
 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
            Gateway::where('id', 20)->update(['visible' => 0]);
 | 
					            Gateway::where('id', 20)->update(['visible' => 0]);
 | 
				
			||||||
            Gateway::where('id', 56)->update(['visible' => 1]);
 | 
					            Gateway::where('id', 56)->update(['visible' => 1]);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /**
 | 
					    /**
 | 
				
			||||||
 | 
				
			|||||||
@ -187,6 +187,11 @@ Route::match(['get', 'post'], 'payment_webhook/{company_key}/{company_gateway_id
 | 
				
			|||||||
    ->name('payment_webhook');
 | 
					    ->name('payment_webhook');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Route::post('api/v1/postmark_webhook', 'PostMarkController@webhook');
 | 
					Route::post('api/v1/postmark_webhook', 'PostMarkController@webhook');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Route::get('token_hash_router', 'OneTimeTokenController@router');
 | 
					Route::get('token_hash_router', 'OneTimeTokenController@router');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Route::get('webcron', 'WebCronController@index');
 | 
					Route::get('webcron', 'WebCronController@index');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Route::get('stripe_connect/{token}', 'StripeConnectController@initialize')->name('stripe_connect.initialization');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Route::fallback('BaseController@notFound');
 | 
					Route::fallback('BaseController@notFound');
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user