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 = new AccountPaymentGateway();
|
||||
$activeAccountPaymentGateway->fill(['payment_gateway_id' => config('attendize.payment_gateway_dummy')]);
|
||||
$paymentGateway = $activeAccountPaymentGateway;
|
||||
} else {
|
||||
$activeAccountPaymentGateway = $event->account->getGateway($event->account->payment_gateway_id);
|
||||
//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;
|
||||
$activeAccountPaymentGateway = $event->account->getGateway($event->account->payment_gateway_id);
|
||||
//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;
|
||||
|
||||
/*
|
||||
* 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)
|
||||
{
|
||||
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 (!session()->get('ticket_order_' . $event_id)) {
|
||||
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);
|
||||
$order = new Order();
|
||||
$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->calculateFinalCosts();
|
||||
|
||||
$payment_failed = $request->get('is_payment_failed') ? 1 : 0;
|
||||
|
||||
$secondsToExpire = Carbon::now()->diffInSeconds($order_session['expires']);
|
||||
|
||||
$viewData = ['event' => $event,
|
||||
|
|
@ -363,7 +365,8 @@ class EventCheckoutController extends Controller
|
|||
'order_requires_payment' => (ceil($order_session['order_total']) == 0) ? false : true,
|
||||
'account_payment_gateway' => $account_payment_gateway,
|
||||
'payment_gateway' => $payment_gateway,
|
||||
'secondsToExpire' => $secondsToExpire
|
||||
'secondsToExpire' => $secondsToExpire,
|
||||
'payment_failed' => $payment_failed
|
||||
];
|
||||
|
||||
return view('Public.ViewEvent.EventPagePayment', $viewData);
|
||||
|
|
@ -380,10 +383,14 @@ class EventCheckoutController extends Controller
|
|||
*/
|
||||
public function postCreateOrder(Request $request, $event_id)
|
||||
{
|
||||
//Add the request data to a session in case payment is required off-site
|
||||
session()->push('ticket_order_' . $event_id . '.request_data', $request->except(['cardnumber', 'cvc']));
|
||||
$request_data = $ticket_order = session()->get('ticket_order_' . $event_id . ".request_data");
|
||||
$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);
|
||||
|
||||
$event = Event::findOrFail($event_id);
|
||||
|
||||
$order_requires_payment = $ticket_order['order_requires_payment'];
|
||||
|
|
@ -416,7 +423,6 @@ class EventCheckoutController extends Controller
|
|||
|
||||
$response = $gateway->startTransaction($order_total, $order_email, $event);
|
||||
|
||||
|
||||
if ($response->isSuccessful()) {
|
||||
|
||||
session()->push('ticket_order_' . $event_id . '.transaction_id',
|
||||
|
|
@ -426,12 +432,11 @@ class EventCheckoutController extends Controller
|
|||
|
||||
} 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
|
||||
//when we return
|
||||
session()->push('ticket_order_' . $event_id . '.transaction_data',
|
||||
$gateway->getTransactionData() + $additionalData);
|
||||
|
||||
session()->push('ticket_order_' . $event_id . '.transaction_data', $gateway->getTransactionData());
|
||||
|
||||
Log::info("Redirect url: " . $response->getRedirectUrl());
|
||||
|
||||
|
|
@ -496,7 +501,7 @@ class EventCheckoutController extends Controller
|
|||
return $this->completeOrder($event_id, false);
|
||||
} else {
|
||||
session()->flash('message', $response->getMessage());
|
||||
return response()->redirectToRoute('showEventCheckout', [
|
||||
return response()->redirectToRoute('showEventPayment', [
|
||||
'event_id' => $event_id,
|
||||
'is_payment_failed' => 1,
|
||||
]);
|
||||
|
|
@ -533,6 +538,10 @@ class EventCheckoutController extends Controller
|
|||
$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'])) {
|
||||
$order->payment_gateway_id = $ticket_order['payment_gateway']->id;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,7 +8,9 @@ use App\Models\Attendee;
|
|||
use App\Models\Event;
|
||||
use App\Models\EventStats;
|
||||
use App\Models\Order;
|
||||
use App\Models\PaymentGateway;
|
||||
use App\Services\Order as OrderService;
|
||||
use App\Services\PaymentGateway\Factory as PaymentGatewayFactory;
|
||||
use DB;
|
||||
use Excel;
|
||||
use Illuminate\Http\Request;
|
||||
|
|
@ -196,11 +198,10 @@ class EventOrdersController extends MyBaseController
|
|||
|
||||
|
||||
/**
|
||||
* Cancels an order
|
||||
*
|
||||
* @param Request $request
|
||||
* @param $order_id
|
||||
* @return mixed
|
||||
* @return \Illuminate\Http\JsonResponse
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function postCancelOrder(Request $request, $order_id)
|
||||
{
|
||||
|
|
@ -244,24 +245,23 @@ class EventOrdersController extends MyBaseController
|
|||
$order->event->currency))]);
|
||||
}
|
||||
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 */
|
||||
$refund_amount = $order->organiser_amount - $order->amount_refunded;
|
||||
}
|
||||
|
||||
$request = $gateway->refund([
|
||||
'transactionReference' => $order->transaction_id,
|
||||
'amount' => $refund_amount,
|
||||
'refundApplicationFee' => floatval($order->booking_fee) > 0 ? true : false,
|
||||
]);
|
||||
$refund_application_fee = floatval($order->booking_fee) > 0 ? true : false;
|
||||
$response = $gateway->refundTransaction($order, $refund_amount, $refund_application_fee);
|
||||
|
||||
$response = $request->send();
|
||||
|
||||
if ($response->isSuccessful()) {
|
||||
if ($response['successful']) {
|
||||
/* Update the event sales volume*/
|
||||
$order->event->decrement('sales_volume', $refund_amount);
|
||||
$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');
|
||||
}
|
||||
} else {
|
||||
$error_message = $response->getMessage();
|
||||
$error_message = $response['error_message'];
|
||||
}
|
||||
|
||||
$order->save();
|
||||
|
||||
} catch (\Exeption $e) {
|
||||
Log::error($e);
|
||||
$error_message = trans("Controllers.refund_exception");
|
||||
|
|
|
|||
|
|
@ -49,4 +49,31 @@ class Dummy
|
|||
public function extractRequestParameters($request) {}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
public function getTransactionData() {
|
||||
public function getTransactionData()
|
||||
{
|
||||
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;
|
||||
|
||||
|
||||
use Illuminate\Support\Facades\Log;
|
||||
|
||||
class StripeSCA
|
||||
|
|
@ -14,7 +13,7 @@ class StripeSCA
|
|||
|
||||
private $gateway;
|
||||
|
||||
private $extra_params = ['paymentMethod','payment_intent'];
|
||||
private $extra_params = ['paymentMethod', 'payment_intent'];
|
||||
|
||||
public function __construct($gateway)
|
||||
{
|
||||
|
|
@ -45,14 +44,14 @@ class StripeSCA
|
|||
|
||||
public function startTransaction($order_total, $order_email, $event)
|
||||
{
|
||||
|
||||
$this->createTransactionData($order_total, $order_email, $event);
|
||||
$response = $this->gateway->authorize($this->transaction_data)->send();
|
||||
|
||||
return $response;
|
||||
}
|
||||
|
||||
public function getTransactionData() {
|
||||
public function getTransactionData()
|
||||
{
|
||||
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'],
|
||||
);
|
||||
];
|
||||
|
||||
$paymentIntent = $this->gateway->fetchPaymentIntent($intentData);
|
||||
$response = $paymentIntent->send();
|
||||
|
|
@ -77,8 +77,41 @@ class StripeSCA
|
|||
$response = $this->gateway->confirm($intentData)->send();
|
||||
}
|
||||
|
||||
|
||||
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('');
|
||||
});
|
||||
|
||||
Schema::table('orders', function($table) {
|
||||
$table->string('payment_intent', 150)->default('');
|
||||
});
|
||||
|
||||
DB::table('payment_gateways')
|
||||
->where('provider_name', 'Stripe')
|
||||
->update(['admin_blade_template' => 'ManageAccount.Partials.Stripe',
|
||||
|
|
|
|||
|
|
@ -31,6 +31,8 @@ return array (
|
|||
'order_ref' => 'Reference',
|
||||
'organiser_booking_fees' => 'Organiser Booking Fees',
|
||||
'payment_gateway' => 'Payment Gateway',
|
||||
'payment_intent' => 'Payment Intent',
|
||||
'payment_failed' => 'Payment failed please try enter your payment details again.',
|
||||
'price' => 'Price',
|
||||
'purchase_date' => 'Purchase Date',
|
||||
'quantity' => 'Quantity',
|
||||
|
|
|
|||
|
|
@ -70,6 +70,12 @@
|
|||
</div>
|
||||
@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)
|
||||
<div class="col-sm-6 col-xs-6">
|
||||
<b>@lang("Public_ViewEvent.business_name")</b><br />
|
||||
|
|
|
|||
|
|
@ -4,6 +4,13 @@
|
|||
@lang("Public_ViewEvent.payment_information")
|
||||
</h1>
|
||||
</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="col-md-12" style="text-align: center">
|
||||
@lang("Public_ViewEvent.below_order_details_header")
|
||||
|
|
|
|||
Loading…
Reference in New Issue