HEX
Server: Apache
System: Linux WWW 6.1.0-40-amd64 #1 SMP PREEMPT_DYNAMIC Debian 6.1.153-1 (2025-09-20) x86_64
User: web11 (1011)
PHP: 8.2.29
Disabled: NONE
Upload Files
File: //var/www/payments-gateway/src/Service/PaymentService.php
<?php
// src/Service/PaymentService.php

namespace App\Service;

use App\Entity\Payment;
use App\Repository\PaymentRepository;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Contracts\HttpClient\HttpClientInterface;

class PaymentService
{
    public function __construct(
        private HttpClientInterface $httpClient,
        private EntityManagerInterface $em,
        private PaymentRepository $paymentRepository,
        private string $apiUsername,
        private string $apiSecret,
        private string $accountName,
        private string $apiUrl,
        private string $hmacKey,
        private string $notificationUrl
    ) {}

    public function initiatePayment(array $data): array
    {
        $existing = $this->paymentRepository->find($data['order_reference']);
        if ($existing && $existing->getStatus() !== 'completed') {
            return ['payment_link' => $existing->getPaymentLink()];
        }

        $payload = [
            'account_name' => $this->accountName,
            'nonce' => uniqid('', true),
            'timestamp' => gmdate('Y-m-d\TH:i:sO'),
            'amount' => $data['amount'],
            'order_reference' => $data['order_reference'],
            'customer_url' => 'https://127.0.0.1',
            'api_username' => $this->apiUsername,
        ];

        $res = $this->httpClient->request('POST', $this->apiUrl, [
            'headers' => [
                'Authorization' => 'Basic ' . base64_encode($this->apiUsername . ':' . $this->apiSecret),
                'Content-Type' => 'application/json'
            ],
            'json' => $payload
        ]);

        $result = $res->toArray();

        $payment = new Payment();
        $payment->setOrderReference($data['order_reference']);
        $payment->setStudentId($data['student_id']);
        $payment->setAmount($data['amount']);
        $payment->setPaymentLink($result['payment_link']);
        $payment->setStatus('pending');
        $payment->setCreatedAt(new \DateTimeImmutable());

        $this->em->persist($payment);
        $this->em->flush();

        return ['payment_link' => $result['payment_link']];
    }

    public function verifyHmac(string $body, ?string $signature): bool
    {
        if (!$signature) return false;

        $expected = 'HMAC ' . base64_encode(hash_hmac('sha1', $body, $this->hmacKey, true));
        return hash_equals($expected, $signature);
    }

    public function processWebhook(array $data): void
    {
        $orderRef = $data['payment_reference'] ?? null;
        $status = $data['payment_state'] ?? null;

        if (!$orderRef || !$status) return;

        $payment = $this->paymentRepository->find($orderRef);
        if ($payment) {
            $payment->setStatus($status);
            $payment->setPaidAt(new \DateTimeImmutable());
            $this->em->flush();
        }
    }

    public function getPaymentRepository(): PaymentRepository
    {
        return $this->paymentRepository;
    }
}