mirror of
https://github.com/getnamingo/registry.git
synced 2025-06-26 06:04:45 +02:00
Added ability for registrars to make their own deposit via Stripe
This commit is contained in:
parent
2236e77d18
commit
b8345209eb
8 changed files with 231 additions and 32 deletions
|
@ -26,20 +26,6 @@ class FinancialsController extends Controller
|
|||
public function deposit(Request $request, Response $response)
|
||||
{
|
||||
if ($_SESSION["auth_roles"] != 0) {
|
||||
if ($request->getMethod() === 'POST') {
|
||||
// Retrieve POST data
|
||||
$data = $request->getParsedBody();
|
||||
$db = $this->container->get('db');
|
||||
$balance = $db->selectRow('SELECT name, email, accountBalance, creditLimit FROM registrar WHERE id = ?',
|
||||
[ $_SESSION["auth_registrar_id"] ]
|
||||
);
|
||||
echo "Payment here";
|
||||
|
||||
return view($response,'admin/financials/deposit-registrar.twig', [
|
||||
'balance' => $balance
|
||||
]);
|
||||
}
|
||||
|
||||
$db = $this->container->get('db');
|
||||
$balance = $db->selectRow('SELECT name, accountBalance, creditLimit FROM registrar WHERE id = ?',
|
||||
[ $_SESSION["auth_registrar_id"] ]
|
||||
|
@ -127,4 +113,142 @@ class FinancialsController extends Controller
|
|||
'registrars' => $registrars
|
||||
]);
|
||||
}
|
||||
|
||||
public function createPayment(Request $request, Response $response)
|
||||
{
|
||||
$postData = $request->getParsedBody();
|
||||
$amount = $postData['amount']; // Make sure to validate and sanitize this amount
|
||||
|
||||
// Set Stripe's secret key
|
||||
\Stripe\Stripe::setApiKey(envi('STRIPE_SECRET_KEY'));
|
||||
|
||||
// Convert amount to cents (Stripe expects the amount in the smallest currency unit)
|
||||
$amountInCents = $amount * 100;
|
||||
|
||||
// Create Stripe Checkout session
|
||||
$checkout_session = \Stripe\Checkout\Session::create([
|
||||
'payment_method_types' => ['card', 'paypal'],
|
||||
'line_items' => [[
|
||||
'price_data' => [
|
||||
'currency' => $_SESSION['_currency'],
|
||||
'product_data' => [
|
||||
'name' => 'Registrar Balance Deposit',
|
||||
],
|
||||
'unit_amount' => $amountInCents,
|
||||
],
|
||||
'quantity' => 1,
|
||||
]],
|
||||
'mode' => 'payment',
|
||||
'success_url' => envi('APP_URL').'/payment-success?session_id={CHECKOUT_SESSION_ID}',
|
||||
'cancel_url' => envi('APP_URL').'/payment-cancel',
|
||||
]);
|
||||
|
||||
// Return session ID to the frontend
|
||||
$response->getBody()->write(json_encode(['id' => $checkout_session->id]));
|
||||
return $response->withHeader('Content-Type', 'application/json');
|
||||
}
|
||||
|
||||
public function success(Request $request, Response $response)
|
||||
{
|
||||
$session_id = $request->getQueryParams()['session_id'] ?? null;
|
||||
$db = $this->container->get('db');
|
||||
|
||||
if ($session_id) {
|
||||
\Stripe\Stripe::setApiKey(envi('STRIPE_SECRET_KEY'));
|
||||
|
||||
try {
|
||||
$session = \Stripe\Checkout\Session::retrieve($session_id);
|
||||
$amountPaid = $session->amount_total; // Amount paid, in cents
|
||||
$amount = $amountPaid / 100;
|
||||
$amountPaidFormatted = number_format($amount, 2, '.', '');
|
||||
$paymentIntentId = $session->payment_intent;
|
||||
|
||||
$isPositiveNumberWithTwoDecimals = filter_var($amount, FILTER_VALIDATE_FLOAT) !== false && preg_match('/^\d+(\.\d{1,2})?$/', $amount);
|
||||
|
||||
if ($isPositiveNumberWithTwoDecimals) {
|
||||
$db->beginTransaction();
|
||||
|
||||
try {
|
||||
$currentDateTime = new \DateTime();
|
||||
$date = $currentDateTime->format('Y-m-d H:i:s.v');
|
||||
$db->insert(
|
||||
'statement',
|
||||
[
|
||||
'registrar_id' => $_SESSION['auth_registrar_id'],
|
||||
'date' => $date,
|
||||
'command' => 'create',
|
||||
'domain_name' => 'deposit',
|
||||
'length_in_months' => 0,
|
||||
'from' => $date,
|
||||
'to' => $date,
|
||||
'amount' => $amount
|
||||
]
|
||||
);
|
||||
|
||||
$db->insert(
|
||||
'payment_history',
|
||||
[
|
||||
'registrar_id' => $_SESSION['auth_registrar_id'],
|
||||
'date' => $date,
|
||||
'description' => 'Registrar Balance Deposit via Stripe ('.$paymentIntentId.')',
|
||||
'amount' => $amount
|
||||
]
|
||||
);
|
||||
|
||||
$db->exec(
|
||||
'UPDATE registrar SET accountBalance = (accountBalance + ?) WHERE id = ?',
|
||||
[
|
||||
$amount,
|
||||
$_SESSION['auth_registrar_id'],
|
||||
]
|
||||
);
|
||||
|
||||
$db->commit();
|
||||
} catch (Exception $e) {
|
||||
$db->rollBack();
|
||||
$balance = $db->selectRow('SELECT name, accountBalance, creditLimit FROM registrar WHERE id = ?',
|
||||
[ $_SESSION["auth_registrar_id"] ]
|
||||
);
|
||||
|
||||
return view($response, 'admin/financials/deposit-registrar.twig', [
|
||||
'error' => $e->getMessage(),
|
||||
'balance' => $balance
|
||||
]);
|
||||
}
|
||||
|
||||
$balance = $db->selectRow('SELECT name, accountBalance, creditLimit FROM registrar WHERE id = ?',
|
||||
[ $_SESSION["auth_registrar_id"] ]
|
||||
);
|
||||
|
||||
return view($response, 'admin/financials/deposit-registrar.twig', [
|
||||
'deposit' => $amount,
|
||||
'balance' => $balance
|
||||
]);
|
||||
} else {
|
||||
$balance = $db->selectRow('SELECT name, accountBalance, creditLimit FROM registrar WHERE id = ?',
|
||||
[ $_SESSION["auth_registrar_id"] ]
|
||||
);
|
||||
|
||||
return view($response, 'admin/financials/deposit-registrar.twig', [
|
||||
'error' => 'Invalid entry: Deposit amount must be positive. Please enter a valid amount.',
|
||||
'balance' => $balance
|
||||
]);
|
||||
}
|
||||
} catch (\Exception $e) {
|
||||
$balance = $db->selectRow('SELECT name, accountBalance, creditLimit FROM registrar WHERE id = ?',
|
||||
[ $_SESSION["auth_registrar_id"] ]
|
||||
);
|
||||
|
||||
return view($response, 'admin/financials/deposit-registrar.twig', [
|
||||
'error' => 'We encountered an issue while processing your payment. Please check your payment details and try again.',
|
||||
'balance' => $balance
|
||||
]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function cancel(Request $request, Response $response)
|
||||
{
|
||||
return view($response,'admin/financials/cancel.twig');
|
||||
}
|
||||
}
|
|
@ -1,8 +1,8 @@
|
|||
{
|
||||
"name": "pinga/pinga-panel",
|
||||
"description": "Pinga Framework Boilerplate",
|
||||
"description": "Namingo Registry Control Panel",
|
||||
"type": "project",
|
||||
"keywords": ["slim", "slim 4", "skeleton", "authentication", "template", "orm","pinga"],
|
||||
"keywords": ["slim", "slim 4", "domain", "registry", "panel"],
|
||||
"homepage": "https://github.com/getpinga/pinga-panel",
|
||||
"license": "MIT",
|
||||
"authors": [
|
||||
|
@ -34,11 +34,12 @@
|
|||
"mevdschee/php-crud-api": "^2.14",
|
||||
"gettext/gettext": "^5.7",
|
||||
"punic/punic": "^3.8",
|
||||
"league/iso3166": "^4.3"
|
||||
"league/iso3166": "^4.3",
|
||||
"stripe/stripe-php": "^13.3"
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"App\\": "app/"
|
||||
}
|
||||
"psr-4": {
|
||||
"App\\": "app/"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -72,4 +72,7 @@ return [
|
|||
'api_key' => $_ENV['MAIL_API_KEY'] ?? 'test-api-key',
|
||||
'api_provider' => $_ENV['MAIL_API_PROVIDER'] ?? 'sendgrid',
|
||||
],
|
||||
'payment' => [
|
||||
'stripe' => $_ENV['STRIPE_SECRET_KEY'] ?? 'stripe-secret-key',
|
||||
],
|
||||
];
|
|
@ -1,6 +1,6 @@
|
|||
APP_NAME='CP'
|
||||
APP_ENV=public
|
||||
APP_URL=http://localhost
|
||||
APP_URL=https://cp.example.com
|
||||
APP_DOMAIN=example.com
|
||||
|
||||
DB_DRIVER=mysql
|
||||
|
@ -22,3 +22,5 @@ MAIL_FROM_ADDRESS='example@domain.com'
|
|||
MAIL_FROM_NAME='Example'
|
||||
MAIL_API_KEY='test-api-key'
|
||||
MAIL_API_PROVIDER='sendgrid'
|
||||
|
||||
STRIPE_SECRET_KEY='stripe-secret-key'
|
51
cp/resources/views/admin/financials/cancel.twig
Normal file
51
cp/resources/views/admin/financials/cancel.twig
Normal file
|
@ -0,0 +1,51 @@
|
|||
{% extends "layouts/app.twig" %}
|
||||
|
||||
{% block title %}{{ __('Deposit Payment Unsuccessful') }}{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<div class="page-wrapper">
|
||||
<!-- Page header -->
|
||||
<div class="page-header d-print-none">
|
||||
<div class="container-xl">
|
||||
<div class="row g-2 align-items-center">
|
||||
<div class="col">
|
||||
<!-- Page pre-title -->
|
||||
<div class="page-pretitle">
|
||||
{{ __('Overview') }}
|
||||
</div>
|
||||
<h2 class="page-title">
|
||||
{{ __('Deposit Payment Unsuccessful') }}
|
||||
</h2>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Page body -->
|
||||
<div class="page-body">
|
||||
<div class="container-xl">
|
||||
<div class="col-12">
|
||||
<div class="card bg-orange-lt">
|
||||
<div class="card-body">
|
||||
<p class="text-secondary">We've noticed that your deposit payment process was not completed. It appears that the payment was either cancelled or failed during the transaction. If this was an error, or if you have any questions, please don't hesitate to contact us. We're here to help ensure your transaction is smooth and secure.</p>
|
||||
<p class="text-secondary">Ready to try again? When you're set to proceed with your deposit, simply return to the <a href="{{route('deposit')}}">Deposit Page</a> to initiate a new payment. We value your partnership and are committed to assisting you every step of the way.</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<footer class="footer footer-transparent d-print-none">
|
||||
<div class="container-xl">
|
||||
<div class="col-12 col-lg-auto mt-3 mt-lg-0">
|
||||
<ul class="list-inline list-inline-dots mb-0">
|
||||
<li class="list-inline-item">
|
||||
Copyright © 2023
|
||||
<a href="https://namingo.org" target="_blank" class="link-secondary">Namingo</a>.
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</footer>
|
||||
</div>
|
||||
{% endblock %}
|
|
@ -52,15 +52,7 @@
|
|||
<div class="card">
|
||||
<div class="card-body">
|
||||
<form id="depositForm" action="/deposit" method="post">
|
||||
{{ csrf.field | raw }}
|
||||
<div class="mb-3">
|
||||
<label for="paymentMethod" class="form-label">Payment Method</label>
|
||||
<select class="form-select" id="paymentMethod" name="method" required>
|
||||
<option selected disabled value="">Choose Method...</option>
|
||||
<option value="1">Stripe</option>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
{{ csrf.field | raw }}
|
||||
<div class="deposit-info">
|
||||
<h5>Current Balance for {{ balance.name }}</h5>
|
||||
<p class="fs-4">${{ balance.accountBalance }}</p>
|
||||
|
@ -79,7 +71,7 @@
|
|||
<div class="card-footer">
|
||||
<div class="row align-items-center">
|
||||
<div class="col-auto">
|
||||
<button type="submit" class="btn btn-primary">Continue to Payment</button>
|
||||
<button type="submit" class="btn btn-primary"><svg xmlns="http://www.w3.org/2000/svg" class="icon icon-tabler icon-tabler-brand-stripe" width="24" height="24" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round"><path stroke="none" d="M0 0h24v24H0z" fill="none"/><path d="M11.453 8.056c0 -.623 .518 -.979 1.442 -.979c1.69 0 3.41 .343 4.605 .923l.5 -4c-.948 -.449 -2.82 -1 -5.5 -1c-1.895 0 -3.373 .087 -4.5 1c-1.172 .956 -2 2.33 -2 4c0 3.03 1.958 4.906 5 6c1.961 .69 3 .743 3 1.5c0 .735 -.851 1.5 -2 1.5c-1.423 0 -3.963 -.609 -5.5 -1.5l-.5 4c1.321 .734 3.474 1.5 6 1.5c2 0 3.957 -.468 5.084 -1.36c1.263 -.979 1.916 -2.268 1.916 -4.14c0 -3.096 -1.915 -4.547 -5 -5.637c-1.646 -.605 -2.544 -1.07 -2.544 -1.807z" /></svg> Deposit with Stripe</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -103,4 +95,27 @@
|
|||
</div>
|
||||
</footer>
|
||||
</div>
|
||||
<script src="https://js.stripe.com/v3/"></script>
|
||||
<script type="text/javascript">
|
||||
var stripe = Stripe('YOUR_PUBLISHABLE_KEY'); // Replace with your publishable key
|
||||
|
||||
document.getElementById('depositForm').addEventListener('submit', function (e) {
|
||||
e.preventDefault();
|
||||
|
||||
var formData = new FormData(this);
|
||||
fetch('/create-payment', {
|
||||
method: 'POST',
|
||||
body: formData
|
||||
})
|
||||
.then(function (response) {
|
||||
return response.json();
|
||||
})
|
||||
.then(function (session) {
|
||||
return stripe.redirectToCheckout({ sessionId: session.id });
|
||||
})
|
||||
.catch(function (error) {
|
||||
console.error('Error:', error);
|
||||
});
|
||||
});
|
||||
</script>
|
||||
{% endblock %}
|
|
@ -165,7 +165,7 @@
|
|||
</a>
|
||||
</div>
|
||||
</li>
|
||||
<li {{ is_current_url('deposit') or is_current_url('transactions') or is_current_url('overview') or is_current_url('invoices') ? 'class="nav-item dropdown active"' : 'class="nav-item dropdown"' }}>
|
||||
<li {{ is_current_url('deposit') or is_current_url('transactions') or is_current_url('overview') or is_current_url('invoices') or is_current_url('success') ? 'class="nav-item dropdown active"' : 'class="nav-item dropdown"' }}>
|
||||
<a class="nav-link dropdown-toggle" href="#" data-bs-toggle="dropdown" data-bs-auto-close="outside" role="button" aria-expanded="false">
|
||||
<span class="nav-link-icon d-md-none d-lg-inline-block"><svg xmlns="http://www.w3.org/2000/svg" class="icon" width="24" height="24" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round"><path stroke="none" d="M0 0h24v24H0z" fill="none"></path><path d="M7 9m0 2a2 2 0 0 1 2 -2h10a2 2 0 0 1 2 2v6a2 2 0 0 1 -2 2h-10a2 2 0 0 1 -2 -2z"></path><path d="M14 14m-2 0a2 2 0 1 0 4 0a2 2 0 1 0 -4 0"></path><path d="M17 9v-2a2 2 0 0 0 -2 -2h-10a2 2 0 0 0 -2 2v6a2 2 0 0 0 2 2h2"></path></svg>
|
||||
</span>
|
||||
|
|
|
@ -69,6 +69,9 @@ $app->group('', function ($route) {
|
|||
|
||||
$route->get('/invoices', FinancialsController::class .':invoices')->setName('invoices');
|
||||
$route->map(['GET', 'POST'], '/deposit', FinancialsController::class .':deposit')->setName('deposit');
|
||||
$route->map(['GET', 'POST'], '/create-payment', FinancialsController::class .':createPayment')->setName('createPayment');
|
||||
$route->map(['GET', 'POST'], '/payment-success', FinancialsController::class .':success')->setName('success');
|
||||
$route->map(['GET', 'POST'], '/payment-cancel', FinancialsController::class .':cancel')->setName('cancel');
|
||||
$route->get('/transactions', FinancialsController::class .':transactions')->setName('transactions');
|
||||
$route->get('/overview', FinancialsController::class .':overview')->setName('overview');
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue