diff --git a/app/Enums/PaymentType.php b/app/Enums/PaymentType.php new file mode 100644 index 0000000..a35559b --- /dev/null +++ b/app/Enums/PaymentType.php @@ -0,0 +1,11 @@ +validate($request, [ + 'amount' => 'required|numeric|min:0', + 'country_id' => 'required|integer|exists:countries,id', + 'payment_type' => 'required|string|in:CASH_IN,CASH_OUT', + 'payment_method' => 'required|string|in:CARD,WALLET', + 'payment_channel' => 'nullable|string', + ]); + + $fees = 0; + + $amount = $request->input('amount'); + $paymentChannel = $request->input('payment_channel'); + $paymentMethod = $request->input('payment_method'); + $paymentType = $request->input('payment_type'); + $countryId = $request->input('country_id'); + $country = Country::where('id', $countryId)->firstOrFail(); + $countryCode = $country->code_country; + + + if($paymentMethod == 'CARD'){ + $aggregator = PaymentAggregator::where('name','like','%stripe%')->first(); + } + + if($paymentMethod == 'WALLET'){ + $aggregator = PaymentAggregator::where('status',1)->first(); + } + + if(!empty($aggregator)){ + $rate = $aggregator->rates()->where('country', $countryCode)->orWhere('country','ALL')->where('type', $paymentType) + ->where('method', $paymentMethod)->when($paymentChannel, function ($q) use($paymentChannel){ + return $q->where('channel',$paymentChannel); + })->first(); + + if(!empty($rate)){ + if(!empty($rate->fixed_fees)){ + $targetCurrency = $country->currency->code; + $sourceCurrency = $targetCurrency; + if(!empty($rate->fixed_fees_currency)){ + $sourceCurrency = $rate->fixed_fees_currency; + } + $fixed_fees = $this->toMoneyAmount($rate->fixed_fees, $sourceCurrency, $targetCurrency); + $fees = (($amount - $fixed_fees) * $rate->rate / 100 ) + $fixed_fees; + }else{ + $fees = $amount * $rate->rate / 100; + } + } + + return $this->successResponse(['fees' => round($fees, 2)]); + }else { + return $this->errorResponse("Aggregateur non disponible"); + } + } } diff --git a/app/Models/Country.php b/app/Models/Country.php new file mode 100755 index 0000000..9939e83 --- /dev/null +++ b/app/Models/Country.php @@ -0,0 +1,56 @@ + 'float', + 'latitude' => 'float', + 'idCurrency' => 'int' + ]; + + protected $fillable = [ + 'code_dial', + 'name', + 'code_country', + 'longitude', + 'latitude', + 'idCurrency' + ]; + + public function currency() + { + return $this->belongsTo(Currency::class, 'idCurrency'); + } +} diff --git a/app/Models/Currency.php b/app/Models/Currency.php new file mode 100644 index 0000000..dfb4087 --- /dev/null +++ b/app/Models/Currency.php @@ -0,0 +1,47 @@ + 'int' + ]; + + protected $fillable = [ + 'code', + 'numeric', + 'symbol', + 'name_en', + 'name_fr' + ]; + + public function countries() + { + return $this->hasMany(Country::class, 'idCurrency'); + } +} diff --git a/app/Models/PaymentAggregator.php b/app/Models/PaymentAggregator.php index 3860253..a331b85 100644 --- a/app/Models/PaymentAggregator.php +++ b/app/Models/PaymentAggregator.php @@ -8,4 +8,8 @@ class PaymentAggregator extends Model { protected $table = 'payment_aggregators'; protected $guarded = ['id']; + + public function rates(){ + return $this->hasMany(PaymentAggregatorRate::class,'aggregator_id'); + } } diff --git a/app/Models/PaymentAggregatorRate.php b/app/Models/PaymentAggregatorRate.php new file mode 100644 index 0000000..f3356dc --- /dev/null +++ b/app/Models/PaymentAggregatorRate.php @@ -0,0 +1,12 @@ +convert($sourceMoney, $targetCurrency, null, RoundingMode::UP); + } + + public function toMoneyAmount($amount, $sourceCurrency, $targetCurrency) + { + return $this->convertMoney($amount, $sourceCurrency, $targetCurrency)->getAmount()->toFloat(); } } diff --git a/composer.json b/composer.json index 7e45b6e..0358838 100644 --- a/composer.json +++ b/composer.json @@ -7,6 +7,7 @@ "require": { "php": "^8.0", "ext-json": "*", + "brick/money": "^0.8.0", "cknow/laravel-money": "^7.0", "darkaonline/swagger-lume": "^9.0", "doctrine/dbal": "^3.6", @@ -15,7 +16,8 @@ "illuminate/session": "^9.52", "laravel/lumen-framework": "^9.0", "propaganistas/laravel-phone": "^5.0", - "stripe/stripe-php": "^10.13" + "stripe/stripe-php": "^10.13", + "ext-pdo": "*" }, "require-dev": { "fakerphp/faker": "^1.9.1", diff --git a/composer.lock b/composer.lock index 5de0210..6b0d353 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "81090437c0e646c7e1df7fd291f0a3ac", + "content-hash": "4835260236c50e25a136ef532dcb5875", "packages": [ { "name": "brick/math", @@ -61,6 +61,64 @@ ], "time": "2023-01-15T23:15:59+00:00" }, + { + "name": "brick/money", + "version": "0.8.0", + "source": { + "type": "git", + "url": "https://github.com/brick/money.git", + "reference": "b530ab64d7f85fdfd5858cde8c57f2f587c8aab8" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/brick/money/zipball/b530ab64d7f85fdfd5858cde8c57f2f587c8aab8", + "reference": "b530ab64d7f85fdfd5858cde8c57f2f587c8aab8", + "shasum": "" + }, + "require": { + "brick/math": "~0.10.1 || ~0.11.0", + "ext-json": "*", + "php": "^8.0" + }, + "require-dev": { + "brick/varexporter": "~0.3.0", + "ext-dom": "*", + "ext-pdo": "*", + "php-coveralls/php-coveralls": "^2.2", + "phpunit/phpunit": "^9.4.3", + "vimeo/psalm": "5.4.0" + }, + "suggest": { + "ext-intl": "Required to format Money objects" + }, + "type": "library", + "autoload": { + "psr-4": { + "Brick\\Money\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "Money and currency library", + "keywords": [ + "brick", + "currency", + "money" + ], + "support": { + "issues": "https://github.com/brick/money/issues", + "source": "https://github.com/brick/money/tree/0.8.0" + }, + "funding": [ + { + "url": "https://github.com/BenMorel", + "type": "github" + } + ], + "time": "2023-01-15T23:59:01+00:00" + }, { "name": "cknow/laravel-money", "version": "v7.1.0", diff --git a/database/migrations/2023_07_11_143815_create_payment_aggregator_rates_table.php b/database/migrations/2023_07_11_143815_create_payment_aggregator_rates_table.php new file mode 100644 index 0000000..6c48c1b --- /dev/null +++ b/database/migrations/2023_07_11_143815_create_payment_aggregator_rates_table.php @@ -0,0 +1,39 @@ +id(); + $table->string('aggregator_id'); + $table->string('country')->comment("ALL : Pour tous les pays"); + $table->string('type')->comment("Cash In or Cash Out"); + $table->string('method')->comment("Methode de paiements"); + $table->string('channel')->nullable()->comment("Canal ou Reseau concerné"); + $table->decimal('rate')->default(0)->comment("Taux de commission"); + $table->decimal('fixed_fees')->nullable()->comment("Frais fixe"); + $table->string('fixed_fees_currency')->nullable()->comment("Monnaie des frais fixes"); + $table->timestamps(); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::dropIfExists('payment_aggregator_rates'); + } +}; diff --git a/routes/web.php b/routes/web.php index 3d088a4..0493f44 100644 --- a/routes/web.php +++ b/routes/web.php @@ -53,6 +53,7 @@ $router->group(['middleware' => 'auth'], function () use ($router) { $router->post('pay','PaymentController@pay'); $router->get('checkStatus/{transaction_id}','PaymentController@checkStatus'); $router->post('payOut','PaymentController@payOut'); + $router->get('fees','PaymentController@getFees'); /** * Yoomee Endpoints