File: /var/www/vhost/disk-apps/demo.sports-crowd.com/app/Core/Payment/Methods/Wompi/WompiStrategy.php
<?php
declare(strict_types=1);
namespace App\Core\Payment\Methods\Wompi;
use App\Core\Payment\Entities\Payment;
use App\Core\Payment\Entities\PaymentIntentResponse;
use App\Core\Payment\Entities\PaymentRetrieveResponse;
use App\Core\Payment\PaymentMethodInterface;
use App\Core\Payment\PaymentStatusEnum;
use Carbon\Carbon;
use GuzzleHttp\Client;
use Illuminate\Http\Request;
class WompiStrategy implements PaymentMethodInterface
{
const EXPIRATION_TIME_DEFAULT = 30; // Tiempo dado en minutos
const PAYMENT_STATUS = [
'APPROVED' => PaymentStatusEnum::CONFIRMED,
'PENDING' => PaymentStatusEnum::PENDING,
'DECLINED' => PaymentStatusEnum::DECLINED
];
private $parameters;
public function __construct(
$parameters
) {
$this->parameters = $parameters;
}
public function pay(Payment $payment): PaymentIntentResponse
{
$amountInCents = $payment->amount()->total() * 100;
$expirationTime = $this->expirationTime();
$signature = $this->generateSignature(
$payment->reference(),
$amountInCents,
$this->parameters->currency,
$this->parameters->client_signature,
$expirationTime
);
$paymentIntentResponse = new PaymentIntentResponse(
PaymentIntentResponse::ACTION_SHOW,
null
);
$confirmUrl = $this->buildConfirmUrl($payment);
$data = [
'gateway_data' => $this->parameters,
'amountInCents' => $amountInCents,
'reference' => $payment->reference(),
'confirm_url' => $confirmUrl,
'signature' => $signature,
'expirationTime' => $expirationTime
];
$paymentIntentResponse->setView('wompi.webcheckout');
$paymentIntentResponse->setData($data);
return $paymentIntentResponse;
}
public function retrieve(Payment $payment): PaymentRetrieveResponse
{
try {
$client = new Client();
$response = $client->get(
$this->parameters->gw_url_prd . "/transactions?reference=" . $payment->reference(),
[
'headers' => ['Authorization' => 'Bearer ' . $this->parameters->client_secret]
]
);
$body = $response->getBody()->getContents();
$data = json_decode($body)->data;
$data = reset($data);
$retrieveResponse = new PaymentRetrieveResponse(
$data->id,
self::PAYMENT_STATUS[$data->status],
$data->status
);
$retrieveResponse->setRawData(json_decode($body)->data);
return $retrieveResponse;
} catch (\Throwable $th) {
return new PaymentRetrieveResponse(
$payment->paymentGatewayTxId(),
PaymentStatusEnum::PENDING,
$th->getMessage()
);
}
}
private function generateSignature(
$reference,
$price,
$currency,
$clientSignature,
$expirationTime = null
) {
if (!$expirationTime) {
$expirationTime = $this->expirationTime();
}
$signatureData = ($reference . '' . $price . '' . $currency . '' . $expirationTime . '' . $clientSignature);
return hash("sha256", $signatureData);
}
private function expirationTime($time = null)
{
return Carbon::now()->addMinutes($time ?? self::EXPIRATION_TIME_DEFAULT)->toISOString();
}
private function buildConfirmUrl($payment)
{
$url = config('app.url') . '/store/wompi/confirm';
$queryString = [
'paymentGatewayId' => $this->parameters->id,
'reference' => $payment->reference()
];
$queryString = array_merge($queryString, $this->parameters->extraConfirmUrlData);
return Request::create($url)->fullUrlWithQuery($queryString);
}
}