diff --git a/app/PaymentDrivers/BasePaymentDriver.php b/app/PaymentDrivers/BasePaymentDriver.php index c0d16dcd027b..bd14c921c05d 100644 --- a/app/PaymentDrivers/BasePaymentDriver.php +++ b/app/PaymentDrivers/BasePaymentDriver.php @@ -70,7 +70,7 @@ class BasePaymentDriver */ protected function gateway() { - +\Log::error("booting {$this->company_gateway->gateway->provider}"); $this->gateway = Omnipay::create($this->company_gateway->gateway->provider); $this->gateway->initialize((array) $this->company_gateway->getConfig()); @@ -160,17 +160,16 @@ class BasePaymentDriver acceptNotification() - convert an incoming request from an off-site gateway to a generic notification object for further processing */ - protected function paymentDetails($paymentMethod = false) + protected function paymentDetails($input) { - $gatewayTypeAlias = $this->gatewayType == GatewayType::TOKEN ? $this->gatewayType : GatewayType::getAliasFromId($this->gatewayType); - $completeUrl = $this->invitation->getLink('complete', true) . '/' . $gatewayTypeAlias; + // $gatewayTypeAlias = $this->gatewayType == GatewayType::TOKEN ? $this->gatewayType : GatewayType::getAliasFromId($this->gatewayType); $data = [ 'currency' => $this->client->getCurrencyCode(), 'transactionType' => 'Purchase', 'clientIp' => request()->getClientIp(), ]; - +/* if ($paymentMethod) { if ($this->customerReferenceParam) { $data[$this->customerReferenceParam] = $paymentMethod->account_gateway_token->token; @@ -181,14 +180,16 @@ class BasePaymentDriver } else { $data['card'] = new CreditCard($this->paymentDetailsFromClient()); } - +*/ return $data; } - public function purchase($data, $items) + public function offsitePurchase($data, $items) { - $response = $this->gateway - ->purchase($data) + $this->gateway(); + + $response = $this->gateway + ->purchase($data) ->setItems($items) ->send(); diff --git a/app/PaymentDrivers/PayPalExpressPaymentDriver.php b/app/PaymentDrivers/PayPalExpressPaymentDriver.php index 2b04e3da27d0..bf5547e7f3d6 100644 --- a/app/PaymentDrivers/PayPalExpressPaymentDriver.php +++ b/app/PaymentDrivers/PayPalExpressPaymentDriver.php @@ -15,6 +15,7 @@ use App\Models\ClientGatewayToken; use App\Models\GatewayType; use App\Utils\Traits\MakesHash; use Illuminate\Http\Request; +use Omnipay\Common\Item; class PayPalExpressPaymentDriver extends BasePaymentDriver { @@ -53,7 +54,7 @@ class PayPalExpressPaymentDriver extends BasePaymentDriver */ public function processPaymentView(array $data) { - $this->purchase(); + $this->offsitePurchase($this->paymentDetails($data), $this->paymentItems($data)); } public function processPaymentResponse($request) @@ -61,15 +62,15 @@ class PayPalExpressPaymentDriver extends BasePaymentDriver } - protected function paymentDetails() + protected function paymentDetails($input) { - $data = parent::paymentDetails(); + $data = parent::paymentDetails($input); - $data['amount'] = $invoice->getRequestedAmount(); - $data['returnUrl'] = $completeUrl; - $data['cancelUrl'] = $this->invitation->getLink(); - $data['description'] = trans('texts.' . $invoice->getEntityType()) . " {$invoice->invoice_number}"; - $data['transactionId'] = $invoice->invoice_number; + $data['amount'] = $input['amount_with_fee']; + $data['returnUrl'] = $this->buildReturnUrl($input); + $data['cancelUrl'] = $this->buildCancelUrl($input); + $data['description'] = $this->buildDescription($input); + $data['transactionId'] = $this->buildTransactionId($input); $data['ButtonSource'] = 'InvoiceNinja_SP'; $data['solutionType'] = 'Sole'; // show 'Pay with credit card' option @@ -78,8 +79,81 @@ class PayPalExpressPaymentDriver extends BasePaymentDriver return $data; } - private function buildReturnUrl() + private function buildReturnUrl($input) { - $url = $this->client->company->domain . "/payment_hook/{$this->company_gateway->id}/{GatewayType::PAYPAL}"; + $url = $this->client->company->domain . "/payment_hook/{$this->company_gateway->id}/{GatewayType::PAYPAL}/"; + $url .= "?hashed_ids=" . implode(",", $input['hashed_ids']); + $url .= "&amount=".$input['amount']; + $url .= "&fee=".$input['fee']; + + return $url; } + + private function buildCancelUrl($input) + { + $url = $this->client->company->domain . '/client/invoices'; + + return $url; + } + + private function buildDescription($input) + { + $invoice_numbers = ""; + + foreach($input['invoices'] as $invoice) + { + $invoice_numbers .= $invoice->invoice_number." "; + } + + return ctrans('texts.invoice_number'). ": {$invoice_numbers}"; + + } + + private function buildTransactionId($input) + { + return implode(",", $input['hashed_ids']); + } + + private function paymentItems($input) : array + { + + $items = []; + $total = 0; + + foreach ($input['invoices'] as $invoice) + { + foreach($invoice->line_items as $invoiceItem) + { + // Some gateways require quantity is an integer + if (floatval($invoiceItem->quantity) != intval($invoiceItem->quantity)) { + return null; + } + + $item = new Item([ + 'name' => $invoiceItem->product_key, + 'description' => substr($invoiceItem->notes, 0, 100), + 'price' => $invoiceItem->cost, + 'quantity' => $invoiceItem->quantity, + ]); + + $items[] = $item; + + $total += $invoiceItem->cost * $invoiceItem->quantity; + } + } + + if ($total != $input['amount_with_fee']) { + $item = new Item([ + 'name' => trans('texts.taxes_and_fees'), + 'description' => '', + 'price' => $input['amount_with_fee'] - $total, + 'quantity' => 1, + ]); + + $items[] = $item; + } + + return $items; + } + } \ No newline at end of file diff --git a/config/ninja.php b/config/ninja.php index 5fe7918ba426..a5ec144f514f 100644 --- a/config/ninja.php +++ b/config/ninja.php @@ -57,6 +57,7 @@ return [ 'clientname' => 'client@example.com', 'password' => 'password', 'stripe' => env('STRIPE_KEYS',''), + 'paypal' => env('PAYPAL_KEYS', ''), ], 'contact' => [ diff --git a/database/seeds/RandomDataSeeder.php b/database/seeds/RandomDataSeeder.php index 9b6c939d8a6a..4db888806d0c 100644 --- a/database/seeds/RandomDataSeeder.php +++ b/database/seeds/RandomDataSeeder.php @@ -171,7 +171,22 @@ class RandomDataSeeder extends Seeder $cg->show_shipping_address = true; $cg->update_details = true; $cg->config = encrypt(config('ninja.testvars.stripe')); - $cg->priority_id = 1; + $cg->priority_id = 2; + $cg->save(); + } + + if(config('ninja.testvars.paypal')) + { + $cg = new CompanyGateway; + $cg->company_id = $company->id; + $cg->user_id = $user->id; + $cg->gateway_key = '38f2c48af60c7dd69e04248cbb24c36e'; + $cg->require_cvv = true; + $cg->show_address = true; + $cg->show_shipping_address = true; + $cg->update_details = true; + $cg->config = encrypt(config('ninja.testvars.paypal')); + $cg->priority_id = 3; $cg->save(); }