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

У меня есть многоэтапная форма для регистрации пользователем в конференции, все шаги находятся на одной странице 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 
    }

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

enter image description here

На данный момент у меня только шаг 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, чтобы объяснить лучше:

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 есть 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, чтобы объяснить лучше:

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);
    }

Затем выполняется шаг 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, показывающий сообщение об успешном завершении кредитной карты после успешного платежа:

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' => 'RegistrationController@storeRegistrationInfo',
    'as'   =>'conferences.storeRegistrationInfo'
]);

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

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

Ответы [ 2 ]

0 голосов
/ 27 мая 2018

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

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

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

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

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

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

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

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

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

0 голосов
/ 26 мая 2018

Нет четких инструкций, вам нужно решить для себя, как организовать ваш код.

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

Так что очевидно, что после выбора способа оплаты вам необходимо сформировать что-то вроде заказа в базе данных.

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