Update Refund journeys
1. Updated the refund journeys so that they use the payment Gateway Factory. 2. Improved request data going in and out of the session. 3. Show error message when Stripe SCA journey fails. 4. Update migration.
This commit is contained in:
parent
8bcf106ffe
commit
0c1f4c8619
|
|
@ -181,22 +181,17 @@ class EventCheckoutController extends Controller
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (config('attendize.enable_dummy_payment_gateway') == TRUE) {
|
$activeAccountPaymentGateway = $event->account->getGateway($event->account->payment_gateway_id);
|
||||||
$activeAccountPaymentGateway = new AccountPaymentGateway();
|
//if no payment gateway configured and no offline pay, don't go to the next step and show user error
|
||||||
$activeAccountPaymentGateway->fill(['payment_gateway_id' => config('attendize.payment_gateway_dummy')]);
|
if (empty($activeAccountPaymentGateway) && !$event->enable_offline_payments) {
|
||||||
$paymentGateway = $activeAccountPaymentGateway;
|
return response()->json([
|
||||||
} else {
|
'status' => 'error',
|
||||||
$activeAccountPaymentGateway = $event->account->getGateway($event->account->payment_gateway_id);
|
'message' => 'No payment gateway configured',
|
||||||
//if no payment gateway configured and no offline pay, don't go to the next step and show user error
|
]);
|
||||||
if (empty($activeAccountPaymentGateway) && !$event->enable_offline_payments) {
|
|
||||||
return response()->json([
|
|
||||||
'status' => 'error',
|
|
||||||
'message' => 'No payment gateway configured',
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
$paymentGateway = $activeAccountPaymentGateway ? $activeAccountPaymentGateway->payment_gateway : false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$paymentGateway = $activeAccountPaymentGateway ? $activeAccountPaymentGateway->payment_gateway : false;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The 'ticket_order_{event_id}' session stores everything we need to complete the transaction.
|
* The 'ticket_order_{event_id}' session stores everything we need to complete the transaction.
|
||||||
*/
|
*/
|
||||||
|
|
@ -280,8 +275,6 @@ class EventCheckoutController extends Controller
|
||||||
|
|
||||||
public function postValidateOrder(Request $request, $event_id)
|
public function postValidateOrder(Request $request, $event_id)
|
||||||
{
|
{
|
||||||
session()->push('ticket_order_' . $event_id . '.request_data', $request->all());
|
|
||||||
|
|
||||||
//If there's no session kill the request and redirect back to the event homepage.
|
//If there's no session kill the request and redirect back to the event homepage.
|
||||||
if (!session()->get('ticket_order_' . $event_id)) {
|
if (!session()->get('ticket_order_' . $event_id)) {
|
||||||
return response()->json([
|
return response()->json([
|
||||||
|
|
@ -293,6 +286,13 @@ class EventCheckoutController extends Controller
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$request_data = session()->get('ticket_order_' . $event_id . ".request_data");
|
||||||
|
$request_data = (!empty($request_data[0])) ? array_merge($request_data[0], $request->all())
|
||||||
|
: $request->all();
|
||||||
|
|
||||||
|
session()->remove('ticket_order_' . $event_id . '.request_data');
|
||||||
|
session()->push('ticket_order_' . $event_id . '.request_data', $request_data);
|
||||||
|
|
||||||
$event = Event::findOrFail($event_id);
|
$event = Event::findOrFail($event_id);
|
||||||
$order = new Order();
|
$order = new Order();
|
||||||
$ticket_order = session()->get('ticket_order_' . $event_id);
|
$ticket_order = session()->get('ticket_order_' . $event_id);
|
||||||
|
|
@ -354,6 +354,8 @@ class EventCheckoutController extends Controller
|
||||||
$orderService = new OrderService($order_session['order_total'], $order_session['total_booking_fee'], $event);
|
$orderService = new OrderService($order_session['order_total'], $order_session['total_booking_fee'], $event);
|
||||||
$orderService->calculateFinalCosts();
|
$orderService->calculateFinalCosts();
|
||||||
|
|
||||||
|
$payment_failed = $request->get('is_payment_failed') ? 1 : 0;
|
||||||
|
|
||||||
$secondsToExpire = Carbon::now()->diffInSeconds($order_session['expires']);
|
$secondsToExpire = Carbon::now()->diffInSeconds($order_session['expires']);
|
||||||
|
|
||||||
$viewData = ['event' => $event,
|
$viewData = ['event' => $event,
|
||||||
|
|
@ -363,7 +365,8 @@ class EventCheckoutController extends Controller
|
||||||
'order_requires_payment' => (ceil($order_session['order_total']) == 0) ? false : true,
|
'order_requires_payment' => (ceil($order_session['order_total']) == 0) ? false : true,
|
||||||
'account_payment_gateway' => $account_payment_gateway,
|
'account_payment_gateway' => $account_payment_gateway,
|
||||||
'payment_gateway' => $payment_gateway,
|
'payment_gateway' => $payment_gateway,
|
||||||
'secondsToExpire' => $secondsToExpire
|
'secondsToExpire' => $secondsToExpire,
|
||||||
|
'payment_failed' => $payment_failed
|
||||||
];
|
];
|
||||||
|
|
||||||
return view('Public.ViewEvent.EventPagePayment', $viewData);
|
return view('Public.ViewEvent.EventPagePayment', $viewData);
|
||||||
|
|
@ -380,10 +383,14 @@ class EventCheckoutController extends Controller
|
||||||
*/
|
*/
|
||||||
public function postCreateOrder(Request $request, $event_id)
|
public function postCreateOrder(Request $request, $event_id)
|
||||||
{
|
{
|
||||||
//Add the request data to a session in case payment is required off-site
|
$request_data = $ticket_order = session()->get('ticket_order_' . $event_id . ".request_data");
|
||||||
session()->push('ticket_order_' . $event_id . '.request_data', $request->except(['cardnumber', 'cvc']));
|
$request_data = array_merge($request_data[0], $request->except(['cardnumber', 'cvc']));
|
||||||
|
|
||||||
|
session()->remove('ticket_order_' . $event_id . '.request_data');
|
||||||
|
session()->push('ticket_order_' . $event_id . '.request_data', $request_data);
|
||||||
|
|
||||||
$ticket_order = session()->get('ticket_order_' . $event_id);
|
$ticket_order = session()->get('ticket_order_' . $event_id);
|
||||||
|
|
||||||
$event = Event::findOrFail($event_id);
|
$event = Event::findOrFail($event_id);
|
||||||
|
|
||||||
$order_requires_payment = $ticket_order['order_requires_payment'];
|
$order_requires_payment = $ticket_order['order_requires_payment'];
|
||||||
|
|
@ -416,7 +423,6 @@ class EventCheckoutController extends Controller
|
||||||
|
|
||||||
$response = $gateway->startTransaction($order_total, $order_email, $event);
|
$response = $gateway->startTransaction($order_total, $order_email, $event);
|
||||||
|
|
||||||
|
|
||||||
if ($response->isSuccessful()) {
|
if ($response->isSuccessful()) {
|
||||||
|
|
||||||
session()->push('ticket_order_' . $event_id . '.transaction_id',
|
session()->push('ticket_order_' . $event_id . '.transaction_id',
|
||||||
|
|
@ -426,12 +432,11 @@ class EventCheckoutController extends Controller
|
||||||
|
|
||||||
} elseif ($response->isRedirect()) {
|
} elseif ($response->isRedirect()) {
|
||||||
|
|
||||||
Log::error("reference : " . $response->getTransactionReference());
|
$additionalData = ($gateway->storeAdditionalData()) ? $gateway->getAdditionalData($response) : array();
|
||||||
|
|
||||||
//As we're going off-site for payment we need to store some data in a session so it's available
|
session()->push('ticket_order_' . $event_id . '.transaction_data',
|
||||||
//when we return
|
$gateway->getTransactionData() + $additionalData);
|
||||||
|
|
||||||
session()->push('ticket_order_' . $event_id . '.transaction_data', $gateway->getTransactionData());
|
|
||||||
|
|
||||||
Log::info("Redirect url: " . $response->getRedirectUrl());
|
Log::info("Redirect url: " . $response->getRedirectUrl());
|
||||||
|
|
||||||
|
|
@ -496,7 +501,7 @@ class EventCheckoutController extends Controller
|
||||||
return $this->completeOrder($event_id, false);
|
return $this->completeOrder($event_id, false);
|
||||||
} else {
|
} else {
|
||||||
session()->flash('message', $response->getMessage());
|
session()->flash('message', $response->getMessage());
|
||||||
return response()->redirectToRoute('showEventCheckout', [
|
return response()->redirectToRoute('showEventPayment', [
|
||||||
'event_id' => $event_id,
|
'event_id' => $event_id,
|
||||||
'is_payment_failed' => 1,
|
'is_payment_failed' => 1,
|
||||||
]);
|
]);
|
||||||
|
|
@ -533,6 +538,10 @@ class EventCheckoutController extends Controller
|
||||||
$order->transaction_id = $ticket_order['transaction_id'][0];
|
$order->transaction_id = $ticket_order['transaction_id'][0];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (isset($ticket_order['transaction_data'][0]['payment_intent'])) {
|
||||||
|
$order->payment_intent = $ticket_order['transaction_data'][0]['payment_intent'];
|
||||||
|
}
|
||||||
|
|
||||||
if ($ticket_order['order_requires_payment'] && !isset($request_data['pay_offline'])) {
|
if ($ticket_order['order_requires_payment'] && !isset($request_data['pay_offline'])) {
|
||||||
$order->payment_gateway_id = $ticket_order['payment_gateway']->id;
|
$order->payment_gateway_id = $ticket_order['payment_gateway']->id;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,9 @@ use App\Models\Attendee;
|
||||||
use App\Models\Event;
|
use App\Models\Event;
|
||||||
use App\Models\EventStats;
|
use App\Models\EventStats;
|
||||||
use App\Models\Order;
|
use App\Models\Order;
|
||||||
|
use App\Models\PaymentGateway;
|
||||||
use App\Services\Order as OrderService;
|
use App\Services\Order as OrderService;
|
||||||
|
use App\Services\PaymentGateway\Factory as PaymentGatewayFactory;
|
||||||
use DB;
|
use DB;
|
||||||
use Excel;
|
use Excel;
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
|
|
@ -196,11 +198,10 @@ class EventOrdersController extends MyBaseController
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Cancels an order
|
|
||||||
*
|
|
||||||
* @param Request $request
|
* @param Request $request
|
||||||
* @param $order_id
|
* @param $order_id
|
||||||
* @return mixed
|
* @return \Illuminate\Http\JsonResponse
|
||||||
|
* @throws \Exception
|
||||||
*/
|
*/
|
||||||
public function postCancelOrder(Request $request, $order_id)
|
public function postCancelOrder(Request $request, $order_id)
|
||||||
{
|
{
|
||||||
|
|
@ -244,24 +245,23 @@ class EventOrdersController extends MyBaseController
|
||||||
$order->event->currency))]);
|
$order->event->currency))]);
|
||||||
}
|
}
|
||||||
if (!$error_message) {
|
if (!$error_message) {
|
||||||
try {
|
|
||||||
$gateway = Omnipay::create($order->payment_gateway->name);
|
|
||||||
|
|
||||||
$gateway->initialize($order->account->getGateway($order->payment_gateway->id)->config);
|
try {
|
||||||
|
|
||||||
|
$payment_gateway_config = $order->account->getGateway($order->payment_gateway->id)->config + [
|
||||||
|
'testMode' => config('attendize.enable_test_payments')];
|
||||||
|
|
||||||
|
$payment_gateway_factory = new PaymentGatewayFactory();
|
||||||
|
$gateway = $payment_gateway_factory->create($order->payment_gateway->name, $payment_gateway_config);
|
||||||
|
|
||||||
if ($refund_type === 'full') { /* Full refund */
|
if ($refund_type === 'full') { /* Full refund */
|
||||||
$refund_amount = $order->organiser_amount - $order->amount_refunded;
|
$refund_amount = $order->organiser_amount - $order->amount_refunded;
|
||||||
}
|
}
|
||||||
|
|
||||||
$request = $gateway->refund([
|
$refund_application_fee = floatval($order->booking_fee) > 0 ? true : false;
|
||||||
'transactionReference' => $order->transaction_id,
|
$response = $gateway->refundTransaction($order, $refund_amount, $refund_application_fee);
|
||||||
'amount' => $refund_amount,
|
|
||||||
'refundApplicationFee' => floatval($order->booking_fee) > 0 ? true : false,
|
|
||||||
]);
|
|
||||||
|
|
||||||
$response = $request->send();
|
if ($response['successful']) {
|
||||||
|
|
||||||
if ($response->isSuccessful()) {
|
|
||||||
/* Update the event sales volume*/
|
/* Update the event sales volume*/
|
||||||
$order->event->decrement('sales_volume', $refund_amount);
|
$order->event->decrement('sales_volume', $refund_amount);
|
||||||
$order->amount_refunded = round(($order->amount_refunded + $refund_amount), 2);
|
$order->amount_refunded = round(($order->amount_refunded + $refund_amount), 2);
|
||||||
|
|
@ -274,10 +274,11 @@ class EventOrdersController extends MyBaseController
|
||||||
$order->order_status_id = config('attendize.order_partially_refunded');
|
$order->order_status_id = config('attendize.order_partially_refunded');
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
$error_message = $response->getMessage();
|
$error_message = $response['error_message'];
|
||||||
}
|
}
|
||||||
|
|
||||||
$order->save();
|
$order->save();
|
||||||
|
|
||||||
} catch (\Exeption $e) {
|
} catch (\Exeption $e) {
|
||||||
Log::error($e);
|
Log::error($e);
|
||||||
$error_message = trans("Controllers.refund_exception");
|
$error_message = trans("Controllers.refund_exception");
|
||||||
|
|
|
||||||
|
|
@ -49,4 +49,31 @@ class Dummy
|
||||||
public function extractRequestParameters($request) {}
|
public function extractRequestParameters($request) {}
|
||||||
|
|
||||||
public function completeTransaction($transactionId) {}
|
public function completeTransaction($transactionId) {}
|
||||||
|
|
||||||
|
public function getAdditionalData() {}
|
||||||
|
|
||||||
|
public function storeAdditionalData() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function refundTransaction($order, $refund_amount, $refund_application_fee) {
|
||||||
|
|
||||||
|
$request = $this->gateway->refund([
|
||||||
|
'transactionReference' => $order->transaction_id,
|
||||||
|
'amount' => $refund_amount,
|
||||||
|
'refundApplicationFee' => $refund_application_fee
|
||||||
|
]);
|
||||||
|
|
||||||
|
$response = $request->send();
|
||||||
|
|
||||||
|
if ($response->isSuccessful()) {
|
||||||
|
$refundResponse['successful'] = true;
|
||||||
|
} else {
|
||||||
|
$refundResponse['successful'] = false;
|
||||||
|
$refundResponse['error_message'] = $response->getMessage();
|
||||||
|
}
|
||||||
|
|
||||||
|
return $refundResponse;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
@ -42,7 +42,8 @@ class Stripe
|
||||||
return $response;
|
return $response;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getTransactionData() {
|
public function getTransactionData()
|
||||||
|
{
|
||||||
return $this->transaction_data;
|
return $this->transaction_data;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -55,6 +56,37 @@ class Stripe
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public function completeTransaction($transactionId) {}
|
public function completeTransaction($transactionId)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getAdditionalData()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public function storeAdditionalData()
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function refundTransaction($order, $refund_amount, $refund_application_fee)
|
||||||
|
{
|
||||||
|
|
||||||
|
$request = $this->gateway->refund([
|
||||||
|
'transactionReference' => $order->transaction_id,
|
||||||
|
'amount' => $refund_amount,
|
||||||
|
'refundApplicationFee' => $refund_application_fee
|
||||||
|
]);
|
||||||
|
|
||||||
|
$response = $request->send();
|
||||||
|
|
||||||
|
if ($response->isSuccessful()) {
|
||||||
|
$refundResponse['successful'] = true;
|
||||||
|
} else {
|
||||||
|
$refundResponse['successful'] = false;
|
||||||
|
$refundResponse['error_message'] = $response->getMessage();
|
||||||
|
}
|
||||||
|
|
||||||
|
return $refundResponse;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -2,7 +2,6 @@
|
||||||
|
|
||||||
namespace Services\PaymentGateway;
|
namespace Services\PaymentGateway;
|
||||||
|
|
||||||
|
|
||||||
use Illuminate\Support\Facades\Log;
|
use Illuminate\Support\Facades\Log;
|
||||||
|
|
||||||
class StripeSCA
|
class StripeSCA
|
||||||
|
|
@ -14,7 +13,7 @@ class StripeSCA
|
||||||
|
|
||||||
private $gateway;
|
private $gateway;
|
||||||
|
|
||||||
private $extra_params = ['paymentMethod','payment_intent'];
|
private $extra_params = ['paymentMethod', 'payment_intent'];
|
||||||
|
|
||||||
public function __construct($gateway)
|
public function __construct($gateway)
|
||||||
{
|
{
|
||||||
|
|
@ -45,14 +44,14 @@ class StripeSCA
|
||||||
|
|
||||||
public function startTransaction($order_total, $order_email, $event)
|
public function startTransaction($order_total, $order_email, $event)
|
||||||
{
|
{
|
||||||
|
|
||||||
$this->createTransactionData($order_total, $order_email, $event);
|
$this->createTransactionData($order_total, $order_email, $event);
|
||||||
$response = $this->gateway->authorize($this->transaction_data)->send();
|
$response = $this->gateway->authorize($this->transaction_data)->send();
|
||||||
|
|
||||||
return $response;
|
return $response;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getTransactionData() {
|
public function getTransactionData()
|
||||||
|
{
|
||||||
return $this->transaction_data;
|
return $this->transaction_data;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -65,11 +64,12 @@ class StripeSCA
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public function completeTransaction($transactionId = '') {
|
public function completeTransaction($transactionId = '')
|
||||||
|
{
|
||||||
|
|
||||||
$intentData = array(
|
$intentData = [
|
||||||
'paymentIntentReference' => $this->options['payment_intent'],
|
'paymentIntentReference' => $this->options['payment_intent'],
|
||||||
);
|
];
|
||||||
|
|
||||||
$paymentIntent = $this->gateway->fetchPaymentIntent($intentData);
|
$paymentIntent = $this->gateway->fetchPaymentIntent($intentData);
|
||||||
$response = $paymentIntent->send();
|
$response = $paymentIntent->send();
|
||||||
|
|
@ -77,8 +77,41 @@ class StripeSCA
|
||||||
$response = $this->gateway->confirm($intentData)->send();
|
$response = $this->gateway->confirm($intentData)->send();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
return $response;
|
return $response;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function getAdditionalData($response)
|
||||||
|
{
|
||||||
|
|
||||||
|
$additionalData['payment_intent'] = $response->getPaymentIntentReference();
|
||||||
|
return $additionalData;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function storeAdditionalData()
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function refundTransaction($order, $refund_amount, $refund_application_fee)
|
||||||
|
{
|
||||||
|
|
||||||
|
$request = $this->gateway->cancel([
|
||||||
|
'transactionReference' => $order->transaction_id,
|
||||||
|
'amount' => $refund_amount,
|
||||||
|
'refundApplicationFee' => $refund_application_fee,
|
||||||
|
'paymentIntentReference' => $order->payment_intent
|
||||||
|
]);
|
||||||
|
|
||||||
|
$response = $request->send();
|
||||||
|
|
||||||
|
if ($response->isCancelled()) {
|
||||||
|
$refundResponse['successful'] = true;
|
||||||
|
} else {
|
||||||
|
$refundResponse['successful'] = false;
|
||||||
|
$refundResponse['error_message'] = $response->getMessage();
|
||||||
|
}
|
||||||
|
|
||||||
|
return $refundResponse;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
@ -22,6 +22,10 @@ class AddDefaultGateways extends Migration
|
||||||
$table->string('checkout_blade_template', 150)->default('');
|
$table->string('checkout_blade_template', 150)->default('');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
Schema::table('orders', function($table) {
|
||||||
|
$table->string('payment_intent', 150)->default('');
|
||||||
|
});
|
||||||
|
|
||||||
DB::table('payment_gateways')
|
DB::table('payment_gateways')
|
||||||
->where('provider_name', 'Stripe')
|
->where('provider_name', 'Stripe')
|
||||||
->update(['admin_blade_template' => 'ManageAccount.Partials.Stripe',
|
->update(['admin_blade_template' => 'ManageAccount.Partials.Stripe',
|
||||||
|
|
|
||||||
|
|
@ -31,6 +31,8 @@ return array (
|
||||||
'order_ref' => 'Reference',
|
'order_ref' => 'Reference',
|
||||||
'organiser_booking_fees' => 'Organiser Booking Fees',
|
'organiser_booking_fees' => 'Organiser Booking Fees',
|
||||||
'payment_gateway' => 'Payment Gateway',
|
'payment_gateway' => 'Payment Gateway',
|
||||||
|
'payment_intent' => 'Payment Intent',
|
||||||
|
'payment_failed' => 'Payment failed please try enter your payment details again.',
|
||||||
'price' => 'Price',
|
'price' => 'Price',
|
||||||
'purchase_date' => 'Purchase Date',
|
'purchase_date' => 'Purchase Date',
|
||||||
'quantity' => 'Quantity',
|
'quantity' => 'Quantity',
|
||||||
|
|
|
||||||
|
|
@ -70,6 +70,12 @@
|
||||||
</div>
|
</div>
|
||||||
@endif
|
@endif
|
||||||
|
|
||||||
|
@if($order->payment_intent)
|
||||||
|
<div class="col-sm-6 col-xs-6">
|
||||||
|
<b>@lang("Order.payment_intent")</b><br> {{$order->payment_intent}}
|
||||||
|
</div>
|
||||||
|
@endif
|
||||||
|
|
||||||
@if ($order->is_business)
|
@if ($order->is_business)
|
||||||
<div class="col-sm-6 col-xs-6">
|
<div class="col-sm-6 col-xs-6">
|
||||||
<b>@lang("Public_ViewEvent.business_name")</b><br />
|
<b>@lang("Public_ViewEvent.business_name")</b><br />
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,13 @@
|
||||||
@lang("Public_ViewEvent.payment_information")
|
@lang("Public_ViewEvent.payment_information")
|
||||||
</h1>
|
</h1>
|
||||||
</div>
|
</div>
|
||||||
|
@if($payment_failed)
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-md-8 alert-danger" style="text-align: left; padding: 10px">
|
||||||
|
@lang("Order.payment_failed")
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
@endif
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-md-12" style="text-align: center">
|
<div class="col-md-12" style="text-align: center">
|
||||||
@lang("Public_ViewEvent.below_order_details_header")
|
@lang("Public_ViewEvent.below_order_details_header")
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue