Commit 591ef1ff by Angel MAS

cobro con mercado pago

parent ddacbe0d
...@@ -13,7 +13,7 @@ use Onestartup\Shop\Model\ClientShop as Client; ...@@ -13,7 +13,7 @@ use Onestartup\Shop\Model\ClientShop as Client;
use Onestartup\Shop\Model\ShippingAddres as Addres; use Onestartup\Shop\Model\ShippingAddres as Addres;
use Onestartup\Shop\Model\SaleShop as Sale; use Onestartup\Shop\Model\SaleShop as Sale;
use Onestartup\Shop\Model\DetailShop as Item; use Onestartup\Shop\Model\DetailShop as Item;
use Onestartup\Shop\Payment\MP;
class CartController extends Controller class CartController extends Controller
{ {
...@@ -98,7 +98,10 @@ class CartController extends Controller ...@@ -98,7 +98,10 @@ class CartController extends Controller
public function shipping() public function shipping()
{ {
//\Session::forget('client'); /*\Session::forget('client');
\Session::forget('cart');
\Session::forget('sale');*/
$client = new Client(); $client = new Client();
$addres = new Addres(); $addres = new Addres();
...@@ -132,6 +135,11 @@ class CartController extends Controller ...@@ -132,6 +135,11 @@ class CartController extends Controller
if(\Session::has('client')) { if(\Session::has('client')) {
$client = \Session::get('client'); $client = \Session::get('client');
$addres = $client->shipping; $addres = $client->shipping;
if (\Session::get('client')->email != $request->email) {
$client = new Client();
$addres = new Addres();
}
} }
/** Crea cliente ········· */ /** Crea cliente ········· */
...@@ -210,6 +218,88 @@ class CartController extends Controller ...@@ -210,6 +218,88 @@ class CartController extends Controller
} }
public function payment(Request $request)
{
if (!\Session::has('client')) {
return redirect()->route('cart.shipping');
}
if (!\Session::has('sale')) {
return redirect()->route('cart.shipping');
}
$sale = Sale::find(\Session::get('sale')->id);
$client = $sale->client;
$items = $sale->items;
$addres = $client->shipping;
$detail = '';
foreach ($sale->items as $item) {
$detail = $detail." ".$item->quantity." ".$item->product->name.", ";
}
$detail = $detail." Envio ". $addres->shipping_price->name ." $". $addres->shipping_price->cost .".00";
$mp = new MP('TEST-7957752184054483-101318-9bbc7ef53f975318d2521f05257cb66a__LB_LC__-60150825');
$payment_data = array(
"transaction_amount" => $this->total() + $addres->shipping_price->cost,
"token" => $request->card_token_id,
"description" => $detail,
"installments" => 1,
"payment_method_id" => $request->paymentMethodId,
"payer" => array (
"email" => $client->email,
"first_name"=>$client->name,
)
);
$payment = $mp->post("/v1/payments", $payment_data);
if ($payment['response']['status'] == 'approved') {
$sale->status = 2;
$sale->transaction_id = $payment['response']['id'];
$sale->save();
\Session::forget('client');
\Session::forget('cart');
\Session::forget('sale');
return redirect()
->route('main.shop')
->with('payment_approved', 'payment_approved');
} elseif ($payment['response']['status'] == 'in_process') {
$sale->status = 3;
$sale->transaction_id = $payment['response']['id'];
$sale->save();
\Session::forget('client');
\Session::forget('cart');
\Session::forget('sale');
return redirect()
->route('main.shop')
->with('payment_pending', 'payment_pending');
} else {
return redirect()
->back()
->with('payment_reject', 'payment_reject');
}
//dd($payment);
return $request;
}
private function total() private function total()
{ {
......
This source diff could not be displayed because it is too large. You can view the blob instead.
<?php
namespace Onestartup\Shop\Payment;
use Exception;
/**
* MercadoPago Integration Library
* Access MercadoPago for payments integration
*
* @author hcasatti
*
*/
$GLOBALS["LIB_LOCATION"] = dirname(__FILE__);
class MP {
const version = "0.5.2";
private $client_id;
private $client_secret;
private $ll_access_token;
private $access_data;
private $sandbox = FALSE;
function __construct() {
$i = func_num_args();
if ($i > 2 || $i < 1) {
throw new MercadoPagoException("Invalid arguments. Use CLIENT_ID and CLIENT SECRET, or ACCESS_TOKEN");
}
if ($i == 1) {
$this->ll_access_token = func_get_arg(0);
}
if ($i == 2) {
$this->client_id = func_get_arg(0);
$this->client_secret = func_get_arg(1);
}
}
public function sandbox_mode($enable = NULL) {
if (!is_null($enable)) {
$this->sandbox = $enable === TRUE;
}
return $this->sandbox;
}
/**
* Get Access Token for API use
*/
public function get_access_token() {
if (isset ($this->ll_access_token) && !is_null($this->ll_access_token)) {
return $this->ll_access_token;
}
$app_client_values = array(
'client_id' => $this->client_id,
'client_secret' => $this->client_secret,
'grant_type' => 'client_credentials'
);
$access_data = MPRestClient::post(array(
"uri" => "/oauth/token",
"data" => $app_client_values,
"headers" => array(
"content-type" => "application/x-www-form-urlencoded"
)
));
if ($access_data["status"] != 200) {
throw new MercadoPagoException ($access_data['response']['message'], $access_data['status']);
}
$this->access_data = $access_data['response'];
return $this->access_data['access_token'];
}
/**
* Get information for specific payment
* @param int $id
* @return array(json)
*/
public function get_payment($id) {
$uri_prefix = $this->sandbox ? "/sandbox" : "";
$request = array(
"uri" => $uri_prefix."/collections/notifications/{$id}",
"params" => array(
"access_token" => $this->get_access_token()
)
);
$payment_info = MPRestClient::get($request);
return $payment_info;
}
public function get_payment_info($id) {
return $this->get_payment($id);
}
/**
* Get information for specific authorized payment
* @param id
* @return array(json)
*/
public function get_authorized_payment($id) {
$request = array(
"uri" => "/authorized_payments/{$id}",
"params" => array(
"access_token" => $this->get_access_token()
)
);
$authorized_payment_info = MPRestClient::get($request);
return $authorized_payment_info;
}
/**
* Refund accredited payment
* @param int $id
* @return array(json)
*/
public function refund_payment($id) {
$request = array(
"uri" => "/collections/{$id}",
"params" => array(
"access_token" => $this->get_access_token()
),
"data" => array(
"status" => "refunded"
)
);
$response = MPRestClient::put($request);
return $response;
}
/**
* Cancel pending payment
* @param int $id
* @return array(json)
*/
public function cancel_payment($id) {
$request = array(
"uri" => "/collections/{$id}",
"params" => array(
"access_token" => $this->get_access_token()
),
"data" => array(
"status" => "cancelled"
)
);
$response = MPRestClient::put($request);
return $response;
}
/**
* Cancel preapproval payment
* @param int $id
* @return array(json)
*/
public function cancel_preapproval_payment($id) {
$request = array(
"uri" => "/preapproval/{$id}",
"params" => array(
"access_token" => $this->get_access_token()
),
"data" => array(
"status" => "cancelled"
)
);
$response = MPRestClient::put($request);
return $response;
}
/**
* Search payments according to filters, with pagination
* @param array $filters
* @param int $offset
* @param int $limit
* @return array(json)
*/
public function search_payment($filters, $offset = 0, $limit = 0) {
$filters["offset"] = $offset;
$filters["limit"] = $limit;
$uri_prefix = $this->sandbox ? "/sandbox" : "";
$request = array(
"uri" => $uri_prefix."/collections/search",
"params" => array_merge ($filters, array(
"access_token" => $this->get_access_token()
))
);
$collection_result = MPRestClient::get($request);
return $collection_result;
}
/**
* Create a checkout preference
* @param array $preference
* @return array(json)
*/
public function create_preference($preference) {
$request = array(
"uri" => "/checkout/preferences",
"params" => array(
"access_token" => $this->get_access_token()
),
"data" => $preference
);
$preference_result = MPRestClient::post($request);
return $preference_result;
}
/**
* Update a checkout preference
* @param string $id
* @param array $preference
* @return array(json)
*/
public function update_preference($id, $preference) {
$request = array(
"uri" => "/checkout/preferences/{$id}",
"params" => array(
"access_token" => $this->get_access_token()
),
"data" => $preference
);
$preference_result = MPRestClient::put($request);
return $preference_result;
}
/**
* Get a checkout preference
* @param string $id
* @return array(json)
*/
public function get_preference($id) {
$request = array(
"uri" => "/checkout/preferences/{$id}",
"params" => array(
"access_token" => $this->get_access_token()
)
);
$preference_result = MPRestClient::get($request);
return $preference_result;
}
/**
* Create a preapproval payment
* @param array $preapproval_payment
* @return array(json)
*/
public function create_preapproval_payment($preapproval_payment) {
$request = array(
"uri" => "/preapproval",
"params" => array(
"access_token" => $this->get_access_token()
),
"data" => $preapproval_payment
);
$preapproval_payment_result = MPRestClient::post($request);
return $preapproval_payment_result;
}
/**
* Get a preapproval payment
* @param string $id
* @return array(json)
*/
public function get_preapproval_payment($id) {
$request = array(
"uri" => "/preapproval/{$id}",
"params" => array(
"access_token" => $this->get_access_token()
)
);
$preapproval_payment_result = MPRestClient::get($request);
return $preapproval_payment_result;
}
/**
* Update a preapproval payment
* @param string $preapproval_payment, $id
* @return array(json)
*/
public function update_preapproval_payment($id, $preapproval_payment) {
$request = array(
"uri" => "/preapproval/{$id}",
"params" => array(
"access_token" => $this->get_access_token()
),
"data" => $preapproval_payment
);
$preapproval_payment_result = MPRestClient::put($request);
return $preapproval_payment_result;
}
/* Generic resource call methods */
/**
* Generic resource get
* @param request
* @param params (deprecated)
* @param authenticate = true (deprecated)
*/
public function get($request, $params = null, $authenticate = true) {
if (is_string ($request)) {
$request = array(
"uri" => $request,
"params" => $params,
"authenticate" => $authenticate
);
}
$request["params"] = isset ($request["params"]) && is_array ($request["params"]) ? $request["params"] : array();
if (!isset ($request["authenticate"]) || $request["authenticate"] !== false) {
$request["params"]["access_token"] = $this->get_access_token();
}
$result = MPRestClient::get($request);
return $result;
}
/**
* Generic resource post
* @param request
* @param data (deprecated)
* @param params (deprecated)
*/
public function post($request, $data = null, $params = null) {
if (is_string ($request)) {
$request = array(
"uri" => $request,
"data" => $data,
"params" => $params
);
}
$request["params"] = isset ($request["params"]) && is_array ($request["params"]) ? $request["params"] : array();
if (!isset ($request["authenticate"]) || $request["authenticate"] !== false) {
$request["params"]["access_token"] = $this->get_access_token();
}
$result = MPRestClient::post($request);
return $result;
}
/**
* Generic resource put
* @param request
* @param data (deprecated)
* @param params (deprecated)
*/
public function put($request, $data = null, $params = null) {
if (is_string ($request)) {
$request = array(
"uri" => $request,
"data" => $data,
"params" => $params
);
}
$request["params"] = isset ($request["params"]) && is_array ($request["params"]) ? $request["params"] : array();
if (!isset ($request["authenticate"]) || $request["authenticate"] !== false) {
$request["params"]["access_token"] = $this->get_access_token();
}
$result = MPRestClient::put($request);
return $result;
}
/**
* Generic resource delete
* @param request
* @param data (deprecated)
* @param params (deprecated)
*/
public function delete($request, $params = null) {
if (is_string ($request)) {
$request = array(
"uri" => $request,
"params" => $params
);
}
$request["params"] = isset ($request["params"]) && is_array ($request["params"]) ? $request["params"] : array();
if (!isset ($request["authenticate"]) || $request["authenticate"] !== false) {
$request["params"]["access_token"] = $this->get_access_token();
}
$result = MPRestClient::delete($request);
return $result;
}
/* **************************************************************************************** */
}
/**
* MercadoPago cURL RestClient
*/
class MPRestClient {
const API_BASE_URL = "https://api.mercadopago.com";
private static function build_request($request) {
if (!extension_loaded ("curl")) {
throw new MercadoPagoException("cURL extension not found. You need to enable cURL in your php.ini or another configuration you have.");
}
if (!isset($request["method"])) {
throw new MercadoPagoException("No HTTP METHOD specified");
}
if (!isset($request["uri"])) {
throw new MercadoPagoException("No URI specified");
}
// Set headers
$headers = array("accept: application/json");
$json_content = true;
$form_content = false;
$default_content_type = true;
if (isset($request["headers"]) && is_array($request["headers"])) {
foreach ($request["headers"] as $h => $v) {
$h = strtolower($h);
$v = strtolower($v);
if ($h == "content-type") {
$default_content_type = false;
$json_content = $v == "application/json";
$form_content = $v == "application/x-www-form-urlencoded";
}
array_push ($headers, $h.": ".$v);
}
}
if ($default_content_type) {
array_push($headers, "content-type: application/json");
}
// Build $connect
$connect = curl_init();
curl_setopt($connect, CURLOPT_USERAGENT, "MercadoPago PHP SDK v" . MP::version);
curl_setopt($connect, CURLOPT_RETURNTRANSFER, true);
curl_setopt($connect, CURLOPT_SSL_VERIFYPEER, true);
curl_setopt($connect, CURLOPT_CAINFO, $GLOBALS["LIB_LOCATION"] . "/cacert.pem");
curl_setopt($connect, CURLOPT_CUSTOMREQUEST, $request["method"]);
curl_setopt($connect, CURLOPT_HTTPHEADER, $headers);
// Set parameters and url
if (isset ($request["params"]) && is_array($request["params"]) && count($request["params"]) > 0) {
$request["uri"] .= (strpos($request["uri"], "?") === false) ? "?" : "&";
$request["uri"] .= self::build_query($request["params"]);
}
curl_setopt($connect, CURLOPT_URL, self::API_BASE_URL . $request["uri"]);
// Set data
if (isset($request["data"])) {
if ($json_content) {
if (gettype($request["data"]) == "string") {
json_decode($request["data"], true);
} else {
$request["data"] = json_encode($request["data"]);
}
if(function_exists('json_last_error')) {
$json_error = json_last_error();
if ($json_error != JSON_ERROR_NONE) {
throw new MercadoPagoException("JSON Error [{$json_error}] - Data: ".$request["data"]);
}
}
} else if ($form_content) {
$request["data"] = self::build_query($request["data"]);
}
curl_setopt($connect, CURLOPT_POSTFIELDS, $request["data"]);
}
return $connect;
}
private static function exec($request) {
// private static function exec($method, $uri, $data, $content_type) {
$connect = self::build_request($request);
$api_result = curl_exec($connect);
$api_http_code = curl_getinfo($connect, CURLINFO_HTTP_CODE);
if ($api_result === FALSE) {
throw new MercadoPagoException (curl_error ($connect));
}
$response = array(
"status" => $api_http_code,
"response" => json_decode($api_result, true)
);
if ($response['status'] >= 400) {
$message = $response['response']['message'];
if (isset ($response['response']['cause'])) {
if (isset ($response['response']['cause']['code']) && isset ($response['response']['cause']['description'])) {
$message .= " - ".$response['response']['cause']['code'].': '.$response['response']['cause']['description'];
} else if (is_array ($response['response']['cause'])) {
foreach ($response['response']['cause'] as $cause) {
$message .= " - ".$cause['code'].': '.$cause['description'];
}
}
}
throw new MercadoPagoException ($message, $response['status']);
}
curl_close($connect);
return $response;
}
private static function build_query($params) {
if (function_exists("http_build_query")) {
return http_build_query($params, "", "&");
} else {
foreach ($params as $name => $value) {
$elements[] = "{$name}=" . urlencode($value);
}
return implode("&", $elements);
}
}
public static function get($request) {
$request["method"] = "GET";
return self::exec($request);
}
public static function post($request) {
$request["method"] = "POST";
return self::exec($request);
}
public static function put($request) {
$request["method"] = "PUT";
return self::exec($request);
}
public static function delete($request) {
$request["method"] = "DELETE";
return self::exec($request);
}
}
class MercadoPagoException extends Exception {
public function __construct($message, $code = 500, Exception $previous = null) {
// Default code 500
parent::__construct($message, $code, $previous);
}
}
\ No newline at end of file
...@@ -16,6 +16,7 @@ class CreateSaleShopsTable extends Migration ...@@ -16,6 +16,7 @@ class CreateSaleShopsTable extends Migration
Schema::create('sale_shops', function (Blueprint $table) { Schema::create('sale_shops', function (Blueprint $table) {
$table->increments('id'); $table->increments('id');
$table->string('transaction_id', 455)->nullable();
$table->tinyInteger('status'); $table->tinyInteger('status');
$table->float('total'); $table->float('total');
......
...@@ -7,7 +7,7 @@ use Illuminate\Database\Eloquent\Model; ...@@ -7,7 +7,7 @@ use Illuminate\Database\Eloquent\Model;
class SaleShop extends Model class SaleShop extends Model
{ {
protected $table = 'sale_shops'; protected $table = 'sale_shops';
protected $fillable = ['status', 'total', 'client_id']; protected $fillable = ['status', 'total', 'client_id', 'transaction_id'];
public function client() public function client()
......
...@@ -59,6 +59,8 @@ Route::group(['middleware' => ['web']], function(){ ...@@ -59,6 +59,8 @@ Route::group(['middleware' => ['web']], function(){
Route::get('cart/cancel', 'Onestartup\Shop\Controller\CartController@cancel')->name('cart.cancel'); Route::get('cart/cancel', 'Onestartup\Shop\Controller\CartController@cancel')->name('cart.cancel');
Route::post('cart/store/client', 'Onestartup\Shop\Controller\CartController@storeClient')->name('cart.store.client'); Route::post('cart/store/client', 'Onestartup\Shop\Controller\CartController@storeClient')->name('cart.store.client');
Route::post('cart/payment', 'Onestartup\Shop\Controller\CartController@payment')->name('cart.payment');
Route::get('cart/update/{product_slug}/{quantity}', 'Onestartup\Shop\Controller\CartController@update') Route::get('cart/update/{product_slug}/{quantity}', 'Onestartup\Shop\Controller\CartController@update')
->where('quantity', '[0-9]+') ->where('quantity', '[0-9]+')
->name('cart.update'); ->name('cart.update');
......
@extends('shop-public::layout') @extends('shop-public::layout')
@section('pageTitle', 'Finalizar compra') @section('pageTitle', 'Finalizar compra')
@section('content') @section('content')
@php @php
setlocale(LC_MONETARY, 'en_US'); setlocale(LC_MONETARY, 'en_US');
@endphp @endphp
<code> <code>
Variables disponibles: Variables disponibles:
<ul> <ul>
...@@ -54,16 +56,124 @@ setlocale(LC_MONETARY, 'en_US'); ...@@ -54,16 +56,124 @@ setlocale(LC_MONETARY, 'en_US');
<section> <section>
<h4>Formulario de pago</h4> <h4>Formulario de pago</h4>
<pre>
form
</pre>
</section>
@include('shop-public::forms.fields-payment')
</section>
@endsection @endsection
@section('scripts_extra') @section('scripts_extra')
<script type="text/javascript">
Mercadopago.setPublishableKey("TEST-73a8fe53-17bf-4060-b2b8-a069cc779a11");
$("#form-pagar-mp").submit(function( event ) {
$('.btn-submit').attr('disabled', 'disabled');
swal({
text: "Espera por favor, estamos enviando tu pago...",
imageUrl: "/assets/img/ripple.gif",
showConfirmButton: false,
allowEscapeKey: false,
allowOutsideClick: false,
closeOnConfirm: false,
closeOnCancel: false
});
var $form = $(this);
Mercadopago.createToken($form, mpResponseHandler);
event.preventDefault();
return false;
});
var mpResponseHandler = function(status, response) {
var $form = $('#form-pagar-mp');
if (response.error) {
alert("ocurri&oacute; un error: "+JSON.stringify(response));
console.log(response);
swal.close();
var error = '<div class="alert alert-dismissable alert-danger">'+
'<button type="button" class="close" data-dismiss="alert" aria-hidden="true">&times;</button>'+
'Haz ingresado valores invalidos: <br>Revisa los datos capturados o intenta con otra tarjeta'+
'</div>';
$("#errors-card").html(error);
$('.btn-submit').removeAttr('disabled');
} else {
var card_token_id = response.id;
$form.append($('<input type="hidden" id="card_token_id" name="card_token_id"/>').val(card_token_id));
//alert("card_token_id: "+card_token_id);
$("#errors-card").html("");
$form.get(0).submit();
}
}
function addEvent(el, eventName, handler){
if (el.addEventListener) {
el.addEventListener(eventName, handler);
} else {
el.attachEvent('on' + eventName, function(){
handler.call(el);
});
}
};
function getBin() {
var ccNumber = document.querySelector('input[data-checkout="cardNumber"]');
return ccNumber.value.replace(/[ .-]/g, '').slice(0, 6);
};
function guessingPaymentMethod(event) {
var bin = getBin();
if (event.type == "keyup") {
if (bin.length >= 6) {
Mercadopago.getPaymentMethod({
"bin": bin
}, setPaymentMethodInfo);
}
} else {
setTimeout(function() {
if (bin.length >= 6) {
Mercadopago.getPaymentMethod({
"bin": bin
}, setPaymentMethodInfo);
}
}, 100);
}
};
function setPaymentMethodInfo(status, response) {
console.log("holiholi");
if (status == 200) {
// do somethings ex: show logo of the payment method
var form = document.querySelector('#form-pagar-mp');
if (document.querySelector("input[name=paymentMethodId]") == null) {
var paymentMethod = document.createElement('input');
paymentMethod.setAttribute('name', "paymentMethodId");
paymentMethod.setAttribute('type', "hidden");
paymentMethod.setAttribute('value', response[0].id);
form.appendChild(paymentMethod);
} else {
document.querySelector("input[name=paymentMethodId]").value = response[0].id;
}
}
};
addEvent(document.querySelector('input[data-checkout="cardNumber"]'), 'keyup', guessingPaymentMethod);
addEvent(document.querySelector('input[data-checkout="cardNumber"]'), 'change', guessingPaymentMethod);
</script>
@endsection @endsection
\ No newline at end of file
<form action="{{route('cart.payment')}}" method="POST" id="form-pagar-mp">
{{ csrf_field() }}
<p>Número de tarjeta</p>
<input type="text" id="cardNumber" data-checkout="cardNumber" placeholder="4509 9535 6623 3704" size="16" name="number" required="required" class="form-control" min="16" max="16" />
<p>Nombre del titular</p>
<input type="text" size="20" name="name" data-checkout="cardholderName" placeholder="Ej. Roberto Carlos" required="required" class="form-control" />
<p>Fecha de expiración</p>
<input type="text" size="2" name="month" data-checkout="cardExpirationMonth" placeholder="Ej. 09" required="required" class="form-control" align="right" />
<input type="text" size="4" name="year" data-checkout="cardExpirationYear" placeholder="Ej. 2018" required="required" class="form-control" align="left"/>
<p>Código de seguridad</p>
<input class="form-white" type="text" size="4" name="cvc" data-checkout="securityCode" placeholder="Ej. 543" required="required" class="form-control"/>
<input name="paymentMethodId" type="hidden">
<button type="submit">
Pagar {{ money_format('%(#10n', ($total + $addres->shipping_price->cost)) }}
</button>
</form>
\ No newline at end of file
...@@ -25,8 +25,27 @@ ...@@ -25,8 +25,27 @@
integrity="sha256-FgpCb/KJQlLNfOu91ta32o/NMZxltwRo8QtmkMRdAu8=" integrity="sha256-FgpCb/KJQlLNfOu91ta32o/NMZxltwRo8QtmkMRdAu8="
crossorigin="anonymous"></script> crossorigin="anonymous"></script>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/jquery-steps/1.1.0/jquery.steps.min.js"></script> <script src="https://secure.mlstatic.com/sdk/javascript/v1/mercadopago.js"></script>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/jquery-validate/1.17.0/jquery.validate.js"></script>
{{-- Mensajes de alerta de pagos --}}
@if(Session::has('payment_approved'))
<script type="text/javascript">
swal("Gracias por tu compra", "El pago ha sido aceptado, revisa tu correo", "success")
</script>
@endif
@if(Session::has('payment_reject'))
<script type="text/javascript">
swal("Pago rechazado", "Tuvimos problemas para procesar tu pago, verifica tus datos o intenta con otra tarjeta", "error")
</script>
@endif
@if(Session::has('payment_pending'))
<script type="text/javascript">
swal("Pago pendiente", "Estamos procesando tu pago, te notificaremos por correo el estatus", "warning")
</script>
@endif
<!-- ******************************************* --> <!-- ******************************************* -->
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment