Каким должен быть поток этого контекста? (Где поставить код для обработки платежа в зависимости от выбранного способа оплаты?)

У меня есть многоступенчатая форма для регистрации пользователем в конференции, все шаги находятся на той же странице registration.blade.php, на шаге 1, а на втором этапе выполняется запрос 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 
    }

Я сомневаюсь, каким должен быть поток, где должен быть размещен код для обработки платежа со ссылками и код для обработки платежа с помощью кредитной карты. Таким образом, можно достичь этого сценария:

enter image description here

На данный момент у меня есть только первый и второй шаги. Чтобы обрабатывать шаги 1 и 2, у меня есть RegistrationController. На шаге 1 информация, введенная пользователем, проверяется с использованием запроса ajax post к storeUserInfo() RegistrationController storeUserInfo() если возвращается 200 пользователь переходит к этапу 2.

На шаге 2 пользователь выбирает способ оплаты, а клики в "перейти к шагу 3" также выполняются ajax-запросом storePaymentMethods() RegistrationController storePaymentMethods() чтобы проверить, выбрал ли пользователь хотя бы один способ оплаты. Я сомневаюсь, что после этого метода верните код 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>

step1 image, чтобы лучше объяснить:

enter image description here

когда пользователь нажимает кнопку "Перейти к шагу 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 существует хранилищеRegistrationInfo() для обработки вышеуказанного запроса 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 возвращается, пользователь находится в шаге2form:

<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>

Шаг 2 image, чтобы лучше объяснить:

enter image description here

Когда пользователь нажимает кнопку "Перейти к шагу 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);
    }

Тогда есть шаг 3 div. В #credit_card_section будет #credit_card_section что 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 image, чтобы лучше объяснить, в зависимости от способа оплаты информация, которая должна быть показана на шаге 3, отличается. Если способ оплаты был кредитной карточкой, также появляется step4 div, показывающий успешное сообщение после успешного платежа с помощью кредитной карты:

enter image description here

Затем есть шаг 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' => '[email protected]',
    'as'   =>'conferences.storeRegistrationInfo'
]);

Маршрут для step2:

Route::post('/conference/{id}/{slug?}/registration/storePaymentMethods', [
    'uses' => '[email protected]',
    'as'   =>'conferences.storePaymentMethods'
]);

Ответы

Ответ 1

Как и в ваших сомнениях, чтобы лучше структурировать ваш код и отдельную логику (концепция DRY), вы должны сделать несколько вещей:

  • Создайте PaymentsController с 3 функциями (для начала вы обязательно добавите больше здесь)

    1. для обработки ваших ссылок
    2. для обработки кредитных карт
    3. для хранения способов оплаты (хранить способ оплаты в сеансе до тех пор, пока пользователь не завершит этап 3)

    Вы совершенно свободны в том, как вы называете эти функции, но я бы предложил что-то вроде processViaReferences, processViaCreditCard и storePaymentMethod.

    Это будет намного легче читать и проверять, если вы их разделяете.

    Создайте для них соответствующие маршруты сообщений и соответствующим образом учтите код cour.

  • Создавайте представления деталей, содержащие только ваши формы.

    Затем @include эти представления @include через @include чтобы они разделились на уровне представления. Для ваших ссылок в javascript/jQuery не забудьте сохранить правильные идентификаторы. Вы также можете извлечь javascript, другие виды представлений деталей или отдельные js файлы, если вы еще этого не сделали.

    Ваш код вида/формы должен перейти к этим представлениям деталей...

Ответ 2

Четких инструкций нет, вам нужно самому решить, как организовать свой код.

Если вы не можете выбрать, где разместить код PHP, ответственный за платеж, я бы поместил обработку обоих платежей в PaymentsController.php

Поэтому очевидно, что после выбора способа оплаты вам нужно создать что-то вроде заказа в базе данных.

  1. В случае ссылок они должны быть привязаны к этому порядку.
  2. В случае использования кредитных карт платеж будет привязан к этому заказу.