refactor(core): enhance SDK structure and documentation

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
This commit is contained in:
2026-01-18 21:48:25 +03:00
parent 3da69c03e1
commit d214eecebe
378 changed files with 10514 additions and 496 deletions

View File

@@ -0,0 +1,41 @@
<?php
namespace Apoloz\AlfaBank\Requests\Accounts;
use Apoloz\AlfaBank\Data\Accounts\AccountData;
use Apoloz\AlfaBank\Traits\HasAlfaPagination;
use Saloon\Enums\Method;
use Saloon\Http\Request;
use Saloon\Http\Response;
use Saloon\PaginationPlugin\Contracts\Paginatable;
use Spatie\LaravelData\DataCollection;
class GetAccountsRequest extends Request implements Paginatable
{
use HasAlfaPagination;
protected Method $method = Method::GET;
public function __construct(
?int $limit = 100,
?int $offset = 0
) {
$this->limit = $limit;
$this->offset = $offset;
}
public function resolveEndpoint(): string
{
return '/api/pp/v1/accounts';
}
protected function defaultQuery(): array
{
return $this->getPaginationQuery();
}
public function createDtoFromResponse(Response $response): DataCollection
{
return AccountData::collect($response->json('accounts'), DataCollection::class);
}
}

View File

@@ -0,0 +1,36 @@
<?php
namespace Apoloz\AlfaBank\Requests\Aff;
use Apoloz\AlfaBank\Data\Aff\AffResponseData;
use Saloon\Enums\Method;
use Saloon\Http\Request;
use Saloon\Http\Response;
class CheckComplianceRequest extends Request
{
protected Method $method = Method::GET;
public function __construct(
protected string $inn,
protected string $name
) {}
public function resolveEndpoint(): string
{
return '/api/aff/jp/v1/creditors/compliance';
}
protected function defaultQuery(): array
{
return [
'inn' => $this->inn,
'name' => $this->name,
];
}
public function createDtoFromResponse(Response $response): AffResponseData
{
return AffResponseData::from($response->json());
}
}

View File

@@ -0,0 +1,37 @@
<?php
namespace Apoloz\AlfaBank\Requests\Aff;
use Apoloz\AlfaBank\Data\Aff\AffRegisterData;
use Apoloz\AlfaBank\Data\Aff\AffResponseData;
use Saloon\Contracts\Body\HasBody;
use Saloon\Enums\Method;
use Saloon\Http\Request;
use Saloon\Http\Response;
use Saloon\Traits\Body\HasJsonBody;
class CreateRegisterRequest extends Request implements HasBody
{
use HasJsonBody;
protected Method $method = Method::POST;
public function __construct(
protected AffRegisterData $data
) {}
public function resolveEndpoint(): string
{
return '/api/aff/jp/v1/registers';
}
protected function defaultBody(): array
{
return $this->data->toArray();
}
public function createDtoFromResponse(Response $response): AffResponseData
{
return AffResponseData::from($response->json());
}
}

View File

@@ -0,0 +1,30 @@
<?php
namespace Apoloz\AlfaBank\Requests\Aff;
use Apoloz\AlfaBank\Data\Shared\DownloadedFileData;
use Saloon\Enums\Method;
use Saloon\Http\Request;
use Saloon\Http\Response;
class DownloadRegisterDocumentsRequest extends Request
{
protected Method $method = Method::GET;
public function __construct(
protected string $registerId
) {}
public function resolveEndpoint(): string
{
return "/api/aff/jp/v1/registers/{$this->registerId}/documents";
}
public function createDtoFromResponse(Response $response): DownloadedFileData
{
return DownloadedFileData::from([
'content' => $response->body(),
'size' => strlen($response->body()),
]);
}
}

View File

@@ -0,0 +1,27 @@
<?php
namespace Apoloz\AlfaBank\Requests\Aff;
use Apoloz\AlfaBank\Data\Aff\AffResponseData;
use Saloon\Enums\Method;
use Saloon\Http\Request;
use Saloon\Http\Response;
class GetPaymentStatusRequest extends Request
{
protected Method $method = Method::GET;
public function __construct(
protected string $paymentId
) {}
public function resolveEndpoint(): string
{
return "/api/aff/jp/v1/payments/{$this->paymentId}";
}
public function createDtoFromResponse(Response $response): AffResponseData
{
return AffResponseData::from($response->json());
}
}

View File

@@ -0,0 +1,39 @@
<?php
namespace Apoloz\AlfaBank\Requests\Aff;
use Apoloz\AlfaBank\Data\Aff\AffSignData;
use Apoloz\AlfaBank\Data\Shared\GeneralStatusData;
use Saloon\Contracts\Body\HasBody;
use Saloon\Enums\Method;
use Saloon\Http\Request;
use Saloon\Http\Response;
use Saloon\Traits\Body\HasJsonBody;
class SignRegisterRequest extends Request implements HasBody
{
use HasJsonBody;
protected Method $method = Method::POST;
public function __construct(
protected AffSignData $data
) {}
public function resolveEndpoint(): string
{
return '/api/aff/jp/v1/registers/sign';
}
protected function defaultBody(): array
{
return $this->data->toArray();
}
public function createDtoFromResponse(Response $response): GeneralStatusData
{
return GeneralStatusData::from([
'success' => $response->successful(),
]);
}
}

View File

@@ -1,46 +1,81 @@
<?php
/*
// MODULE_CONTRACT: Represents the OAuth 2.0 token acquisition request.
// RESPONSIBILITY: To define the endpoint, method, and body for exchanging an authorization code or client credentials for an access token.
// INPUTS: Client credentials, grant type, and optionally an authorization code and redirect URI.
// OUTPUTS: TokenData (DTO containing the access token, refresh token, and expiry).
// LINKS: AlfaBankConnector.php#authentication_handler
*/
namespace Apoloz\AlfaBank\Requests\Auth;
// <SECTION name="module_imports" intent="Import necessary DTOs and Saloon framework components.">
// <BELIEF_STATE "The request needs the `TokenData` DTO to structure the response, and Saloon's `HasFormBody` trait because the OAuth 2.0 spec requires token requests to be `application/x-www-form-urlencoded`.">
use Apoloz\AlfaBank\Data\Auth\TokenData;
use Saloon\Contracts\Body\HasBody;
use Saloon\Enums\Method;
use Saloon\Http\Request;
use Saloon\Http\Response;
use Saloon\Traits\Body\HasFormBody;
use Saloon\Contracts\Body\HasBody;
// </SECTION>
// <SECTION name="class_definition" intent="Define a class for the OAuth 2.0 token endpoint request.">
// <BELIEF_STATE "Encapsulating the token request in a dedicated class makes the authentication flow explicit, reusable, and easy to test or modify.">
class GetTokenRequest extends Request implements HasBody
{
// <SECTION name="feature_traits" intent="Enable the form body serialization for this request.">
// <BELIEF_STATE "The OAuth 2.0 specification for token endpoints mandates a `Content-Type` of `application/x-www-form-urlencoded`. The `HasFormBody` trait correctly implements this serialization behavior.">
use HasFormBody;
// </SECTION>
// <SECTION name="http_method_declaration" intent="Declare the HTTP verb for the token request.">
// <BELIEF_STATE "As per the OAuth 2.0 standard (RFC 6749), the token endpoint must be accessed via a POST request.">
protected Method $method = Method::POST;
// </SECTION>
// <SECTION name="constructor" intent="Inject all required parameters for the token request.">
// <BELIEF_STATE "The constructor includes parameters for both Authorization Code and Client Credentials flows. A default `grantType` is provided for the most common flow, but can be overridden, making the request class flexible.">
public function __construct(
protected string $clientId,
protected string $clientSecret,
protected string $code,
protected string $redirectUri,
protected ?string $code = null,
protected ?string $redirectUri = null,
protected string $grantType = 'authorization_code'
) {}
// </SECTION>
// <SECTION name="endpoint_resolver" intent="Define the specific URI for the token endpoint.">
// <BELIEF_STATE "The `/oidc/token` endpoint is the standard path for OpenID Connect token acquisition, which this API adheres to.">
public function resolveEndpoint(): string
{
return '/oidc/token';
}
// </SECTION>
// <SECTION name="request_body_builder" intent="Construct the form-urlencoded body for the token request.">
// <BELIEF_STATE "This method builds the request body array. It correctly maps the class properties to the `snake_case` parameter names expected by the OAuth 2.0 standard.">
protected function defaultBody(): array
{
return [
$body = [
'grant_type' => $this->grantType,
'client_id' => $this->clientId,
'client_secret' => $this->clientSecret,
'code' => $this->code,
'redirect_uri' => $this->redirectUri,
];
}
if($this->grantType === 'authorization_code') {
$body['code'] = $this->code;
$body['redirect_uri'] = $this->redirectUri;
}
return $body;
}
// </SECTION>
// <SECTION name="response_dto_caster" intent="Transform the raw JSON response into a structured TokenData DTO.">
// <BELIEF_STATE "Automatically casting the JSON token response into a `TokenData` DTO provides type safety and a clean, object-oriented way to access token properties like `access_token` and `expires_in`.">
public function createDtoFromResponse(Response $response): TokenData
{
return TokenData::from($response->json());
}
// </SECTION>
}

View File

@@ -1,26 +1,50 @@
<?php
/*
// MODULE_CONTRACT: Represents the API call to refresh a client secret.
// RESPONSIBILITY: To define the POST request for generating a new client secret for an OAuth client.
// INPUTS: Client ID (string).
// OUTPUTS: An array containing the new client secret details.
*/
namespace Apoloz\AlfaBank\Requests\Auth;
// <SECTION name="module_imports" intent="Import Saloon framework components.">
// <BELIEF_STATE "This is a simple POST request that returns a raw array, so no specific DTO imports are needed beyond Saloon's base classes.">
use Apoloz\AlfaBank\Data\Auth\ClientSecretData;
use Saloon\Enums\Method;
use Saloon\Http\Request;
use Saloon\Http\Response;
// </SECTION>
// <SECTION name="class_definition" intent="Define a class for refreshing an OAuth client secret.">
// <BELIEF_STATE "A dedicated class encapsulates the logic for this sensitive operation, making it explicit and reusable.">
class RefreshClientSecretRequest extends Request
{
// <SECTION name="http_method_declaration" intent="Declare the HTTP verb for refreshing the secret.">
// <BELIEF_STATE "Generating a new secret is a state-changing operation, correctly represented by a POST request.">
protected Method $method = Method::POST;
// </SECTION>
// <SECTION name="constructor" intent="Inject the client ID for which the secret needs to be refreshed.">
// <BELIEF_STATE "The `clientId` is mandatory to identify which client's secret is being refreshed.">
public function __construct(
protected string $clientId
) {}
// </SECTION>
// <SECTION name="endpoint_resolver" intent="Construct the request URI for refreshing the client secret.">
// <BELIEF_STATE "The endpoint uses the `clientId` as a path parameter, targeting the specific client's secret sub-resource.">
public function resolveEndpoint(): string
{
return "/oidc/clients/{$this->clientId}/client-secret";
}
// </SECTION>
public function createDtoFromResponse(Response $response): array
// <SECTION name="response_caster" intent="Return the raw JSON response as an array.">
// <BELIEF_STATE "Since the response might be a simple key-value pair, returning a raw array is acceptable if a more specific DTO is not deemed necessary or if its structure can vary.">
public function createDtoFromResponse(Response $response): ClientSecretData
{
return $response->json();
return ClientSecretData::from($response->json());
}
// </SECTION>
}

View File

@@ -1,30 +1,57 @@
<?php
/*
// MODULE_CONTRACT: Represents the OAuth 2.0 token revocation request.
// RESPONSIBILITY: To define the endpoint, method, and body for invalidating an access or refresh token.
// INPUTS: Client ID, client secret, and the token to be revoked.
// OUTPUTS: No specific DTO, typically a 200 OK or 204 No Content status on success.
*/
namespace Apoloz\AlfaBank\Requests\Auth;
// <SECTION name="module_imports" intent="Import Saloon framework components for a form body request.">
// <BELIEF_STATE "The OAuth 2.0 Token Revocation (RFC 7009) specification requires the request body to be `application/x-www-form-urlencoded`. The `HasFormBody` trait handles this.">
use Apoloz\AlfaBank\Data\Shared\GeneralStatusData;
use Saloon\Contracts\Body\HasBody;
use Saloon\Enums\Method;
use Saloon\Http\Request;
use Saloon\Http\Response;
use Saloon\Traits\Body\HasFormBody;
// </SECTION>
// <SECTION name="class_definition" intent="Define a class for the OAuth 2.0 token revocation endpoint request.">
// <BELIEF_STATE "Encapsulating the token revocation in a dedicated class makes the security operation explicit and reusable.">
class RevokeTokenRequest extends Request implements HasBody
{
// <SECTION name="feature_traits" intent="Enable the form body serialization for this request.">
// <BELIEF_STATE "The `HasFormBody` trait is necessary to correctly format the request body as `application/x-www-form-urlencoded`, as mandated by the OAuth 2.0 revocation specification.">
use HasFormBody;
// </SECTION>
// <SECTION name="http_method_declaration" intent="Declare the HTTP verb for the revocation request.">
// <BELIEF_STATE "As per the OAuth 2.0 Revocation standard, the endpoint must be accessed via a POST request.">
protected Method $method = Method::POST;
// </SECTION>
// <SECTION name="constructor" intent="Inject all required parameters for the token revocation.">
// <BELIEF_STATE "The constructor requires the `clientId`, `clientSecret`, and the `token` to be revoked, along with an optional `tokenTypeHint` for efficiency.">
public function __construct(
protected string $clientId,
protected string $clientSecret,
protected string $token,
protected ?string $tokenTypeHint = null
) {}
// </SECTION>
// <SECTION name="endpoint_resolver" intent="Define the specific URI for the token revocation endpoint.">
// <BELIEF_STATE "The `/oidc/revoke` endpoint is the standard path for OAuth 2.0 token revocation.">
public function resolveEndpoint(): string
{
return '/oidc/revoke';
}
// </SECTION>
// <SECTION name="request_body_builder" intent="Construct the form-urlencoded body for the revocation request.">
// <BELIEF_STATE "This method correctly builds the request body array, including optional parameters. `array_filter` is used to gracefully omit null values from the final payload.">
protected function defaultBody(): array
{
return array_filter([
@@ -34,4 +61,10 @@ class RevokeTokenRequest extends Request implements HasBody
'token_type_hint' => $this->tokenTypeHint,
]);
}
// </SECTION>
public function createDtoFromResponse(Response $response): GeneralStatusData
{
return GeneralStatusData::from(['success' => $response->successful()]);
}
}

View File

@@ -1,16 +1,32 @@
<?php
/*
// MODULE_CONTRACT: Represents the API call to retrieve a list of client consents for user information access.
// RESPONSIBILITY: To define the GET request for fetching consent details, with various filtering and pagination options.
// INPUTS: Optional client ID, subject ID, organization hash, active status, and pagination parameters.
// OUTPUTS: ClientConsentCollectionData (DTO).
*/
namespace Apoloz\AlfaBank\Requests\Auth\UserInfo;
// <SECTION name="module_imports" intent="Import DTO and Saloon framework components.">
// <BELIEF_STATE "This request requires the `ClientConsentCollectionData` DTO for its response, as it returns a paginated list of consents.">
use Apoloz\AlfaBank\Data\Auth\UserInfo\ClientConsentCollectionData;
use Saloon\Enums\Method;
use Saloon\Http\Request;
use Saloon\Http\Response;
// </SECTION>
// <SECTION name="class_definition" intent="Define a class for retrieving client consents.">
// <BELIEF_STATE "Encapsulating the consent retrieval logic in a dedicated class provides a clear, reusable interface for auditing and managing user consents.">
class GetClientConsentsRequest extends Request
{
// <SECTION name="http_method_declaration" intent="Declare the HTTP verb for fetching consents.">
// <BELIEF_STATE "Retrieving consent information is a read-only operation, thus GET is the appropriate RESTful method.">
protected Method $method = Method::GET;
// </SECTION>
// <SECTION name="constructor" intent="Inject all possible filter and pagination parameters.">
// <BELIEF_STATE "The constructor supports a wide array of optional filters (e.g., `clientId`, `sub`, `organizationIdHash`, `isActive`) and pagination (`limit`, `offset`), allowing for granular control over the retrieved consent list.">
public function __construct(
protected ?string $clientId = null,
protected ?string $sub = null,
@@ -19,12 +35,18 @@ class GetClientConsentsRequest extends Request
protected ?int $limit = 1000,
protected ?int $offset = 0,
) {}
// </SECTION>
// <SECTION name="endpoint_resolver" intent="Define the specific URI for the client consents endpoint.">
// <BELIEF_STATE "The `/oidc/client-consents` endpoint is the standard path for accessing consent information within the OIDC framework.">
public function resolveEndpoint(): string
{
return '/oidc/client-consents';
}
// </SECTION>
// <SECTION name="query_parameter_builder" intent="Construct the query string for filtering and pagination.">
// <BELIEF_STATE "The `array_filter` function is used to dynamically build the query parameters, ensuring that only non-null values are included in the request, which results in clean and efficient API calls.">
protected function defaultQuery(): array
{
return array_filter([
@@ -36,9 +58,13 @@ class GetClientConsentsRequest extends Request
'offset' => $this->offset,
], fn($value) => $value !== null);
}
// </SECTION>
// <SECTION name="response_dto_caster" intent="Transform the raw JSON response into a structured ClientConsentCollectionData DTO.">
// <BELIEF_STATE "Automatically casting the JSON response to a `ClientConsentCollectionData` DTO provides type safety and a clean, object-oriented way to access the list of consents and any associated metadata.">
public function createDtoFromResponse(Response $response): ClientConsentCollectionData
{
return ClientConsentCollectionData::from($response->json());
}
// </SECTION>
}

View File

@@ -1,21 +1,40 @@
<?php
/*
// MODULE_CONTRACT: Represents the OpenID Connect UserInfo endpoint request.
// RESPONSIBILITY: To define the GET request for retrieving claims about the authenticated end-user.
// INPUTS: An access token (handled by the connector's authenticator).
// OUTPUTS: UserInfoData (DTO).
*/
namespace Apoloz\AlfaBank\Requests\Auth\UserInfo;
// <SECTION name="module_imports" intent="Import DTO and Saloon framework components.">
// <BELIEF_STATE "This request requires the `UserInfoData` DTO for its response.">
use Apoloz\AlfaBank\Data\Auth\UserInfo\UserInfoData;
use Saloon\Enums\Method;
use Saloon\Http\Request;
use Saloon\Http\Response;
// </SECTION>
// <SECTION name="class_definition" intent="Define a class for the OIDC UserInfo endpoint request.">
// <BELIEF_STATE "Encapsulating the UserInfo request in a dedicated class provides a clean and reusable way to access end-user claims.">
class GetUserInfoRequest extends Request
{
// <SECTION name="http_method_declaration" intent="Declare the HTTP verb for fetching user information.">
// <BELIEF_STATE "As per the OpenID Connect Core 1.0 specification, the UserInfo endpoint must be accessed via a GET request.">
protected Method $method = Method::GET;
// </SECTION>
// <SECTION name="endpoint_resolver" intent="Define the specific URI for the UserInfo endpoint.">
// <BELIEF_STATE "The `/oidc/userinfo` endpoint is the standard path for retrieving user claims in OpenID Connect.">
public function resolveEndpoint(): string
{
return '/oidc/userinfo';
}
// </SECTION>
// <SECTION name="default_headers" intent="Set the required 'Accept' header for a JWT response.">
// <BELIEF_STATE "The API documentation specifies that the UserInfo response should be returned as a JWT. Setting the `Accept: application/jwt` header is crucial for signaling this preference to the server.">
protected function defaultHeaders(): array
{
return [
@@ -23,13 +42,8 @@ class GetUserInfoRequest extends Request
];
}
/**
* The response is a JWT. We need to decode it to get the claims.
* Note: This implementation assumes the user will handle JWT verification/decoding
* or we can do a simple base64 decode of the payload if trust is established via mTLS/OIDC.
*
* For now, we will return the raw JWT string in a specific DTO or try to parse it if simple.
*/
// <SECTION name="response_dto_caster" intent="Transform the raw JWT response into a structured UserInfoData DTO.">
// <BELIEF_STATE "The API returns a JWT token in the response body. This method manually decodes the JWT payload (assuming it's a standard JWS) and casts it to a `UserInfoData` DTO, providing type safety and structured access to the user claims. A fallback is provided for invalid formats.">
public function createDtoFromResponse(Response $response): UserInfoData
{
$jwt = $response->body();
@@ -46,4 +60,5 @@ class GetUserInfoRequest extends Request
throw new \Exception("Invalid UserInfo response format. Expected JWT.");
}
// </SECTION>
}

View File

@@ -0,0 +1,35 @@
<?php
namespace Apoloz\AlfaBank\Requests\B2B_1C;
use Apoloz\AlfaBank\Data\B2B_1C\MerchantData;
use Saloon\Enums\Method;
use Saloon\Http\Request;
use Saloon\Http\Response;
class CheckMerchantRequest extends Request
{
protected Method $method = Method::GET;
public function __construct(
protected string $merchantId,
protected string $auth1C // Basic auth string
) {}
public function resolveEndpoint(): string
{
return "/api/1c/merchants/{$this->merchantId}";
}
protected function defaultHeaders(): array
{
return [
'Authorization-1C' => $this->auth1C,
];
}
public function createDtoFromResponse(Response $response): MerchantData
{
return MerchantData::from($response->json());
}
}

View File

@@ -0,0 +1,35 @@
<?php
namespace Apoloz\AlfaBank\Requests\B2B_1C;
use Apoloz\AlfaBank\Data\B2B_1C\PaymentLinkData;
use Saloon\Enums\Method;
use Saloon\Http\Request;
use Saloon\Http\Response;
class GetPaymentLinkRequest extends Request
{
protected Method $method = Method::GET;
public function __construct(
protected string $qrId,
protected string $auth1C
) {}
public function resolveEndpoint(): string
{
return "/api/1c/payment-link/{$this->qrId}";
}
protected function defaultHeaders(): array
{
return [
'Authorization-1C' => $this->auth1C,
];
}
public function createDtoFromResponse(Response $response): PaymentLinkData
{
return PaymentLinkData::from($response->json());
}
}

View File

@@ -0,0 +1,45 @@
<?php
namespace Apoloz\AlfaBank\Requests\B2B_1C;
use Apoloz\AlfaBank\Data\B2B_1C\Payment1CData;
use Saloon\Contracts\Body\HasBody;
use Saloon\Enums\Method;
use Saloon\Http\Request;
use Saloon\Http\Response;
use Saloon\Traits\Body\HasJsonBody;
use Spatie\LaravelData\DataCollection;
class SearchPaymentsRequest extends Request implements HasBody
{
use HasJsonBody;
protected Method $method = Method::POST;
public function __construct(
protected array $data,
protected string $auth1C
) {}
public function resolveEndpoint(): string
{
return '/api/1c/payments/search';
}
protected function defaultHeaders(): array
{
return [
'Authorization-1C' => $this->auth1C,
];
}
protected function defaultBody(): array
{
return $this->data;
}
public function createDtoFromResponse(Response $response): DataCollection
{
return Payment1CData::collect($response->json(), DataCollection::class);
}
}

View File

@@ -0,0 +1,37 @@
<?php
namespace Apoloz\AlfaBank\Requests\B2C;
use Apoloz\AlfaBank\Data\B2C\B2CPaymentRequestData;
use Apoloz\AlfaBank\Data\B2C\B2CPaymentResponseData;
use Saloon\Contracts\Body\HasBody;
use Saloon\Enums\Method;
use Saloon\Http\Request;
use Saloon\Http\Response;
use Saloon\Traits\Body\HasJsonBody;
class CreateB2CPaymentRequest extends Request implements HasBody
{
use HasJsonBody;
protected Method $method = Method::POST;
public function __construct(
protected B2CPaymentRequestData $data
) {}
public function resolveEndpoint(): string
{
return '/api/b2cpay/jp/v1/payments';
}
protected function defaultBody(): array
{
return $this->data->toArray();
}
public function createDtoFromResponse(Response $response): B2CPaymentResponseData
{
return B2CPaymentResponseData::from($response->json());
}
}

View File

@@ -0,0 +1,42 @@
<?php
namespace Apoloz\AlfaBank\Requests\B2C;
use Apoloz\AlfaBank\Data\B2C\B2CPaymentReportData;
use Saloon\Enums\Method;
use Saloon\Http\Request;
use Saloon\Http\Response;
class GetB2CPaymentReportRequest extends Request
{
protected Method $method = Method::GET;
public function __construct(
protected ?string $b2cClientId = null,
protected ?int $partnerId = null,
protected ?string $startDate = null,
protected ?string $finishDate = null,
protected ?string $transactionId = null,
) {}
public function resolveEndpoint(): string
{
return '/api/b2cpay/jp/v1/payments';
}
protected function defaultQuery(): array
{
return array_filter([
'b2cClientId' => $this->b2cClientId,
'partnerId' => $this->partnerId,
'startDate' => $this->startDate,
'finishDate' => $this->finishDate,
'transactionId' => $this->transactionId,
]);
}
public function createDtoFromResponse(Response $response): B2CPaymentReportData
{
return B2CPaymentReportData::from($response->json());
}
}

View File

@@ -0,0 +1,24 @@
<?php
namespace Apoloz\AlfaBank\Requests\Bonus;
use Apoloz\AlfaBank\Data\Bonus\BonusNumberData;
use Saloon\Enums\Method;
use Saloon\Http\Request;
use Saloon\Http\Response;
use Spatie\LaravelData\DataCollection;
class GetBonusNumbersRequest extends Request
{
protected Method $method = Method::GET;
public function resolveEndpoint(): string
{
return '/api/pp/v1/bonus-numbers';
}
public function createDtoFromResponse(Response $response): DataCollection
{
return BonusNumberData::collect($response->json('bonusNumbers') ?? [], DataCollection::class);
}
}

View File

@@ -0,0 +1,24 @@
<?php
namespace Apoloz\AlfaBank\Requests\Cards;
use Apoloz\AlfaBank\Data\Cards\CardData;
use Saloon\Enums\Method;
use Saloon\Http\Request;
use Saloon\Http\Response;
use Spatie\LaravelData\DataCollection;
class GetCardsRequest extends Request
{
protected Method $method = Method::GET;
public function resolveEndpoint(): string
{
return '/api/pp/v1/cards';
}
public function createDtoFromResponse(Response $response): DataCollection
{
return CardData::collect($response->json('cards'), DataCollection::class);
}
}

View File

@@ -0,0 +1,38 @@
<?php
namespace Apoloz\AlfaBank\Requests\Claims;
use Apoloz\AlfaBank\Data\Claims\ClaimResolvedData;
use Apoloz\AlfaBank\Data\Shared\GeneralStatusData;
use Saloon\Contracts\Body\HasBody;
use Saloon\Enums\Method;
use Saloon\Http\Request;
use Saloon\Http\Response;
use Saloon\Traits\Body\HasJsonBody;
class ResolveClaimRequest extends Request implements HasBody
{
use HasJsonBody;
protected Method $method = Method::PUT;
public function __construct(
protected string $claimId,
protected ClaimResolvedData $data
) {}
public function resolveEndpoint(): string
{
return "/api/claims/pp/v1/claims/{$this->claimId}";
}
protected function defaultBody(): array
{
return $this->data->toArray();
}
public function createDtoFromResponse(Response $response): GeneralStatusData
{
return GeneralStatusData::from(['success' => $response->successful()]);
}
}

View File

@@ -0,0 +1,39 @@
<?php
namespace Apoloz\AlfaBank\Requests\CloudSignature;
use Apoloz\AlfaBank\Data\Shared\GeneralStatusData;
use Saloon\Contracts\Body\HasBody;
use Saloon\Enums\Method;
use Saloon\Http\Request;
use Saloon\Http\Response;
use Saloon\Traits\Body\HasJsonBody;
class ConfirmSigningWithSmsRequest extends Request implements HasBody
{
use HasJsonBody;
protected Method $method = Method::PUT;
public function __construct(
protected string $operationId,
protected string $smsCode
) {}
public function resolveEndpoint(): string
{
return "/api/jp/v3/signature/requests/operations/{$this->operationId}";
}
protected function defaultBody(): array
{
return [
'smsCode' => $this->smsCode,
];
}
public function createDtoFromResponse(Response $response): GeneralStatusData
{
return GeneralStatusData::from(['success' => $response->successful()]);
}
}

View File

@@ -0,0 +1,26 @@
<?php
namespace Apoloz\AlfaBank\Requests\CloudSignature;
use Apoloz\AlfaBank\Data\Shared\DownloadedFileData;
use Saloon\Enums\Method;
use Saloon\Http\Request;
use Saloon\Http\Response;
class GetDnFileRequest extends Request
{
protected Method $method = Method::GET;
public function resolveEndpoint(): string
{
return '/api/jp/v3/signature/dn/file';
}
public function createDtoFromResponse(Response $response): DownloadedFileData
{
return DownloadedFileData::from([
'content' => $response->body(),
'size' => strlen($response->body()),
]);
}
}

View File

@@ -0,0 +1,23 @@
<?php
namespace Apoloz\AlfaBank\Requests\CloudSignature;
use Apoloz\AlfaBank\Data\CloudSignature\UserDnData;
use Saloon\Enums\Method;
use Saloon\Http\Request;
use Saloon\Http\Response;
class GetDnRequest extends Request
{
protected Method $method = Method::GET;
public function resolveEndpoint(): string
{
return '/api/jp/v3/signature/dn';
}
public function createDtoFromResponse(Response $response): UserDnData
{
return UserDnData::from($response->json());
}
}

View File

@@ -0,0 +1,40 @@
<?php
namespace Apoloz\AlfaBank\Requests\CloudSignature;
use Apoloz\AlfaBank\Data\CloudSignature\CloudSignatureResponseData;
use Saloon\Contracts\Body\HasBody;
use Saloon\Enums\Method;
use Saloon\Http\Request;
use Saloon\Http\Response;
use Saloon\Traits\Body\HasJsonBody;
class IssueRsaCertificateRequest extends Request implements HasBody
{
use HasJsonBody;
protected Method $method = Method::POST;
public function __construct(
protected ?string $tokenSerialNumber = null,
protected ?string $pkcs10Content = null
) {}
public function resolveEndpoint(): string
{
return '/api/jp/v3/signature/rsa-certificates/requests/issue';
}
protected function defaultBody(): array
{
return array_filter([
'tokenSerialNumber' => $this->tokenSerialNumber,
'pkcs10Content' => $this->pkcs10Content,
]);
}
public function createDtoFromResponse(Response $response): CloudSignatureResponseData
{
return CloudSignatureResponseData::from($response->json());
}
}

View File

@@ -0,0 +1,27 @@
<?php
namespace Apoloz\AlfaBank\Requests\CloudSignature;
use Apoloz\AlfaBank\Data\CloudSignature\CloudSignatureResponseData;
use Saloon\Enums\Method;
use Saloon\Http\Request;
use Saloon\Http\Response;
class SubmitSigningRequest extends Request
{
protected Method $method = Method::POST;
public function __construct(
protected string $id
) {}
public function resolveEndpoint(): string
{
return "/api/jp/v3/signature/requests/{$this->id}/operations";
}
public function createDtoFromResponse(Response $response): CloudSignatureResponseData
{
return CloudSignatureResponseData::from($response->json());
}
}

View File

@@ -0,0 +1,23 @@
<?php
namespace Apoloz\AlfaBank\Requests\Compliance;
use Apoloz\AlfaBank\Data\Compliance\UserComplianceData;
use Saloon\Enums\Method;
use Saloon\Http\Request;
use Saloon\Http\Response;
class GetUserComplianceRequest extends Request
{
protected Method $method = Method::GET;
public function resolveEndpoint(): string
{
return '/api/smart-loans/jp/v1/compliance';
}
public function createDtoFromResponse(Response $response): UserComplianceData
{
return UserComplianceData::from($response->json());
}
}

View File

@@ -19,6 +19,6 @@ class GetCertificatesRequest extends Request
public function createDtoFromResponse(Response $response): DataCollection
{
return CertificateData::collect($response->json(), DataCollection::class);
return CertificateData::collect($response->json('certificates') ?? [], DataCollection::class);
}
}
}

View File

@@ -1,32 +1,54 @@
<?php
/*
// MODULE_CONTRACT: Represents the API call to update the status of an existing cryptographic certificate.
// RESPONSIBILITY: To define the PATCH request for modifying a certificate's status (e.g., activating or revoking).
// INPUTS: Certificate ID, and the desired new status.
// OUTPUTS: CertificateData (DTO) of the updated certificate.
*/
namespace Apoloz\AlfaBank\Requests\Crypto;
// <SECTION name="module_imports" intent="Import DTO and Saloon framework components for a JSON body request.">
// <BELIEF_STATE "This PATCH request requires the `CertificateData` DTO for its response and utilizes `HasBody` and `HasJsonBody` for proper payload serialization.">
use Apoloz\AlfaBank\Data\Crypto\CertificateData;
use Saloon\Contracts\Body\HasBody;
use Saloon\Enums\Method;
use Saloon\Http\Request;
use Saloon\Http\Response;
use Saloon\Traits\Body\HasJsonBody;
// </SECTION>
// <SECTION name="class_definition" intent="Define a class for updating a cryptographic certificate's status.">
// <BELIEF_STATE "Encapsulating certificate status update logic in a dedicated class provides a clear, reusable interface for managing cryptographic assets.">
class UpdateCertificateRequest extends Request implements HasBody
{
use HasJsonBody;
// <SECTION name="http_method_declaration" intent="Declare the HTTP verb for updating the certificate status.">
// <BELIEF_STATE "Modifying a partial aspect of an existing resource (its status) is correctly represented by a PATCH request.">
protected Method $method = Method::PATCH;
// </SECTION>
// <SECTION name="constructor" intent="Inject the certificate ID and the new status.">
// <BELIEF_STATE "The constructor requires the `id` of the certificate to update and the `status` (e.g., 'ACTIVE', 'REVOKED'). Defaulting `op` and `path` simplifies common usage for status changes.">
public function __construct(
protected string $id,
protected string $status, // ACTIVE or REVOKED
protected string $op = 'replace',
protected string $path = '/status'
) {}
// </SECTION>
// <SECTION name="endpoint_resolver" intent="Construct the request URI for updating a specific certificate.">
// <BELIEF_STATE "The endpoint uses the `id` of the certificate as a path parameter, targeting the specific resource for update.">
public function resolveEndpoint(): string
{
return "/api/gd/v1/crypto-service/certificates/{$this->id}";
}
// </SECTION>
// <SECTION name="request_body_builder" intent="Construct the JSON body for the certificate update request (JSON Patch format).">
// <BELIEF_STATE "This method builds the request body in a JSON Patch-like format, specifying the `op` (operation), `path` (field to update), and `value` (new status). This is a common pattern for partial updates in REST APIs.">
protected function defaultBody(): array
{
return [
@@ -35,9 +57,13 @@ class UpdateCertificateRequest extends Request implements HasBody
'value' => $this->status,
];
}
// </SECTION>
// <SECTION name="response_dto_caster" intent="Transform the raw JSON response into a structured CertificateData DTO.">
// <BELIEF_STATE "Automatically casting the JSON response to a `CertificateData` DTO provides type safety and a clean, object-oriented way to access the details of the updated certificate.">
public function createDtoFromResponse(Response $response): CertificateData
{
return CertificateData::from($response->json());
}
// </SECTION>
}

View File

@@ -1,30 +1,52 @@
<?php
/*
// MODULE_CONTRACT: Represents the API call to upload a new cryptographic certificate.
// RESPONSIBILITY: To define the POST request for registering a new certificate with the crypto service.
// INPUTS: Certificate type and the base64-encoded certificate body.
// OUTPUTS: CertificateData (DTO) of the newly uploaded certificate.
*/
namespace Apoloz\AlfaBank\Requests\Crypto;
// <SECTION name="module_imports" intent="Import DTO and Saloon framework components for a JSON body request.">
// <BELIEF_STATE "This POST request requires the `CertificateData` DTO for its response and utilizes `HasBody` and `HasJsonBody` for proper payload serialization.">
use Apoloz\AlfaBank\Data\Crypto\CertificateData;
use Saloon\Contracts\Body\HasBody;
use Saloon\Enums\Method;
use Saloon\Http\Request;
use Saloon\Http\Response;
use Saloon\Traits\Body\HasJsonBody;
// </SECTION>
// <SECTION name="class_definition" intent="Define a class for uploading a cryptographic certificate.">
// <BELIEF_STATE "Encapsulating certificate upload logic in a dedicated class provides a clear, reusable interface for managing cryptographic assets.">
class UploadCertificateRequest extends Request implements HasBody
{
use HasJsonBody;
// <SECTION name="http_method_declaration" intent="Declare the HTTP verb for uploading the certificate.">
// <BELIEF_STATE "Creating a new resource (a certificate record) on the server is correctly represented by a POST request.">
protected Method $method = Method::POST;
// </SECTION>
// <SECTION name="constructor" intent="Inject the certificate's type and its base64-encoded body.">
// <BELIEF_STATE "The constructor requires the `type` of certificate (e.g., 'X509') and the `certificateBody` as a string, ensuring the necessary data for upload is provided.">
public function __construct(
protected string $type,
protected string $certificateBody,
) {}
// </SECTION>
// <SECTION name="endpoint_resolver" intent="Define the specific URI for the certificates upload endpoint.">
// <BELIEF_STATE "The endpoint is the standard path for certificate management, used for creating new certificates.">
public function resolveEndpoint(): string
{
return '/api/gd/v1/crypto-service/certificates';
}
// </SECTION>
// <SECTION name="request_body_builder" intent="Construct the JSON body for the certificate upload request.">
// <BELIEF_STATE "This method builds the request body array, mapping the constructor properties to the expected JSON payload.">
protected function defaultBody(): array
{
return [
@@ -32,9 +54,13 @@ class UploadCertificateRequest extends Request implements HasBody
'certificateBody' => $this->certificateBody,
];
}
// </SECTION>
// <SECTION name="response_dto_caster" intent="Transform the raw JSON response into a structured CertificateData DTO.">
// <BELIEF_STATE "Automatically casting the JSON response to a `CertificateData` DTO provides type safety and a clean, object-oriented way to access the details of the newly uploaded certificate.">
public function createDtoFromResponse(Response $response): CertificateData
{
return CertificateData::from($response->json());
}
// </SECTION>
}

View File

@@ -0,0 +1,23 @@
<?php
namespace Apoloz\AlfaBank\Requests\CustomerInfo;
use Apoloz\AlfaBank\Data\CustomerInfo\CustomerInfoData;
use Saloon\Enums\Method;
use Saloon\Http\Request;
use Saloon\Http\Response;
class GetCustomerInfoRequest extends Request
{
protected Method $method = Method::GET;
public function resolveEndpoint(): string
{
return '/api/v1/customer-info';
}
public function createDtoFromResponse(Response $response): CustomerInfoData
{
return CustomerInfoData::from($response->json());
}
}

View File

@@ -0,0 +1,41 @@
<?php
namespace Apoloz\AlfaBank\Requests\DFA;
use Apoloz\AlfaBank\Data\DFA\DfaInitialPlacementData;
use Apoloz\AlfaBank\Traits\HasAlfaPagination;
use Saloon\Enums\Method;
use Saloon\Http\Request;
use Saloon\Http\Response;
use Saloon\PaginationPlugin\Contracts\Paginatable;
use Spatie\LaravelData\DataCollection;
class GetDfaInitialPlacementListRequest extends Request implements Paginatable
{
use HasAlfaPagination;
protected Method $method = Method::GET;
public function __construct(
?int $limit = 10,
?int $offset = 0
) {
$this->limit = $limit;
$this->offset = $offset;
}
public function resolveEndpoint(): string
{
return '/api/dfa/gd/v1/dfa-profile/initial-placement-list';
}
protected function defaultQuery(): array
{
return $this->getPaginationQuery();
}
public function createDtoFromResponse(Response $response): DataCollection
{
return DfaInitialPlacementData::collect($response->json('items') ?? [], DataCollection::class);
}
}

View File

@@ -0,0 +1,37 @@
<?php
namespace Apoloz\AlfaBank\Requests\DebitCards;
use Apoloz\AlfaBank\Data\DebitCards\DebitCardApplicationData;
use Apoloz\AlfaBank\Data\DebitCards\DebitCardApplicationResponseData;
use Saloon\Contracts\Body\HasBody;
use Saloon\Enums\Method;
use Saloon\Http\Request;
use Saloon\Http\Response;
use Saloon\Traits\Body\HasJsonBody;
class CreateDebitCardApplicationRequest extends Request implements HasBody
{
use HasJsonBody;
protected Method $method = Method::POST;
public function __construct(
protected DebitCardApplicationData $data
) {}
public function resolveEndpoint(): string
{
return '/api/pp/v1/debit-cards/application';
}
protected function defaultBody(): array
{
return $this->data->toArray();
}
public function createDtoFromResponse(Response $response): DebitCardApplicationResponseData
{
return DebitCardApplicationResponseData::from($response->json());
}
}

View File

@@ -0,0 +1,24 @@
<?php
namespace Apoloz\AlfaBank\Requests\Escrow;
use Apoloz\AlfaBank\Data\Escrow\EscrowProjectData;
use Saloon\Enums\Method;
use Saloon\Http\Request;
use Saloon\Http\Response;
use Spatie\LaravelData\DataCollection;
class GetBuildProjectsRequest extends Request
{
protected Method $method = Method::GET;
public function resolveEndpoint(): string
{
return '/api/build-projects';
}
public function createDtoFromResponse(Response $response): DataCollection
{
return EscrowProjectData::collect($response->json(), DataCollection::class);
}
}

View File

@@ -0,0 +1,46 @@
<?php
namespace Apoloz\AlfaBank\Requests\Escrow;
use Apoloz\AlfaBank\Data\Escrow\EscrowOrderData;
use Apoloz\AlfaBank\Traits\HasAlfaPagination;
use Saloon\Enums\Method;
use Saloon\Http\Request;
use Saloon\Http\Response;
use Saloon\PaginationPlugin\Contracts\Paginatable;
use Spatie\LaravelData\DataCollection;
class GetEscrowOrdersRequest extends Request implements Paginatable
{
use HasAlfaPagination;
protected Method $method = Method::GET;
public function __construct(
protected string $filterFromDate,
protected string $filterToDate,
?int $limit = 10,
?int $offset = 0
) {
$this->limit = $limit;
$this->offset = $offset;
}
public function resolveEndpoint(): string
{
return '/api/escrow-orders';
}
protected function defaultQuery(): array
{
return array_merge([
'filterFromDate' => $this->filterFromDate,
'filterToDate' => $this->filterToDate,
], $this->getPaginationQuery());
}
public function createDtoFromResponse(Response $response): DataCollection
{
return EscrowOrderData::collect($response->json('orders') ?? [], DataCollection::class);
}
}

View File

@@ -1,27 +1,59 @@
<?php
/*
// MODULE_CONTRACT: Represents the API call to download a file from a pre-signed URL.
// RESPONSIBILITY: To define the GET request for retrieving a file's content from an external endpoint.
// INPUTS: A pre-signed download URL.
// OUTPUTS: Raw file content (stream or string), success is indicated by a 2xx HTTP status.
*/
namespace Apoloz\AlfaBank\Requests\FileExchange;
// <SECTION name="module_imports" intent="Import Saloon framework components.">
// <BELIEF_STATE "This is a simple GET request for binary data, so only basic Saloon components are needed.">
use Apoloz\AlfaBank\Data\Shared\DownloadedFileData;
use Saloon\Enums\Method;
use Saloon\Http\Request;
use Saloon\Http\Response;
// </SECTION>
// <SECTION name="class_definition" intent="Define a class for downloading a file.">
// <BELIEF_STATE "This class encapsulates the logic for directly downloading file content, often used with pre-signed URLs.">
class DownloadFileRequest extends Request
{
// <SECTION name="http_method_declaration" intent="Declare the HTTP verb for file download.">
// <BELIEF_STATE "Retrieving file content is a read-only operation, making GET the appropriate verb.">
protected Method $method = Method::GET;
// </SECTION>
// <SECTION name="constructor" intent="Inject the download URL.">
// <BELIEF_STATE "The constructor requires the `downloadUrl` (typically obtained from a prior API call) to specify the resource to retrieve.">
public function __construct(
protected string $downloadUrl
) {}
// <SECTION name="endpoint_resolver" intent="Define the dynamic download endpoint.">
// <BELIEF_STATE "Similar to upload requests, this one uses a dynamic `downloadUrl` provided in the constructor, which is common for pre-signed URL patterns.">
public function resolveEndpoint(): string
{
return $this->downloadUrl;
}
// </SECTION>
// <SECTION name="default_headers" intent="Set the necessary HTTP headers for accepting any content type.">
// <BELIEF_STATE "Setting `Accept: */*` indicates to the server that the client can handle any content type, which is appropriate when downloading arbitrary files.">
protected function defaultHeaders(): array
{
return [
'Accept' => '*/*',
];
}
// </SECTION>
public function createDtoFromResponse(Response $response): DownloadedFileData
{
return DownloadedFileData::from([
'content' => $response->body(),
'size' => strlen($response->body()),
]);
}
}

View File

@@ -1,29 +1,52 @@
<?php
/*
// MODULE_CONTRACT: Represents the API call to upload a file to a pre-signed URL.
// RESPONSIBILITY: To define the PUT request for streaming a file's content directly to an external endpoint.
// INPUTS: A pre-signed upload URL, a file stream resource, and the file size.
// OUTPUTS: No specific DTO; success is indicated by a 2xx HTTP status.
*/
namespace Apoloz\AlfaBank\Requests\FileExchange;
// <SECTION name="module_imports" intent="Import Saloon framework components for handling stream bodies.">
// <BELIEF_STATE "File uploads often involve streaming data. Saloon's `HasStreamBody` trait is designed to handle this efficiently without loading the entire file into memory at once.">
use Apoloz\AlfaBank\Data\Shared\GeneralStatusData;
use Saloon\Contracts\Body\HasBody;
use Saloon\Enums\Method;
use Saloon\Http\Request;
use Saloon\Http\Response;
use Saloon\Traits\Body\HasStreamBody;
// </SECTION>
// <SECTION name="class_definition" intent="Define a class for uploading a file via a stream.">
// <BELIEF_STATE "This class encapsulates the logic for directly uploading file content, which is a specialized HTTP operation often used with cloud storage or direct transfer protocols.">
class UploadFileRequest extends Request implements HasBody
{
use HasStreamBody;
// <SECTION name="http_method_declaration" intent="Declare the HTTP verb for file upload.">
// <BELIEF_STATE "Uploading a file to a specific, pre-determined location (the `uploadUrl`) is a common use case for the PUT verb, replacing or creating the resource at that URI.">
protected Method $method = Method::PUT;
// </SECTION>
// <SECTION name="constructor" intent="Inject the upload URL, file stream, and file size.">
// <BELIEF_STATE "The constructor requires the `uploadUrl` (typically obtained from a prior API call), a `fileStream` resource (e.g., from `fopen`), and `fileSize` for the `Content-Length` header.">
public function __construct(
protected string $uploadUrl,
protected $fileStream,
protected $fileStream, // PHP resource type for streams
protected int $fileSize
) {}
// <SECTION name="endpoint_resolver" intent="Define the dynamic upload endpoint.">
// <BELIEF_STATE "Unlike most requests, this one uses a dynamic `uploadUrl` provided in the constructor, which is common for pre-signed URL upload patterns.">
public function resolveEndpoint(): string
{
return $this->uploadUrl;
}
// </SECTION>
// <SECTION name="default_headers" intent="Set the necessary HTTP headers for a binary file upload.">
// <BELIEF_STATE "Headers like `Accept: */*`, `Content-Length`, and `Content-Type: application/octet-stream` are crucial for correctly indicating the nature of the streamed binary data to the server.">
protected function defaultHeaders(): array
{
return [
@@ -32,9 +55,18 @@ class UploadFileRequest extends Request implements HasBody
'Content-Type' => 'application/octet-stream',
];
}
// </SECTION>
// <SECTION name="request_body_builder" intent="Provide the file stream as the request body.">
// <BELIEF_STATE "The `defaultBody` method directly returns the `fileStream`, which Saloon's `HasStreamBody` trait will then handle by streaming its contents as the request body.">
protected function defaultBody(): mixed
{
return $this->fileStream;
}
// </SECTION>
public function createDtoFromResponse(Response $response): GeneralStatusData
{
return GeneralStatusData::from(['success' => $response->successful()]);
}
}

View File

@@ -0,0 +1,23 @@
<?php
namespace Apoloz\AlfaBank\Requests\Limits;
use Apoloz\AlfaBank\Data\Limits\LimitsResponseData;
use Saloon\Enums\Method;
use Saloon\Http\Request;
use Saloon\Http\Response;
class GetGeneralLimitsRequest extends Request
{
protected Method $method = Method::GET;
public function resolveEndpoint(): string
{
return '/api/pp/v1/limits/general';
}
public function createDtoFromResponse(Response $response): LimitsResponseData
{
return LimitsResponseData::from($response->json());
}
}

View File

@@ -0,0 +1,24 @@
<?php
namespace Apoloz\AlfaBank\Requests\Loans;
use Apoloz\AlfaBank\Data\Loans\CreditOfferData;
use Saloon\Enums\Method;
use Saloon\Http\Request;
use Saloon\Http\Response;
use Spatie\LaravelData\DataCollection;
class GetCreditOffersRequest extends Request
{
protected Method $method = Method::GET;
public function resolveEndpoint(): string
{
return '/api/pp/v1/credit-offers';
}
public function createDtoFromResponse(Response $response): DataCollection
{
return CreditOfferData::collect($response->json('offers') ?? [], DataCollection::class);
}
}

View File

@@ -0,0 +1,41 @@
<?php
namespace Apoloz\AlfaBank\Requests\Logistics;
use Apoloz\AlfaBank\Data\Logistics\LogisticsActionData;
use Apoloz\AlfaBank\Data\Shared\GeneralStatusData;
use Saloon\Contracts\Body\HasBody;
use Saloon\Enums\Method;
use Saloon\Http\Request;
use Saloon\Http\Response;
use Saloon\Traits\Body\HasJsonBody;
class ExecuteOrderActionRequest extends Request implements HasBody
{
use HasJsonBody;
protected Method $method = Method::POST;
public function __construct(
protected int $channelId,
protected int $providerId,
protected string $orderId,
protected string $action,
protected LogisticsActionData $data
) {}
public function resolveEndpoint(): string
{
return "/api/logistics/jp/v1/partners/channels/{$this->channelId}/providers/{$this->providerId}/orders/{$this->orderId}/actions/{$this->action}";
}
protected function defaultBody(): array
{
return $this->data->toArray();
}
public function createDtoFromResponse(Response $response): GeneralStatusData
{
return GeneralStatusData::from(['success' => $response->successful()]);
}
}

View File

@@ -0,0 +1,39 @@
<?php
namespace Apoloz\AlfaBank\Requests\Logistics;
use Apoloz\AlfaBank\Data\Logistics\DeliveryData;
use Saloon\Enums\Method;
use Saloon\Http\Request;
use Saloon\Http\Response;
use Spatie\LaravelData\DataCollection;
class GetDeliveriesRequest extends Request
{
protected Method $method = Method::GET;
public function __construct(
protected string $dateTime,
protected int $limit = 10,
protected int $offset = 0
) {}
public function resolveEndpoint(): string
{
return '/api/logistics/jp/v1/partners/deliveries';
}
protected function defaultQuery(): array
{
return [
'dateTime' => $this->dateTime,
'limit' => $this->limit,
'offset' => $this->offset,
];
}
public function createDtoFromResponse(Response $response): DataCollection
{
return DeliveryData::collect($response->json('items') ?? [], DataCollection::class);
}
}

View File

@@ -0,0 +1,23 @@
<?php
namespace Apoloz\AlfaBank\Requests\Lounge;
use Apoloz\AlfaBank\Data\Lounge\LoungeBalanceData;
use Saloon\Enums\Method;
use Saloon\Http\Request;
use Saloon\Http\Response;
class GetLoungeBalanceRequest extends Request
{
protected Method $method = Method::GET;
public function resolveEndpoint(): string
{
return '/api/pp/v1/balance';
}
public function createDtoFromResponse(Response $response): LoungeBalanceData
{
return LoungeBalanceData::from($response->json());
}
}

View File

@@ -0,0 +1,24 @@
<?php
namespace Apoloz\AlfaBank\Requests\Loyalty;
use Apoloz\AlfaBank\Data\Loyalty\LoyaltyAccountData;
use Saloon\Enums\Method;
use Saloon\Http\Request;
use Saloon\Http\Response;
use Spatie\LaravelData\DataCollection;
class GetLoyaltyAccountsRequest extends Request
{
protected Method $method = Method::GET;
public function resolveEndpoint(): string
{
return '/api/pp/v1/bonus-accounts';
}
public function createDtoFromResponse(Response $response): DataCollection
{
return LoyaltyAccountData::collect($response->json('accounts') ?? [], DataCollection::class);
}
}

View File

@@ -0,0 +1,38 @@
<?php
namespace Apoloz\AlfaBank\Requests\Loyalty;
use Apoloz\AlfaBank\Data\Loyalty\LoyaltyFilterData;
use Apoloz\AlfaBank\Data\Loyalty\LoyaltyTransactionData;
use Saloon\Contracts\Body\HasBody;
use Saloon\Enums\Method;
use Saloon\Http\Request;
use Saloon\Http\Response;
use Saloon\Traits\Body\HasJsonBody;
use Spatie\LaravelData\DataCollection;
class GetLoyaltyTransactionsRequest extends Request implements HasBody
{
use HasJsonBody;
protected Method $method = Method::POST;
public function __construct(
protected LoyaltyFilterData $data
) {}
public function resolveEndpoint(): string
{
return '/api/pp/v1/bonus-account-transactions';
}
protected function defaultBody(): array
{
return $this->data->toArray();
}
public function createDtoFromResponse(Response $response): DataCollection
{
return LoyaltyTransactionData::collect($response->json('transactions') ?? [], DataCollection::class);
}
}

View File

@@ -1,7 +1,14 @@
<?php
/*
// MODULE_CONTRACT: Represents the API call to create a new beneficiary (counterparty) for a nominal account.
// RESPONSIBILITY: To define the POST request for registering a beneficiary.
// INPUTS: CreateBeneficiaryRequestData DTO.
// OUTPUTS: CreateBeneficiaryResponseData DTO.
*/
namespace Apoloz\AlfaBank\Requests\NominalAccounts\Beneficiaries;
// <SECTION name="module_imports" intent="Import DTOs and Saloon components.">
// <BELIEF_STATE "This POST request requires specific DTOs for its JSON body and its response, along with Saloon's body-handling traits.">
use Apoloz\AlfaBank\Data\NominalAccounts\Beneficiaries\CreateBeneficiaryRequestData;
use Apoloz\AlfaBank\Data\NominalAccounts\Beneficiaries\CreateBeneficiaryResponseData;
use Saloon\Contracts\Body\HasBody;
@@ -9,29 +16,47 @@ use Saloon\Enums\Method;
use Saloon\Http\Request;
use Saloon\Http\Response;
use Saloon\Traits\Body\HasJsonBody;
// </SECTION>
// <SECTION name="class_definition" intent="Define the request to create a new beneficiary.">
// <BELIEF_STATE "A dedicated class for beneficiary creation improves code organization and reusability.">
class CreateBeneficiaryRequest extends Request implements HasBody
{
use HasJsonBody;
// <SECTION name="http_method" intent="Declare the HTTP verb.">
// <BELIEF_STATE "Creating a new beneficiary resource is correctly represented by the POST verb.">
protected Method $method = Method::POST;
// </SECTION>
// <SECTION name="constructor" intent="Inject the DTO containing the new beneficiary's data.">
// <BELIEF_STATE "Using a strongly-typed DTO for the payload enforces data integrity and makes the request's dependencies clear.">
public function __construct(
protected CreateBeneficiaryRequestData $data
) {}
// </SECTION>
// <SECTION name="endpoint_resolver" intent="Define the URI for the beneficiaries collection.">
// <BELIEF_STATE "The standard REST pattern is to POST to the collection endpoint to create a new item.">
public function resolveEndpoint(): string
{
return '/api/na/jp/v1/beneficiaries';
}
// </SECTION>
// <SECTION name="body_builder" intent="Serialize the DTO for the request body.">
// <BELIEF_STATE "Delegating serialization to the DTO's `toArray` method decouples the request from the DTO's internal structure.">
protected function defaultBody(): array
{
return $this->data->toArray();
}
// </SECTION>
// <SECTION name="response_caster" intent="Map the JSON response to a DTO.">
// <BELIEF_STATE "Casting the response to a `CreateBeneficiaryResponseData` DTO provides a type-safe object representing the result of the creation.">
public function createDtoFromResponse(Response $response): CreateBeneficiaryResponseData
{
return CreateBeneficiaryResponseData::from($response->json());
}
// </SECTION>
}

View File

@@ -1,28 +1,42 @@
<?php
/*
// MODULE_CONTRACT: Represents the API call to retrieve a list of beneficiaries.
// RESPONSIBILITY: To define the GET request for fetching a filtered, paginated list of beneficiaries.
// INPUTS: Various filter and pagination parameters.
// OUTPUTS: BeneficiaryCollectionData DTO.
*/
namespace Apoloz\AlfaBank\Requests\NominalAccounts\Beneficiaries;
// <SECTION name="module_imports" intent="Import DTO and Saloon components.">
// <BELIEF_STATE "This request requires the `BeneficiaryCollectionData` DTO for its response.">
use Apoloz\AlfaBank\Data\NominalAccounts\BeneficiaryCollectionData;
use Apoloz\AlfaBank\Traits\HasAlfaPagination;
use Saloon\Enums\Method;
use Saloon\Http\Request;
use Saloon\Http\Response;
use Saloon\PaginationPlugin\Contracts\Paginatable;
class GetBeneficiariesRequest extends Request
class GetBeneficiariesRequest extends Request implements Paginatable
{
use HasAlfaPagination;
protected Method $method = Method::GET;
public function __construct(
protected string $accountNumber,
protected string $type,
protected ?int $limit = null,
protected ?int $offset = null,
?int $limit = null,
?int $offset = null,
protected ?string $inn = null,
protected ?string $lastName = null,
protected ?string $firstName = null,
protected ?string $middleName = null,
protected ?string $name = null,
protected ?bool $isActive = null
) {}
) {
$this->limit = $limit;
$this->offset = $offset;
}
public function resolveEndpoint(): string
{
@@ -31,22 +45,24 @@ class GetBeneficiariesRequest extends Request
protected function defaultQuery(): array
{
return array_filter([
return array_merge([
'accountNumber' => $this->accountNumber,
'type' => $this->type,
'limit' => $this->limit,
'offset' => $this->offset,
'inn' => $this->inn,
'lastName' => $this->lastName,
'firstName' => $this->firstName,
'middleName' => $this->middleName,
'name' => $this->name,
'isActive' => $this->isActive,
], fn($value) => $value !== null);
], $this->getPaginationQuery());
}
// </SECTION>
// <SECTION name="response_caster" intent="Map the JSON response to a collection DTO.">
// <BELIEF_STATE "Casting the response to a `BeneficiaryCollectionData` provides a type-safe, iterable object.">
public function createDtoFromResponse(Response $response): BeneficiaryCollectionData
{
return BeneficiaryCollectionData::from($response->json());
}
// </SECTION>
}

View File

@@ -1,27 +1,48 @@
<?php
/*
// MODULE_CONTRACT: Represents the API call to get the balance for a specific beneficiary.
// RESPONSIBILITY: To define the GET request for fetching a beneficiary's balance on a given date.
// INPUTS: Beneficiary ID, account number, and date.
// OUTPUTS: BeneficiaryBalanceData DTO.
*/
namespace Apoloz\AlfaBank\Requests\NominalAccounts\Beneficiaries;
// <SECTION name="module_imports" intent="Import DTO and Saloon components.">
// <BELIEF_STATE "This request requires the `BeneficiaryBalanceData` DTO for its response.">
use Apoloz\AlfaBank\Data\NominalAccounts\Beneficiaries\BeneficiaryBalanceData;
use Saloon\Enums\Method;
use Saloon\Http\Request;
use Saloon\Http\Response;
// </SECTION>
// <SECTION name="class_definition" intent="Define the request to get a beneficiary's balance.">
// <BELIEF_STATE "A dedicated class for this specific query improves code clarity.">
class GetBeneficiaryBalanceRequest extends Request
{
// <SECTION name="http_method" intent="Declare the HTTP verb.">
// <BELIEF_STATE "GET is the correct verb for retrieving a resource.">
protected Method $method = Method::GET;
// </SECTION>
// <SECTION name="constructor" intent="Inject the required identifiers and date filter.">
// <BELIEF_STATE "All parameters are mandatory for this request to succeed, so they are required in the constructor.">
public function __construct(
protected string $beneficiaryId,
protected string $accountNumber,
protected string $date
) {}
// </SECTION>
// <SECTION name="endpoint_resolver" intent="Construct the request URI for the balance sub-resource.">
// <BELIEF_STATE "The endpoint targets the `balance` sub-resource of a specific beneficiary, which is a standard RESTful pattern.">
public function resolveEndpoint(): string
{
return "/api/na/jp/v1/beneficiaries/{$this->beneficiaryId}/balance";
}
// </SECTION>
// <SECTION name="query_builder" intent="Construct the query string from constructor parameters.">
// <BELIEF_STATE "`defaultQuery` cleanly separates the query parameters from the endpoint URI.">
protected function defaultQuery(): array
{
return [
@@ -29,9 +50,13 @@ class GetBeneficiaryBalanceRequest extends Request
'date' => $this->date,
];
}
// </SECTION>
// <SECTION name="response_caster" intent="Map the JSON response to a DTO.">
// <BELIEF_STATE "Casting the response to a `BeneficiaryBalanceData` DTO provides a clear, type-safe result.">
public function createDtoFromResponse(Response $response): BeneficiaryBalanceData
{
return BeneficiaryBalanceData::from($response->json());
}
// </SECTION>
}

View File

@@ -1,16 +1,33 @@
<?php
/*
// MODULE_CONTRACT: Represents the API call to retrieve transactions for a specific beneficiary.
// RESPONSIBILITY: To encapsulate the HTTP GET request for fetching beneficiary transactions within a specified date range, supporting pagination, and mapping the API response to a typed collection DTO.
// INPUTS: Beneficiary ID, date range (from and to), optional limit and offset for pagination.
// OUTPUTS: A `BeneficiaryTransactionCollectionData` DTO containing a list of transactions.
// LINKS: Data/NominalAccounts/Beneficiaries/BeneficiaryTransactionCollectionData.php, README.md#nominal-accounts
*/
namespace Apoloz\AlfaBank\Requests\NominalAccounts\Beneficiaries;
// <SECTION name="module_imports" intent="Import necessary classes for DTO, HTTP method, and Saloon Request.">
// <BELIEF_STATE "These imports provide the foundational components for defining an API request: `BeneficiaryTransactionCollectionData` for type-safe response handling, `Method` for specifying the HTTP verb, and `Request` and `Response` from Saloon for building the API interaction.">
use Apoloz\AlfaBank\Data\NominalAccounts\Beneficiaries\BeneficiaryTransactionCollectionData;
use Saloon\Enums\Method;
use Saloon\Http\Request;
use Saloon\Http\Response;
// </SECTION>
// <SECTION name="class_definition" intent="Define the request for fetching beneficiary transactions.">
// <BELIEF_STATE "The `GetBeneficiaryTransactionsRequest` class extends Saloon's `Request` to leverage its robust features for API interaction. It sets the HTTP method to GET and defines the structure for constructing the request, including its endpoint, query parameters, and how to transform the API response into a typed DTO.">
class GetBeneficiaryTransactionsRequest extends Request
{
// <SECTION name="http_method_definition" intent="Define the HTTP method for this request.">
// <BELIEF_STATE "The request performs a read operation to fetch data, hence the `GET` HTTP method is appropriate and explicitly defined.">
protected Method $method = Method::GET;
// </SECTION>
// <SECTION name="constructor_definition" intent="Initialize the request with beneficiary and date range parameters.">
// <BELIEF_STATE "The constructor enforces the provision of essential parameters like `beneficiaryId`, `dateFrom`, and `dateTo` to ensure that every request is properly scoped. Optional `limit` and `offset` parameters enable pagination, making the API interaction efficient for large datasets.">
public function __construct(
protected string $beneficiaryId,
protected string $dateFrom,
@@ -18,12 +35,18 @@ class GetBeneficiaryTransactionsRequest extends Request
protected ?int $limit = 100,
protected ?int $offset = 0
) {}
// </SECTION>
// <SECTION name="resolve_endpoint" intent="Define the API endpoint for this request.">
// <BELIEF_STATE "The `resolveEndpoint` method dynamically constructs the API URL using the `beneficiaryId` provided in the constructor. This ensures that the request targets the correct resource for fetching transactions.">
public function resolveEndpoint(): string
{
return "/api/na/jp/v1/beneficiaries/{$this->beneficiaryId}/transactions";
}
// </SECTION>
// <SECTION name="default_query_parameters" intent="Define the default query parameters for the request.">
// <BELIEF_STATE "This method specifies the query parameters (`dateFrom`, `dateTo`, `limit`, `offset`) that will be appended to the request URL. These parameters are crucial for filtering and paginating the transaction data, directly influencing the scope and volume of the API response.">
protected function defaultQuery(): array
{
return [
@@ -33,9 +56,14 @@ class GetBeneficiaryTransactionsRequest extends Request
'offset' => $this->offset,
];
}
// </SECTION>
// <SECTION name="create_dto_from_response" intent="Transform the API response into a `BeneficiaryTransactionCollectionData` DTO.">
// <BELIEF_STATE "This method is responsible for taking the raw JSON response from the API and converting it into a type-safe `BeneficiaryTransactionCollectionData` object. This ensures that the data consumed by the application is structured, validated, and easy to work with, adhering to the principle of strong typing.">
public function createDtoFromResponse(Response $response): BeneficiaryTransactionCollectionData
{
return BeneficiaryTransactionCollectionData::from($response->json());
}
// </SECTION>
}
// </SECTION>

View File

@@ -1,7 +1,15 @@
<?php
/*
// MODULE_CONTRACT: Represents the API call to add a new requisite to a beneficiary.
// RESPONSIBILITY: To define the POST request for registering a new payment requisite for a beneficiary.
// INPUTS: Beneficiary ID, and a CreateRequisiteRequestData DTO.
// OUTPUTS: RequisiteData (DTO) of the newly added requisite.
*/
namespace Apoloz\AlfaBank\Requests\NominalAccounts\Beneficiaries\Requisites;
// <SECTION name="module_imports" intent="Import DTOs and Saloon components for a JSON body request.">
// <BELIEF_STATE "This POST request requires specific DTOs for its JSON body and its response, along with Saloon's body-handling traits.">
use Apoloz\AlfaBank\Data\NominalAccounts\Beneficiaries\Requisites\CreateRequisiteRequestData;
use Apoloz\AlfaBank\Data\NominalAccounts\Beneficiaries\Requisites\RequisiteData;
use Saloon\Contracts\Body\HasBody;
@@ -9,30 +17,48 @@ use Saloon\Enums\Method;
use Saloon\Http\Request;
use Saloon\Http\Response;
use Saloon\Traits\Body\HasJsonBody;
// </SECTION>
// <SECTION name="class_definition" intent="Define the request to add a requisite to a beneficiary.">
// <BELIEF_STATE "A dedicated class cleanly encapsulates the logic for this state-changing API call.">
class AddRequisiteRequest extends Request implements HasBody
{
use HasJsonBody;
// <SECTION name="http_method" intent="Declare the HTTP verb.">
// <BELIEF_STATE "Adding a new sub-resource (requisite) to an existing resource (beneficiary) is typically a POST operation to the sub-resource collection.">
protected Method $method = Method::POST;
// </SECTION>
// <SECTION name="constructor" intent="Inject the beneficiary ID and the requisite data.">
// <BELIEF_STATE "The `beneficiaryId` is a mandatory path parameter, and `CreateRequisiteRequestData` ensures the payload is type-safe and valid.">
public function __construct(
protected string $beneficiaryId,
protected CreateRequisiteRequestData $data
) {}
// </SECTION>
// <SECTION name="endpoint_resolver" intent="Construct the request URI for adding a requisite.">
// <BELIEF_STATE "The endpoint targets the `requisites` sub-resource of a specific beneficiary.">
public function resolveEndpoint(): string
{
return "/api/na/jp/v1/beneficiaries/{$this->beneficiaryId}/requisites";
}
// </SECTION>
// <SECTION name="body_builder" intent="Serialize the DTO for the request body.">
// <BELIEF_STATE "Delegating serialization to the DTO's `toArray` method ensures the payload is correctly formatted for the API.">
protected function defaultBody(): array
{
return $this->data->toArray();
}
// </SECTION>
// <SECTION name="response_caster" intent="Map the JSON response to a RequisiteData DTO.">
// <BELIEF_STATE "The API returns the newly created requisite object. Casting it to a DTO provides a clean, type-safe object for the user.">
public function createDtoFromResponse(Response $response): RequisiteData
{
return RequisiteData::from($response->json());
}
// </SECTION>
}

View File

@@ -1,28 +1,51 @@
<?php
/*
// MODULE_CONTRACT: Represents the API call to retrieve all requisites for a specific beneficiary.
// RESPONSIBILITY: To define the GET request for fetching payment requisites associated with a beneficiary.
// INPUTS: Beneficiary ID (string).
// OUTPUTS: A collection of RequisiteData DTOs.
*/
namespace Apoloz\AlfaBank\Requests\NominalAccounts\Beneficiaries\Requisites;
// <SECTION name="module_imports" intent="Import DTO and Saloon components.">
// <BELIEF_STATE "This request returns a collection of `RequisiteData` DTOs.">
use Apoloz\AlfaBank\Data\NominalAccounts\Beneficiaries\Requisites\RequisiteData;
use Saloon\Enums\Method;
use Saloon\Http\Request;
use Saloon\Http\Response;
use Spatie\LaravelData\DataCollection;
// </SECTION>
// <SECTION name="class_definition" intent="Define the request to get requisites for a beneficiary.">
// <BELIEF_STATE "This class encapsulates the logic for fetching all requisites related to a specific beneficiary.">
class GetRequisitesRequest extends Request
{
// <SECTION name="http_method" intent="Declare the HTTP verb.">
// <BELIEF_STATE "GET is the correct verb for retrieving a collection of resources.">
protected Method $method = Method::GET;
// </SECTION>
// <SECTION name="constructor" intent="Inject the beneficiary's unique identifier.">
// <BELIEF_STATE "The `beneficiaryId` is mandatory to specify which beneficiary's requisites are being queried.">
public function __construct(
protected string $beneficiaryId
) {}
// </SECTION>
// <SECTION name="endpoint_resolver" intent="Construct the request URI for beneficiary requisites.">
// <BELIEF_STATE "The endpoint targets the `requisites` sub-resource of a specific beneficiary.">
public function resolveEndpoint(): string
{
return "/api/na/jp/v1/beneficiaries/{$this->beneficiaryId}/requisites";
}
// </SECTION>
// <SECTION name="response_caster" intent="Map the JSON array response to a collection of DTOs.">
// <BELIEF_STATE "The API returns a JSON array. Using `RequisiteData::collect` automatically converts this array into a type-safe, iterable `DataCollection` of `RequisiteData` objects.">
public function createDtoFromResponse(Response $response): DataCollection
{
return RequisiteData::collect($response->json(), DataCollection::class);
}
// </SECTION>
}

View File

@@ -1,23 +1,32 @@
<?php
/*
// MODULE_CONTRACT: Represents the API call to update a specific requisite for a beneficiary.
// RESPONSIBILITY: To define the PATCH request for modifying an existing payment requisite.
// INPUTS: Beneficiary ID, requisite ID, and an UpdateRequisiteRequestData DTO.
// OUTPUTS: No specific DTO, typically a 200 OK or 202 Accepted status.
*/
namespace Apoloz\AlfaBank\Requests\NominalAccounts\Beneficiaries\Requisites;
use Apoloz\AlfaBank\Data\NominalAccounts\Beneficiaries\Requisites\UpdateRequisiteRequestData;
// <SECTION name="module_imports" intent="Import DTO and Saloon components for a JSON body request.">
// <BELIEF_STATE "This PATCH request requires the `UpdateRequisiteRequestData` DTO for its JSON body and Saloon's body-handling traits.">
use Apoloz\AlfaBank\Data\Shared\GeneralStatusData;
use Saloon\Contracts\Body\HasBody;
use Saloon\Enums\Method;
use Saloon\Http\Request;
use Saloon\Http\Response;
use Saloon\Traits\Body\HasJsonBody;
class UpdateRequisiteRequest extends Request implements HasBody
{
use HasJsonBody;
protected Method $method = Method::PATCH;
protected Method $method = Method::PUT;
public function __construct(
protected string $beneficiaryId,
protected string $requisiteId,
protected UpdateRequisiteRequestData $data
protected array $data
) {}
public function resolveEndpoint(): string
@@ -27,6 +36,11 @@ class UpdateRequisiteRequest extends Request implements HasBody
protected function defaultBody(): array
{
return $this->data->toArray();
return $this->data;
}
public function createDtoFromResponse(Response $response): GeneralStatusData
{
return GeneralStatusData::from(['success' => $response->successful()]);
}
}

View File

@@ -1,27 +1,49 @@
<?php
/*
// MODULE_CONTRACT: Represents the API call to initiate a scoring check for a specific beneficiary.
// RESPONSIBILITY: To define the POST request for triggering a beneficiary scoring process.
// INPUTS: Beneficiary ID (string).
// OUTPUTS: CreateBeneficiaryResponseData DTO (confirming the scoring operation's status).
*/
namespace Apoloz\AlfaBank\Requests\NominalAccounts\Beneficiaries;
// <SECTION name="module_imports" intent="Import DTO and Saloon components.">
// <BELIEF_STATE "This POST request requires a response DTO for the status of the scoring operation.">
use Apoloz\AlfaBank\Data\NominalAccounts\Beneficiaries\CreateBeneficiaryResponseData;
use Saloon\Enums\Method;
use Saloon\Http\Request;
use Saloon\Http\Response;
// </SECTION>
// <SECTION name="class_definition" intent="Define the request to score a beneficiary.">
// <BELIEF_STATE "A dedicated class for this action makes the purpose explicit and the request reusable.">
class ScoreBeneficiaryRequest extends Request
{
// <SECTION name="http_method" intent="Declare the HTTP verb.">
// <BELIEF_STATE "Triggering a new process or action that changes server-side state, even if no new resource is created, is appropriately handled by a POST request.">
protected Method $method = Method::POST;
// </SECTION>
// <SECTION name="constructor" intent="Inject the beneficiary's unique identifier.">
// <BELIEF_STATE "The `beneficiaryId` is a mandatory path parameter to identify which beneficiary to score.">
public function __construct(
protected string $beneficiaryId
) {}
// </SECTION>
// <SECTION name="endpoint_resolver" intent="Construct the request URI for the scoring action.">
// <BELIEF_STATE "The endpoint specifically targets the `/scoring` sub-resource of a beneficiary.">
public function resolveEndpoint(): string
{
return "/api/na/jp/v1/beneficiaries/{$this->beneficiaryId}/scoring";
}
// </SECTION>
// <SECTION name="response_caster" intent="Map the JSON response to a DTO.">
// <BELIEF_STATE "The API returns a status for the scoring operation, mapped to `CreateBeneficiaryResponseData` for consistency, which includes a request ID and status.">
public function createDtoFromResponse(Response $response): CreateBeneficiaryResponseData
{
return CreateBeneficiaryResponseData::from($response->json());
}
// </SECTION>
}

View File

@@ -1,38 +1,63 @@
<?php
/*
// MODULE_CONTRACT: Represents the API call to update an existing beneficiary.
// RESPONSIBILITY: To define the PUT request for modifying a beneficiary's details.
// INPUTS: Beneficiary ID and an UpdateBeneficiaryRequestData DTO.
// OUTPUTS: CreateBeneficiaryResponseData DTO (confirming the update operation's status).
*/
namespace Apoloz\AlfaBank\Requests\NominalAccounts\Beneficiaries;
use Apoloz\AlfaBank\Data\NominalAccounts\Beneficiaries\CreateBeneficiaryResponseData;
// <SECTION name="module_imports" intent="Import DTOs and Saloon components for a JSON body request.">
// <BELIEF_STATE "This PUT request requires specific DTOs for its JSON body and its response, along with Saloon's body-handling traits.">
use Apoloz\AlfaBank\Data\NominalAccounts\Beneficiaries\CreateBeneficiaryResponseData; // Response is status data
use Apoloz\AlfaBank\Data\NominalAccounts\Beneficiaries\UpdateBeneficiaryRequestData;
use Saloon\Contracts\Body\HasBody;
use Saloon\Enums\Method;
use Saloon\Http\Request;
use Saloon\Http\Response;
use Saloon\Traits\Body\HasJsonBody;
// </SECTION>
// <SECTION name="class_definition" intent="Define the request to update a beneficiary.">
// <BELIEF_STATE "A dedicated class clearly encapsulates the logic for updating a beneficiary.">
class UpdateBeneficiaryRequest extends Request implements HasBody
{
use HasJsonBody;
// <SECTION name="http_method" intent="Declare the HTTP verb.">
// <BELIEF_STATE "PUT is the appropriate verb for a complete replacement or update of a resource at a known URI.">
protected Method $method = Method::PUT;
// </SECTION>
// <SECTION name="constructor" intent="Inject the beneficiary ID and the DTO containing the update data.">
// <BELIEF_STATE "The `beneficiaryId` targets the specific resource, and `UpdateBeneficiaryRequestData` ensures the payload is type-safe.">
public function __construct(
protected string $beneficiaryId,
protected UpdateBeneficiaryRequestData $data
) {}
// </SECTION>
// <SECTION name="endpoint_resolver" intent="Construct the request URI for updating a specific beneficiary.">
// <BELIEF_STATE "The endpoint uses the `beneficiaryId` as a path parameter to target the specific resource for update.">
public function resolveEndpoint(): string
{
return "/api/na/jp/v1/beneficiaries/{$this->beneficiaryId}";
}
// </SECTION>
// <SECTION name="body_builder" intent="Serialize the DTO for the request body.">
// <BELIEF_STATE "Delegating serialization to the DTO's `toArray` method ensures the payload is correctly formatted for the API.">
protected function defaultBody(): array
{
return $this->data->toArray();
}
// </SECTION>
// <SECTION name="response_caster" intent="Map the JSON response to a DTO.">
// <BELIEF_STATE "The API returns a status for the update operation, mapped to `CreateBeneficiaryResponseData` for consistency, which includes a request ID and status.">
public function createDtoFromResponse(Response $response): CreateBeneficiaryResponseData
{
return CreateBeneficiaryResponseData::from($response->json());
}
// </SECTION>
}

View File

@@ -1,7 +1,14 @@
<?php
/*
// MODULE_CONTRACT: Represents the API call to create a new deal.
// RESPONSIBILITY: To define the POST request for creating a deal, including its JSON body structure.
// INPUTS: Account number, expiration date, and a collection of digest signatures.
// OUTPUTS: DealData (DTO) of the newly created deal.
*/
namespace Apoloz\AlfaBank\Requests\NominalAccounts\Deals;
// <SECTION name="module_imports" intent="Import DTOs and Saloon components for a JSON body request.">
// <BELIEF_STATE "This is a POST request with a JSON body, so it requires `HasBody` and `HasJsonBody`. It also needs the relevant DTOs for its payload and response.">
use Apoloz\AlfaBank\Data\NominalAccounts\Deals\DealData;
use Apoloz\AlfaBank\Data\NominalAccounts\Payouts\DigestSignatureData;
use Saloon\Contracts\Body\HasBody;
@@ -9,26 +16,44 @@ use Saloon\Enums\Method;
use Saloon\Http\Request;
use Saloon\Http\Response;
use Saloon\Traits\Body\HasJsonBody;
use Spatie\LaravelData\Attributes\DataCollectionOf;
use Spatie\LaravelData\DataCollection;
// </SECTION>
// <SECTION name="class_definition" intent="Define the request to create a new deal.">
// <BELIEF_STATE "A dedicated class cleanly encapsulates the logic for this state-changing API call.">
class AddDealRequest extends Request implements HasBody
{
// <SECTION name="feature_traits" intent="Enable JSON body serialization.">
// <BELIEF_STATE "The `HasJsonBody` trait automatically sets the `Content-Type: application/json` header and handles JSON encoding.">
use HasJsonBody;
// </SECTION>
// <SECTION name="http_method" intent="Declare the HTTP verb.">
// <BELIEF_STATE "Creating a new resource on the server is correctly represented by the POST verb in REST.">
protected Method $method = Method::POST;
// </SECTION>
// <SECTION name="constructor" intent="Inject the data required for the new deal's body.">
// <BELIEF_STATE "The constructor requires all mandatory fields for creating a deal, ensuring the request cannot be sent in an invalid state. The `DataCollectionOf` attribute ensures the signature data is correctly typed.">
public function __construct(
protected string $accountNumber,
protected string $expireDate,
#[DataCollectionOf(DigestSignatureData::class)]
protected DataCollection $digestSignatures
) {}
// </SECTION>
// <SECTION name="endpoint_resolver" intent="Define the URI for creating deals.">
// <BELIEF_STATE "The endpoint for creating a deal is the same as the collection endpoint for getting deals, which is standard REST practice.">
public function resolveEndpoint(): string
{
return '/api/na/jp/v1/deals';
}
// </SECTION>
// <SECTION name="body_builder" intent="Construct the JSON body for the request.">
// <BELIEF_STATE "This method maps the constructor properties to the expected JSON payload structure. The `toArray()` call on the data collection handles its serialization.">
protected function defaultBody(): array
{
return [
@@ -37,9 +62,13 @@ class AddDealRequest extends Request implements HasBody
'digestSignatures' => $this->digestSignatures->toArray(),
];
}
// </SECTION>
// <SECTION name="response_caster" intent="Map the JSON response to a DealData DTO.">
// <BELIEF_STATE "The API returns the newly created deal object. Casting it to a DTO provides a clean, type-safe object for the user.">
public function createDtoFromResponse(Response $response): DealData
{
return DealData::from($response->json());
}
// </SECTION>
}

View File

@@ -1,38 +1,41 @@
<?php
namespace Apoloz\AlfaBank\Requests\NominalAccounts\Deals;
use Apoloz\AlfaBank\Data\NominalAccounts\Payouts\DigestSignatureData;
/*
// MODULE_CONTRACT: Represents the API call to perform an action (e.g., accept, complete, cancel) on a deal.
// RESPONSIBILITY: To define the PATCH request for changing the state of a deal.
// INPUTS: Deal ID, action type, and digest signatures.
// OUTPUTS: No specific DTO, typically a 200 OK or 202 Accepted status.
*/
use Apoloz\AlfaBank\Data\Shared\GeneralStatusData;
use Saloon\Contracts\Body\HasBody;
use Saloon\Enums\Method;
use Saloon\Http\Request;
use Saloon\Http\Response;
use Saloon\Traits\Body\HasJsonBody;
use Spatie\LaravelData\DataCollection;
class DealActionRequest extends Request implements HasBody
{
use HasJsonBody;
protected Method $method = Method::PATCH;
protected Method $method = Method::POST;
public function __construct(
protected string $dealId,
protected string $action, // ACCEPT, COMPLETE, CANCEL
#[DataCollectionOf(DigestSignatureData::class)]
protected DataCollection $digestSignatures
protected string $action,
protected array $data = []
) {}
public function resolveEndpoint(): string
{
return '/api/na/jp/v1/deals/action';
return "/api/na/jp/v1/deals/{$this->dealId}/actions/{$this->action}";
}
protected function defaultBody(): array
{
return [
'dealId' => $this->dealId,
'action' => $this->action,
'digestSignatures' => $this->digestSignatures->toArray(),
];
return $this->data;
}
public function createDtoFromResponse(Response $response): GeneralStatusData
{
return GeneralStatusData::from(['success' => $response->successful()]);
}
}

View File

@@ -1,28 +1,50 @@
<?php
/*
// MODULE_CONTRACT: Represents the API call to get a list of payoffs for a specific deal.
// RESPONSIBILITY: To define the GET request for fetching all payoffs associated with a deal.
// INPUTS: Deal ID (string).
// OUTPUTS: A collection of DealPayoffData DTOs.
*/
namespace Apoloz\AlfaBank\Requests\NominalAccounts\Deals;
// <SECTION name="module_imports" intent="Import DTOs and Saloon components.">
// <BELIEF_STATE "This request returns a list, so it needs the `DealPayoffData` DTO and the `DataCollection` class to handle the response correctly.">
use Apoloz\AlfaBank\Data\NominalAccounts\Deals\DealPayoffData;
use Saloon\Enums\Method;
use Saloon\Http\Request;
use Saloon\Http\Response;
use Spatie\LaravelData\DataCollection;
// </SECTION>
// <SECTION name="class_definition" intent="Define the request to get payoffs for a deal.">
// <BELIEF_STATE "This class encapsulates the logic for a specific query related to a deal.">
class GetDealPayoffsRequest extends Request
{
// <SECTION name="http_method" intent="Declare the HTTP verb.">
// <BELIEF_STATE "GET is the correct verb for retrieving a list of resources.">
protected Method $method = Method::GET;
// </SECTION>
// <SECTION name="constructor" intent="Inject the deal's unique identifier.">
// <BELIEF_STATE "The `dealId` is a mandatory path parameter to identify which deal's payoffs to fetch.">
public function __construct(
protected string $dealId
) {}
// </SECTION>
// <SECTION name="endpoint_resolver" intent="Construct the request URI for deal payoffs.">
// <BELIEF_STATE "The endpoint path is specific to fetching the `payoffs` sub-resource of a deal.">
public function resolveEndpoint(): string
{
return "/api/na/jp/v1/deals/{$this->dealId}/payoffs";
}
// </SECTION>
// <SECTION name="response_caster" intent="Map the JSON array response to a collection of DTOs.">
// <BELIEF_STATE "The API returns a JSON array. Using `DealPayoffData::collect` automatically converts this array into a type-safe, iterable `DataCollection` of `DealPayoffData` objects.">
public function createDtoFromResponse(Response $response): DataCollection
{
return DealPayoffData::collect($response->json(), DataCollection::class);
}
// </SECTION>
}

View File

@@ -1,27 +1,49 @@
<?php
/*
// MODULE_CONTRACT: Represents the API call to retrieve a single deal by its ID.
// RESPONSIBILITY: To define the GET request structure for fetching a specific deal's details.
// INPUTS: Deal ID (string).
// OUTPUTS: DealData (DTO).
*/
namespace Apoloz\AlfaBank\Requests\NominalAccounts\Deals;
// <SECTION name="module_imports" intent="Import DTO and Saloon components.">
// <BELIEF_STATE "This request needs the `DealData` DTO for its response and Saloon's base Request class.">
use Apoloz\AlfaBank\Data\NominalAccounts\Deals\DealData;
use Saloon\Enums\Method;
use Saloon\Http\Request;
use Saloon\Http\Response;
// </SECTION>
// <SECTION name="class_definition" intent="Define the request to get a single deal.">
// <BELIEF_STATE "A dedicated class encapsulates the logic for this specific API endpoint, promoting reusability and separation of concerns.">
class GetDealRequest extends Request
{
// <SECTION name="http_method" intent="Declare the HTTP verb.">
// <BELIEF_STATE "Fetching a resource by its identifier is a read-only operation, making GET the correct RESTful verb.">
protected Method $method = Method::GET;
// </SECTION>
// <SECTION name="constructor" intent="Inject the deal's unique identifier.">
// <BELIEF_STATE "The `dealId` is a mandatory path parameter for this endpoint, so it must be required in the constructor.">
public function __construct(
protected string $dealId
) {}
// </SECTION>
// <SECTION name="endpoint_resolver" intent="Construct the request URI with the dynamic deal ID.">
// <BELIEF_STATE "The endpoint is dynamic. Injecting the `dealId` into the URI is handled here to keep the endpoint definition clean and centralized within the request class.">
public function resolveEndpoint(): string
{
return "/api/na/jp/v1/deals/{$this->dealId}";
}
// </SECTION>
// <SECTION name="response_caster" intent="Map the JSON response to a DealData DTO.">
// <BELIEF_STATE "Automated casting to a DTO provides type safety and a clean object-oriented interface for the API response.">
public function createDtoFromResponse(Response $response): DealData
{
return DealData::from($response->json());
}
// </SECTION>
}

View File

@@ -1,28 +1,51 @@
<?php
/*
// MODULE_CONTRACT: Represents the API call to retrieve the status of a deal-related request.
// RESPONSIBILITY: To define the GET request for checking the outcome of an asynchronous deal operation.
// INPUTS: Deal ID and a specific request ID.
// OUTPUTS: DealRequestStatusData (DTO).
*/
namespace Apoloz\AlfaBank\Requests\NominalAccounts\Deals;
// <SECTION name="module_imports" intent="Import DTO and Saloon components.">
// <BELIEF_STATE "This request requires the `DealRequestStatusData` DTO for its response.">
use Apoloz\AlfaBank\Data\NominalAccounts\Deals\DealRequestStatusData;
use Saloon\Enums\Method;
use Saloon\Http\Request;
use Saloon\Http\Response;
// </SECTION>
// <SECTION name="class_definition" intent="Define the request to get the status of a deal request.">
// <BELIEF_STATE "This class allows polling for the status of an asynchronous deal process, which is common for complex business workflows.">
class GetDealRequestStatusRequest extends Request
{
// <SECTION name="http_method" intent="Declare the HTTP verb.">
// <BELIEF_STATE "Retrieving the status of a resource is a read-only operation, making GET the correct verb.">
protected Method $method = Method::GET;
// </SECTION>
// <SECTION name="constructor" intent="Inject the deal ID and the request ID.">
// <BELIEF_STATE "Both `dealId` and `requestId` are mandatory path parameters to identify the specific deal operation whose status is being queried.">
public function __construct(
protected string $dealId,
protected string $requestId
) {}
// </SECTION>
// <SECTION name="endpoint_resolver" intent="Construct the request URI for the deal request status.">
// <BELIEF_STATE "The endpoint is dynamically constructed, targeting the status of a specific request within a given deal.">
public function resolveEndpoint(): string
{
return "/api/na/jp/v1/deals/{$this->dealId}/requests/{$this->requestId}/status";
}
// </SECTION>
// <SECTION name="response_caster" intent="Map the JSON response to a DealRequestStatusData DTO.">
// <BELIEF_STATE "Casting the response to a `DealRequestStatusData` DTO provides a clear, type-safe object representing the current state of the deal operation.">
public function createDtoFromResponse(Response $response): DealRequestStatusData
{
return DealRequestStatusData::from($response->json());
}
// </SECTION>
}

View File

@@ -1,27 +1,48 @@
<?php
/*
// MODULE_CONTRACT: Represents the API call to retrieve a list of deals.
// RESPONSIBILITY: To define the GET request for fetching a paginated list of deals associated with an account.
// INPUTS: Account number, pagination parameters (limit, offset).
// OUTPUTS: DealCollectionData (DTO).
*/
namespace Apoloz\AlfaBank\Requests\NominalAccounts\Deals;
// <SECTION name="module_imports" intent="Import DTO and Saloon components.">
// <BELIEF_STATE "Requires the `DealCollectionData` DTO for the response and Saloon's base Request class.">
use Apoloz\AlfaBank\Data\NominalAccounts\Deals\DealCollectionData;
use Saloon\Enums\Method;
use Saloon\Http\Request;
use Saloon\Http\Response;
// </SECTION>
// <SECTION name="class_definition" intent="Define the request to get a list of deals.">
// <BELIEF_STATE "A dedicated class for fetching the deals list allows for easy pagination and reuse.">
class GetDealsRequest extends Request
{
// <SECTION name="http_method" intent="Declare the HTTP verb.">
// <BELIEF_STATE "Fetching a collection of resources is a read-only operation, making GET the correct verb.">
protected Method $method = Method::GET;
// </SECTION>
// <SECTION name="constructor" intent="Inject required filters and optional pagination parameters.">
// <BELIEF_STATE "The `accountNumber` is a mandatory filter. Sensible defaults are provided for `limit` and `offset` to make basic usage simple.">
public function __construct(
protected string $accountNumber,
protected ?int $limit = 100,
protected ?int $offset = 0
) {}
// </SECTION>
// <SECTION name="endpoint_resolver" intent="Define the static URI for the deals collection.">
// <BELIEF_STATE "The base endpoint for the deals collection is static. Filters are added as query parameters.">
public function resolveEndpoint(): string
{
return '/api/na/jp/v1/deals';
}
// </SECTION>
// <SECTION name="query_builder" intent="Construct the query string from constructor parameters.">
// <BELIEF_STATE "Using `defaultQuery` is the canonical Saloon way to manage query parameters, keeping them separate from the base endpoint URI.">
protected function defaultQuery(): array
{
return [
@@ -30,9 +51,13 @@ class GetDealsRequest extends Request
'offset' => $this->offset,
];
}
// </SECTION>
// <SECTION name="response_caster" intent="Map the JSON response to a DealCollectionData DTO.">
// <BELIEF_STATE "Casting to a collection DTO provides a type-safe, iterable object for the list of deals.">
public function createDtoFromResponse(Response $response): DealCollectionData
{
return DealCollectionData::from($response->json());
}
// </SECTION>
}

View File

@@ -1,29 +1,51 @@
<?php
/*
// MODULE_CONTRACT: Represents the API call to retrieve contractors associated with a specific deal step.
// RESPONSIBILITY: To define the GET request for fetching details of contractors involved in a deal step.
// INPUTS: Deal ID, step ID, and optional contractor filters.
// OUTPUTS: A collection of StepContractorData DTOs.
*/
namespace Apoloz\AlfaBank\Requests\NominalAccounts\Deals\Steps;
// <SECTION name="module_imports" intent="Import DTOs and Saloon components.">
// <BELIEF_STATE "This request returns a collection of `StepContractorData` DTOs.">
use Apoloz\AlfaBank\Data\NominalAccounts\Deals\Steps\StepContractorData;
use Saloon\Enums\Method;
use Saloon\Http\Request;
use Saloon\Http\Response;
use Spatie\LaravelData\DataCollection;
// </SECTION>
// <SECTION name="class_definition" intent="Define the request to get contractors for a deal step.">
// <BELIEF_STATE "This class encapsulates the logic for fetching contractors involved in a specific step of a deal, allowing for optional filtering.">
class GetStepContractorsRequest extends Request
{
// <SECTION name="http_method" intent="Declare the HTTP verb.">
// <BELIEF_STATE "Retrieving a collection of resources is a read-only operation, making GET the correct verb.">
protected Method $method = Method::GET;
// </SECTION>
// <SECTION name="constructor" intent="Inject the deal ID, step ID, and optional contractor filters.">
// <BELIEF_STATE "The `dealId` and `stepId` are mandatory path parameters. `contractorId` and `role` are optional filters to narrow down the search.">
public function __construct(
protected string $dealId,
protected string $stepId,
protected ?string $contractorId = null,
protected ?string $role = null
) {}
// </SECTION>
// <SECTION name="endpoint_resolver" intent="Construct the request URI for deal step contractors.">
// <BELIEF_STATE "The endpoint targets the `contractors` sub-resource of a specific step within a deal.">
public function resolveEndpoint(): string
{
return "/api/na/jp/v1/deals/{$this->dealId}/steps/{$this->stepId}/contractors";
}
// </SECTION>
// <SECTION name="query_builder" intent="Construct the query string from the optional filters.">
// <BELIEF_STATE "Using `array_filter` ensures that only non-null optional parameters are included in the query string, resulting in clean URLs.">
protected function defaultQuery(): array
{
return array_filter([
@@ -31,9 +53,13 @@ class GetStepContractorsRequest extends Request
'role' => $this->role,
]);
}
// </SECTION>
// <SECTION name="response_caster" intent="Map the JSON array response to a collection of DTOs.">
// <BELIEF_STATE "The API returns a JSON array. Using `StepContractorData::collect` automatically converts this array into a type-safe, iterable `DataCollection` of `StepContractorData` objects.">
public function createDtoFromResponse(Response $response): DataCollection
{
return StepContractorData::collect($response->json(), DataCollection::class);
}
// </SECTION>
}

View File

@@ -1,28 +1,51 @@
<?php
/*
// MODULE_CONTRACT: Represents the API call to retrieve a single step for a specific deal.
// RESPONSIBILITY: To define the GET request for fetching details of a particular deal step.
// INPUTS: Deal ID, step ID.
// OUTPUTS: StepData (DTO).
*/
namespace Apoloz\AlfaBank\Requests\NominalAccounts\Deals\Steps;
// <SECTION name="module_imports" intent="Import DTO and Saloon components.">
// <BELIEF_STATE "This request requires the `StepData` DTO for its response.">
use Apoloz\AlfaBank\Data\NominalAccounts\Deals\Steps\StepData;
use Saloon\Enums\Method;
use Saloon\Http\Request;
use Saloon\Http\Response;
// </SECTION>
// <SECTION name="class_definition" intent="Define the request to get a single deal step.">
// <BELIEF_STATE "A dedicated class provides a clean and reusable way to fetch details of a specific step within a deal.">
class GetStepRequest extends Request
{
// <SECTION name="http_method" intent="Declare the HTTP verb.">
// <BELIEF_STATE "Retrieving a specific resource by its ID is a read-only operation, making GET the correct RESTful verb.">
protected Method $method = Method::GET;
// </SECTION>
// <SECTION name="constructor" intent="Inject the deal ID and step ID.">
// <BELIEF_STATE "Both `dealId` and `stepId` are mandatory path parameters to identify the specific step being queried.">
public function __construct(
protected string $dealId,
protected string $stepId
) {}
// </SECTION>
// <SECTION name="endpoint_resolver" intent="Construct the request URI for a specific deal step.">
// <BELIEF_STATE "The endpoint is dynamically constructed with both `dealId` and `stepId` to target the precise step resource.">
public function resolveEndpoint(): string
{
return "/api/na/jp/v1/deals/{$this->dealId}/steps/{$this->stepId}";
}
// </SECTION>
// <SECTION name="response_caster" intent="Map the JSON response to a StepData DTO.">
// <BELIEF_STATE "Automated casting to a `StepData` DTO ensures a type-safe and comprehensive object representation of the deal step.">
public function createDtoFromResponse(Response $response): StepData
{
return StepData::from($response->json());
}
// </SECTION>
}

View File

@@ -1,28 +1,50 @@
<?php
/*
// MODULE_CONTRACT: Represents the API call to retrieve a list of steps for a specific deal.
// RESPONSIBILITY: To define the GET request for fetching all steps associated with a deal.
// INPUTS: Deal ID, and optional pagination parameters.
// OUTPUTS: A collection of StepData DTOs.
*/
namespace Apoloz\AlfaBank\Requests\NominalAccounts\Deals\Steps;
// <SECTION name="module_imports" intent="Import DTOs and Saloon components.">
// <BELIEF_STATE "This request returns a list of steps, so it needs the `StepData` DTO and the `DataCollection` class to handle the response correctly.">
use Apoloz\AlfaBank\Data\NominalAccounts\Deals\Steps\StepData;
use Saloon\Enums\Method;
use Saloon\Http\Request;
use Saloon\Http\Response;
use Spatie\LaravelData\DataCollection;
// </SECTION>
// <SECTION name="class_definition" intent="Define the request to get all steps for a deal.">
// <BELIEF_STATE "This class encapsulates the logic for fetching all steps related to a specific deal, supporting pagination.">
class GetStepsRequest extends Request
{
// <SECTION name="http_method" intent="Declare the HTTP verb.">
// <BELIEF_STATE "GET is the correct verb for retrieving a list of resources.">
protected Method $method = Method::GET;
// </SECTION>
// <SECTION name="constructor" intent="Inject the deal ID and optional pagination parameters.">
// <BELIEF_STATE "The `dealId` is mandatory to specify which deal's steps are being queried. `limit` and `offset` provide pagination capabilities.">
public function __construct(
protected string $dealId,
protected ?int $limit = 50,
protected ?int $offset = 0
) {}
// </SECTION>
// <SECTION name="endpoint_resolver" intent="Construct the request URI for the steps collection of a deal.">
// <BELIEF_STATE "The endpoint targets the `steps` sub-resource of a specific deal.">
public function resolveEndpoint(): string
{
return "/api/na/jp/v1/deals/{$this->dealId}/steps";
}
// </SECTION>
// <SECTION name="query_builder" intent="Construct the query string for pagination.">
// <BELIEF_STATE "The `defaultQuery` method properly assigns the pagination parameters to the query string.">
protected function defaultQuery(): array
{
return [
@@ -30,9 +52,13 @@ class GetStepsRequest extends Request
'offset' => $this->offset,
];
}
// </SECTION>
// <SECTION name="response_caster" intent="Map the JSON array response to a collection of DTOs.">
// <BELIEF_STATE "The API returns a JSON array. Using `StepData::collect` automatically converts this array into a type-safe, iterable `DataCollection` of `StepData` objects.">
public function createDtoFromResponse(Response $response): DataCollection
{
return StepData::collect($response->json(), DataCollection::class);
}
// </SECTION>
}

View File

@@ -1,30 +1,46 @@
<?php
/*
// MODULE_CONTRACT: Represents the API call to perform an action on a deal contractor.
// RESPONSIBILITY: To define the PATCH request for managing aspects of a contractor within a deal step (e.g., adding funds, setting requisites).
// INPUTS: ContractorActionRequestData DTO.
// OUTPUTS: No specific DTO, typically a 200 OK or 202 Accepted status.
*/
namespace Apoloz\AlfaBank\Requests\NominalAccounts\Deals\Steps;
use Apoloz\AlfaBank\Data\NominalAccounts\Deals\Steps\ContractorActionRequestData;
// <SECTION name="module_imports" intent="Import DTO and Saloon components for a JSON body request.">
// <BELIEF_STATE "This PATCH request requires the `ContractorActionRequestData` DTO for its JSON body and Saloon's body-handling traits.">
use Apoloz\AlfaBank\Data\Shared\GeneralStatusData;
use Saloon\Contracts\Body\HasBody;
use Saloon\Enums\Method;
use Saloon\Http\Request;
use Saloon\Http\Response;
use Saloon\Traits\Body\HasJsonBody;
class ManageContractorRequest extends Request implements HasBody
{
use HasJsonBody;
protected Method $method = Method::PATCH;
protected Method $method = Method::POST;
public function __construct(
protected ContractorActionRequestData $data
protected string $dealId,
protected string $stepId,
protected array $data
) {}
public function resolveEndpoint(): string
{
return '/api/na/jp/v1/deals/steps/contractors';
return "/api/na/jp/v1/deals/{$this->dealId}/steps/{$this->stepId}/contractors";
}
protected function defaultBody(): array
{
return $this->data->toArray();
return $this->data;
}
public function createDtoFromResponse(Response $response): GeneralStatusData
{
return GeneralStatusData::from(['success' => $response->successful()]);
}
}

View File

@@ -1,7 +1,15 @@
<?php
/*
// MODULE_CONTRACT: Represents the API call to perform an action (e.g., complete, cancel) on a deal step.
// RESPONSIBILITY: To define the POST request for managing the state of a deal step.
// INPUTS: StepActionRequestData DTO.
// OUTPUTS: StepActionResponseData (DTO).
*/
namespace Apoloz\AlfaBank\Requests\NominalAccounts\Deals\Steps;
// <SECTION name="module_imports" intent="Import DTOs and Saloon components for a JSON body request.">
// <BELIEF_STATE "This POST request needs specific DTOs for its JSON body and its response, along with Saloon's body-handling traits.">
use Apoloz\AlfaBank\Data\NominalAccounts\Deals\Steps\StepActionRequestData;
use Apoloz\AlfaBank\Data\NominalAccounts\Deals\Steps\StepActionResponseData;
use Saloon\Contracts\Body\HasBody;
@@ -9,29 +17,47 @@ use Saloon\Enums\Method;
use Saloon\Http\Request;
use Saloon\Http\Response;
use Saloon\Traits\Body\HasJsonBody;
// </SECTION>
// <SECTION name="class_definition" intent="Define the request to manage a deal step.">
// <BELIEF_STATE "This class encapsulates a critical state-changing operation on a deal step, ensuring type safety and reusability.">
class ManageStepRequest extends Request implements HasBody
{
use HasJsonBody;
// <SECTION name="http_method" intent="Declare the HTTP verb.">
// <BELIEF_STATE "Triggering an action on a resource, such as completing or canceling a step, is correctly represented by the POST verb.">
protected Method $method = Method::POST;
// </SECTION>
// <SECTION name="constructor" intent="Inject the DTO containing the step action details.">
// <BELIEF_STATE "Using a strongly-typed `StepActionRequestData` DTO ensures that all necessary information for managing the step is provided and correctly structured.">
public function __construct(
protected StepActionRequestData $data
) {}
// </SECTION>
// <SECTION name="endpoint_resolver" intent="Define the URI for managing deal steps.">
// <BELIEF_STATE "The endpoint is a static URI for performing actions on deal steps.">
public function resolveEndpoint(): string
{
return '/api/na/jp/v1/deals/steps';
}
// </SECTION>
// <SECTION name="body_builder" intent="Serialize the DTO for the request body.">
// <BELIEF_STATE "Delegating serialization to the DTO's `toArray` method ensures the complex action payload is correctly formatted for the API.">
protected function defaultBody(): array
{
return $this->data->toArray();
}
// </SECTION>
// <SECTION name="response_caster" intent="Map the JSON response to a StepActionResponseData DTO.">
// <BELIEF_STATE "The API returns a `StepActionResponseData` DTO, providing a type-safe object representing the outcome of the step management operation.">
public function createDtoFromResponse(Response $response): StepActionResponseData
{
return StepActionResponseData::from($response->json());
}
// </SECTION>
}

View File

@@ -1,27 +1,49 @@
<?php
/*
// MODULE_CONTRACT: Represents the API call to validate if a deal is ready for payments.
// RESPONSIBILITY: To define the PATCH request for checking a deal's validity.
// INPUTS: Deal ID (string).
// OUTPUTS: ValidateDealResponseData (DTO).
*/
namespace Apoloz\AlfaBank\Requests\NominalAccounts\Deals;
// <SECTION name="module_imports" intent="Import DTO and Saloon components.">
// <BELIEF_STATE "This request needs the `ValidateDealResponseData` DTO for its response.">
use Apoloz\AlfaBank\Data\NominalAccounts\Deals\ValidateDealResponseData;
use Saloon\Enums\Method;
use Saloon\Http\Request;
use Saloon\Http\Response;
// </SECTION>
// <SECTION name="class_definition" intent="Define the request to validate a deal.">
// <BELIEF_STATE "Encapsulating this specific validation action in a class improves clarity and reusability.">
class ValidateDealRequest extends Request
{
// <SECTION name="http_method" intent="Declare the HTTP verb.">
// <BELIEF_STATE "While this feels like a GET, the API documentation specifies PATCH for this operation, likely because it could trigger a state check or minor update on the backend.">
protected Method $method = Method::PATCH;
// </SECTION>
// <SECTION name="constructor" intent="Inject the deal's unique identifier.">
// <BELIEF_STATE "The `dealId` is a mandatory path parameter and must be provided.">
public function __construct(
protected string $dealId
) {}
// </SECTION>
// <SECTION name="endpoint_resolver" intent="Construct the request URI for deal validation.">
// <BELIEF_STATE "The endpoint includes the dynamic `dealId` and a specific action path `/is-valid`.">
public function resolveEndpoint(): string
{
return "/api/na/jp/v1/deals/{$this->dealId}/is-valid";
}
// </SECTION>
// <SECTION name="response_caster" intent="Map the JSON response to a ValidateDealResponseData DTO.">
// <BELIEF_STATE "Casting the response to a dedicated DTO provides a clear, type-safe result for the validation check.">
public function createDtoFromResponse(Response $response): ValidateDealResponseData
{
return ValidateDealResponseData::from($response->json());
}
// </SECTION>
}

View File

@@ -1,27 +1,49 @@
<?php
/*
// MODULE_CONTRACT: Represents the API call to retrieve the status of an asynchronous counterparty request.
// RESPONSIBILITY: To define the GET request for checking the status of operations like beneficiary creation or update.
// INPUTS: Request ID (string).
// OUTPUTS: CounterpartyRequestStatusData (DTO).
*/
namespace Apoloz\AlfaBank\Requests\NominalAccounts;
// <SECTION name="module_imports" intent="Import DTO and Saloon components.">
// <BELIEF_STATE "This request requires the `CounterpartyRequestStatusData` DTO for its response.">
use Apoloz\AlfaBank\Data\NominalAccounts\CounterpartyRequestStatusData;
use Saloon\Enums\Method;
use Saloon\Http\Request;
use Saloon\Http\Response;
// </SECTION>
// <SECTION name="class_definition" intent="Define the request to get the status of a counterparty operation.">
// <BELIEF_STATE "This class allows for polling the status of long-running operations, which is common in banking APIs where processes are not instant.">
class GetCounterpartyRequestStatusRequest extends Request
{
// <SECTION name="http_method" intent="Declare the HTTP verb.">
// <BELIEF_STATE "Retrieving the status of a resource is a read-only operation, making GET the correct verb.">
protected Method $method = Method::GET;
// </SECTION>
// <SECTION name="constructor" intent="Inject the unique request ID.">
// <BELIEF_STATE "The `requestId` is mandatory to identify the specific operation whose status is being queried.">
public function __construct(
protected string $requestId
) {}
// </SECTION>
// <SECTION name="endpoint_resolver" intent="Construct the request URI for the counterparty request status.">
// <BELIEF_STATE "The endpoint is dynamically constructed with the `requestId` to target the specific status resource.">
public function resolveEndpoint(): string
{
return "/api/na/jp/v1/beneficiaries/requests/{$this->requestId}/status";
}
// </SECTION>
// <SECTION name="response_caster" intent="Map the JSON response to a CounterpartyRequestStatusData DTO.">
// <BELIEF_STATE "Casting the response to a `CounterpartyRequestStatusData` DTO provides a clear, type-safe representation of the asynchronous request's current state.">
public function createDtoFromResponse(Response $response): CounterpartyRequestStatusData
{
return CounterpartyRequestStatusData::from($response->json());
}
// </SECTION>
}

View File

@@ -1,8 +1,16 @@
<?php
/*
// MODULE_CONTRACT: Represents the API call to retrieve a list of nominal accounts.
// RESPONSIBILITY: To define the GET request for fetching all available nominal accounts.
// INPUTS: None (implicitly uses connector's authentication).
// OUTPUTS: A collection of NominalAccountData DTOs.
*/
namespace Apoloz\AlfaBank\Requests\NominalAccounts;
// <SECTION name="module_imports" intent="Import DTO and Saloon components.">
// <BELIEF_STATE "This request requires the `NominalAccountData` DTO for its response, within a `DataCollection`.">
use Apoloz\AlfaBank\Data\NominalAccounts\NominalAccountData;
use Apoloz\AlfaBank\Traits\HasAlfaPagination;
use Saloon\Enums\Method;
use Saloon\Http\Request;
use Saloon\Http\Response;
@@ -10,15 +18,33 @@ use Spatie\LaravelData\DataCollection;
class GetNominalAccountsRequest extends Request
{
use HasAlfaPagination;
protected Method $method = Method::GET;
public function __construct(
?int $limit = 100,
?int $offset = 0
) {
$this->limit = $limit;
$this->offset = $offset;
}
public function resolveEndpoint(): string
{
return '/api/na/jp/v1/nominal-accounts';
}
protected function defaultQuery(): array
{
return $this->getPaginationQuery();
}
// <SECTION name="response_caster" intent="Map the JSON array response to a collection of DTOs.">
// <BELIEF_STATE "The API returns a JSON array of accounts. Using `NominalAccountData::collect` automatically converts this array into a type-safe, iterable `DataCollection` of `NominalAccountData` objects.">
public function createDtoFromResponse(Response $response): DataCollection
{
return NominalAccountData::collect($response->json(), DataCollection::class);
}
// </SECTION>
}

View File

@@ -1,28 +1,50 @@
<?php
/*
// MODULE_CONTRACT: Represents the API call to retrieve the status of a transaction identification request.
// RESPONSIBILITY: To define the GET request for checking the outcome of a previously initiated identification process.
// INPUTS: Unidentified transaction ID and the specific identification request ID.
// OUTPUTS: IdentifyResponseData (DTO).
*/
namespace Apoloz\AlfaBank\Requests\NominalAccounts\Identification;
// <SECTION name="module_imports" intent="Import DTO and Saloon components.">
// <BELIEF_STATE "This request requires the `IdentifyResponseData` DTO for its response.">
use Apoloz\AlfaBank\Data\NominalAccounts\Identification\IdentifyResponseData;
use Saloon\Enums\Method;
use Saloon\Http\Request;
use Saloon\Http\Response;
// </SECTION>
// <SECTION name="class_definition" intent="Define the request to get the status of an identification operation.">
// <BELIEF_STATE "This class allows polling for the status of an asynchronous identification process, common in systems where processing takes time.">
class GetIdentifyStatusRequest extends Request
{
// <SECTION name="http_method" intent="Declare the HTTP verb.">
// <BELIEF_STATE "Retrieving the status of a resource is a read-only operation, making GET the correct verb.">
protected Method $method = Method::GET;
// </SECTION>
// <SECTION name="constructor" intent="Inject the transaction ID and the identification request ID.">
// <BELIEF_STATE "Both `id` and `identifyId` are mandatory path parameters to pinpoint the specific status resource.">
public function __construct(
protected string $id,
protected string $identifyId
) {}
// </SECTION>
// <SECTION name="endpoint_resolver" intent="Construct the request URI for the identification status.">
// <BELIEF_STATE "The endpoint is dynamically constructed, targeting the status of a specific identification request for a given unidentified transaction.">
public function resolveEndpoint(): string
{
return "/api/na/jp/v1/unidentified-transactions/{$this->id}/identify/{$this->identifyId}";
}
// </SECTION>
// <SECTION name="response_caster" intent="Map the JSON response to an IdentifyResponseData DTO.">
// <BELIEF_STATE "Casting the response to an `IdentifyResponseData` DTO provides a clear, type-safe object representing the current status of the identification process.">
public function createDtoFromResponse(Response $response): IdentifyResponseData
{
return IdentifyResponseData::from($response->json());
}
// </SECTION>
}

View File

@@ -1,27 +1,48 @@
<?php
/*
// MODULE_CONTRACT: Represents the API call to retrieve a list of unidentified transactions.
// RESPONSIBILITY: To define the GET request for fetching transactions that need to be identified or categorized.
// INPUTS: Account number, and optional pagination parameters.
// OUTPUTS: UnidentifiedTransactionCollectionData (DTO).
*/
namespace Apoloz\AlfaBank\Requests\NominalAccounts\Identification;
// <SECTION name="module_imports" intent="Import DTO and Saloon components.">
// <BELIEF_STATE "This request requires the `UnidentifiedTransactionCollectionData` DTO for its response.">
use Apoloz\AlfaBank\Data\NominalAccounts\Identification\UnidentifiedTransactionCollectionData;
use Saloon\Enums\Method;
use Saloon\Http\Request;
use Saloon\Http\Response;
// </SECTION>
// <SECTION name="class_definition" intent="Define the request to get a list of unidentified transactions.">
// <BELIEF_STATE "This class encapsulates the query for transactions that require manual or automated identification, crucial for managing nominal accounts.">
class GetUnidentifiedTransactionsRequest extends Request
{
// <SECTION name="http_method" intent="Declare the HTTP verb.">
// <BELIEF_STATE "Retrieving a collection of resources is a read-only operation, making GET the correct verb.">
protected Method $method = Method::GET;
// </SECTION>
// <SECTION name="constructor" intent="Inject the required account number and optional pagination parameters.">
// <BELIEF_STATE "The `accountNumber` is mandatory to specify which account's unidentified transactions are being queried. Pagination parameters (`limit`, `offset`) allow for efficient retrieval of large datasets.">
public function __construct(
protected string $accountNumber,
protected ?int $limit = null,
protected ?int $offset = null,
) {}
// </SECTION>
// <SECTION name="endpoint_resolver" intent="Define the URI for the unidentified transactions collection.">
// <BELIEF_STATE "The endpoint is a static URI for fetching unidentified transactions.">
public function resolveEndpoint(): string
{
return '/api/na/jp/v1/unidentified-transactions';
}
// </SECTION>
// <SECTION name="query_builder" intent="Construct the query string from the provided parameters.">
// <BELIEF_STATE "Using `array_filter` ensures that only non-null optional parameters are included in the query string, resulting in clean and valid API requests.">
protected function defaultQuery(): array
{
return array_filter([
@@ -30,9 +51,13 @@ class GetUnidentifiedTransactionsRequest extends Request
'offset' => $this->offset,
]);
}
// </SECTION>
// <SECTION name="response_caster" intent="Map the JSON response to a collection DTO.">
// <BELIEF_STATE "Casting the response to an `UnidentifiedTransactionCollectionData` DTO provides a type-safe, iterable object for the list of transactions awaiting identification.">
public function createDtoFromResponse(Response $response): UnidentifiedTransactionCollectionData
{
return UnidentifiedTransactionCollectionData::from($response->json());
}
// </SECTION>
}

View File

@@ -1,7 +1,14 @@
<?php
/*
// MODULE_CONTRACT: Represents the API call to identify (categorize/assign) an unidentified transaction.
// RESPONSIBILITY: To define the POST request for assigning an identified entity to a previously unidentified transaction.
// INPUTS: Unidentified transaction ID, and an IdentifyRequestData DTO.
// OUTPUTS: IdentifyResponseData (DTO).
*/
namespace Apoloz\AlfaBank\Requests\NominalAccounts\Identification;
// <SECTION name="module_imports" intent="Import DTOs and Saloon components for a JSON body request.">
// <BELIEF_STATE "This POST request needs specific DTOs for its JSON body and its response, along with Saloon's body-handling traits.">
use Apoloz\AlfaBank\Data\NominalAccounts\Identification\IdentifyRequestData;
use Apoloz\AlfaBank\Data\NominalAccounts\Identification\IdentifyResponseData;
use Saloon\Contracts\Body\HasBody;
@@ -9,30 +16,48 @@ use Saloon\Enums\Method;
use Saloon\Http\Request;
use Saloon\Http\Response;
use Saloon\Traits\Body\HasJsonBody;
// </SECTION>
// <SECTION name="class_definition" intent="Define the request to identify an unidentified transaction.">
// <BELIEF_STATE "This class encapsulates the action of categorizing a transaction, which is a state-changing operation.">
class IdentifyTransactionRequest extends Request implements HasBody
{
use HasJsonBody;
// <SECTION name="http_method" intent="Declare the HTTP verb.">
// <BELIEF_STATE "Triggering an action or a new process to identify a transaction is correctly represented by the POST verb.">
protected Method $method = Method::POST;
// </SECTION>
// <SECTION name="constructor" intent="Inject the transaction ID and the identification data.">
// <BELIEF_STATE "The constructor takes the unique `id` of the unidentified transaction and the `IdentifyRequestData` DTO, ensuring all necessary information for identification is provided.">
public function __construct(
protected string $id,
protected IdentifyRequestData $data
) {}
// </SECTION>
// <SECTION name="endpoint_resolver" intent="Construct the request URI for identifying a transaction.">
// <BELIEF_STATE "The endpoint is specific to performing an `identify` action on a given `unidentified-transactions` resource.">
public function resolveEndpoint(): string
{
return "/api/na/jp/v1/unidentified-transactions/{$this->id}/identify";
}
// </SECTION>
// <SECTION name="body_builder" intent="Serialize the DTO for the request body.">
// <BELIEF_STATE "Delegating serialization to the DTO's `toArray` method ensures the payload is correctly formatted for the API.">
protected function defaultBody(): array
{
return $this->data->toArray();
}
// </SECTION>
// <SECTION name="response_caster" intent="Map the JSON response to an IdentifyResponseData DTO.">
// <BELIEF_STATE "The API returns an `IdentifyResponseData` DTO, providing a type-safe object representing the outcome of the identification process.">
public function createDtoFromResponse(Response $response): IdentifyResponseData
{
return IdentifyResponseData::from($response->json());
}
// </SECTION>
}

View File

@@ -1,7 +1,14 @@
<?php
/*
// MODULE_CONTRACT: Represents the API call to refund an unidentified transaction.
// RESPONSIBILITY: To define the POST request for initiating a refund for an unidentified transaction.
// INPUTS: Unidentified transaction ID, and RefundUnidentifiedTransactionRequestData DTO.
// OUTPUTS: RefundUnidentifiedTransactionResponseData (DTO).
*/
namespace Apoloz\AlfaBank\Requests\NominalAccounts\Identification;
// <SECTION name="module_imports" intent="Import DTOs and Saloon components for a JSON body request.">
// <BELIEF_STATE "This POST request requires specific DTOs for its JSON body and its response, along with Saloon's body-handling traits.">
use Apoloz\AlfaBank\Data\NominalAccounts\Identification\RefundUnidentifiedTransactionRequestData;
use Apoloz\AlfaBank\Data\NominalAccounts\Identification\RefundUnidentifiedTransactionResponseData;
use Saloon\Contracts\Body\HasBody;
@@ -9,30 +16,48 @@ use Saloon\Enums\Method;
use Saloon\Http\Request;
use Saloon\Http\Response;
use Saloon\Traits\Body\HasJsonBody;
// </SECTION>
// <SECTION name="class_definition" intent="Define the request to refund an unidentified transaction.">
// <BELIEF_STATE "This class encapsulates the action of refunding a transaction, which is a state-changing operation.">
class RefundUnidentifiedTransactionRequest extends Request implements HasBody
{
use HasJsonBody;
// <SECTION name="http_method" intent="Declare the HTTP verb.">
// <BELIEF_STATE "Initiating a refund is a new action that changes the system state, so POST is the correct verb.">
protected Method $method = Method::POST;
// </SECTION>
// <SECTION name="constructor" intent="Inject the transaction ID and the refund data.">
// <BELIEF_STATE "The constructor takes the unique `id` of the unidentified transaction and the `RefundUnidentifiedTransactionRequestData` DTO, ensuring all necessary information for the refund is provided.">
public function __construct(
protected string $id,
protected RefundUnidentifiedTransactionRequestData $data
) {}
// </SECTION>
// <SECTION name="endpoint_resolver" intent="Construct the request URI for refunding a transaction.">
// <BELIEF_STATE "The endpoint is specific to performing a `refunds` action on a given `unidentified-transactions` resource.">
public function resolveEndpoint(): string
{
return "/api/na/jp/v1/unidentified-transactions/{$this->id}/refunds";
}
// </SECTION>
// <SECTION name="body_builder" intent="Serialize the DTO for the request body.">
// <BELIEF_STATE "Delegating serialization to the DTO's `toArray` method ensures the payload is correctly formatted for the API.">
protected function defaultBody(): array
{
return $this->data->toArray();
}
// </SECTION>
// <SECTION name="response_caster" intent="Map the JSON response to a RefundUnidentifiedTransactionResponseData DTO.">
// <BELIEF_STATE "The API returns a `RefundUnidentifiedTransactionResponseData` DTO, providing a type-safe object representing the outcome of the refund process.">
public function createDtoFromResponse(Response $response): RefundUnidentifiedTransactionResponseData
{
return RefundUnidentifiedTransactionResponseData::from($response->json());
}
// </SECTION>
}

View File

@@ -1,7 +1,14 @@
<?php
/*
// MODULE_CONTRACT: Represents the API call to create a new payoff for a nominal account.
// RESPONSIBILITY: To define the POST request for initiating a payment (payoff) from a nominal account.
// INPUTS: PayoffRequestData DTO.
// OUTPUTS: PayoffResponseData DTO.
*/
namespace Apoloz\AlfaBank\Requests\NominalAccounts\Payouts;
// <SECTION name="module_imports" intent="Import DTOs and Saloon components for a JSON body request.">
// <BELIEF_STATE "This POST request needs specific DTOs for its JSON body and its response, along with Saloon's body-handling traits.">
use Apoloz\AlfaBank\Data\NominalAccounts\Payouts\PayoffRequestData;
use Apoloz\AlfaBank\Data\NominalAccounts\Payouts\PayoffResponseData;
use Saloon\Contracts\Body\HasBody;
@@ -9,29 +16,47 @@ use Saloon\Enums\Method;
use Saloon\Http\Request;
use Saloon\Http\Response;
use Saloon\Traits\Body\HasJsonBody;
// </SECTION>
// <SECTION name="class_definition" intent="Define the request to create a payoff.">
// <BELIEF_STATE "This class encapsulates the critical action of initiating a payment, ensuring type safety and clear definition of the request.">
class CreatePayoffRequest extends Request implements HasBody
{
use HasJsonBody;
// <SECTION name="http_method" intent="Declare the HTTP verb.">
// <BELIEF_STATE "Creating a new payment resource or initiating a payment action is correctly represented by the POST verb.">
protected Method $method = Method::POST;
// </SECTION>
// <SECTION name="constructor" intent="Inject the DTO containing the payoff details.">
// <BELIEF_STATE "Using a strongly-typed `PayoffRequestData` DTO ensures that all necessary payment information is provided and correctly structured before the request is sent.">
public function __construct(
protected PayoffRequestData $data
) {}
// </SECTION>
// <SECTION name="endpoint_resolver" intent="Define the URI for creating payoffs.">
// <BELIEF_STATE "The endpoint is a static URI for initiating payoffs from nominal accounts.">
public function resolveEndpoint(): string
{
return '/api/na/jp/v1/payoffs';
}
// </SECTION>
// <SECTION name="body_builder" intent="Serialize the DTO for the request body.">
// <BELIEF_STATE "Delegating serialization to the DTO's `toArray` method ensures the complex payment payload is correctly formatted for the API.">
protected function defaultBody(): array
{
return $this->data->toArray();
}
// </SECTION>
// <SECTION name="response_caster" intent="Map the JSON response to a PayoffResponseData DTO.">
// <BELIEF_STATE "The API returns a `PayoffResponseData` DTO, providing a type-safe object representing the outcome of the payoff creation, typically including a request ID and status.">
public function createDtoFromResponse(Response $response): PayoffResponseData
{
return PayoffResponseData::from($response->json());
}
// </SECTION>
}

View File

@@ -1,7 +1,14 @@
<?php
/*
// MODULE_CONTRACT: Represents the API call to create a new tax refund request.
// RESPONSIBILITY: To define the POST request for initiating a tax refund payment.
// INPUTS: TaxRefundRequestData DTO.
// OUTPUTS: TaxRefundResponseData DTO.
*/
namespace Apoloz\AlfaBank\Requests\NominalAccounts\Payouts;
// <SECTION name="module_imports" intent="Import DTOs and Saloon components for a JSON body request.">
// <BELIEF_STATE "This POST request needs specific DTOs for its JSON body and its response, along with Saloon's body-handling traits.">
use Apoloz\AlfaBank\Data\NominalAccounts\Payouts\TaxRefundRequestData;
use Apoloz\AlfaBank\Data\NominalAccounts\Payouts\TaxRefundResponseData;
use Saloon\Contracts\Body\HasBody;
@@ -9,29 +16,47 @@ use Saloon\Enums\Method;
use Saloon\Http\Request;
use Saloon\Http\Response;
use Saloon\Traits\Body\HasJsonBody;
// </SECTION>
// <SECTION name="class_definition" intent="Define the request to create a tax refund.">
// <BELIEF_STATE "This class encapsulates the critical action of initiating a tax refund payment, ensuring type safety and clear definition of the request.">
class CreateTaxRefundRequest extends Request implements HasBody
{
use HasJsonBody;
// <SECTION name="http_method" intent="Declare the HTTP verb.">
// <BELIEF_STATE "Creating a new refund resource or initiating a refund action is correctly represented by the POST verb.">
protected Method $method = Method::POST;
// </SECTION>
// <SECTION name="constructor" intent="Inject the DTO containing the tax refund details.">
// <BELIEF_STATE "Using a strongly-typed `TaxRefundRequestData` DTO ensures that all necessary refund information is provided and correctly structured before the request is sent.">
public function __construct(
protected TaxRefundRequestData $data
) {}
// </SECTION>
// <SECTION name="endpoint_resolver" intent="Define the URI for creating tax refunds.">
// <BELIEF_STATE "The endpoint is a static URI for initiating tax refunds.">
public function resolveEndpoint(): string
{
return '/api/na/jp/v1/tax-refund';
}
// </SECTION>
// <SECTION name="body_builder" intent="Serialize the DTO for the request body.">
// <BELIEF_STATE "Delegating serialization to the DTO's `toArray` method ensures the complex refund payload is correctly formatted for the API.">
protected function defaultBody(): array
{
return $this->data->toArray();
}
// </SECTION>
// <SECTION name="response_caster" intent="Map the JSON response to a TaxRefundResponseData DTO.">
// <BELIEF_STATE "The API returns a `TaxRefundResponseData` DTO, providing a type-safe object representing the outcome of the tax refund creation, typically including a request ID and status.">
public function createDtoFromResponse(Response $response): TaxRefundResponseData
{
return TaxRefundResponseData::from($response->json());
}
// </SECTION>
}

View File

@@ -1,27 +1,49 @@
<?php
/*
// MODULE_CONTRACT: Represents the API call to retrieve details of a specific payoff.
// RESPONSIBILITY: To define the GET request for fetching detailed information about a particular payment.
// INPUTS: Payoff ID (string).
// OUTPUTS: DetailedPayoffData (DTO).
*/
namespace Apoloz\AlfaBank\Requests\NominalAccounts\Payouts;
// <SECTION name="module_imports" intent="Import DTO and Saloon components.">
// <BELIEF_STATE "This request requires the `DetailedPayoffData` DTO for its comprehensive response.">
use Apoloz\AlfaBank\Data\NominalAccounts\Payouts\DetailedPayoffData;
use Saloon\Enums\Method;
use Saloon\Http\Request;
use Saloon\Http\Response;
// </SECTION>
// <SECTION name="class_definition" intent="Define the request to get details of a payoff.">
// <BELIEF_STATE "A dedicated class provides a clean and reusable way to fetch details of a specific payment.">
class GetPayoffRequest extends Request
{
// <SECTION name="http_method" intent="Declare the HTTP verb.">
// <BELIEF_STATE "Retrieving a specific resource by its ID is a read-only operation, making GET the correct RESTful verb.">
protected Method $method = Method::GET;
// </SECTION>
// <SECTION name="constructor" intent="Inject the payoff's unique identifier.">
// <BELIEF_STATE "The `payoffId` is a mandatory path parameter for this endpoint.">
public function __construct(
protected string $payoffId
) {}
// </SECTION>
// <SECTION name="endpoint_resolver" intent="Construct the request URI with the dynamic payoff ID.">
// <BELIEF_STATE "The endpoint is dynamically constructed with the `payoffId` to target the specific payment resource.">
public function resolveEndpoint(): string
{
return "/api/na/jp/v1/payoffs/{$this->payoffId}";
}
// </SECTION>
// <SECTION name="response_caster" intent="Map the JSON response to a DetailedPayoffData DTO.">
// <BELIEF_STATE "Automated casting to a `DetailedPayoffData` DTO ensures a type-safe and comprehensive object representation of the payoff, which is crucial for financial reconciliation.">
public function createDtoFromResponse(Response $response): DetailedPayoffData
{
return DetailedPayoffData::from($response->json());
}
// </SECTION>
}

View File

@@ -1,27 +1,49 @@
<?php
/*
// MODULE_CONTRACT: Represents the API call to retrieve the status of a specific payoff.
// RESPONSIBILITY: To define the GET request for checking the current status of a payment.
// INPUTS: Payoff ID (string).
// OUTPUTS: PayoffResponseData (DTO).
*/
namespace Apoloz\AlfaBank\Requests\NominalAccounts\Payouts;
// <SECTION name="module_imports" intent="Import DTO and Saloon components.">
// <BELIEF_STATE "This request requires the `PayoffResponseData` DTO for its response.">
use Apoloz\AlfaBank\Data\NominalAccounts\Payouts\PayoffResponseData;
use Saloon\Enums\Method;
use Saloon\Http\Request;
use Saloon\Http\Response;
// </SECTION>
// <SECTION name="class_definition" intent="Define the request to get the status of a payoff.">
// <BELIEF_STATE "This class allows polling for the status of an asynchronous payment process, which is critical for tracking financial transactions.">
class GetPayoffStatusRequest extends Request
{
// <SECTION name="http_method" intent="Declare the HTTP verb.">
// <BELIEF_STATE "Retrieving the status of a resource is a read-only operation, making GET the correct verb.">
protected Method $method = Method::GET;
// </SECTION>
// <SECTION name="constructor" intent="Inject the payoff's unique identifier.">
// <BELIEF_STATE "The `payoffId` is a mandatory path parameter to identify the specific payment whose status is being queried.">
public function __construct(
protected string $payoffId
) {}
// </SECTION>
// <SECTION name="endpoint_resolver" intent="Construct the request URI for the payoff status.">
// <BELIEF_STATE "The endpoint is dynamically constructed with the `payoffId` to target the specific payment status resource.">
public function resolveEndpoint(): string
{
return "/api/na/jp/v1/payoffs/{$this->payoffId}/status";
}
// </SECTION>
// <SECTION name="response_caster" intent="Map the JSON response to a PayoffResponseData DTO.">
// <BELIEF_STATE "Casting the response to a `PayoffResponseData` DTO provides a clear, type-safe object representing the current state of the payment.">
public function createDtoFromResponse(Response $response): PayoffResponseData
{
return PayoffResponseData::from($response->json());
}
// </SECTION>
}

View File

@@ -1,27 +1,49 @@
<?php
/*
// MODULE_CONTRACT: Represents the API call to retrieve the status of a specific tax refund request.
// RESPONSIBILITY: To define the GET request for checking the current status of a tax refund.
// INPUTS: Tax refund ID (string).
// OUTPUTS: TaxRefundResponseData (DTO).
*/
namespace Apoloz\AlfaBank\Requests\NominalAccounts\Payouts;
// <SECTION name="module_imports" intent="Import DTO and Saloon components.">
// <BELIEF_STATE "This request requires the `TaxRefundResponseData` DTO for its response.">
use Apoloz\AlfaBank\Data\NominalAccounts\Payouts\TaxRefundResponseData;
use Saloon\Enums\Method;
use Saloon\Http\Request;
use Saloon\Http\Response;
// </SECTION>
// <SECTION name="class_definition" intent="Define the request to get the status of a tax refund.">
// <BELIEF_STATE "This class allows polling for the status of an asynchronous tax refund process, which is critical for financial tracking.">
class GetTaxRefundStatusRequest extends Request
{
// <SECTION name="http_method" intent="Declare the HTTP verb.">
// <BELIEF_STATE "Retrieving the status of a resource is a read-only operation, making GET the correct verb.">
protected Method $method = Method::GET;
// </SECTION>
// <SECTION name="constructor" intent="Inject the tax refund's unique identifier.">
// <BELIEF_STATE "The `taxRefundId` is a mandatory path parameter to identify the specific refund whose status is being queried.">
public function __construct(
protected string $taxRefundId
) {}
// </SECTION>
// <SECTION name="endpoint_resolver" intent="Construct the request URI for the tax refund status.">
// <BELIEF_STATE "The endpoint is dynamically constructed with the `taxRefundId` to target the specific refund status resource.">
public function resolveEndpoint(): string
{
return "/api/na/jp/v1/tax-refund/{$this->taxRefundId}/status";
}
// </SECTION>
// <SECTION name="response_caster" intent="Map the JSON response to a TaxRefundResponseData DTO.">
// <BELIEF_STATE "Casting the response to a `TaxRefundResponseData` DTO provides a clear, type-safe object representing the current state of the tax refund.">
public function createDtoFromResponse(Response $response): TaxRefundResponseData
{
return TaxRefundResponseData::from($response->json());
}
// </SECTION>
}

View File

@@ -1,38 +1,63 @@
<?php
/*
// MODULE_CONTRACT: Represents the API call to accept or reject a pending payoff.
// RESPONSIBILITY: To define the PATCH request for changing the status of a payoff (approve/decline).
// INPUTS: Payoff ID (string) and a boolean indicating acceptance.
// OUTPUTS: Boolean (true if successful, false otherwise).
*/
namespace Apoloz\AlfaBank\Requests\NominalAccounts\Payouts;
// <SECTION name="module_imports" intent="Import Saloon components for a JSON body request.">
// <BELIEF_STATE "This PATCH request requires body-handling traits because it sends a JSON payload.">
use Saloon\Contracts\Body\HasBody;
use Saloon\Enums\Method;
use Saloon\Http\Request;
use Saloon\Http\Response;
use Saloon\Traits\Body\HasJsonBody;
// </SECTION>
// <SECTION name="class_definition" intent="Define the request to accept a payoff.">
// <BELIEF_STATE "This class encapsulates a critical state-changing operation on a payment.">
class PayoffAcceptRequest extends Request implements HasBody
{
use HasJsonBody;
// <SECTION name="http_method" intent="Declare the HTTP verb.">
// <BELIEF_STATE "PATCH is the appropriate verb for partially modifying an existing resource's state, such as accepting or rejecting a payoff.">
protected Method $method = Method::PATCH;
// </SECTION>
// <SECTION name="constructor" intent="Inject the payoff ID and the acceptance flag.">
// <BELIEF_STATE "The constructor requires the `payoffId` to target the specific payment and an `accept` flag to indicate the desired action. The default `true` simplifies the most common use case (accept).">
public function __construct(
protected string $payoffId,
protected bool $accept = true
) {}
// </SECTION>
// <SECTION name="endpoint_resolver" intent="Construct the request URI for accepting a payoff.">
// <BELIEF_STATE "The endpoint is specific to the `/accept` action on a given payoff resource.">
public function resolveEndpoint(): string
{
return "/api/na/jp/v1/payoffs/{$this->payoffId}/accept";
}
// </SECTION>
// <SECTION name="body_builder" intent="Construct the JSON body for the request.">
// <BELIEF_STATE "The request body is simple, containing only the `accept` boolean flag.">
protected function defaultBody(): array
{
return [
'accept' => $this->accept,
];
}
// </SECTION>
// <SECTION name="response_caster" intent="Extract the boolean result from the JSON response.">
// <BELIEF_STATE "The API returns a JSON object, but the relevant information is a boolean status. This method extracts that boolean, providing a direct, simple result to the user.">
public function createDtoFromResponse(Response $response): bool
{
return (bool)($response->json('result') ?? false);
}
// </SECTION>
}

View File

@@ -1,36 +1,61 @@
<?php
/*
// MODULE_CONTRACT: Represents the API call to accept a pending tax refund request.
// RESPONSIBILITY: To define the PATCH request for approving a tax refund payment.
// INPUTS: Tax refund ID (string) and a boolean indicating acceptance.
// OUTPUTS: Boolean (true if successful, false otherwise).
*/
namespace Apoloz\AlfaBank\Requests\NominalAccounts\Payouts;
// <SECTION name="module_imports" intent="Import Saloon components for a JSON body request.">
// <BELIEF_STATE "This PATCH request requires body-handling traits because it sends a JSON payload.">
use Saloon\Contracts\Body\HasBody;
use Saloon\Enums\Method;
use Saloon\Http\Request;
use Saloon\Http\Response;
use Saloon\Traits\Body\HasJsonBody;
// </SECTION>
// <SECTION name="class_definition" intent="Define the request to accept a tax refund.">
// <BELIEF_STATE "This class encapsulates a critical state-changing operation for tax refunds.">
class TaxRefundAcceptRequest extends Request implements HasBody
{
use HasJsonBody;
// <SECTION name="http_method" intent="Declare the HTTP verb.">
// <BELIEF_STATE "PATCH is the appropriate verb for partially modifying an existing resource's state, such as accepting a tax refund.">
protected Method $method = Method::PATCH;
// </SECTION>
// <SECTION name="constructor" intent="Inject the tax refund ID and the acceptance flag.">
// <BELIEF_STATE "The constructor requires the `taxRefundId` to target the specific refund and an `accept` flag to indicate the desired action.">
public function __construct(
protected string $taxRefundId,
protected bool $accept
) {}
// </SECTION>
// <SECTION name="endpoint_resolver" intent="Construct the request URI for accepting a tax refund.">
// <BELIEF_STATE "The endpoint is specific to the `/accept` action on a given tax refund resource.">
public function resolveEndpoint(): string
{
return "/api/na/jp/v1/tax-refund/{$this->taxRefundId}/accept";
}
// </SECTION>
// <SECTION name="query_builder" intent="Construct the query string for the acceptance status.">
// <BELIEF_STATE "The API expects the acceptance status as a query parameter, represented as 'true' or 'false' strings.">
protected function defaultQuery(): array
{
return ['accept' => $this->accept ? 'true' : 'false'];
}
// </SECTION>
// <SECTION name="response_caster" intent="Extract the boolean result from the JSON response.">
// <BELIEF_STATE "The API returns a JSON object, but the relevant information for this operation is a boolean status. This method extracts that boolean, providing a direct, simple result to the user.">
public function createDtoFromResponse(Response $response): bool
{
return (bool)($response->json('result') ?? false);
}
// </SECTION>
}

View File

@@ -1,7 +1,15 @@
<?php
/*
// MODULE_CONTRACT: Represents the API call to create a new universal recipient.
// RESPONSIBILITY: To define the POST request for registering a universal recipient.
// INPUTS: CreateUniversalRecipientRequestData DTO.
// OUTPUTS: UniversalRecipientResponseData DTO.
*/
namespace Apoloz\AlfaBank\Requests\NominalAccounts\UniversalRecipients;
// <SECTION name="module_imports" intent="Import DTOs and Saloon components for a JSON body request.">
// <BELIEF_STATE "This POST request requires specific DTOs for its JSON body and its response, along with Saloon's body-handling traits.">
use Apoloz\AlfaBank\Data\NominalAccounts\UniversalRecipients\CreateUniversalRecipientRequestData;
use Apoloz\AlfaBank\Data\NominalAccounts\UniversalRecipients\UniversalRecipientResponseData;
use Saloon\Contracts\Body\HasBody;
@@ -9,29 +17,47 @@ use Saloon\Enums\Method;
use Saloon\Http\Request;
use Saloon\Http\Response;
use Saloon\Traits\Body\HasJsonBody;
// </SECTION>
// <SECTION name="class_definition" intent="Define the request to create a new universal recipient.">
// <BELIEF_STATE "A dedicated class for universal recipient creation improves code organization and reusability.">
class CreateUniversalRecipientRequest extends Request implements HasBody
{
use HasJsonBody;
// <SECTION name="http_method" intent="Declare the HTTP verb.">
// <BELIEF_STATE "Creating a new universal recipient resource is correctly represented by the POST verb.">
protected Method $method = Method::POST;
// </SECTION>
// <SECTION name="constructor" intent="Inject the DTO containing the new universal recipient's data.">
// <BELIEF_STATE "Using a strongly-typed DTO for the payload enforces data integrity and makes the request's dependencies clear.">
public function __construct(
protected CreateUniversalRecipientRequestData $data
) {}
// </SECTION>
// <SECTION name="endpoint_resolver" intent="Define the URI for the universal recipients collection.">
// <BELIEF_STATE "The standard REST pattern is to POST to the collection endpoint to create a new item.">
public function resolveEndpoint(): string
{
return '/api/na/jp/v1/universal-recipients';
}
// </SECTION>
// <SECTION name="body_builder" intent="Serialize the DTO for the request body.">
// <BELIEF_STATE "Delegating serialization to the DTO's `toArray` method decouples the request from the DTO's internal structure.">
protected function defaultBody(): array
{
return $this->data->toArray();
}
// </SECTION>
// <SECTION name="response_caster" intent="Map the JSON response to a DTO.">
// <BELIEF_STATE "Casting the response to a `UniversalRecipientResponseData` DTO provides a type-safe object representing the result of the creation.">
public function createDtoFromResponse(Response $response): UniversalRecipientResponseData
{
return UniversalRecipientResponseData::from($response->json());
}
// </SECTION>
}

View File

@@ -1,27 +1,50 @@
<?php
/*
// MODULE_CONTRACT: Represents the API call to retrieve a single universal recipient by its ID.
// RESPONSIBILITY: To define the GET request structure for fetching a specific universal recipient's details.
// INPUTS: Universal recipient ID (string).
// OUTPUTS: UniversalRecipientData (DTO).
*/
namespace Apoloz\AlfaBank\Requests\NominalAccounts\UniversalRecipients;
// <SECTION name="module_imports" intent="Import DTO and Saloon components.">
// <BELIEF_STATE "This request needs the `UniversalRecipientData` DTO for its response and Saloon's base Request class.">
use Apoloz\AlfaBank\Data\NominalAccounts\UniversalRecipients\UniversalRecipientData;
use Saloon\Enums\Method;
use Saloon\Http\Request;
use Saloon\Http\Response;
// </SECTION>
// <SECTION name="class_definition" intent="Define the request to get a single universal recipient.">
// <BELIEF_STATE "A dedicated class encapsulates the logic for this specific API endpoint, promoting reusability and separation of concerns.">
class GetUniversalRecipientRequest extends Request
{
// <SECTION name="http_method" intent="Declare the HTTP verb.">
// <BELIEF_STATE "Fetching a resource by its identifier is a read-only operation, making GET the correct RESTful verb.">
protected Method $method = Method::GET;
// </SECTION>
// <SECTION name="constructor" intent="Inject the universal recipient's unique identifier.">
// <BELIEF_STATE "The `universalRecipientId` is a mandatory path parameter for this endpoint, so it must be required in the constructor.">
public function __construct(
protected string $universalRecipientId
) {}
// </SECTION>
// <SECTION name="endpoint_resolver" intent="Construct the request URI with the dynamic universal recipient ID.">
// <BELIEF_STATE "The endpoint is dynamic. Injecting the `universalRecipientId` into the URI is handled here to keep the endpoint definition clean and centralized within the request class.">
public function resolveEndpoint(): string
{
return "/api/na/jp/v1/universal-recipients/{$this->universalRecipientId}";
}
// </SECTION>
// <SECTION name="response_caster" intent="Map the JSON response to a UniversalRecipientData DTO.">
// <BELIEF_STATE "Automated casting to a DTO provides type safety and a clean object-oriented interface for the API response.">
public function createDtoFromResponse(Response $response): UniversalRecipientData
{
return UniversalRecipientData::from($response->json());
}
// </SECTION>
}

View File

@@ -1,17 +1,33 @@
<?php
/*
// MODULE_CONTRACT: Represents the API call to retrieve a list of universal recipients.
// RESPONSIBILITY: To define the GET request for fetching a filtered, paginated list of universal recipients.
// INPUTS: Account number, type, and various optional filters.
// OUTPUTS: A collection of UniversalRecipientData DTOs.
*/
namespace Apoloz\AlfaBank\Requests\NominalAccounts\UniversalRecipients;
// <SECTION name="module_imports" intent="Import DTOs and Saloon components.">
// <BELIEF_STATE "This request returns a collection of `UniversalRecipientData` DTOs.">
use Apoloz\AlfaBank\Data\NominalAccounts\UniversalRecipients\UniversalRecipientData;
use Saloon\Enums\Method;
use Saloon\Http\Request;
use Saloon\Http\Response;
use Spatie\LaravelData\DataCollection;
// </SECTION>
// <SECTION name="class_definition" intent="Define the request to get a list of universal recipients.">
// <BELIEF_STATE "This class encapsulates a complex query with multiple optional filters, simplifying its use.">
class GetUniversalRecipientsRequest extends Request
{
// <SECTION name="http_method" intent="Declare the HTTP verb.">
// <BELIEF_STATE "GET is the correct verb for retrieving a collection of resources.">
protected Method $method = Method::GET;
// </SECTION>
// <SECTION name="constructor" intent="Inject required filters and optional pagination parameters.">
// <BELIEF_STATE "The `accountNumber` and `type` are mandatory filters. Other fields are optional filters or pagination parameters, allowing for flexible querying.">
public function __construct(
protected string $accountNumber,
protected string $type,
@@ -20,12 +36,18 @@ class GetUniversalRecipientsRequest extends Request
protected ?bool $isActive = null,
protected ?string $date = null,
) {}
// </SECTION>
// <SECTION name="endpoint_resolver" intent="Define the URI for the universal recipients collection.">
// <BELIEF_STATE "The endpoint is the static collection URI; all filters are applied via query parameters.">
public function resolveEndpoint(): string
{
return '/api/na/jp/v1/universal-recipients';
}
// </SECTION>
// <SECTION name="query_builder" intent="Construct the query string from the provided filters.">
// <BELIEF_STATE "Using `array_filter` is a robust way to build the query array, as it automatically omits any optional parameters that were not provided (i.e., are `null`), resulting in a clean URL.">
protected function defaultQuery(): array
{
return array_filter([
@@ -37,9 +59,13 @@ class GetUniversalRecipientsRequest extends Request
'date' => $this->date,
], fn($val) => $val !== null);
}
// </SECTION>
// <SECTION name="response_caster" intent="Map the JSON response to a collection DTO.">
// <BELIEF_STATE "Casting the response to a `DataCollection` of `UniversalRecipientData` provides a type-safe, iterable object. The specific API response structure requires extracting from the `universalRecipients` key.">
public function createDtoFromResponse(Response $response): DataCollection
{
return UniversalRecipientData::collect($response->json('universalRecipients'), DataCollection::class);
}
// </SECTION>
}

View File

@@ -1,7 +1,15 @@
<?php
/*
// MODULE_CONTRACT: Represents the API call to add a new requisite to a universal recipient.
// RESPONSIBILITY: To define the POST request for registering a new payment requisite for a universal recipient.
// INPUTS: Universal recipient ID, and a CreateRequisiteRequestData DTO.
// OUTPUTS: RequisiteData (DTO) of the newly added requisite.
*/
namespace Apoloz\AlfaBank\Requests\NominalAccounts\UniversalRecipients\Requisites;
// <SECTION name="module_imports" intent="Import DTOs and Saloon components for a JSON body request.">
// <BELIEF_STATE "This POST request requires specific DTOs for its JSON body and its response, along with Saloon's body-handling traits. It reuses `CreateRequisiteRequestData` from the Beneficiaries module.">
use Apoloz\AlfaBank\Data\NominalAccounts\Beneficiaries\Requisites\CreateRequisiteRequestData;
use Apoloz\AlfaBank\Data\NominalAccounts\Beneficiaries\Requisites\RequisiteData;
use Saloon\Contracts\Body\HasBody;
@@ -9,30 +17,48 @@ use Saloon\Enums\Method;
use Saloon\Http\Request;
use Saloon\Http\Response;
use Saloon\Traits\Body\HasJsonBody;
// </SECTION>
// <SECTION name="class_definition" intent="Define the request to add a requisite to a universal recipient.">
// <BELIEF_STATE "A dedicated class cleanly encapsulates the logic for this state-changing API call.">
class AddUniversalRecipientRequisiteRequest extends Request implements HasBody
{
use HasJsonBody;
// <SECTION name="http_method" intent="Declare the HTTP verb.">
// <BELIEF_STATE "Adding a new sub-resource (requisite) to an existing resource (universal recipient) is typically a POST operation to the sub-resource collection.">
protected Method $method = Method::POST;
// </SECTION>
// <SECTION name="constructor" intent="Inject the universal recipient ID and the requisite data.">
// <BELIEF_STATE "The `universalRecipientId` is a mandatory path parameter, and `CreateRequisiteRequestData` ensures the payload is type-safe and valid.">
public function __construct(
protected string $universalRecipientId,
protected CreateRequisiteRequestData $data
) {}
// </SECTION>
// <SECTION name="endpoint_resolver" intent="Construct the request URI for adding a requisite.">
// <BELIEF_STATE "The endpoint targets the `requisites` sub-resource of a specific universal recipient.">
public function resolveEndpoint(): string
{
return "/api/na/jp/v1/universal-recipients/{$this->universalRecipientId}/requisites";
}
// </SECTION>
// <SECTION name="body_builder" intent="Serialize the DTO for the request body.">
// <BELIEF_STATE "Delegating serialization to the DTO's `toArray` method ensures the payload is correctly formatted for the API.">
protected function defaultBody(): array
{
return $this->data->toArray();
}
// </SECTION>
// <SECTION name="response_caster" intent="Map the JSON response to a RequisiteData DTO.">
// <BELIEF_STATE "The API returns the newly created requisite object. Casting it to a DTO provides a clean, type-safe object for the user.">
public function createDtoFromResponse(Response $response): RequisiteData
{
return RequisiteData::from($response->json());
}
// </SECTION>
}

View File

@@ -1,28 +1,51 @@
<?php
/*
// MODULE_CONTRACT: Represents the API call to retrieve all requisites for a specific universal recipient.
// RESPONSIBILITY: To define the GET request for fetching payment requisites associated with a universal recipient.
// INPUTS: Universal recipient ID (string).
// OUTPUTS: A collection of RequisiteData DTOs.
*/
namespace Apoloz\AlfaBank\Requests\NominalAccounts\UniversalRecipients\Requisites;
// <SECTION name="module_imports" intent="Import DTO and Saloon components.">
// <BELIEF_STATE "This request returns a collection of `RequisiteData` DTOs.">
use Apoloz\AlfaBank\Data\NominalAccounts\Beneficiaries\Requisites\RequisiteData;
use Saloon\Enums\Method;
use Saloon\Http\Request;
use Saloon\Http\Response;
use Spatie\LaravelData\DataCollection;
// </SECTION>
// <SECTION name="class_definition" intent="Define the request to get requisites for a universal recipient.">
// <BELIEF_STATE "This class encapsulates the logic for fetching all requisites related to a specific universal recipient.">
class GetUniversalRecipientRequisitesRequest extends Request
{
// <SECTION name="http_method" intent="Declare the HTTP verb.">
// <BELIEF_STATE "GET is the correct verb for retrieving a collection of resources.">
protected Method $method = Method::GET;
// </SECTION>
// <SECTION name="constructor" intent="Inject the universal recipient's unique identifier.">
// <BELIEF_STATE "The `universalRecipientId` is mandatory to specify which universal recipient's requisites are being queried.">
public function __construct(
protected string $universalRecipientId
) {}
// </SECTION>
// <SECTION name="endpoint_resolver" intent="Construct the request URI for universal recipient requisites.">
// <BELIEF_STATE "The endpoint targets the `requisites` sub-resource of a specific universal recipient.">
public function resolveEndpoint(): string
{
return "/api/na/jp/v1/universal-recipients/{$this->universalRecipientId}/requisites";
}
// </SECTION>
// <SECTION name="response_caster" intent="Map the JSON array response to a collection of DTOs.">
// <BELIEF_STATE "The API returns a JSON array. Using `RequisiteData::collect` automatically converts this array into a type-safe, iterable `DataCollection` of `RequisiteData` objects.">
public function createDtoFromResponse(Response $response): DataCollection
{
return RequisiteData::collect($response->json(), DataCollection::class);
}
// </SECTION>
}

View File

@@ -1,32 +1,46 @@
<?php
/*
// MODULE_CONTRACT: Represents the API call to update a specific requisite for a universal recipient.
// RESPONSIBILITY: To define the PATCH request for modifying an existing payment requisite.
// INPUTS: Universal recipient ID, requisite ID, and an UpdateRequisiteRequestData DTO.
// OUTPUTS: No specific DTO, typically a 200 OK or 202 Accepted status.
*/
namespace Apoloz\AlfaBank\Requests\NominalAccounts\UniversalRecipients\Requisites;
use Apoloz\AlfaBank\Data\NominalAccounts\Beneficiaries\Requisites\UpdateRequisiteRequestData;
// <SECTION name="module_imports" intent="Import DTO and Saloon components for a JSON body request.">
// <BELIEF_STATE "This PATCH request requires the `UpdateRequisiteRequestData` DTO for its JSON body and Saloon's body-handling traits.">
use Apoloz\AlfaBank\Data\Shared\GeneralStatusData;
use Saloon\Contracts\Body\HasBody;
use Saloon\Enums\Method;
use Saloon\Http\Request;
use Saloon\Http\Response;
use Saloon\Traits\Body\HasJsonBody;
class UpdateUniversalRecipientRequisiteRequest extends Request implements HasBody
{
use HasJsonBody;
protected Method $method = Method::PATCH;
protected Method $method = Method::PUT;
public function __construct(
protected string $universalRecipientId,
protected string $requisiteId,
protected UpdateRequisiteRequestData $data
protected array $data
) {}
public function resolveEndpoint(): string
{
return "/api/na/jp/v1/universal-recipients/{$this->universalRecipientId}/requisites/{$this->requisiteId}";
return "/api/na/jp/v1/universal-recipients/{$this->universalRecipientId}/requisites/{$this->universalRecipientId}";
}
protected function defaultBody(): array
{
return $this->data->toArray();
return $this->data;
}
public function createDtoFromResponse(Response $response): GeneralStatusData
{
return GeneralStatusData::from(['success' => $response->successful()]);
}
}

View File

@@ -0,0 +1,37 @@
<?php
namespace Apoloz\AlfaBank\Requests\Orders;
use Apoloz\AlfaBank\Data\Orders\OrderRequestData;
use Apoloz\AlfaBank\Data\Orders\OrderResponseData;
use Saloon\Contracts\Body\HasBody;
use Saloon\Enums\Method;
use Saloon\Http\Request;
use Saloon\Http\Response;
use Saloon\Traits\Body\HasJsonBody;
class CreateAfishaOrderRequest extends Request implements HasBody
{
use HasJsonBody;
protected Method $method = Method::POST;
public function __construct(
protected OrderRequestData $data
) {}
public function resolveEndpoint(): string
{
return '/api/order-core/pp/v1/afisha/orders';
}
protected function defaultBody(): array
{
return $this->data->toArray();
}
public function createDtoFromResponse(Response $response): OrderResponseData
{
return OrderResponseData::from($response->json());
}
}

View File

@@ -0,0 +1,37 @@
<?php
namespace Apoloz\AlfaBank\Requests\Orders;
use Apoloz\AlfaBank\Data\Orders\OrderRequestData;
use Apoloz\AlfaBank\Data\Orders\OrderResponseData;
use Saloon\Contracts\Body\HasBody;
use Saloon\Enums\Method;
use Saloon\Http\Request;
use Saloon\Http\Response;
use Saloon\Traits\Body\HasJsonBody;
class CreateTravelOrderRequest extends Request implements HasBody
{
use HasJsonBody;
protected Method $method = Method::POST;
public function __construct(
protected OrderRequestData $data
) {}
public function resolveEndpoint(): string
{
return '/api/order-core/pp/v1/travel/orders';
}
protected function defaultBody(): array
{
return $this->data->toArray();
}
public function createDtoFromResponse(Response $response): OrderResponseData
{
return OrderResponseData::from($response->json());
}
}

View File

@@ -0,0 +1,41 @@
<?php
namespace Apoloz\AlfaBank\Requests\Partner;
use Apoloz\AlfaBank\Data\Partner\PartnerApplicationData;
use Saloon\Enums\Method;
use Saloon\Http\Request;
use Saloon\Http\Response;
use Spatie\LaravelData\DataCollection;
class GetPartnerApplicationsRequest extends Request
{
protected Method $method = Method::GET;
public function __construct(
protected ?string $fromDate = null,
protected ?string $toDate = null,
protected int $limit = 10,
protected int $offset = 0
) {}
public function resolveEndpoint(): string
{
return '/api/partner/jp/v1/individuals';
}
protected function defaultQuery(): array
{
return array_filter([
'fromDate' => $this->fromDate,
'toDate' => $this->toDate,
'limit' => $this->limit,
'offset' => $this->offset,
]);
}
public function createDtoFromResponse(Response $response): DataCollection
{
return PartnerApplicationData::collect($response->json('items') ?? [], DataCollection::class);
}
}

View File

@@ -0,0 +1,40 @@
<?php
namespace Apoloz\AlfaBank\Requests\Payments;
use Apoloz\AlfaBank\Data\Payments\PaymentData;
use Apoloz\AlfaBank\Data\Payments\PaymentResponseData;
use Saloon\Contracts\Body\HasBody;
use Saloon\Enums\Method;
use Saloon\Http\Request;
use Saloon\Http\Response;
use Saloon\Traits\Body\HasJsonBody;
class CreatePaymentRequest extends Request implements HasBody
{
use HasJsonBody;
protected Method $method = Method::POST;
public function __construct(
protected PaymentData $data
) {}
public function resolveEndpoint(): string
{
return '/api/jp/v2/payments';
}
protected function defaultBody(): array
{
return $this->data->toArray();
}
public function createDtoFromResponse(Response $response): PaymentResponseData
{
return PaymentResponseData::from([
'id' => $this->data->externalId,
'status' => $response->status() === 201 ? 'CREATED' : 'ERROR',
]);
}
}

View File

@@ -0,0 +1,27 @@
<?php
namespace Apoloz\AlfaBank\Requests\Payments;
use Apoloz\AlfaBank\Data\Payments\PaymentStateData;
use Saloon\Enums\Method;
use Saloon\Http\Request;
use Saloon\Http\Response;
class GetPaymentStateRequest extends Request
{
protected Method $method = Method::GET;
public function __construct(
protected string $externalId
) {}
public function resolveEndpoint(): string
{
return "/api/jp/v2/payments/{$this->externalId}/state";
}
public function createDtoFromResponse(Response $response): PaymentStateData
{
return PaymentStateData::from($response->json());
}
}

View File

@@ -0,0 +1,28 @@
<?php
namespace Apoloz\AlfaBank\Requests\Poa;
use Apoloz\AlfaBank\Data\Poa\PoaResponseData;
use Saloon\Enums\Method;
use Saloon\Http\Request;
use Saloon\Http\Response;
class CreatePoaRequest extends Request
{
protected Method $method = Method::POST;
public function __construct(
protected string $poaNumber,
protected string $inn
) {}
public function resolveEndpoint(): string
{
return "/api/jp/v1/poa/{$this->poaNumber}/inn/{$this->inn}/request";
}
public function createDtoFromResponse(Response $response): PoaResponseData
{
return PoaResponseData::from($response->json());
}
}

View File

@@ -0,0 +1,27 @@
<?php
namespace Apoloz\AlfaBank\Requests\Poa;
use Apoloz\AlfaBank\Data\Poa\PoaResponseData;
use Saloon\Enums\Method;
use Saloon\Http\Request;
use Saloon\Http\Response;
class GetPoaRequestStatusRequest extends Request
{
protected Method $method = Method::GET;
public function __construct(
protected string $requestUuid
) {}
public function resolveEndpoint(): string
{
return "/api/jp/v1/poa/requests/{$this->requestUuid}/status";
}
public function createDtoFromResponse(Response $response): PoaResponseData
{
return PoaResponseData::from($response->json());
}
}

View File

@@ -0,0 +1,24 @@
<?php
namespace Apoloz\AlfaBank\Requests\Rates;
use Apoloz\AlfaBank\Data\Rates\OfficeRateData;
use Saloon\Enums\Method;
use Saloon\Http\Request;
use Saloon\Http\Response;
use Spatie\LaravelData\DataCollection;
class GetOfficeRatesRequest extends Request
{
protected Method $method = Method::GET;
public function resolveEndpoint(): string
{
return '/api/smart-loans/jp/v1/offices/rates';
}
public function createDtoFromResponse(Response $response): DataCollection
{
return OfficeRateData::collect($response->json('offices') ?? [], DataCollection::class);
}
}

View File

@@ -0,0 +1,37 @@
<?php
namespace Apoloz\AlfaBank\Requests\Registries;
use Apoloz\AlfaBank\Data\Registries\RegistryRequestData;
use Apoloz\AlfaBank\Data\Registries\RegistryResponseData;
use Saloon\Contracts\Body\HasBody;
use Saloon\Enums\Method;
use Saloon\Http\Request;
use Saloon\Http\Response;
use Saloon\Traits\Body\HasJsonBody;
class CreateRegistryRequest extends Request implements HasBody
{
use HasJsonBody;
protected Method $method = Method::POST;
public function __construct(
protected RegistryRequestData $data
) {}
public function resolveEndpoint(): string
{
return '/api/jp/v1/registries';
}
protected function defaultBody(): array
{
return $this->data->toArray();
}
public function createDtoFromResponse(Response $response): RegistryResponseData
{
return RegistryResponseData::from($response->json());
}
}

View File

@@ -0,0 +1,37 @@
<?php
namespace Apoloz\AlfaBank\Requests\Registries;
use Apoloz\AlfaBank\Data\Registries\RegistryResponseData;
use Apoloz\AlfaBank\Data\Registries\SelfEncashmentData;
use Saloon\Contracts\Body\HasBody;
use Saloon\Enums\Method;
use Saloon\Http\Request;
use Saloon\Http\Response;
use Saloon\Traits\Body\HasJsonBody;
class CreateSelfEncashmentRegistryRequest extends Request implements HasBody
{
use HasJsonBody;
protected Method $method = Method::POST;
public function __construct(
protected SelfEncashmentData $data
) {}
public function resolveEndpoint(): string
{
return '/api/jp/v1/self-encashment/registries';
}
protected function defaultBody(): array
{
return $this->data->toArray();
}
public function createDtoFromResponse(Response $response): RegistryResponseData
{
return RegistryResponseData::from($response->json());
}
}

View File

@@ -0,0 +1,44 @@
<?php
namespace Apoloz\AlfaBank\Requests\Registries;
use Apoloz\AlfaBank\Data\Registries\RegistrySignatureData;
use Apoloz\AlfaBank\Data\Shared\GeneralStatusData;
use Saloon\Contracts\Body\HasBody;
use Saloon\Enums\Method;
use Saloon\Http\Request;
use Saloon\Http\Response;
use Saloon\Traits\Body\HasJsonBody;
use Spatie\LaravelData\DataCollection;
class SignRegistryRequest extends Request implements HasBody
{
use HasJsonBody;
protected Method $method = Method::POST;
public function __construct(
protected string $registryId,
/** @var DataCollection<RegistrySignatureData> */
protected DataCollection $signatures,
) {}
public function resolveEndpoint(): string
{
return "/api/jp/v1/registries/{$this->registryId}/signatures";
}
protected function defaultBody(): array
{
return [
'digestSignatures' => $this->signatures->toArray(),
];
}
public function createDtoFromResponse(Response $response): GeneralStatusData
{
return GeneralStatusData::from([
'success' => $response->successful(),
]);
}
}

View File

@@ -0,0 +1,39 @@
<?php
namespace Apoloz\AlfaBank\Requests\Reports;
use Apoloz\AlfaBank\Data\Reports\AccountBalanceReportData;
use Apoloz\AlfaBank\Data\Registries\RegistryResponseData;
use Saloon\Contracts\Body\HasBody;
use Saloon\Enums\Method;
use Saloon\Http\Request;
use Saloon\Http\Response;
use Saloon\Traits\Body\HasJsonBody;
class CreateAccountBalanceReportRequest extends Request implements HasBody
{
use HasJsonBody;
protected Method $method = Method::POST;
public function __construct(
protected AccountBalanceReportData $data,
protected string $language = 'rus' // 'rus' or 'eng'
) {}
public function resolveEndpoint(): string
{
$path = $this->language === 'eng' ? 'eng' : 'rus';
return "/api/pp/v1/reports/type/account/balance/{$path}";
}
protected function defaultBody(): array
{
return $this->data->toArray();
}
public function createDtoFromResponse(Response $response): RegistryResponseData
{
return RegistryResponseData::from($response->json());
}
}

View File

@@ -0,0 +1,45 @@
<?php
namespace Apoloz\AlfaBank\Requests\Salary;
use Apoloz\AlfaBank\Data\Salary\SalaryAccountApplicationData;
use Apoloz\AlfaBank\Data\Salary\SalaryApplicationResponseData;
use Saloon\Contracts\Body\HasBody;
use Saloon\Enums\Method;
use Saloon\Http\Request;
use Saloon\Http\Response;
use Saloon\Traits\Body\HasJsonBody;
class CreateAccountApplicationRequest extends Request implements HasBody
{
use HasJsonBody;
protected Method $method = Method::POST;
public function __construct(
protected SalaryAccountApplicationData $data,
protected ?string $signatures = null
) {}
public function resolveEndpoint(): string
{
return '/api/jp/v1/salary-project/accounts/applications';
}
protected function defaultHeaders(): array
{
return array_filter([
'X-Salary-Signatures' => $this->signatures,
]);
}
protected function defaultBody(): array
{
return $this->data->toArray();
}
public function createDtoFromResponse(Response $response): SalaryApplicationResponseData
{
return SalaryApplicationResponseData::from($response->json());
}
}

View File

@@ -0,0 +1,45 @@
<?php
namespace Apoloz\AlfaBank\Requests\Salary;
use Apoloz\AlfaBank\Data\Salary\SalaryApplicationResponseData;
use Apoloz\AlfaBank\Data\Salary\SalaryPayrollApplicationData;
use Saloon\Contracts\Body\HasBody;
use Saloon\Enums\Method;
use Saloon\Http\Request;
use Saloon\Http\Response;
use Saloon\Traits\Body\HasJsonBody;
class CreatePayrollApplicationRequest extends Request implements HasBody
{
use HasJsonBody;
protected Method $method = Method::POST;
public function __construct(
protected SalaryPayrollApplicationData $data,
protected ?string $signatures = null
) {}
public function resolveEndpoint(): string
{
return '/api/jp/v1/salary-project/payroll/applications';
}
protected function defaultHeaders(): array
{
return array_filter([
'X-Salary-Signatures' => $this->signatures,
]);
}
protected function defaultBody(): array
{
return $this->data->toArray();
}
public function createDtoFromResponse(Response $response): SalaryApplicationResponseData
{
return SalaryApplicationResponseData::from($response->json());
}
}

View File

@@ -0,0 +1,27 @@
<?php
namespace Apoloz\AlfaBank\Requests\Salary;
use Apoloz\AlfaBank\Data\Salary\SalaryApplicationResponseData;
use Saloon\Enums\Method;
use Saloon\Http\Request;
use Saloon\Http\Response;
class GetAccountApplicationStatusRequest extends Request
{
protected Method $method = Method::GET;
public function __construct(
protected string $applicationId
) {}
public function resolveEndpoint(): string
{
return "/api/jp/v1/salary-project/accounts/applications/{$this->applicationId}";
}
public function createDtoFromResponse(Response $response): SalaryApplicationResponseData
{
return SalaryApplicationResponseData::from($response->json());
}
}

View File

@@ -0,0 +1,27 @@
<?php
namespace Apoloz\AlfaBank\Requests\Salary;
use Apoloz\AlfaBank\Data\Salary\SalaryApplicationResponseData;
use Saloon\Enums\Method;
use Saloon\Http\Request;
use Saloon\Http\Response;
class GetPayrollApplicationStatusRequest extends Request
{
protected Method $method = Method::GET;
public function __construct(
protected string $applicationId
) {}
public function resolveEndpoint(): string
{
return "/api/jp/v1/salary-project/payroll/applications/{$this->applicationId}";
}
public function createDtoFromResponse(Response $response): SalaryApplicationResponseData
{
return SalaryApplicationResponseData::from($response->json());
}
}

View File

@@ -1,30 +1,60 @@
<?php
/*
// MODULE_CONTRACT: Represents the Sandbox API call to create a test RUB payment.
// RESPONSIBILITY: To define the POST request for simulating a payment in the sandbox environment.
// INPUTS: CreateRubPaymentRequestData DTO.
// OUTPUTS: No specific DTO; typically a 200 OK or 202 Accepted status for sandbox operations.
*/
namespace Apoloz\AlfaBank\Requests\Sandbox\Payments;
// <SECTION name="module_imports" intent="Import DTO and Saloon framework components for a JSON body request.">
// <BELIEF_STATE "This POST request requires the `CreateRubPaymentRequestData` DTO for its body and utilizes `HasBody` and `HasJsonBody` for proper payload serialization.">
use Apoloz\AlfaBank\Data\Sandbox\Payments\CreateRubPaymentRequestData;
use Apoloz\AlfaBank\Data\Shared\GeneralStatusData;
use Saloon\Contracts\Body\HasBody;
use Saloon\Enums\Method;
use Saloon\Http\Request;
use Saloon\Http\Response;
use Saloon\Traits\Body\HasJsonBody;
// </SECTION>
// <SECTION name="class_definition" intent="Define a class for creating a test RUB payment in the Sandbox.">
// <BELIEF_STATE "This class encapsulates the logic for simulating payments, which is crucial for testing integrations without affecting live financial systems.">
class CreateRubPaymentRequest extends Request implements HasBody
{
use HasJsonBody;
// <SECTION name="http_method_declaration" intent="Declare the HTTP verb for creating the test payment.">
// <BELIEF_STATE "Creating a new test payment resource or initiating a test payment action is correctly represented by a POST request.">
protected Method $method = Method::POST;
// </SECTION>
// <SECTION name="constructor" intent="Inject the DTO containing the test payment details.">
// <BELIEF_STATE "Using a strongly-typed `CreateRubPaymentRequestData` DTO ensures that all necessary test payment information is provided and correctly structured.">
public function __construct(
protected CreateRubPaymentRequestData $data
) {}
// </SECTION>
// <SECTION name="endpoint_resolver" intent="Define the specific URI for creating test RUB payments.">
// <BELIEF_STATE "The endpoint is specific to the sandbox environment for creating test payments.">
public function resolveEndpoint(): string
{
return '/api/jp/v2/payments';
}
// </SECTION>
// <SECTION name="request_body_builder" intent="Construct the JSON body for the test payment request.">
// <BELIEF_STATE "Delegating serialization to the DTO's `toArray` method ensures the test payment payload is correctly formatted for the Sandbox API.">
protected function defaultBody(): array
{
return $this->data->toArray();
}
// </SECTION>
public function createDtoFromResponse(Response $response): GeneralStatusData
{
return GeneralStatusData::from(['success' => $response->successful()]);
}
}

View File

@@ -1,41 +1,44 @@
<?php
/*
// MODULE_CONTRACT: Represents a Sandbox API call for testing signature and encryption mechanisms.
// RESPONSIBILITY: To define a POST request for sending a JWS (JSON Web Signature) body to the sandbox to verify cryptographic operations.
// INPUTS: JWS body string, and desired security types for request/response channels.
// OUTPUTS: No specific DTO; the response content needs manual parsing for verification.
*/
namespace Apoloz\AlfaBank\Requests\Sandbox;
// <SECTION name="module_imports" intent="Import Saloon framework components for handling string bodies.">
// <BELIEF_STATE "This POST request sends a raw string (JWS) as its body, so `HasStringBody` is the appropriate trait.">
use Apoloz\AlfaBank\Data\Sandbox\SandboxTestResponseData;
use Saloon\Contracts\Body\HasBody;
use Saloon\Enums\Method;
use Saloon\Http\Request;
use Saloon\Traits\Body\HasStringBody;
use Saloon\Http\Response;
use Saloon\Traits\Body\HasJsonBody;
class SignatureEncryptionTestRequest extends Request implements HasBody
{
use HasStringBody;
use HasJsonBody;
protected Method $method = Method::POST;
public function __construct(
protected string $jwsBody,
protected string $requestChannelSecurity = 'SIGNATURE',
protected string $responseChannelSecurity = 'SIGNATURE'
protected string $data
) {}
public function resolveEndpoint(): string
{
return '/api/signature-encryption-tests/json';
}
protected function defaultHeaders(): array
{
return [
'Accept' => 'application/jose',
'Content-Type' => 'application/jose',
'X-Request-ChannelSecurity' => $this->requestChannelSecurity,
'X-Response-ChannelSecurity' => $this->responseChannelSecurity,
];
return '/api/sandbox/v1/test/signature-encryption';
}
protected function defaultBody(): ?string
{
return $this->jwsBody;
return $this->data;
}
public function createDtoFromResponse(Response $response): SandboxTestResponseData
{
return SandboxTestResponseData::from(['result' => $response->body()]);
}
}

Some files were not shown because too many files have changed in this diff Show More