У меня есть многоэтапная форма для регистрации пользователем в конференции, все шаги находятся на одной странице registration.blade.php
, на шаге 1 и шаге 2 выполняется ajax-запрос для проверки полей формы.
Шаги:
- Шаг 1 - сбор информации о пользователе ( имя и номер банка )
- Шаг 2 - сбор платежаметод ( кредитная карта или ссылки )
- Шаг 3 - это платеж
- Шаг 4 показывает сообщение об успешном завершении ( этот шаг появляется только после успешного платежа скредитная карта, при использовании метода оплаты по ссылкам этот шаг не отображается, при способе оплаты по ссылкам отображается только шаг 1, 2 и 3 )
Я сомневаюсь, что между шагом 2 и 3.
Если для выполнения приведенного ниже кода необходимы выбранные ссылки на метод оплаты, то при этом генерируются некоторые ссылки на платеж, а затем представляются ссылки на пользователя на шаге 3. Когда пользователь платит, система получает уведомление и должнавставить в таблицу платежей price
, payment_method_id
, registration_id
и status
( оплачено ).
Код для обработки платежей со ссылками:
public function ReferencesCharge(Request $request)
{
$payment_info = [
'name' => "user name",
'email' => 'user email',
'value' => 'registration total price',
'id' => 'registration id',
];
$newPayment = new Payment($payment_info);
$reference = $newPayment->gererateReferences();
//$reference returns an array with necessary codes to present to the user so he can pay
// after generate references is necessary:
// show in step 3 the generated references
// insert an entry in the payments table when the system receives a notification from 3rd party service informing that the user did the payment
}
Если выбранный платеж был кредитной картой, необходимо выполнить приведенный ниже код для снятия средств с кредитной карты и после этого вставить в таблицу платежей price
, payment_method_id
, registration_id
иstatus
( оплачено ).И затем пользователь должен быть перенаправлен на шаг 4, чтобы показать сообщение об успехе:
Код для обработки платежей по кредитным картам:
public function creditCardCharge(Request $request)
{
Stripe::setApiKey(config('services.stripe.secret'));
$source = $request->stripeToken;
try{
Charge::create([
'currency' => 'eur',
'amount' => 2500,
'source' => $source,
]);
}
catch(\Exception $e){
return response()->json(['status' => $e->getMessage()], 422);
}
// after charging the card with success:
// insert an entry in the payments table
// redirect to success confirmation step to inform the user that payment was done with success
}
Я сомневаюсь, как потокдолжно быть там, где должен быть размещен код для обработки платежа со ссылками и код для обработки платежа с помощью кредитной карты.Таким образом, возможно достичь этого сценария:
На данный момент у меня только шаг 1 и шаг 2 работают должным образом.Для обработки шагов 1 и 2 у меня есть RegistrationController
.На шаге 1 информация, введенная пользователем, проверяется с использованием пост-запроса ajax к методу storeUserInfo()
RegistrationController
, если возвращается 200
, пользователь переходит к шагу 2.
На шаге 2 пользовательвыбирает способ оплаты и нажимает кнопку «перейти к шагу 3», также выполняется ajax-запрос к storePaymentMethods()
из RegistrationController
, чтобы проверить, выбрал ли пользователь хотя бы 1 способ оплаты.Я сомневаюсь, что после этого метода код возврата 200 будет таким, каким должен быть процесс.
В зависимости от способа оплаты необходимо выполнить соответствующий код, указанный выше ( код, который генерирует ссылки на платеж или код для снятия средств с кредитной карты).
Итак, я сомневаюсь, как организовать этот код с точки зрения контроллеров и методов, куда поместить тот код, который должен выполняться в зависимости от выбранного способа оплаты.Вы знаете, каким должен быть поток, чтобы достичь этого?
Возможно, подход может быть чем-то похожим на приведенное ниже в storePaymentMethods()
, но, кажется, не совсем правильно делать все в этом методе:
public function storePaymentMethods(Request $request){
$request->validate([
'payment_method' => 'required',
]);
if($request->payment_method == "references"){
// generate codes and present to the user that codes
}
else if($request->payment_method == "credit_card"){
// show credit card inputs to the user
// and process the credit card payment with stripe
}
return response()->json([
'success' => true,
'message' => 'success',
'payment_method' => $request->payment_method,
], 200);
}
Полная сводкапотока регистрации с многоэтапной формой, которую я имею на данный момент:
Итак, для шага 1 есть форма:
<div>
<form method="post" id="step1form" action="">
{{csrf_field()}}
<!-- fields of the step 1-->
<input type="submit" href="#step2" id="goToStep2" class="btn next-step" value="Go to step 2"/>
</form>
</div>
изображение шага 1, чтобы объяснить лучше:
, когда пользователь нажимает кнопку «Перейти к шагу 2», делается ajax-запрос для проверки данных и, если ошибок нет, код200 возвращается, и пользователь переходит к шагу 2:
$('#goToStep2').on('click', function (event) {
event.preventDefault();
var custom_form = $("#" + page_form_id_step1);
$.ajax({
method: "POST",
url: '{{ route('conferences.storeRegistrationInfo', compact('id','slug') ) }}',
data: custom_form.serialize(),
datatype: 'json',
success: function (data, textStatus, jqXHR) {
var $active = $('.nav-pills li a.active');
nextTab($active);
},
error: function (data) {
// show errors
}
});
});
Затем в ConferencesController есть storeRegistrationInfo () для обработки вышеуказанного ajax-запроса:
public function storeRegistrationInfo(Request $request, $id, $slug = null, Validator $validator){
$rules = [];
$messages = [];
$rules["name_invoice"] = 'required|max:255|string';
$rules["TIN_invoice"] = ['required', 'string', new ValidTIN()];
$validator = Validator::make($request->all(), $rules, $messages);
$errors = $validator->errors();
$errors = json_decode($errors);
if($validator->fails()) {
return response()->json([
'success' => false,
'errors' => $errors
], 422);
}
return response()->json([
'success' => true,
'message' => 'success'
], 200);
}
Итак, есликод 200 возвращается, пользователь находится в форме step2:
<div>
<form method="post" id="step2form" action="">
{{csrf_field()}}
<!-- fields of the step 2-->
<input type="submit" href="#step3" id="goToStep3" class="btn next-step" value="Go to step 3"/>
</form>
</div>
изображение step2, чтобы объяснить лучше:
Когда пользователь нажимаетв кнопке «Перейти к шагу 3» делается ajax-запрос для проверки данных, и если ошибок нет, код 200 возвращаетсяи пользователь переходит к шагу 3, запрос ajax:
$("#credit_card_section").hide();
$("#references_section").hide();
var page_form_id_step2 = "step2form";
$('#goToStep3').on('click', function (event) {
event.preventDefault();
var custom_form = $("#" + page_form_id_step2);
$.ajax({
method: "POST",
url: '{{ route('conferences.storePaymentMethods', compact('id','slug') ) }}',
data: custom_form.serialize(),
datatype: 'json',
success: function (data, textStatus, jqXHR) {
var result = data;
if(result['payment_method'] == 'credit_card'){
$("#credit_card_section").show();
$("#references_section").hide();
}else{
$("#references_section").show();
$("#credit_card_section").hide();
}
var $active = $('.nav-pills li a.active');
nextTab($active);
},
error: function (data) {
// show errors
}
});
});
ConferenceController имеет функцию storePayment () для обработки вышеуказанного ajax-запроса, он проверяет, выбрал ли пользователь способ оплаты и, если да, возвращает код 200
:
public function storePaymentMethods(Request $request){
$request->validate([
'payment_method' => 'required',
]);
return response()->json([
'success' => true,
'message' => 'success',
'payment_method' => $request->payment_method,
], 200);
}
Затем выполняется шаг step3,В шаге div будет отображаться div #credit_card_section
видимый или #references_section
видимый в зависимости от способа оплаты, выбранного на предыдущем шаге ( кредитная карта или ссылки ):
<div>
<form method="post" id="step3form" action="">
{{csrf_field()}}
<div id="credit_card_section">
<!-- present necessary fields to
payments with credit card-->
</div>
<div id="references_section">
<!-- present generated reference to the user so he can pay-->
</div>
</form>
</div>
step3
Изображение для объяснения лучше, в зависимости от способа оплаты информация, которую необходимо показать на шаге 3, может отличаться.Если в качестве способа оплаты использовалась кредитная карта, также появляется step4
div, показывающий сообщение об успешном завершении кредитной карты после успешного платежа:
Затемэто шаг 4 div, который должен показывать сообщение об успешном завершении после оплаты с помощью кредитной карты:
<div id="step4">
<p>
<i class="fa fa-plus" aria-hidden="true"></i>
Payment and registration completed with success.
</p>
</div>
// Возобновить методы RegistrationController, которые у меня есть на данный момент, RegistrationController является контроллеромчто у меня есть, что обрабатывает многоступенчатую форму
class RegistrationController extends Controller
{
public :function storeQuantities(Request $request, $id, $slug = null){
// method that stores in session the ticket types
// selected by the user in the conference details page
Session::put('selectedRtypes', $selectedRtypes);
Session::put('allParticipants' , $allParticipants);
Session::put('customQuestions' , $selectedRtypes[$rtype->name]['questions']);
// and then redirects the user to the registartion page registration.blade.php
// using the route 'conferences.registration
// this route is associated with the displayRegistrationPage() method
return redirect(route('conferences.registration',['id' => $id, 'slug' => $slug]));
}
// method of the route 'conferences.registration' that displays
// the registration.blade.php that is the page with the multi step form
public function displayRegistrationPage(Request $request, $id, $slug=null){
// get the session values
$selectedRtypes = Session::get('selectedRtypes');
$allParticipants = Session::get('allParticipants');
$customQuestions = Session::get('customQuestions');
// redirect the user to the registration.blade.php
if(isset($selectedRtypes)) {
return view('conferences.registration',
['selectedRtypes' => $selectedRtypes, 'customQuestions' => $customQuestions, 'id' => $id, 'slug' => $slug]);
}
else{
// return user to the conference details page
return redirect(route('conferences.show',['id' => $id, 'slug' => $slug]));
}
}
/* the following methods are to handle the registration
multi step form of the registration.blade.php view */
// method to handle the step1 of the multi step form
public function storeRegistrationInfo(Request $request, $id, $slug = null, Validator $validator){
// get and validate the fields of the step1
// and returns code 200 if al is ok
return response()->json([
'success' => true,
'message' => 'success'
], 200);
}
// method to handle the step2 of the multi step form
public function storePaymentMethods(Request $request){
// validate if the payment_method field was filled
// if was filled return code 200
// and returns the payment_method
//so in the step 3 div is possible to show a section for
// when the payment_method is credit card (#credit_card_section)
or transfers ("transfers_section")
return response()->json([
'success' => true,
'message' => 'success',
'payment_method' => $request->payment_method,
], 200);
}
}
Маршрут для step1
:
Route::post('/conference/{id}/{slug?}/registration/storeRegistrationInfo', [
'uses' => 'RegistrationController@storeRegistrationInfo',
'as' =>'conferences.storeRegistrationInfo'
]);
Маршрут для step2
:
Route::post('/conference/{id}/{slug?}/registration/storePaymentMethods', [
'uses' => 'RegistrationController@storePaymentMethods',
'as' =>'conferences.storePaymentMethods'
]);