1
0
mirror of https://github.com/invoiceninja/invoiceninja.git synced 2024-11-15 07:33:04 +01:00
invoiceninja/app/Services/Client/PaymentMethod.php

251 lines
9.4 KiB
PHP
Raw Normal View History

2021-01-18 02:36:13 +01:00
<?php
/**
* Invoice Ninja (https://invoiceninja.com).
*
* @link https://github.com/invoiceninja/invoiceninja source repository
*
2024-04-12 06:15:41 +02:00
* @copyright Copyright (c) 2024. 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\Payment;
use App\Utils\Traits\MakesHash;
class PaymentMethod
{
use MakesHash;
2023-08-08 12:39:46 +02:00
/** @var \Illuminate\Support\Collection<CompanyGateway> $gateways **/
2021-01-18 02:36:13 +01:00
private $gateways;
private $payment_methods;
private $payment_urls = [];
2024-06-18 04:57:15 +02:00
public function __construct(private Client $client, private float $amount)
2021-01-18 02:36:13 +01:00
{
}
public function run()
2021-01-18 02:36:13 +01:00
{
$this->getGateways()
2024-06-15 08:51:34 +02:00
->getMethods();
2021-01-18 03:12:48 +01:00
return $this->getPaymentUrls();
2021-01-18 02:36:13 +01:00
}
public function getPaymentUrls()
{
2024-08-22 00:14:28 +02:00
$pu = collect($this->payment_urls);
$keys = $pu->pluck('gateway_type_id');
$contains_both = $keys->contains('1') && $keys->contains('29'); //handle the case where PayPal Advanced cards + regular CC is present
2024-08-22 08:45:06 +02:00
$this->payment_urls = $pu->when($contains_both, function ($methods) {
return $methods->reject(function ($item) {
2024-08-22 00:14:28 +02:00
return $item['gateway_type_id'] == '29';
});
})->toArray();
2021-01-18 02:36:13 +01:00
return $this->payment_urls;
2024-08-22 00:14:28 +02:00
2021-01-18 02:36:13 +01:00
}
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');
2024-06-15 02:03:25 +02:00
// We need to check for "0" here as we disable a payment gateway for a client with the number "0"
2021-01-18 02:36:13 +01:00
if ($company_gateways || $company_gateways == '0') {
$transformed_ids = $this->transformKeys(explode(',', $company_gateways));
2024-06-15 02:03:25 +02:00
//gateways disabled
2024-09-05 07:55:14 +02:00
if ($company_gateways == '0') {
$transformed_ids = [];
2023-10-26 04:57:44 +02:00
}
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
});
2023-09-25 05:19:08 +02:00
2021-01-18 02:36:13 +01:00
} else {
2023-08-08 11:44:52 +02:00
$this->gateways = CompanyGateway::query()
->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')
->where('is_deleted', false)->get();
2021-01-18 02:36:13 +01:00
}
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));
2024-09-05 07:55:14 +02:00
if ($company_gateways == '0') {
$transformed_ids = [];
}
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 {
2023-08-08 11:44:52 +02:00
$this->gateways = CompanyGateway::query()
->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')
->where('is_deleted', false)->get();
2021-01-18 02:36:13 +01:00
}
return $this;
}
private function getMethods()
{
2021-01-18 03:12:48 +01:00
$this->payment_methods = [];
2021-01-18 02:36:13 +01:00
foreach ($this->gateways as $gateway) {
//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-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)) {
2024-06-18 04:57:15 +02:00
if ($this->validGatewayForAmount($gateway->fees_and_limits->{$type}) && $gateway->fees_and_limits->{$type}->is_enabled) {
2021-01-18 02:36:13 +01:00
$this->payment_methods[] = [$gateway->id => $type];
}
} else {
}
}
}
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());
2024-06-15 08:51:34 +02:00
//@15-06-2024
2024-09-05 07:55:14 +02:00
foreach ($this->payment_methods as $key => $type) {
2024-08-22 08:45:06 +02:00
foreach ($type as $gateway_id => $gateway_type_id) {
2024-06-18 04:57:15 +02:00
$gate = $this->gateways->where('id', $gateway_id)->first();
$this->buildUrl($gate, $gateway_type_id);
2024-06-15 08:51:34 +02:00
}
}
2024-08-22 08:45:06 +02:00
2024-06-15 08:51:34 +02:00
//@15-06-2024
2024-08-22 08:45:06 +02:00
$this->payment_methods = [];
2024-06-15 08:51:34 +02:00
2021-01-18 02:36:13 +01:00
/* 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-18 03:12:48 +01:00
foreach ($gateway->driver($this->client)->gatewayTypes() as $type) {
2024-07-14 13:28:54 +02:00
if (isset($gateway->fees_and_limits) && is_object($gateway->fees_and_limits) && property_exists($gateway->fees_and_limits, GatewayType::CREDIT_CARD)) { //@phpstan-ignore-line
if ($this->validGatewayForAmount($gateway->fees_and_limits->{GatewayType::CREDIT_CARD}, $this->amount)) {
2024-06-15 08:51:34 +02:00
$this->buildUrl($gateway, $type);
}
2021-01-18 02:36:13 +01:00
} else {
2024-06-15 08:51:34 +02:00
$this->buildUrl($gateway, null);
2021-01-18 02:36:13 +01:00
}
}
}
2024-06-27 01:14:49 +02:00
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 (
$this->client->service()->getCreditBalance() > $this->amount
&& $this->client->getSetting('use_credits_payment') == 'always') {
$payment_urls = [];
}
$this->payment_urls[] = [
'label' => ctrans('texts.apply_credit'),
'company_gateway_id' => CompanyGateway::GATEWAY_CREDIT,
'gateway_type_id' => GatewayType::CREDIT,
2024-07-28 11:08:04 +02:00
'is_paypal' => false,
2024-06-27 01:14:49 +02:00
];
}
2021-01-18 03:12:48 +01:00
return $this;
2021-01-18 02:36:13 +01:00
}
2024-08-22 08:45:06 +02:00
2024-06-15 08:51:34 +02:00
//@15-06-2024
private function buildUrl(CompanyGateway $gateway, ?int $type = null)
{
2024-08-22 08:45:06 +02:00
2024-06-15 08:51:34 +02:00
$fee_label = $gateway->calcGatewayFeeLabel($this->amount, $this->client, $type);
if (! $type || (GatewayType::CUSTOM == $type)) {
$this->payment_urls[] = [
'label' => $gateway->getConfigField('name').$fee_label,
'company_gateway_id' => $gateway->id,
'gateway_type_id' => GatewayType::CREDIT_CARD,
2024-07-27 00:48:51 +02:00
'is_paypal' => $gateway->isPayPal(),
2024-06-15 08:51:34 +02:00
];
} else {
$this->payment_urls[] = [
'label' => $gateway->getTypeAlias($type).$fee_label,
'company_gateway_id' => $gateway->id,
'gateway_type_id' => $type,
2024-07-27 00:48:51 +02:00
'is_paypal' => $gateway->isPayPal(),
2024-06-15 08:51:34 +02:00
];
}
2024-06-18 04:57:15 +02:00
return $this;
2024-06-15 08:51:34 +02:00
}
2024-06-18 04:57:15 +02:00
private function validGatewayForAmount($fees_and_limits_for_payment_type): bool
2021-01-18 02:36:13 +01:00
{
if (isset($fees_and_limits_for_payment_type)) {
$fees_and_limits = $fees_and_limits_for_payment_type;
} else {
return true;
}
2024-08-22 08:45:06 +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;
}
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;
}
}