mirror of
				https://github.com/invoiceninja/invoiceninja.git
				synced 2025-10-31 02:17:30 -04:00 
			
		
		
		
	
		
			
				
	
	
		
			241 lines
		
	
	
		
			7.7 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
			
		
		
	
	
			241 lines
		
	
	
		
			7.7 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
| <?php
 | |
| 
 | |
| /**
 | |
|  * Invoice Ninja (https://invoiceninja.com).
 | |
|  *
 | |
|  * @link https://github.com/invoiceninja/invoiceninja source repository
 | |
|  *
 | |
|  * @copyright Copyright (c) 2022. Invoice Ninja LLC (https://invoiceninja.com)
 | |
|  *
 | |
|  * @license https://www.elastic.co/licensing/elastic-license
 | |
|  */
 | |
| 
 | |
| namespace App\PaymentDrivers\PayTrace;
 | |
| 
 | |
| use App\Exceptions\PaymentFailed;
 | |
| use App\Jobs\Util\SystemLogger;
 | |
| use App\Models\ClientGatewayToken;
 | |
| use App\Models\GatewayType;
 | |
| use App\Models\Invoice;
 | |
| use App\Models\Payment;
 | |
| use App\Models\PaymentHash;
 | |
| use App\Models\PaymentType;
 | |
| use App\Models\SystemLog;
 | |
| use App\PaymentDrivers\PayFastPaymentDriver;
 | |
| use App\PaymentDrivers\PaytracePaymentDriver;
 | |
| use App\Utils\Traits\MakesHash;
 | |
| use Illuminate\Http\Request;
 | |
| use Illuminate\Support\Facades\Cache;
 | |
| use Illuminate\Support\Str;
 | |
| 
 | |
| class CreditCard
 | |
| {
 | |
|     use MakesHash;
 | |
| 
 | |
|     public $paytrace;
 | |
| 
 | |
|     public function __construct(PaytracePaymentDriver $paytrace)
 | |
|     {
 | |
|         $this->paytrace = $paytrace;
 | |
|     }
 | |
| 
 | |
|     public function authorizeView($data)
 | |
|     {
 | |
|         $data['client_key'] = $this->paytrace->getAuthToken();
 | |
|         $data['gateway'] = $this->paytrace;
 | |
| 
 | |
|         return render('gateways.paytrace.authorize', $data);
 | |
|     }
 | |
| 
 | |
|     public function authorizeResponse($request)
 | |
|     {
 | |
|         $data = $request->all();
 | |
| 
 | |
|         $response = $this->createCustomer($data);
 | |
| 
 | |
|         return redirect()->route('client.payment_methods.index');
 | |
|     }
 | |
| 
 | |
|     private function createCustomer($data)
 | |
|     {
 | |
|         $post_data = [
 | |
|             'customer_id' => Str::random(32),
 | |
|             'hpf_token' => $data['HPF_Token'],
 | |
|             'enc_key' => $data['enc_key'],
 | |
|             'integrator_id' =>  $this->paytrace->company_gateway->getConfigField('integratorId'),
 | |
|             'billing_address' => $this->buildBillingAddress(),
 | |
|         ];
 | |
| 
 | |
|         $response = $this->paytrace->gatewayRequest('/v1/customer/pt_protect_create', $post_data);
 | |
| 
 | |
|         if (! $response->success) {
 | |
|             $error = 'Error creating customer in gateway';
 | |
|             $error_code = isset($response->response_code) ? $response->response_code : 'PT_ERR';
 | |
| 
 | |
|             if (isset($response->errors)) {
 | |
|                 foreach ($response->errors as $err) {
 | |
|                     $error = end($err);
 | |
|                 }
 | |
|             }
 | |
| 
 | |
|             $data = [
 | |
|                 'response' => $response,
 | |
|                 'error' => $error,
 | |
|                 'error_code' => $error_code,
 | |
|             ];
 | |
| 
 | |
|             return $this->paytrace->processUnsuccessfulTransaction($data);
 | |
|         }
 | |
| 
 | |
|         $cgt = [];
 | |
|         $cgt['token'] = $response->customer_id;
 | |
|         $cgt['payment_method_id'] = GatewayType::CREDIT_CARD;
 | |
| 
 | |
|         $profile = $this->getCustomerProfile($response->customer_id);
 | |
| 
 | |
|         $payment_meta = new \stdClass;
 | |
|         $payment_meta->exp_month = $profile->credit_card->expiration_month;
 | |
|         $payment_meta->exp_year = $profile->credit_card->expiration_year;
 | |
|         $payment_meta->brand = 'CC';
 | |
|         $payment_meta->last4 = $profile->credit_card->masked_number;
 | |
|         $payment_meta->type = GatewayType::CREDIT_CARD;
 | |
| 
 | |
|         $cgt['payment_meta'] = $payment_meta;
 | |
| 
 | |
|         $token = $this->paytrace->storeGatewayToken($cgt, []);
 | |
| 
 | |
|         return $response;
 | |
|     }
 | |
| 
 | |
|     private function getCustomerProfile($customer_id)
 | |
|     {
 | |
|         $profile = $this->paytrace->gatewayRequest('/v1/customer/export', [
 | |
|             'integrator_id' =>  $this->paytrace->company_gateway->getConfigField('integratorId'),
 | |
|             'customer_id' => $customer_id,
 | |
|         ]);
 | |
| 
 | |
|         return $profile->customers[0];
 | |
|     }
 | |
| 
 | |
|     private function buildBillingAddress()
 | |
|     {
 | |
|         $data = [
 | |
|             'name' => $this->paytrace->client->present()->name(),
 | |
|             'street_address' => $this->paytrace->client->address1,
 | |
|             'city' => $this->paytrace->client->city,
 | |
|             'state' => $this->paytrace->client->state,
 | |
|             'zip' => $this->paytrace->client->postal_code,
 | |
|         ];
 | |
| 
 | |
|         return $data;
 | |
|     }
 | |
| 
 | |
|     public function paymentView($data)
 | |
|     {
 | |
|         $data['client_key'] = $this->paytrace->getAuthToken();
 | |
|         $data['gateway'] = $this->paytrace;
 | |
| 
 | |
|         return render('gateways.paytrace.pay', $data);
 | |
|     }
 | |
| 
 | |
|     public function paymentResponse(Request $request)
 | |
|     {
 | |
|         $response_array = $request->all();
 | |
| 
 | |
|         if ($request->token) {
 | |
|             $token = ClientGatewayToken::find($this->decodePrimaryKey($request->token));
 | |
| 
 | |
|             return $this->processTokenPayment($token->token, $request);
 | |
|         }
 | |
| 
 | |
|         if ($request->has('store_card') && $request->input('store_card') === true) {
 | |
|             $response = $this->createCustomer($request->all());
 | |
| 
 | |
|             return $this->processTokenPayment($response->customer_id, $request);
 | |
|         }
 | |
| 
 | |
|         //process a regular charge here:
 | |
|         $data = [
 | |
|             'hpf_token' => $response_array['HPF_Token'],
 | |
|             'enc_key' => $response_array['enc_key'],
 | |
|             'integrator_id' =>  $this->paytrace->company_gateway->getConfigField('integratorId'),
 | |
|             'billing_address' => $this->buildBillingAddress(),
 | |
|             'amount' => $request->input('amount_with_fee'),
 | |
|             'invoice_id' => $this->harvestInvoiceId(),
 | |
|         ];
 | |
| 
 | |
|         $response = $this->paytrace->gatewayRequest('/v1/transactions/sale/pt_protect', $data);
 | |
| 
 | |
|         if ($response->success) {
 | |
|             return $this->processSuccessfulPayment($response);
 | |
|         }
 | |
| 
 | |
|         return $this->processUnsuccessfulPayment($response);
 | |
|     }
 | |
| 
 | |
|     public function processTokenPayment($token, $request)
 | |
|     {
 | |
|         $data = [
 | |
|             'customer_id' => $token,
 | |
|             'integrator_id' =>  $this->paytrace->company_gateway->getConfigField('integratorId'),
 | |
|             'amount' => $request->input('amount_with_fee'),
 | |
|         ];
 | |
| 
 | |
|         $response = $this->paytrace->gatewayRequest('/v1/transactions/sale/by_customer', $data);
 | |
| 
 | |
|         if ($response->success) {
 | |
|             $this->paytrace->logSuccessfulGatewayResponse(['response' => $response, 'data' => $this->paytrace->payment_hash], SystemLog::TYPE_PAYTRACE);
 | |
| 
 | |
|             return $this->processSuccessfulPayment($response);
 | |
|         }
 | |
| 
 | |
|         return $this->processUnsuccessfulPayment($response);
 | |
|     }
 | |
| 
 | |
|     private function harvestInvoiceId()
 | |
|     {
 | |
|         $_invoice = collect($this->paytrace->payment_hash->data->invoices)->first();
 | |
|         $invoice = Invoice::withTrashed()->find($this->decodePrimaryKey($_invoice->invoice_id));
 | |
| 
 | |
|         if ($invoice) {
 | |
|             return ctrans('texts.invoice_number').'# '.$invoice->number;
 | |
|         }
 | |
| 
 | |
|         return ctrans('texts.invoice_number').'####';
 | |
|     }
 | |
| 
 | |
|     private function processSuccessfulPayment($response)
 | |
|     {
 | |
|         $amount = array_sum(array_column($this->paytrace->payment_hash->invoices(), 'amount')) + $this->paytrace->payment_hash->fee_total;
 | |
| 
 | |
|         $payment_record = [];
 | |
|         $payment_record['amount'] = $amount;
 | |
|         $payment_record['payment_type'] = PaymentType::CREDIT_CARD_OTHER;
 | |
|         $payment_record['gateway_type_id'] = GatewayType::CREDIT_CARD;
 | |
|         $payment_record['transaction_reference'] = $response->transaction_id;
 | |
| 
 | |
|         $payment = $this->paytrace->createPayment($payment_record, Payment::STATUS_COMPLETED);
 | |
| 
 | |
|         return redirect()->route('client.payments.show', ['payment' => $this->encodePrimaryKey($payment->id)]);
 | |
|     }
 | |
| 
 | |
|     private function processUnsuccessfulPayment($response)
 | |
|     {
 | |
|         $error = $response->status_message;
 | |
| 
 | |
|         if (property_exists($response, 'approval_message') && $response->approval_message) {
 | |
|             $error .= " - {$response->approval_message}";
 | |
|         }
 | |
| 
 | |
|         $error_code = property_exists($response, 'approval_message') ? $response->approval_message : 'Undefined code';
 | |
| 
 | |
|         $data = [
 | |
|             'response' => $response,
 | |
|             'error' => $error,
 | |
|             'error_code' => $error_code,
 | |
|         ];
 | |
| 
 | |
|         return $this->paytrace->processUnsuccessfulTransaction($data);
 | |
|     }
 | |
| }
 |