Skip to content

Commit

Permalink
Merchant Pay out
Browse files Browse the repository at this point in the history
  • Loading branch information
rooneyi committed Oct 13, 2024
1 parent d634da5 commit 28f6fdc
Show file tree
Hide file tree
Showing 5 changed files with 137 additions and 14 deletions.
3 changes: 2 additions & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,8 @@
"symfony/http-client": "^7.0",
"webmozart/assert": "^1.11",
"symfony/serializer": "^7.0",
"symfony/property-access": "^7.0"
"symfony/property-access": "^7.0",
"ext-http": "*"
},
"require-dev": {
"phpstan/phpstan": "^1.10",
Expand Down
34 changes: 21 additions & 13 deletions src/Client.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,12 @@
namespace Devscast\Flexpay;

use Devscast\Flexpay\Exception\NetworkException;
use Devscast\Flexpay\Request\MerchantPayOutRequest;
use Devscast\Flexpay\Request\MobileRequest;
use Devscast\Flexpay\Request\Request;
use Devscast\Flexpay\Request\VposRequest;
use Devscast\Flexpay\Response\CheckResponse;
use Devscast\Flexpay\Response\FlexpayResponse;
use Devscast\Flexpay\Response\MerchantPayOutResponse;
use Devscast\Flexpay\Response\PaymentResponse;
use Devscast\Flexpay\Response\VposResponse;
use Symfony\Component\HttpClient\HttpClient;
Expand Down Expand Up @@ -58,6 +59,25 @@ public function __construct(
);
}

public function merchantPayOut(MerchantPayOutRequest $request): MerchantPayOutResponse
{
$request->setCredential($this->credential);

try {
/** @var MerchantPayOutResponse $response */
$response = $this->getMappedData(
type: MerchantPayOutResponse::class,
data: $this->http->request('POST', $this->environment->getMerchantPayOutUrl(), [
'json' => $request->getPayload(),
])->toArray()
);

return $response;
} catch (\Throwable $e) {
$this->createExceptionFromResponse($e);
}
}

/**
* Permet d'envoyer une directement intention de paiement sur le mobile money du client
*
Expand Down Expand Up @@ -108,18 +128,6 @@ public function vpos(VposRequest $request): VposResponse
}
}

/**
* @throws NetworkException
*/
public function pay(Request $request): PaymentResponse|VposResponse
{
return match (true) {
$request instanceof MobileRequest => $this->mobile($request),
$request instanceof VposRequest => $this->vpos($request),
default => throw new \RuntimeException('Unsupported request')
};
}

/**
* Cette interface permet de vérifier l’état d’une requête de paiement envoyée à FlexPay.
*
Expand Down
8 changes: 8 additions & 0 deletions src/Environment.php
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,14 @@ public function getCheckStatusUrl(string $orderNumber): string
};
}

public function getMerchantPayOutUrl(): string
{
return match ($this) {
self::LIVE => 'https://backend.flexpay.cd/merchant/payout',
self::SANDBOX => sprintf('%s/merchant/payout', $this->getBaseUrl()),
};
}

private function getBaseUrl(): string
{
return match ($this) {
Expand Down
69 changes: 69 additions & 0 deletions src/Request/MerchantPayOutRequest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
<?php

declare(strict_types=1);

namespace Devscast\Flexpay\Request;

use Devscast\Flexpay\Credential;
use Devscast\Flexpay\Data\Currency;
use Symfony\Component\HttpClient\HttpClient;
use Symfony\Contracts\HttpClient\Exception\ClientExceptionInterface;
use Symfony\Contracts\HttpClient\Exception\DecodingExceptionInterface;
use Symfony\Contracts\HttpClient\Exception\RedirectionExceptionInterface;
use Symfony\Contracts\HttpClient\Exception\ServerExceptionInterface;
use Symfony\Contracts\HttpClient\Exception\TransportExceptionInterface;
use Symfony\Contracts\HttpClient\HttpClientInterface;
use Webmozart\Assert\Assert;

final class MerchantPayOutRequest extends Request
{
private HttpClientInterface $client;

private string $apiUrl = 'https://api.flexpay.cd/api/merchantPayOutService';

public function __construct(
float $amount,
string $reference,
Currency $currency,
string $callbackUrl,
public string $phone,
public Credential $credentials,
public string $telephone,
public int $type = 1,
) {
$this->client = HttpClient::create();

Assert::length($this->telephone, 12, 'The phone number should be 12 characters long, eg: 243123456789');

parent::__construct($amount, $reference, $currency, $callbackUrl);
}

public function getPayload(): array
{
return [
'merchant' => $this->merchant,
'type' => $this->type,
'reference' => $this->reference,
'phone' => $this->telephone,
'amount' => $this->amount,
'currency' => $this->currency->value,
'callbackUrl' => $this->callbackUrl,
];
}

/**
* @throws TransportExceptionInterface
* @throws ServerExceptionInterface
* @throws RedirectionExceptionInterface
* @throws DecodingExceptionInterface
* @throws ClientExceptionInterface
*/
public function sendRequest(): array
{
$response = $this->client->request('POST', $this->apiUrl, [
'json' => $this->getPayload(),
]);

return $response->toArray();
}
}
37 changes: 37 additions & 0 deletions src/Response/MerchantPayOutResponse.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
<?php

declare(strict_types=1);

namespace Devscast\Flexpay\Response;

use Symfony\Contracts\HttpClient\ResponseInterface;

final class MerchantPayOutResponse extends FlexpayResponse
{
public function getResponse(ResponseInterface $response): array
{
try {
$dataResponse = $response->toArray();

if (isset($dataResponse['code']) && $dataResponse['code'] === '200') {
return [
'status' => 'Transaction sent successfully.',
'message' => $dataResponse['message'] ?? 'Transaction succeeded',
'transaction_id' => $dataResponse['transactionId'] ?? null,
];
}

return [
'status' => 'Transaction failed.',
'message' => $dataResponse['message'] ?? 'Transaction failed',
'code' => $dataResponse['code'] ?? 'Unknown error',
];

} catch (\Exception $e) {
return [
'status' => 'Error processing response.',
'message' => 'Error: ' . $e->getMessage(),
];
}
}
}

0 comments on commit 28f6fdc

Please sign in to comment.