src/Gateway.php
<?php
namespace Omnipay\Pesapal;
use GuzzleHttp\Client;
use GuzzleHttp\Psr7\Request;
use Omnipay\Common\AbstractGateway;
use Omnipay\Pesapal\OAuth\OAuthConsumer;
use Omnipay\Pesapal\OAuth\OAuthException;
use Omnipay\Pesapal\OAuth\OAuthRequest;
use Omnipay\Pesapal\OAuth\OAuthSignatureMethod_Hmac_Sha1;
use SimpleXMLElement;
/**
* @method authorize(array $options = array())
* @method completeAuthorize(array $options = array())
* @method capture(array $options = array())
* @method purchase(array $options = array())
* @method completePurchase(array $options = array())
* @method refund(array $options = array())
* @method void(array $options = array())
* @method createCard(array $options = array())
* @method updateCard(array $options = array())
* @method deleteCard(array $options = array())
*/
class Gateway extends AbstractGateway
{
const XMLNS = 'http://www.pesapal.com';
const PROD_DOMAIN = 'www.pesapal.com';
const DEBUG_DOMAIN = 'https://demo.pesapal.com';
/**
* @return string
*/
public function getName()
{
return 'Pesapal';
}
/**
* @param string $key
* @param string $secret
*
* @return Gateway
*/
public function setCredentials(
string $key,
string $secret
): self {
return $this->setParameter('key', $key)
->setParameter('secret', $secret);
}
/**
* @return string
*/
public function getKey(): string
{
return $this->getParameter('key');
}
/**
* @return string
*/
public function getSecret(): string
{
return $this->getParameter('secret');
}
/**
* @return Gateway
*/
public function setDebug(): self
{
return $this->setParameter('debug', true);
}
/**
* @return bool
*/
public function getDebug(): bool
{
return $this->getParameter('debug') ?? false;
}
/**
* @param string $callbackUrl
*
* @return Gateway
*/
public function setCallbackUrl(string $callbackUrl): self
{
return $this->setParameter('callbackUrl', $callbackUrl);
}
/**
* @return string
*/
public function getCallbackUrl(): string
{
return $this->getParameter('callbackUrl');
}
/**
* @param string $email
* @param string $reference
* @param string $description
* @param float $amount
* @param string|null $currency
* @param string $type
* @param string|null $firstName
* @param string|null $lastName
* @param string|null $phoneNumber
*
* @return string
*/
public function getIframeSrc(
string $email,
string $reference,
string $description,
float $amount,
string $currency = null,
string $type = 'MERCHANT',
string $firstName = null,
string $lastName = null,
string $phoneNumber = null
): string {
$xmlPayload = $this
->arrayToXml(
[
'Email' => $email,
'Reference' => $reference,
'Description' => $description,
'Amount' => $amount,
'Currency' => $currency,
'Type' => $type,
'FirstName' => $firstName,
'LastName' => $lastName,
'PhoneNumber' => $phoneNumber,
'xmlns' => $this::XMLNS,
],
new SimpleXMLElement('<PesapalDirectOrderInfo/>')
)->asXML();
return (string) $this->getIframeRequest($xmlPayload);
}
/**
* @return OAuthConsumer
*/
protected function getConsumer(): OAuthConsumer
{
return new OAuthConsumer(
$this->getKey(),
$this->getSecret(),
$this->getCallbackUrl()
);
}
/**
* @param string $xmlPayload
*
* @return OAuthRequest
*/
protected function getIframeRequest(
string $xmlPayload
): OAuthRequest {
$consumer = $this->getConsumer();
//post transaction to pesapal
$iframeRequest = OAuthRequest::getRequest(
$consumer,
$this->getApiDomain().'/API/PostPesapalDirectOrderV4'
);
$iframeRequest->set_parameter('oauth_callback', $this->getCallbackUrl());
$iframeRequest->set_parameter('pesapal_request_data', $xmlPayload);
$iframeRequest->sign_request(new OAuthSignatureMethod_Hmac_Sha1(), $consumer);
return $iframeRequest;
}
/**
* Process the pin message frmo pesapal,
* this will query the pesapal api and
* return a transaction status.
*
* @param string $type
* @param string $id
* @param string $reference
*
* @throws OAuthException
*
* @return string
*/
public function getTransactionStatus(
string $type,
string $id,
string $reference
): string {
$response = null;
if (
$type == 'CHANGE'
&& !empty($id)
) {
// get transaction status
$statusRequest = OAuthRequest::getRequest(
$this->getConsumer(),
$this->getApiDomain().'/api/querypaymentstatus'
);
$statusRequest->set_parameter('pesapal_merchant_reference', $reference);
$statusRequest->set_parameter('pesapal_transaction_tracking_id', $id);
$statusRequest->sign_request(new OAuthSignatureMethod_Hmac_Sha1(), $this->getConsumer());
$client = new Client();
$response = $client
->send(
new Request(
'GET',
(string) $statusRequest
)
);
if (!$response) {
throw new OAuthException($response);
}
}
return $this->transformResponse($response);
}
/**
* @param array $array
* @param SimpleXMLElement $xml
*
* @return SimpleXMLElement
*/
private function arrayToXml(array $array, SimpleXMLElement $xml)
{
foreach ($array as $key => $value) {
is_array($value)
? $this->arrayToXml($value, $xml->addChild($key))
: $xml->addChild($key, $value);
}
return $xml;
}
/**
* @return string
*/
protected function getApiDomain(): string
{
return $this->getDebug()
? $this::DEBUG_DOMAIN
: $this::PROD_DOMAIN;
}
/**
* @param $response
*
* @return string
*/
protected function transformResponse($response): string
{
return 'COMPLETED';
}
}