File: /var/www/vhost/disk-apps/demo.sports-crowd.com/app/Http/Controllers/WompiApiController.php
<?php
namespace App\Http\Controllers;
use App\Core\Order\Application\OrderService;
use App\Core\Payment\Application\PaymentTransactionService;
use App\Core\Payment\PaymentMethodContext;
use App\Core\Payment\Methods\WompiApi\WompiApiClient;
use App\Core\Payment\Methods\WompiApi\WompiApiException;
use App\Core\Payment\Methods\WompiApi\WompiApiStrategy;
use App\Core\Ticket\Application\TicketService;
use Illuminate\Http\Request;
use App\Http\Controllers\Interfaces\PaymentGatewayControllerInterface;
use App\Models\UserPaymentSource;
use Illuminate\Http\Response;
class WompiApiController extends PaymentGatewayBridgeController implements PaymentGatewayControllerInterface
{
private $orderService;
private $ticketService;
private $paymentTransactionService;
private $util;
public function __construct()
{
$this->determinateWebService('wompiapi', 'wompiapi');
$this->orderService = new OrderService();
$this->ticketService = new TicketService();
$this->paymentTransactionService = new PaymentTransactionService();
$this->util = new UtilController();
}
public function payment(Request $request)
{
// no implemented
}
public function confirmFromWompi(Request $request)
{
$orderPaymentTransaction = $this->orderService->getByReference($request->reference);
$ticketPaymentTransaction = $this->ticketService->getByReference($request->reference);
$genericPaymentTransaction = $this->paymentTransactionService->getByReference($request->reference);
$paymentTransaction = $orderPaymentTransaction ?? $ticketPaymentTransaction ?? $genericPaymentTransaction;
if (!is_null($paymentTransaction)) {
if ($paymentTransaction === $orderPaymentTransaction) {
$this->orderService->setPaymentGatewayTxId($paymentTransaction, $request->id);
}
if ($paymentTransaction === $ticketPaymentTransaction) {
$this->ticketService->setPaymentGatewayTxId($paymentTransaction, $request->id);
}
if ($paymentTransaction === $genericPaymentTransaction) {
$this->paymentTransactionService->setPaymentGatewayTxId($paymentTransaction, $request->id);
}
}
$processPayment = new PaymentController($request);
return $processPayment->payment($request);
}
public function userPaymentSources(Request $request)
{
$origin = null;
$orderPaymentTransaction = $this->orderService->getByReference($request->reference);
$ticketPaymentTransaction = $this->ticketService->getByReference($request->reference);
$genericPaymentTransaction = $this->paymentTransactionService->getByReference($request->reference);
$paymentTransaction = $orderPaymentTransaction ?? $ticketPaymentTransaction ?? $genericPaymentTransaction;
if (!is_null($paymentTransaction)) {
if ($paymentTransaction === $orderPaymentTransaction) {
$paymentSources = UserPaymentSource::select('payment_source')
->where('user_id', $paymentTransaction->client_id)
->where('gateway_payment_id', $paymentTransaction->gateway_payments_id)
->get();
}
if ($paymentTransaction === $ticketPaymentTransaction) {
$paymentSources = UserPaymentSource::select('payment_source')
->where('user_id', $paymentTransaction->user_id_log)
->where('gateway_payment_id', $paymentTransaction->gateway_payments_id)
->get();
}
if ($paymentTransaction === $genericPaymentTransaction) {
$payment = $this->paymentTransactionService->buildPayment($paymentTransaction);
$paymentSources = UserPaymentSource::select('payment_source')
->where('user_id', $payment->customer()->id())
->where('gateway_payment_id', $payment->paymentGatewayId())
->get();
}
}
return response()->json($paymentSources);
}
public function doPayment(Request $request)
{
try {
$transaction = $this->createTransaction($request);
return response()->json($transaction);
} catch (\Throwable $th) {
return response()->json(['message' => $th->getMessage()], Response::HTTP_INTERNAL_SERVER_ERROR);
}
}
private function createTransaction($request)
{
$origin = null;
$orderPaymentTransaction = $this->orderService->getByReference($request->reference);
$ticketPaymentTransaction = $this->ticketService->getByReference($request->reference);
$genericPaymentTransaction = $this->paymentTransactionService->getByReference($request->reference);
$paymentTransaction = $orderPaymentTransaction ?? $ticketPaymentTransaction ?? $genericPaymentTransaction;
$currency = 'COP';
if (!is_null($paymentTransaction)) {
if ($paymentTransaction === $orderPaymentTransaction) {
$origin = 'order';
$paymentMethodContext = PaymentMethodContext::init($paymentTransaction->gateway_payments_id);
$amount = $paymentTransaction->total_price;
}
if ($paymentTransaction === $ticketPaymentTransaction) {
$origin = 'ticket';
$paymentMethodContext = PaymentMethodContext::init($paymentTransaction->gateway_payments_id);
$amount = $paymentTransaction->total;
}
if ($paymentTransaction === $genericPaymentTransaction) {
$origin = 'generic';
$payment = $this->paymentTransactionService->buildPayment($paymentTransaction);
$paymentMethodContext = PaymentMethodContext::init($payment->paymentGatewayId());
$amount = $payment->amount()->total();
// $currency = $payment->amount()->currency();
}
}
$paymentTransaction->origin = $origin;
$gatewayParameters = $paymentMethodContext->parameters();
$wompiApiClient = new WompiApiClient($gatewayParameters);
$amountInCents = $amount * 100;
$signature = WompiApiStrategy::generateSignature(
$request->reference,
$amountInCents,
$currency,
$gatewayParameters->client_signature
);
$transaction = (object)[
"amount_in_cents" => $amountInCents,
"currency" => "COP",
"signature" => $signature,
"customer_email" => $request->email,
"reference" => $request->reference,
"customer_data" => (object)[
"phone_number" => $request->phone_number,
"full_name" => $request->full_name,
"legal_id" => $request->document_number,
"legal_id_type" => $request->document_type
],
"payment_method" => (object)[
"type" => $request->payment_method,
"installments" => $request->installments
]
];
if ($request->has('payment_source')) {
$transaction->payment_source_id = $request->payment_source;
} else {
$cardToken = $this->tokenizeCard($wompiApiClient, $request);
if ($request->has('store_payment_source')) {
$paymentSource = $this->createUserPaymentSource(
$wompiApiClient,
$request,
$paymentTransaction,
$cardToken->data->id
);
$transaction->payment_source_id = $paymentSource->data->id;
} else {
$transaction->acceptance_token = $request->accept_wompi_termcons;
$transaction->payment_method->token = $cardToken->data->id;
$paymentTransaction->membership->auto_renew = false;
$paymentTransaction->membership->save();
}
}
try {
$transactionResponse = $wompiApiClient->createTransaction($transaction);
} catch (WompiApiException $th) {
throw $th;
}
// TODO: this line avoids errors when transactions is being updated - check and refactor
unset($paymentTransaction->origin);
if (!is_null($paymentTransaction)) {
if ($paymentTransaction === $orderPaymentTransaction) {
$this->orderService->setPaymentGatewayTxId($paymentTransaction, $transactionResponse->data->id);
}
if ($paymentTransaction === $ticketPaymentTransaction) {
$this->ticketService->setPaymentGatewayTxId($paymentTransaction, $transactionResponse->data->id);
}
if ($paymentTransaction === $genericPaymentTransaction) {
$this->paymentTransactionService->setPaymentGatewayTxId(
$paymentTransaction, $transactionResponse->data->id
);
}
}
return $transactionResponse;
}
private function tokenizeCard($wompiApiClient, $request)
{
$cardTokenRequest = (object)[
"number" => $request->card_number, // Número de tarjeta (como un string, sin espacios)
"exp_month" => $request->exp_month, // Mes de expiración (como string de 2 dígitos)
"exp_year" => $request->exp_year, // Año de expiración (como string de 2 dígitos)
"cvc" => $request->cvc, // Código de seguridad (como string de 3 o 4 dígitos)
"card_holder" => $request->card_holder // Nombre del tarjeta habiente (string de mínimo 5 caracteres)
];
return $wompiApiClient->tokenizeCard($cardTokenRequest);
}
public function createUserPaymentSource($wompiApiClient, $request, $paymentTransaction, $token)
{
$paymentSourceRequest = (object)[
"type" => $request->payment_method,
"token" => $token,
"customer_email" => $request->email,
"acceptance_token" => $request->accept_wompi_termcons
];
$paymentSource = $wompiApiClient->createPaymentSource($paymentSourceRequest);
$userPaymentSourceData = [
"gateway_payment_id" => $paymentTransaction->gateway_payments_id,
"payment_source" => $paymentSource->data
];
if ($paymentTransaction->origin === 'order') {
$userPaymentSourceData['user_id'] = $paymentTransaction->client_id;
}
if ($paymentTransaction->origin === 'ticket') {
$userPaymentSourceData['user_id'] = $paymentTransaction->user_id_log;
}
if ($paymentTransaction->origin === 'generic') {
if ($paymentTransaction->purchase) {
$userPaymentSourceData['user_id'] = $paymentTransaction->purchase->user_id;
}
if ($paymentTransaction->tournament) {
$userPaymentSourceData['user_id'] = $paymentTransaction->tournament->academy_user->user->id;
}
if ($paymentTransaction->membership) {
$userPaymentSourceData['user_id'] = $paymentTransaction->membership->user->id;
}
}
UserPaymentSource::create($userPaymentSourceData);
return $paymentSource;
}
public function webhooksListener(Request $request)
{
$this->util->logFile($request);
$requestContent = json_decode($request->getContent());
$gatewayTxId = $requestContent->data->transaction->id;
$reference = $requestContent->data->transaction->reference;
$orderPaymentTransaction = $this->orderService->getByReference($reference);
$ticketPaymentTransaction = $this->ticketService->getByReference($reference);
$genericPaymentTransaction = $this->paymentTransactionService->getByReference($reference);
$paymentTransaction = $orderPaymentTransaction ?? $ticketPaymentTransaction ?? $genericPaymentTransaction;
if (!is_null($paymentTransaction)) {
if ($paymentTransaction === $orderPaymentTransaction) {
$this->orderService->setPaymentGatewayTxId($paymentTransaction, $gatewayTxId);
$this->orderService->validatePayment($paymentTransaction);
}
if ($paymentTransaction === $ticketPaymentTransaction) {
$this->ticketService->setPaymentGatewayTxId($paymentTransaction, $gatewayTxId);
$this->ticketService->validatePayment($paymentTransaction);
}
if ($paymentTransaction === $genericPaymentTransaction) {
$this->paymentTransactionService->setPaymentGatewayTxId($paymentTransaction, $gatewayTxId);
$this->paymentTransactionService->validatePayment($paymentTransaction);
}
}
return response('OK', Response::HTTP_OK);
}
public function getTransactionByReference(Request $request)
{
// no implemented
}
public function validatePayment($transactionId, $reference)
{
// no implemented
}
public function responseTransaction(Request $request)
{
// no implemented
}
public function getAuthorizationCode($gatewayResponse)
{
return null;
}
public function getPaymentMethod($gatewayResponse){
return null;
}
}