Skip to content

Commit

Permalink
#2 payment api documentation
Browse files Browse the repository at this point in the history
  • Loading branch information
skoro committed Aug 26, 2024
1 parent 84b3dc8 commit 988100b
Show file tree
Hide file tree
Showing 3 changed files with 87 additions and 8 deletions.
35 changes: 27 additions & 8 deletions src/Controller/Api/V1/PaymentController.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
namespace App\Controller\Api\V1;

use App\Dto\PaymentGatewayDto;
use App\Dto\PaymentStatusDto;
use App\Entity\Order;
use App\Entity\OrderStatus;
use App\Event\AfterPaymentCallbackHandlerEvent;
Expand All @@ -13,6 +14,8 @@
use App\Order\Workflow\OrderWorkflowFactory;
use App\Payment\Common\GatewayInterface;
use App\Payment\PaymentGatewayRegistry;
use Nelmio\ApiDocBundle\Annotation\Model;
use OpenApi\Attributes as OA;
use Symfony\Bridge\Doctrine\Attribute\MapEntity;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\JsonResponse;
Expand All @@ -30,6 +33,12 @@ public function __construct(
) {
}

#[OA\Get(description: 'Get the available payment gateways.')]
#[OA\Response(
response: 200,
description: 'A list of available payment gateways.',
content: new Model(type: PaymentGatewayDto::class),
)]
#[Route('/gateways', name: 'gateways', methods: 'GET', format: 'json')]
public function getAvailableGateways(): JsonResponse
{
Expand All @@ -44,6 +53,13 @@ public function getAvailableGateways(): JsonResponse
return $this->json($gatewayCollection);
}

#[OA\Post(
description: 'Payment callback handler invoked by the payment gateway.',
)]
#[OA\Response(
response: 200,
description: 'Successful handled.',
)]
#[Route('/{order_uuid}/handler', name: 'callback_handler', methods: 'POST', format: 'json')]
public function paymentCallbackHandler(
#[MapEntity(mapping: ['order_uuid' => 'uuid'])] Order $order,
Expand Down Expand Up @@ -76,6 +92,16 @@ public function paymentCallbackHandler(
return new Response();
}

#[OA\Get(description: 'Get a payment status of the provided order from the payment gateway.')]
#[OA\Response(
response: 200,
description: 'Order payment status.',
content: new Model(type: PaymentStatusDto::class),
)]
#[OA\Response(
response: 404,
description: 'Order not found.',
)]
#[Route('/{order_uuid}/status', name: 'status', methods: 'GET', format: 'json')]
public function getPaymentStatus(
#[MapEntity(mapping: ['order_uuid' => 'uuid'])] Order $order,
Expand All @@ -89,13 +115,6 @@ public function getPaymentStatus(
$event = $this->eventDispatcher->dispatch(new PaymentStatusEvent($order, $statusResponse));
$statusResponse = $event->paymentStatusResponse;

return $this->json([
'payment_gateway' => $paymentGateway->getId(),
'success' => $statusResponse->isSuccessful(),
'transaction_id' => $statusResponse->getTransactionId(),
'message' => $statusResponse->getMessage(),
'code' => $statusResponse->getCode(),
'data' => $statusResponse,
]);
return $this->json(PaymentStatusDto::makeFromResponse($paymentGateway->getId(), $statusResponse));
}
}
9 changes: 9 additions & 0 deletions src/Dto/PaymentGatewayDto.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,21 @@

use App\Payment\Common\GatewayInterface;
use Symfony\Component\Serializer\Attribute\SerializedName;
use OpenApi\Attributes as OA;

#[OA\Schema(
description: 'Payment Gateway object.'
)]
final readonly class PaymentGatewayDto
{
public function __construct(
#[OA\Property(description: 'Payment gateway id.')]
public string $id,

#[OA\Property(description: 'Payment gateway name.')]
public string $name,

#[OA\Property(description: 'When test mode is positive, no real payments done.')]
#[SerializedName('test_mode')] public bool $isTestMode,
) {
}
Expand Down
51 changes: 51 additions & 0 deletions src/Dto/PaymentStatusDto.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
<?php

declare(strict_types=1);

namespace App\Dto;

use App\Payment\Common\Message\ResponseInterface;
use Symfony\Component\Serializer\Attribute\SerializedName;
use OpenApi\Attributes as OA;

#[OA\Schema(
description: 'Payment status object.',
)]
final readonly class PaymentStatusDto
{
public function __construct(

#[OA\Property(description: 'Payment gateway id.')]
#[SerializedName('payment_gateway')] public string $paymentGatewayId,

#[OA\Property(description: 'Transaction result.')]
#[SerializedName('success')] public bool $isSuccess,

#[OA\Property(description: 'Transaction id from the payment gateway side.')]
#[SerializedName('transaction_id')] public string $transactionId,

#[OA\Property(description: 'An error message.')]
public string $message,

#[OA\Property(description: 'An error code.')]
public string $code,

#[OA\Property(description: 'A payment status transaction as it was received from the payment gateway.')]
public array $data,
) {
}

public static function makeFromResponse(
string $paymentGatewayId,
ResponseInterface $response,
): self {
return new self(
paymentGatewayId: $paymentGatewayId,
isSuccess: $response->isSuccessful(),
transactionId: $response->getTransactionId(),
message: $response->getMessage(),
code: $response->getCode(),
data: $response->getRawData(),
);
}
}

0 comments on commit 988100b

Please sign in to comment.