2021-01-18 02:36:13 +01:00
|
|
|
<?php
|
|
|
|
/**
|
|
|
|
* Invoice Ninja (https://invoiceninja.com).
|
|
|
|
*
|
|
|
|
* @link https://github.com/invoiceninja/invoiceninja source repository
|
|
|
|
*
|
2022-04-27 05:20:41 +02:00
|
|
|
* @copyright Copyright (c) 2022. Invoice Ninja LLC (https://invoiceninja.com)
|
2021-01-18 02:36:13 +01:00
|
|
|
*
|
2021-06-16 08:58:16 +02:00
|
|
|
* @license https://www.elastic.co/licensing/elastic-license
|
2021-01-18 02:36:13 +01:00
|
|
|
*/
|
|
|
|
|
|
|
|
namespace App\Services\Client;
|
|
|
|
|
2021-01-18 03:12:48 +01:00
|
|
|
use App\Models\Client;
|
2021-01-18 02:36:13 +01:00
|
|
|
use App\Models\CompanyGateway;
|
|
|
|
use App\Models\GatewayType;
|
|
|
|
use App\Models\Invoice;
|
|
|
|
use App\Models\Payment;
|
|
|
|
use App\Utils\Ninja;
|
|
|
|
use App\Utils\Traits\MakesHash;
|
|
|
|
|
|
|
|
class PaymentMethod
|
|
|
|
{
|
|
|
|
use MakesHash;
|
|
|
|
|
|
|
|
private $client;
|
|
|
|
|
|
|
|
private $amount;
|
|
|
|
|
|
|
|
private $gateways;
|
|
|
|
|
|
|
|
private $payment_methods;
|
|
|
|
|
|
|
|
private $payment_urls = [];
|
|
|
|
|
2021-01-18 03:12:48 +01:00
|
|
|
public function __construct(Client $client, float $amount)
|
2021-01-18 02:36:13 +01:00
|
|
|
{
|
|
|
|
$this->client = $client;
|
|
|
|
$this->amount = $amount;
|
|
|
|
}
|
|
|
|
|
2021-01-18 03:12:48 +01:00
|
|
|
public function run()
|
2021-01-18 02:36:13 +01:00
|
|
|
{
|
|
|
|
|
|
|
|
$this->getGateways()
|
|
|
|
->getMethods()
|
|
|
|
->buildUrls();
|
2021-01-18 03:12:48 +01:00
|
|
|
|
|
|
|
|
|
|
|
return $this->getPaymentUrls();
|
2021-01-18 02:36:13 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
public function getPaymentUrls()
|
|
|
|
{
|
|
|
|
return $this->payment_urls;
|
|
|
|
}
|
|
|
|
|
|
|
|
public function getPaymentMethods()
|
|
|
|
{
|
|
|
|
return $this->payment_methods;
|
|
|
|
}
|
2021-01-18 03:12:48 +01:00
|
|
|
|
2021-01-18 02:36:13 +01:00
|
|
|
private function getGateways()
|
|
|
|
{
|
|
|
|
|
|
|
|
$company_gateways = $this->client->getSetting('company_gateway_ids');
|
|
|
|
|
|
|
|
//we need to check for "0" here as we disable a payment gateway for a client with the number "0"
|
|
|
|
if ($company_gateways || $company_gateways == '0') {
|
|
|
|
|
|
|
|
$transformed_ids = $this->transformKeys(explode(',', $company_gateways));
|
|
|
|
|
2022-02-20 21:51:49 +01:00
|
|
|
$this->gateways = $this->client
|
|
|
|
->company
|
|
|
|
->company_gateways
|
2021-01-18 02:36:13 +01:00
|
|
|
->whereIn('id', $transformed_ids)
|
2021-08-05 14:30:22 +02:00
|
|
|
->where('is_deleted', false)
|
|
|
|
->whereNull('deleted_at')
|
2021-01-18 02:36:13 +01:00
|
|
|
->where('gateway_key', '!=', '54faab2ab6e3223dbe848b1686490baa')
|
|
|
|
->sortby(function ($model) use ($transformed_ids) { //company gateways are sorted in order of priority
|
|
|
|
return array_search($model->id, $transformed_ids);// this closure sorts for us
|
2022-02-20 21:51:49 +01:00
|
|
|
});
|
2021-01-18 02:36:13 +01:00
|
|
|
|
|
|
|
} else {
|
|
|
|
|
2022-02-18 06:31:17 +01:00
|
|
|
$this->gateways = CompanyGateway::with('gateway')
|
|
|
|
->where('company_id', $this->client->company_id)
|
2021-01-18 02:36:13 +01:00
|
|
|
->where('gateway_key', '!=', '54faab2ab6e3223dbe848b1686490baa')
|
2021-08-05 14:30:22 +02:00
|
|
|
->whereNull('deleted_at')
|
2022-02-18 06:31:17 +01:00
|
|
|
->where('is_deleted', false)->get();
|
2021-01-18 02:36:13 +01:00
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
return $this;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private function getCustomGateways()
|
|
|
|
{
|
|
|
|
|
|
|
|
$company_gateways = $this->client->getSetting('company_gateway_ids');
|
|
|
|
|
|
|
|
//we need to check for "0" here as we disable a payment gateway for a client with the number "0"
|
|
|
|
if ($company_gateways || $company_gateways == '0') {
|
|
|
|
|
|
|
|
$transformed_ids = $this->transformKeys(explode(',', $company_gateways));
|
|
|
|
|
2022-02-20 21:51:49 +01:00
|
|
|
$this->gateways = $this->client
|
|
|
|
->company
|
|
|
|
->company_gateways
|
2021-01-18 02:36:13 +01:00
|
|
|
->whereIn('id', $transformed_ids)
|
2021-08-05 14:30:22 +02:00
|
|
|
->where('is_deleted', false)
|
|
|
|
->whereNull('deleted_at')
|
2021-01-27 06:18:30 +01:00
|
|
|
->where('gateway_key', '54faab2ab6e3223dbe848b1686490baa')
|
2021-01-18 02:36:13 +01:00
|
|
|
->sortby(function ($model) use ($transformed_ids) { //company gateways are sorted in order of priority
|
|
|
|
return array_search($model->id, $transformed_ids);// this closure sorts for us
|
2022-02-20 21:51:49 +01:00
|
|
|
});
|
2021-01-18 02:36:13 +01:00
|
|
|
|
|
|
|
} else {
|
|
|
|
|
2022-02-18 06:31:17 +01:00
|
|
|
$this->gateways = CompanyGateway::with('gateway')
|
|
|
|
->where('company_id', $this->client->company_id)
|
2021-01-27 06:18:30 +01:00
|
|
|
->where('gateway_key', '54faab2ab6e3223dbe848b1686490baa')
|
2021-08-05 14:30:22 +02:00
|
|
|
->whereNull('deleted_at')
|
2022-02-18 06:31:17 +01:00
|
|
|
->where('is_deleted', false)->get();
|
2021-01-18 02:36:13 +01:00
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return $this;
|
|
|
|
}
|
|
|
|
|
|
|
|
private function getMethods()
|
|
|
|
{
|
2022-05-18 00:47:54 +02:00
|
|
|
|
2021-01-18 03:12:48 +01:00
|
|
|
$this->payment_methods = [];
|
2021-01-18 02:36:13 +01:00
|
|
|
|
|
|
|
foreach ($this->gateways as $gateway) {
|
2021-01-27 02:06:25 +01:00
|
|
|
|
2021-12-30 23:23:54 +01:00
|
|
|
//if gateway doesn't exist or is not implemented - continue here //todo
|
|
|
|
if(!$gateway->driver($this->client))
|
|
|
|
continue;
|
|
|
|
|
2021-01-18 03:12:48 +01:00
|
|
|
foreach ($gateway->driver($this->client)->gatewayTypes() as $type) {
|
2021-01-27 02:06:25 +01:00
|
|
|
|
2021-05-11 13:47:19 +02:00
|
|
|
if (isset($gateway->fees_and_limits) && is_object($gateway->fees_and_limits) && property_exists($gateway->fees_and_limits, $type)) {
|
2021-01-21 02:33:39 +01:00
|
|
|
|
|
|
|
if ($this->validGatewayForAmount($gateway->fees_and_limits->{$type}, $this->amount) && $gateway->fees_and_limits->{$type}->is_enabled) {
|
2021-01-27 02:06:25 +01:00
|
|
|
|
2021-01-18 02:36:13 +01:00
|
|
|
$this->payment_methods[] = [$gateway->id => $type];
|
2022-05-18 00:47:54 +02:00
|
|
|
|
2021-01-18 02:36:13 +01:00
|
|
|
}
|
2021-01-21 02:33:39 +01:00
|
|
|
|
2021-01-18 02:36:13 +01:00
|
|
|
} else {
|
2022-05-18 00:47:54 +02:00
|
|
|
|
2021-01-18 02:36:13 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
//transform from Array to Collection
|
|
|
|
$payment_methods_collections = collect($this->payment_methods);
|
|
|
|
|
|
|
|
//** Plucks the remaining keys into its own collection
|
|
|
|
$this->payment_methods = $payment_methods_collections->intersectByKeys($payment_methods_collections->flatten(1)->unique());
|
|
|
|
|
|
|
|
/* Loop through custom gateways if any exist and append them to the methods collection*/
|
|
|
|
$this->getCustomGateways();
|
|
|
|
|
|
|
|
//note we have to use GatewayType::CREDIT_CARD as alias for CUSTOM
|
|
|
|
foreach ($this->gateways as $gateway) {
|
2021-01-27 06:18:30 +01:00
|
|
|
|
2021-01-18 03:12:48 +01:00
|
|
|
foreach ($gateway->driver($this->client)->gatewayTypes() as $type) {
|
2021-01-27 06:18:30 +01:00
|
|
|
|
2021-05-16 09:06:04 +02:00
|
|
|
if (isset($gateway->fees_and_limits) && is_object($gateway->fees_and_limits) && property_exists($gateway->fees_and_limits, GatewayType::CREDIT_CARD)) {
|
2021-01-27 06:18:30 +01:00
|
|
|
|
|
|
|
if ($this->validGatewayForAmount($gateway->fees_and_limits->{GatewayType::CREDIT_CARD}, $this->amount))
|
2021-05-16 09:07:07 +02:00
|
|
|
$this->payment_methods[] = [$gateway->id => $type];
|
2021-01-27 06:18:30 +01:00
|
|
|
|
2021-01-18 02:36:13 +01:00
|
|
|
} else {
|
2021-01-27 06:18:30 +01:00
|
|
|
$this->payment_methods[] = [$gateway->id => NULL];
|
2021-01-18 02:36:13 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-01-18 03:12:48 +01:00
|
|
|
return $this;
|
2021-01-18 02:36:13 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
private function buildUrls()
|
|
|
|
{
|
|
|
|
|
2021-01-18 03:12:48 +01:00
|
|
|
foreach ($this->payment_methods as $key => $child_array) {
|
2021-01-18 02:36:13 +01:00
|
|
|
foreach ($child_array as $gateway_id => $gateway_type_id) {
|
|
|
|
$gateway = CompanyGateway::find($gateway_id);
|
|
|
|
|
2021-03-26 09:18:25 +01:00
|
|
|
$fee_label = $gateway->calcGatewayFeeLabel($this->amount, $this->client, $gateway_type_id);
|
2021-01-18 02:36:13 +01:00
|
|
|
|
2021-06-01 00:09:38 +02:00
|
|
|
if(!$gateway_type_id || (GatewayType::CUSTOM == $gateway_type_id)){
|
2021-01-18 02:36:13 +01:00
|
|
|
|
|
|
|
$this->payment_urls[] = [
|
|
|
|
'label' => $gateway->getConfigField('name') . $fee_label,
|
|
|
|
'company_gateway_id' => $gateway_id,
|
|
|
|
'gateway_type_id' => GatewayType::CREDIT_CARD,
|
|
|
|
];
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
$this->payment_urls[] = [
|
|
|
|
'label' => $gateway->getTypeAlias($gateway_type_id) . $fee_label,
|
|
|
|
'company_gateway_id' => $gateway_id,
|
|
|
|
'gateway_type_id' => $gateway_type_id,
|
|
|
|
];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (($this->client->getSetting('use_credits_payment') == 'option' || $this->client->getSetting('use_credits_payment') == 'always') && $this->client->service()->getCreditBalance() > 0) {
|
|
|
|
|
|
|
|
// Show credits as only payment option if both statements are true.
|
|
|
|
if (
|
2021-01-18 03:12:48 +01:00
|
|
|
$this->client->service()->getCreditBalance() > $this->amount
|
2021-01-18 02:36:13 +01:00
|
|
|
&& $this->client->getSetting('use_credits_payment') == 'always') {
|
|
|
|
$payment_urls = [];
|
|
|
|
}
|
|
|
|
|
2021-01-24 07:44:14 +01:00
|
|
|
$this->payment_urls[] = [
|
2021-01-18 02:36:13 +01:00
|
|
|
'label' => ctrans('texts.apply_credit'),
|
|
|
|
'company_gateway_id' => CompanyGateway::GATEWAY_CREDIT,
|
|
|
|
'gateway_type_id' => GatewayType::CREDIT,
|
|
|
|
];
|
|
|
|
}
|
|
|
|
|
|
|
|
return $this;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
private function validGatewayForAmount($fees_and_limits_for_payment_type, $amount) :bool
|
|
|
|
{
|
|
|
|
if (isset($fees_and_limits_for_payment_type)) {
|
|
|
|
$fees_and_limits = $fees_and_limits_for_payment_type;
|
|
|
|
} else {
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2022-05-18 00:47:54 +02:00
|
|
|
if ((property_exists($fees_and_limits, 'min_limit')) && $fees_and_limits->min_limit !== null && $fees_and_limits->min_limit != -1 && ($this->amount < $fees_and_limits->min_limit && $this->amount != -1)) {
|
2021-01-18 02:36:13 +01:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2022-05-18 00:47:54 +02:00
|
|
|
if ((property_exists($fees_and_limits, 'max_limit')) && $fees_and_limits->max_limit !== null && $fees_and_limits->max_limit != -1 && ($this->amount > $fees_and_limits->max_limit && $this->amount != -1)) {
|
2021-01-18 02:36:13 +01:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2021-01-24 07:44:14 +01:00
|
|
|
}
|