From 5443fb8fa2b71b851f03cc34ea2e8f6e32313022 Mon Sep 17 00:00:00 2001 From: Djery-Tom Date: Sun, 9 Oct 2022 00:58:41 +0100 Subject: [PATCH] Add payment service while pay insurances invoices --- .env.example | 10 +- .../InsuranceInvoiceController.php | 107 ++++++++++++++++-- app/Models/PaymentAggregator.php | 11 ++ app/Models/PaymentTransaction.php | 11 ++ bootstrap/app.php | 3 +- composer.json | 1 + config/variable.php | 8 ++ resources/lang/en/errors.php | 6 +- resources/lang/fr/errors.php | 6 +- 9 files changed, 149 insertions(+), 14 deletions(-) create mode 100644 app/Models/PaymentAggregator.php create mode 100644 app/Models/PaymentTransaction.php create mode 100644 config/variable.php diff --git a/.env.example b/.env.example index 3481adc..1296f77 100644 --- a/.env.example +++ b/.env.example @@ -17,7 +17,7 @@ DB_PASSWORD=vps@2017GA MAIL_HOST=mail.ilink-app.com MAIL_USERNAME=noreply@ilink-app.com -MAIL_PASSWORD=ilink2017GA +MAIL_PASSWORD=Reply@iLink2022@@@ MAIL_FROM_ADDRESS=noreply@ilink-app.com MAIL_FROM_NAME="iLink World" MAIL_ENCRYPTION=tls @@ -35,3 +35,11 @@ SWAGGER_DOCS_TOKEN=ZfMqCAdHHrSH8ADdXreIejgjJtOwsH4K SENTRY_LARAVEL_DSN=https://cb0057643b0c4ce5805e49b5b54bd5c3@o1053292.ingest.sentry.io/6037678 SENTRY_TRACES_SAMPLE_RATE=1 + +DEFAULT_COUNTRY_CODE=GA +DEFAULT_DIAL_CODE=+241 + +PAYMENT_SERVICE_URL=localhost:8087 +PAYMENT_SERVICE_KEY=U14YhuyFhweMeYpIYj8Ft2jm4cVgbMzD + +SEND_MAIL=false diff --git a/app/Http/Controllers/InsuranceInvoiceController.php b/app/Http/Controllers/InsuranceInvoiceController.php index 7aa07e0..f72bf25 100644 --- a/app/Http/Controllers/InsuranceInvoiceController.php +++ b/app/Http/Controllers/InsuranceInvoiceController.php @@ -20,12 +20,15 @@ use App\Models\NhInsurancesSubscription; use App\Models\NhInsurancesSubscriptionsHistory; use App\Models\NhMonthsPricesGrid; use App\Models\NhNetworksConfig; +use App\Models\PaymentAggregator; +use App\Models\PaymentTransaction; use App\Models\User; use App\Models\Wallet; use App\Rules\PasswordValidation; use App\Traits\Helper; use Carbon\Carbon; use DateTime; +use GuzzleHttp\Client; use Illuminate\Database\Eloquent\Collection; use Illuminate\Http\Request; use Illuminate\Http\UploadedFile; @@ -210,9 +213,24 @@ class InsuranceInvoiceController extends Controller * ), * @OA\Property(property="payment_method", * type="string", - * enum = {"wallet" ,"mobile_money","card"}, + * enum = {"wallet" ,"mobile_money","card","ALL"}, * example = "wallet", * description="Methode de paiement" + * ), + * @OA\Property(property="payment_phone", + * type="string", + * example = "+237690716639", + * description="Numero de telephone avec lequel on souhaite payer de paiement" + * ), + * @OA\Property(property="payment_transaction_id", + * type="string", + * example = "ASMFOSDFFDODF", + * description="ID de la transaction de paiement" + * ), + * @OA\Property(property="payment_token", + * type="string", + * example = "133232669895665656", + * description="Token la transaction de paiement" * ) * ), * example = {"password":"adbc1215448", "amount" : 50000 , "payment_method" : "wallet" } @@ -234,9 +252,14 @@ class InsuranceInvoiceController extends Controller $this->validate($request, [ 'password' => 'required|string', 'amount' => 'required|numeric|min:0', - 'payment_method' => 'required|in:wallet,mobile_money,card' + 'payment_method' => 'required|string', + 'payment_phone' => 'required_unless:payment_method,wallet|string', + 'payment_transaction_id' => 'nullable|exists:payment_transactions,transaction_id', // A envoyer apres avoir effectuer le paiement + 'payment_token' => 'required_with:payment_transaction_id|string', // A envoyer apres avoir effectuer le paiement + 'otp' => 'nullable|string' ]); + $transaction_id = $request->input('payment_transaction_id'); $amountToPaid = $request->input('amount'); $payment_method = $request->input('payment_method'); $invoice = NhInsurancesInvoice::findOrFail($id); @@ -275,9 +298,30 @@ class InsuranceInvoiceController extends Controller return $this->errorResponse(trans('errors.minimum amount_to_paid', ['amount' => $this->toMoneyWithCurrencyCode($invoice->amount_per_split, $currency)])); } - if ($payment_method == 'wallet' && $user->wallet->balance < $amountToPaid) { - $remains_amount = $amountToPaid - $user->wallet->balance; - return $this->errorResponse(trans('errors.insufficient_balance', ['amount' => $this->toMoneyWithCurrencyCode($remains_amount, $currency)])); + if (empty($transaction_id)) { + + if ($payment_method == 'wallet') { + if ($user->wallet->balance < $amountToPaid) { + $remains_amount = $amountToPaid - $user->wallet->balance; + return $this->errorResponse(trans('errors.insufficient_balance', ['amount' => $this->toMoneyWithCurrencyCode($remains_amount, $currency)])); + } + } else { + $aggregator = PaymentAggregator::where('status', 1)->first(); + if (!$aggregator) { + return $this->errorResponse(trans('errors.payment_not_available')); + } + } + + } else { + $transaction = PaymentTransaction::where('transaction_id', $transaction_id)->where('payment_token', $request->input('payment_token'))->where('state', 'ACCEPTED')->first(); + if (!$transaction) { + return $this->errorResponse(trans('errors.payment_not_found'), 404); + } + $payment = NhInsurancesPayment::where('payment_id', $transaction_id)->first(); + if ($payment) { + return $this->errorResponse(trans('errors.payment_invalid'), 400); + } + $amountToPaid = $transaction->amount; } try { @@ -289,14 +333,57 @@ class InsuranceInvoiceController extends Controller $walletHyperviseur->save(); $user->balance_nano_health += $amountToPaid; - if ($payment_method == 'wallet') { - $user->wallet->balance -= $amountToPaid; - } - $user->wallet->save(); $user->save(); + if (empty($transaction_id)) { + if ($payment_method == 'wallet') { + $user->wallet->balance -= $amountToPaid; + $user->wallet->save(); + } else { + + // Pay through payment service + $client = new Client([ + 'base_uri' => config('variable.payment_service_url'), + 'headers' => [ + 'Authorization' => config('variable.payment_service_key'), + ] + ]); + + $paymentResponse = $client->post('/pay', [ + 'json' => [ + 'aggregator_id' => $aggregator->id, + 'amount' => $amountToPaid, + 'currency' => $user->network->country->currency_code, + 'customer_id' => $user->id, + 'customer_email' => $user->email, + 'customer_name' => $user->lastname, + 'customer_surname' => $user->lastname, + 'customer_phone_number' => $request->input('payment_phone'), + 'customer_address' => $user->adresse, + 'customer_country' => $user->network->country->code_country, + 'customer_city' => $user->adresse, + 'customer_state' => $user->network->country->code_country, + 'customer_zip_code' => '00237', + 'payment_method' => $request->input('payment_method'), + 'reason' => trans('states.receipt'), + 'otp' => $request->input('otp') + ], + 'http_errors' => false + ]); + + $responseData = json_decode($paymentResponse->getBody()->getContents()); + $responseCode = $paymentResponse->getStatusCode(); + if ($responseCode == 200) { +// $transaction_id = $responseData->response->transaction_id; + return $this->successResponse($responseData->response); + } else { + return $this->errorResponse($responseData->error ?? trans('errors.unexpected_error'), $responseCode); + } + } + } + $payment = NhInsurancesPayment::create([ - 'payment_id' => $this->generateID('nh_insurances_payments', 'payment_id', 10), + 'payment_id' => $transaction_id, 'invoice_id' => $invoice->id, 'amount' => $amountToPaid ]); diff --git a/app/Models/PaymentAggregator.php b/app/Models/PaymentAggregator.php new file mode 100644 index 0000000..3860253 --- /dev/null +++ b/app/Models/PaymentAggregator.php @@ -0,0 +1,11 @@ +configure('services'); $app->configure('sentry'); $app->configure('dompdf'); $app->configure('mail'); +$app->configure('variable'); $app->alias('mailer', Illuminate\Mail\Mailer::class); $app->alias('mailer', Illuminate\Contracts\Mail\Mailer::class); $app->alias('mailer', Illuminate\Contracts\Mail\MailQueue::class); @@ -111,7 +112,7 @@ $app->register('Sentry\Laravel\ServiceProvider'); $app->register('Sentry\Laravel\Tracing\ServiceProvider'); $app->register(\Barryvdh\DomPDF\ServiceProvider::class); $app->register(Illuminate\Mail\MailServiceProvider::class); - +$app->register(Flipbox\LumenGenerator\LumenGeneratorServiceProvider::class); /* |-------------------------------------------------------------------------- | Load The Application Routes diff --git a/composer.json b/composer.json index b619e70..ff8d3b1 100644 --- a/composer.json +++ b/composer.json @@ -13,6 +13,7 @@ "brick/money": "^0.5.2", "darkaonline/swagger-lume": "^8.0", "fightbulc/moment": "^1.33", + "flipbox/lumen-generator": "^9.1", "guzzlehttp/guzzle": "^7.3", "illuminate/mail": "^8.80", "kitloong/laravel-migrations-generator": "^5.0", diff --git a/config/variable.php b/config/variable.php new file mode 100644 index 0000000..15e95cb --- /dev/null +++ b/config/variable.php @@ -0,0 +1,8 @@ + env('DEFAULT_COUNTRY_CODE', 'GA'), + 'default_dial_code' => env('DEFAULT_DIAL_CODE', '+241'), + 'payment_service_url' => env('PAYMENT_SERVICE_URL', ''), + 'payment_service_key' => env('PAYMENT_SERVICE_KEY', ''), + 'send_mail' => env('SEND_MAIL', false) +]; diff --git a/resources/lang/en/errors.php b/resources/lang/en/errors.php index 7e032a0..2140a1b 100755 --- a/resources/lang/en/errors.php +++ b/resources/lang/en/errors.php @@ -72,5 +72,9 @@ return [ 'consultation_prescription_not_found' => "The consultation attached to this prescription does not exist", 'minimum amount_to_paid' => "The minimum amount to pay is :amount", 'maximum amount_to_paid' => "The maximum amount to pay is :amount", - "unpaid_bill" => "You have an unpaid bill" + "unpaid_bill" => "You have an unpaid bill", + "amount_not_allowed" => "This amount is not allowed. It must be between :min and :max", + 'payment_not_available' => "Payment not available at this time. Please try again later", + 'payment_not_found' => "Payment not found", + 'payment_invalid' => "Invalid payment" ]; diff --git a/resources/lang/fr/errors.php b/resources/lang/fr/errors.php index 7613adb..291fbcf 100755 --- a/resources/lang/fr/errors.php +++ b/resources/lang/fr/errors.php @@ -75,5 +75,9 @@ return [ 'sheet_prescriptions_duplicata' => "La feuille de soins a des duplicata de prescriptions médicales", 'minimum_amount_to_paid' => "Le montant minimum à payer est de :amount", 'maximum_amount_to_paid' => "Le montant maximum à payer est de :amount", - "unpaid_bill" => "Vous avez une facture non payée" + "unpaid_bill" => "Vous avez une facture non payée", + "amount_not_allowed" => "Ce montant n'est pas autorisé. Il doit être compris entre :min et :max", + 'payment_not_available' => "Paiement non disponible pour le moment. Veuillez réessayer plus tard", + 'payment_not_found' => "Paiement non trouvé", + 'payment_invalid' => "Paiement invalide" ];