Home > Enterprise >  fix double payments - double purchases
fix double payments - double purchases

Time:09-18

i'm implementing an online payment platform similar to paypal, the problem is that when they click on the buy button 2 times or more quickly and this causes the payment to register twice instead of once

When you click buy execute this action:

     public function invoke(Request $request) {
    
      $payment_id = $request->get('payment_id');
    
      $credenciales = config('services.mercadopago.token');
      $request->get('user_id'));
    
      $response = Http::get("https://api.mercadopago.com/v1/payments/$payment_id" . "?access_token=$credenciales");
      
      $response = json_decode($response);

  $request->session()->put('order', $response->order->id);
  $request->session()->put('ingreso', $response->transaction_details->net_received_amount);
  $request->session()->put('monto', $response->transaction_details->total_paid_amount);
  $request->session()->put('method', $response->payment_type_id); 
 $status = $response->status;

If the answer is approved run this:

if($status == 'approved') {


  Income::insert([
    'user_id'       => Session::get('user_id'),
    'evento_id'       => Session::get('variableName'),
    //Guardar el personal seleccionado
    'mp_id'  => Session::get('order'),
    'metodo'        => Session::get('metodo'),
    'monto'        => Session::get('monto'),
    'rrpp_id'         => Session::get('rrpp'),
    'ingreso'        => Session::get('ingreso'),


  ]);

  OrderNew::insert([
    'user_id'       => Session::get('user_id'),
    'dia_id'       => Session::get('variableName'),
    //Guardar el personal seleccionado
    'whatsapp'  => Session::get('telefono'),
    'cantidad'        => Session::get('cantidad'),
    'anticipada'        => Session::get('anticipada'),
    'horario'        => Session::get('horario'),
    'rrpp'         => Session::get('rrpp'),
    'pagado'        => '1',
    'tipo'        => 'vip',
    'codigo'        => rand(1580, 4005),


  ]);

in the first model I register the incoming money and in the second model I register the customer's order

and there is the problem, if they click on Buy several times, the records are duplicated and they get free products

How can I limit or solve this problem?

CodePudding user response:

Instead of Insert use updateOrCreate or maybe firstOrCreate that accepts 2 parameters, first one an array to check the values against database records and second to insert/find data. If the records match, it will be updated/retrieved, otherwise a new one will be created. Please check Laravel docs for updateOrCreate or firstOrCreate.

In your case, for example:

Income::firstOrCreate([
    'user_id'       => Session::get('user_id'),
    'evento_id'       => Session::get('variableName'),
    //Guardar el personal seleccionado
    'mp_id'  => Session::get('order'),
    'metodo'        => Session::get('metodo'),
    'monto'        => Session::get('monto'),
    'rrpp_id'         => Session::get('rrpp'),
    'ingreso'        => Session::get('ingreso'),
  ]);

This will check the exact records and if it finds a match it retrieves the data, otherwise creates one which avoids duplicated entries.

However, since your second query has a random number generated, it will not find a match if we pass only one arguement, therefore, as a first arguement we need to pass the array to be checked against the database (all data, except for the rand() part).

OrderNew::firstOrCreate(
  [
    'user_id'       => Session::get('user_id'),
    'dia_id'       => Session::get('variableName'),
    //Guardar el personal seleccionado
    'whatsapp'  => Session::get('telefono'),
    'cantidad'        => Session::get('cantidad'),
    'anticipada'        => Session::get('anticipada'),
    'horario'        => Session::get('horario'),
    'rrpp'         => Session::get('rrpp'),
    'pagado'        => '1',
    'tipo'        => 'vip',
  ],
  [
    'user_id'       => Session::get('user_id'),
    'dia_id'       => Session::get('variableName'),
    //Guardar el personal seleccionado
    'whatsapp'  => Session::get('telefono'),
    'cantidad'        => Session::get('cantidad'),
    'anticipada'        => Session::get('anticipada'),
    'horario'        => Session::get('horario'),
    'rrpp'         => Session::get('rrpp'),
    'pagado'        => '1',
    'tipo'        => 'vip',
    'codigo'        => rand(1580, 4005),
  ]);

According to your data, you can change the array of data to be checked against the database.

CodePudding user response:

Specify that the route should not allow concurrent requests from the same session.

Route::get('/deposit',ExampleController::class)->block(10);
  • Related