mirror of
				https://github.com/invoiceninja/invoiceninja.git
				synced 2025-10-31 09:07:32 -04:00 
			
		
		
		
	
		
			
				
	
	
		
			220 lines
		
	
	
		
			6.7 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
			
		
		
	
	
			220 lines
		
	
	
		
			6.7 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
| <?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://www.elastic.co/licensing/elastic-license
 | |
|  */
 | |
| 
 | |
| namespace App\PaymentDrivers;
 | |
| 
 | |
| use App\Exceptions\PaymentFailed;
 | |
| use App\Jobs\Mail\PaymentFailureMailer;
 | |
| use App\Jobs\Util\SystemLogger;
 | |
| use App\Models\GatewayType;
 | |
| use App\Models\Invoice;
 | |
| use App\Models\PaymentType;
 | |
| use App\Models\SystemLog;
 | |
| use App\Utils\Traits\MakesHash;
 | |
| use Omnipay\Common\Item;
 | |
| use Omnipay\Omnipay;
 | |
| 
 | |
| class PayPalExpressPaymentDriver extends BaseDriver
 | |
| {
 | |
|     use MakesHash;
 | |
| 
 | |
|     public $token_billing = false;
 | |
| 
 | |
|     public $can_authorise_credit_card = false;
 | |
| 
 | |
|     private $omnipay_gateway;
 | |
| 
 | |
|     const SYSTEM_LOG_TYPE = SystemLog::TYPE_PAYPAL;
 | |
| 
 | |
|     public function gatewayTypes()
 | |
|     {
 | |
|         return [
 | |
|             GatewayType::PAYPAL,
 | |
|         ];
 | |
|     }
 | |
| 
 | |
|     /**
 | |
|      * Initialize Omnipay PayPal_Express gateway.
 | |
|      *
 | |
|      * @return void
 | |
|      */
 | |
|     private function initializeOmnipayGateway(): void
 | |
|     {
 | |
|         $this->omnipay_gateway = Omnipay::create(
 | |
|             $this->company_gateway->gateway->provider
 | |
|         );
 | |
| 
 | |
|         $this->omnipay_gateway->initialize((array) $this->company_gateway->getConfig());
 | |
|     }
 | |
| 
 | |
|     public function setPaymentMethod($payment_method_id)
 | |
|     {
 | |
|         // PayPal doesn't have multiple ways of paying.
 | |
|         // There's just one, off-site redirect.
 | |
| 
 | |
|         return $this;
 | |
|     }
 | |
| 
 | |
|     public function authorizeView($payment_method)
 | |
|     {
 | |
|         // PayPal doesn't support direct authorization.
 | |
| 
 | |
|         return $this;
 | |
|     }
 | |
| 
 | |
|     public function authorizeResponse($request)
 | |
|     {
 | |
|         // PayPal doesn't support direct authorization.
 | |
| 
 | |
|         return $this;
 | |
|     }
 | |
| 
 | |
|     public function processPaymentView($data)
 | |
|     {
 | |
|         $this->initializeOmnipayGateway();
 | |
| 
 | |
|         $this->payment_hash->data = array_merge((array) $this->payment_hash->data, ['amount' => $data['total']['amount_with_fee']]);
 | |
|         $this->payment_hash->save();
 | |
| 
 | |
|         $response = $this->omnipay_gateway
 | |
|             ->purchase($this->generatePaymentDetails($data))
 | |
|             ->setItems($this->generatePaymentItems($data))
 | |
|             ->send();
 | |
| 
 | |
|         if ($response->isRedirect()) {
 | |
|             return $response->redirect();
 | |
|         }
 | |
| 
 | |
|         PaymentFailureMailer::dispatch($this->client, $response->getData(), $this->client->company, $data['total']['amount_with_fee']);
 | |
| 
 | |
|         $message = [
 | |
|             'server_response' => $response->getMessage(),
 | |
|             'data' => $this->payment_hash->data,
 | |
|         ];
 | |
| 
 | |
|         SystemLogger::dispatch(
 | |
|             $message,
 | |
|             SystemLog::CATEGORY_GATEWAY_RESPONSE,
 | |
|             SystemLog::EVENT_GATEWAY_FAILURE,
 | |
|             SystemLog::TYPE_PAYPAL,
 | |
|             $this->client,
 | |
|             $this->client->company,
 | |
|         );
 | |
| 
 | |
|         throw new PaymentFailed($response->getMessage(), $response->getCode());
 | |
|     }
 | |
| 
 | |
|     public function processPaymentResponse($request)
 | |
|     {
 | |
|         $this->initializeOmnipayGateway();
 | |
| 
 | |
|         $response = $this->omnipay_gateway
 | |
|             ->completePurchase(['amount' => $this->payment_hash->data->amount, 'currency' => $this->client->getCurrencyCode()])
 | |
|             ->send();
 | |
| 
 | |
|         if ($response->isCancelled()) {
 | |
|             return redirect()->route('client.invoices.index')->with('warning', ctrans('texts.status_cancelled'));
 | |
|         }
 | |
| 
 | |
|         if ($response->isSuccessful()) {
 | |
|             $data = [
 | |
|                 'payment_method' => $response->getData()['TOKEN'],
 | |
|                 'payment_type' => PaymentType::PAYPAL,
 | |
|                 'amount' => $this->payment_hash->data->amount,
 | |
|                 'transaction_reference' => $response->getTransactionReference(),
 | |
|                 'gateway_type_id' => GatewayType::PAYPAL,
 | |
|             ];
 | |
| 
 | |
|             $payment = $this->createPayment($data, \App\Models\Payment::STATUS_COMPLETED);
 | |
| 
 | |
|             SystemLogger::dispatch(
 | |
|                 ['response' => (array)$response->getData(), 'data' => $data],
 | |
|                 SystemLog::CATEGORY_GATEWAY_RESPONSE,
 | |
|                 SystemLog::EVENT_GATEWAY_SUCCESS,
 | |
|                 SystemLog::TYPE_PAYPAL,
 | |
|                 $this->client,
 | |
|                 $this->client->company,
 | |
|             );
 | |
| 
 | |
|             return redirect()->route('client.payments.show', ['payment' => $this->encodePrimaryKey($payment->id)]);
 | |
|         }
 | |
| 
 | |
|         if (!$response->isSuccessful()) {
 | |
| 
 | |
|             $data = $response->getData();
 | |
| 
 | |
|             PaymentFailureMailer::dispatch($this->client, $response->getMessage(), $this->client->company, $this->payment_hash->data->amount);
 | |
| 
 | |
|             $message = [
 | |
|                 'server_response' => $data['L_LONGMESSAGE0'],
 | |
|                 'data' => $this->payment_hash->data,
 | |
|             ];
 | |
| 
 | |
|             SystemLogger::dispatch(
 | |
|                 $message,
 | |
|                 SystemLog::CATEGORY_GATEWAY_RESPONSE,
 | |
|                 SystemLog::EVENT_GATEWAY_FAILURE,
 | |
|                 SystemLog::TYPE_PAYPAL,
 | |
|                 $this->client,
 | |
|                 $this->client->company,
 | |
|             );
 | |
| 
 | |
|             throw new PaymentFailed($response->getMessage(), $response->getCode());
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     public function generatePaymentDetails(array $data)
 | |
|     {
 | |
|         return [
 | |
|             'currency' => $this->client->getCurrencyCode(),
 | |
|             'transactionType' => 'Purchase',
 | |
|             'clientIp' => request()->getClientIp(),
 | |
|             'amount' => $data['total']['amount_with_fee'],
 | |
|             'returnUrl' => route('client.payments.response', [
 | |
|                 'company_gateway_id' => $this->company_gateway->id,
 | |
|                 'payment_hash' => $this->payment_hash->hash,
 | |
|                 'payment_method_id' => GatewayType::PAYPAL,
 | |
|             ]),
 | |
|             'cancelUrl' => $this->client->company->domain() . '/client/invoices',
 | |
|             'description' => implode(',', collect($this->payment_hash->data->invoices)
 | |
|                 ->map(function ($invoice) {
 | |
|                     return sprintf('%s: %s', ctrans('texts.invoice_number'), $invoice->invoice_number);
 | |
|                 })->toArray()),
 | |
|             'transactionId' => $this->payment_hash->hash . '-' . time(),
 | |
|             'ButtonSource' => 'InvoiceNinja_SP',
 | |
|             'solutionType' => 'Sole',
 | |
|         ];
 | |
|     }
 | |
| 
 | |
|     public function generatePaymentItems(array $data)
 | |
|     {
 | |
| 
 | |
|         $_invoice = collect($this->payment_hash->data->invoices)->first();
 | |
|         $invoice = Invoice::withTrashed()->find($this->decodePrimaryKey($_invoice->invoice_id));
 | |
| 
 | |
|         $line_item = collect($invoice->line_items)->first();
 | |
| 
 | |
|         $items = [];
 | |
| 
 | |
|         $items[] = new Item([
 | |
|                 'name' => " ",
 | |
|                 'description' => ctrans('texts.invoice_number') . "# " . $invoice->number,
 | |
|                 'price' => $data['total']['amount_with_fee'],
 | |
|                 'quantity' => 1,
 | |
|             ]);
 | |
| 
 | |
|         return $items;
 | |
| 
 | |
|     }
 | |
| 
 | |
| }
 |