Skip to content
31 changes: 31 additions & 0 deletions app/Casts/Settings/CurrencyCast.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
<?php

namespace App\Casts\Settings;

use App\Helpers\CurrencyHelper;
use Spatie\LaravelSettings\SettingsCasts\SettingsCast;

class CurrencyCast implements SettingsCast
{
protected CurrencyHelper $currencyHelper;

public function __construct()
{
$this->currencyHelper = new CurrencyHelper();
}

public function get($payload): mixed
{
// Conversion will only take place when the value is displayed.
return $payload;
}

public function set($payload): int
{
if ($payload === null) {
return 0;
}

return $this->currencyHelper->prepareForDatabase($payload);
}
}
2 changes: 1 addition & 1 deletion app/Classes/PaymentExtension.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,5 +10,5 @@ abstract class PaymentExtension extends AbstractExtension
/**
* Returns the redirect url of the payment gateway to redirect the user to
*/
abstract public static function getRedirectUrl(Payment $payment, ShopProduct $shopProduct, string $totalPriceString): string;
abstract public static function getRedirectUrl(Payment $payment, ShopProduct $shopProduct, int $totalPrice): string;
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,13 @@

namespace App\Extensions\PaymentGateways\MercadoPago;

use App\Classes\AbstractExtension;
use App\Classes\PaymentExtension;
use App\Enums\PaymentStatus;
use App\Events\PaymentEvent;
use App\Events\UserUpdateCreditsEvent;
use App\Models\Payment;
use App\Models\ShopProduct;
use App\Models\User;
use App\Traits\Coupon as CouponTrait;
use Exception;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
Expand All @@ -24,10 +23,8 @@
/**
* Summary of MercadoPagoExtension
*/
class MercadoPagoExtension extends AbstractExtension
class MercadoPagoExtension extends PaymentExtension
{
use CouponTrait;

public static function getConfig(): array
{
return [
Expand All @@ -38,7 +35,7 @@ public static function getConfig(): array
];
}

public static function getRedirectUrl(Payment $payment, ShopProduct $shopProduct, string $totalPriceString): string
public static function getRedirectUrl(Payment $payment, ShopProduct $shopProduct, int $totalPrice): string
{
/**
* For Mercado Pago to work correctly,
Expand All @@ -49,6 +46,9 @@ public static function getRedirectUrl(Payment $payment, ShopProduct $shopProduct
throw new Exception(__('It is not possible to purchase via MercadoPago: APP_URL does not have HTTPS, required by Mercado Pago.'));
}

// Converts from cents to decimal places.
$totalPrice = $totalPrice / 1000;

$user = Auth::user();
$user = User::findOrFail($user->id);
$url = 'https://api.mercadopago.com/checkout/preferences';
Expand All @@ -72,7 +72,7 @@ public static function getRedirectUrl(Payment $payment, ShopProduct $shopProduct
[
'title' => "Order #{$payment->id} - " . $shopProduct->name,
'quantity' => 1,
'unit_price' => floatval($totalPriceString),
'unit_price' => $totalPrice,
'currency_id' => $shopProduct->currency_code,
],
],
Expand Down
19 changes: 12 additions & 7 deletions app/Extensions/PaymentGateways/Mollie/MollieExtension.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,14 @@

namespace App\Extensions\PaymentGateways\Mollie;

use App\Classes\AbstractExtension;
use App\Classes\PaymentExtension;
use App\Enums\PaymentStatus;
use App\Events\PaymentEvent;
use App\Events\UserUpdateCreditsEvent;
use App\Models\Payment;
use App\Models\ShopProduct;
use App\Models\User;
use App\Notifications\ConfirmPaymentNotification;
use App\Traits\Coupon as CouponTrait;
use Exception;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\RedirectResponse;
Expand All @@ -22,10 +21,8 @@
/**
* Summary of PayPalExtension
*/
class MollieExtension extends AbstractExtension
class MollieExtension extends PaymentExtension
{
use CouponTrait;

public static function getConfig(): array
{
return [
Expand All @@ -36,8 +33,16 @@ public static function getConfig(): array
];
}

public static function getRedirectUrl(Payment $payment, ShopProduct $shopProduct, string $totalPriceString): string
public static function getRedirectUrl(Payment $payment, ShopProduct $shopProduct, int $totalPrice): string
{
/**
* Mollie requires the price to be a string with two decimal places.
* The price is in cents, so we need to divide by 10 to get the value in 100 factors.
* The price is also in the format of 0.00, so we need to format it to two decimal places.
*/
$priceCents = $totalPrice / 10;
$totalPrice = number_format($priceCents / 100, 2, '.', '');

$url = 'https://api.mollie.com/v2/payments';
$settings = new MollieSettings();
try {
Expand All @@ -47,7 +52,7 @@ public static function getRedirectUrl(Payment $payment, ShopProduct $shopProduct
])->post($url, [
'amount' => [
'currency' => $shopProduct->currency_code,
'value' => $totalPriceString,
'value' => $totalPrice,
],
'description' => "Order #{$payment->id} - " . $shopProduct->name,
'redirectUrl' => route('payment.MollieSuccess', ['payment_id' => $payment->id]),
Expand Down
12 changes: 6 additions & 6 deletions app/Extensions/PaymentGateways/PayPal/PayPalExtension.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@
use App\Models\Payment;
use App\Models\ShopProduct;
use App\Models\User;
use App\Traits\Coupon as CouponTrait;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Redirect;
Expand All @@ -27,8 +26,6 @@
*/
class PayPalExtension extends PaymentExtension
{
use CouponTrait;

public static function getConfig(): array
{
return [
Expand All @@ -37,8 +34,11 @@ public static function getConfig(): array
];
}

public static function getRedirectUrl(Payment $payment, ShopProduct $shopProduct, string $totalPriceString): string
public static function getRedirectUrl(Payment $payment, ShopProduct $shopProduct, int $totalPrice): string
{
// Converts from cents to decimal places.
$totalPrice = $totalPrice / 1000;

$request = new OrdersCreateRequest();
$request->prefer('return=representation');
$request->body = [
Expand All @@ -48,12 +48,12 @@ public static function getRedirectUrl(Payment $payment, ShopProduct $shopProduct
"reference_id" => uniqid(),
"description" => $shopProduct->display,
"amount" => [
"value" => $totalPriceString,
"value" => $totalPrice,
'currency_code' => strtoupper($shopProduct->currency_code),
'breakdown' => [
'item_total' => [
'currency_code' => strtoupper($shopProduct->currency_code),
'value' => $totalPriceString,
'value' => $totalPrice,
],

/* Removed due to errors in the coupon discount calculation. Its not used in other paymentgateways aswell and basically nice to have but unnessecary
Expand Down
17 changes: 8 additions & 9 deletions app/Extensions/PaymentGateways/Stripe/StripeExtension.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

namespace App\Extensions\PaymentGateways\Stripe;

use App\Classes\AbstractExtension;
use App\Classes\PaymentExtension;
use App\Enums\PaymentStatus;
use App\Events\PaymentEvent;
use App\Events\UserUpdateCreditsEvent;
Expand All @@ -19,7 +19,7 @@
use Stripe\Stripe;
use Stripe\StripeClient;

class StripeExtension extends AbstractExtension
class StripeExtension extends PaymentExtension
{
use CouponTrait;

Expand All @@ -43,11 +43,10 @@ public static function getConfig(): array
];
}

public static function getRedirectUrl(Payment $payment, ShopProduct $shopProduct, string $totalPriceString): string
public static function getRedirectUrl(Payment $payment, ShopProduct $shopProduct, int $totalPrice): string
{
// check if the total price is valid for stripe
$totalPriceNumber = floatval($totalPriceString);
if (!self::checkPriceAmount($totalPriceNumber, strtoupper($shopProduct->currency_code), 'stripe')) {
if (!self::checkPriceAmount(floatval($totalPrice), strtoupper($shopProduct->currency_code), 'stripe')) {
throw new Exception('Invalid price amount');
}

Expand All @@ -61,7 +60,7 @@ public static function getRedirectUrl(Payment $payment, ShopProduct $shopProduct
'name' => $shopProduct->display,
'description' => $shopProduct->description,
],
'unit_amount_decimal' => self::convertAmount($totalPriceString, $shopProduct->currency_code),
'unit_amount_decimal' => self::convertAmount($totalPrice, $shopProduct->currency_code),
],
'quantity' => 1,
],
Expand Down Expand Up @@ -377,13 +376,13 @@ public static function checkPriceAmount(float $amount, string $currencyCode, st
protected static function convertAmount(float $amount, string $currency): int
{
if (in_array($currency, self::ZERO_DECIMAL_CURRENCIES, true)) {
return $amount;
return $amount / 1000;
}

if (in_array($currency, self::THREE_DECIMAL_CURRENCIES, true)) {
return $amount * 1000;
return $amount;
}

return $amount * 100;
return $amount / 10;
}
}
13 changes: 13 additions & 0 deletions app/Facades/Currency.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<?php

namespace App\Facades;

use Illuminate\Support\Facades\Facade;

class Currency extends Facade
{
protected static function getFacadeAccessor()
{
return 'currency';
}
}
37 changes: 37 additions & 0 deletions app/Helpers/CurrencyHelper.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
<?php

namespace App\Helpers;

use NumberFormatter;

class CurrencyHelper
{
private function convertForDisplay($amount)
{
return $amount / 1000;
}

public function formatForDisplay($amount, $decimals = 2)
{
return number_format($this->convertForDisplay($amount), $decimals, ',', '.');
}

public function formatForForm($amount, $decimals = 2)
{
return number_format($this->convertForDisplay($amount), $decimals, '.', '');
}

public function prepareForDatabase($amount)
{
return (int)($amount * 1000);
}

public function formatToCurrency(int $amount, $currency_code, $locale = null,)
{
$locale = $locale ?: str_replace('_', '-', app()->getLocale());

$formatter = new NumberFormatter($locale, NumberFormatter::CURRENCY);

return $formatter->formatCurrency($this->convertForDisplay($amount), $currency_code);
}
}
5 changes: 3 additions & 2 deletions app/Http/Controllers/Admin/CouponController.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

namespace App\Http\Controllers\Admin;

use App\Helpers\CurrencyHelper;
use App\Http\Controllers\Controller;
use App\Models\Coupon;
use App\Settings\LocaleSettings;
Expand Down Expand Up @@ -215,12 +216,12 @@ public function dataTable()
->editColumn('uses', function (Coupon $coupon) {
return "{$coupon->uses} / {$coupon->max_uses}";
})
->editColumn('value', function (Coupon $coupon) {
->editColumn('value', function (Coupon $coupon, CurrencyHelper $currencyHelper) {
if ($coupon->type === 'percentage') {
return $coupon->value . "%";
}

return number_format($coupon->value, 2, '.', '');
return $currencyHelper->formatForDisplay($coupon->value);
})
->editColumn('expires_at', function (Coupon $coupon) {
if (!$coupon->expires_at) {
Expand Down
3 changes: 2 additions & 1 deletion app/Http/Controllers/Admin/OverViewController.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
namespace App\Http\Controllers\Admin;

use App\Classes\PterodactylClient;
use App\Helpers\CurrencyHelper;
use App\Settings\PterodactylSettings;
use App\Settings\GeneralSettings;
use App\Http\Controllers\Controller;
Expand Down Expand Up @@ -30,7 +31,7 @@ public function __construct(PterodactylSettings $ptero_settings)
$this->pterodactyl = new PterodactylClient($ptero_settings);
}

public function index(GeneralSettings $general_settings)
public function index(GeneralSettings $general_settings, CurrencyHelper $currencyHelper)
{
$this->checkAnyPermission([self::READ_PERMISSION,self::SYNC_PERMISSION]);

Expand Down
Loading