Shiva
457
13
Laravel

Issues with sending an email with a pdf attachment

Posted 3 months ago by Shiva

I have a page that when the user successfully pays they get sent an email with an invoice.

The problems I'm having is that I keep getting this error

Trying to get property 'name' of non-object

It refers to this line

$user_name = $order->user->name;

I do know that this works because if I dd($user_name) I get the correct name.

The other problem I'm having is that, even though I get the above error I still get sent the invoice, but I don't get one invoice, I get multiple emails with the invoice attached.

This is my successPayment function

public function successPayment(Request $request)
{
    $menus_child = Menu::where('menu_id', 0)->with('menusP')->get();
    $contacts = Contact::all();

    if(Auth::check())
    {
        $orders = Order::all();
        $user_id = Auth::user()->id;

        foreach($orders as $order)
        {
            $exists = Order::find($order->id)->where('user_id', $user_id)->latest()->first();
            $exists->status = 'success';

            $exists->save();

            $invoice_number = Session::get('invoice_number');

            $order_number = Order::where('invoice_number', $invoice_number)->get();

            $user_name = $order->user->name;

            $order_item = unserialize($order->cart);
            $address = json_decode($order->address);

            PDF::setOptions(['defaultFont' => 'sans-serif']);
            $pdf = PDF::loadView('public.pdf.invoice', compact('order', 'user_name', 'order_item', 'address'));
            

            Mail::send('layouts.emails.invoice', [], function($message) use($pdf){
                $message->to('[email protected]', 'Testing PDF order')->subject('Someone has contacted you');
                $message->attachData($pdf->output(), 'invoice.pdf');
            });

        }
    }else{
        return redirect()->route('public.home');
    }

    return view('public.payfast.success', compact('menus_child', 'contacts'));
}

My order confirmation page. This is where the user adds their details and makes sure that the order is correct.

<div class="content_wrapper">
    <h1>Order Confirmation</h1>
    <?php
        $delivery = getDeliveryFee();
    ?>

    {{ $invoice_number }}
    <div class="row">
        <div class="col-lg-12">
            <div class="row">
                <div class="col-lg-12 mt-15">
                    @if($message = Session::get('success'))
                        <div class="alert alert-success" role="alert">
                            {{ $message }}
                        
                            <button type="button" class="close" data-dismiss="alert" aria-label="Close">
                                <span aria-hidden="true">&times;</span>
                            </button>
                        </div>
                    @endif

                    @if($message = Session::get('error'))
                        <div class="alert alert-danger" role="alert">
                            {{ $message }}

                            <button type="button" class="close" data-dismiss="alert" aria-label="Close">
                                <span aria-hidden="true">&times;</span>
                            </button>
                        </div>
                    @endif
                </div>
            </div>
        </div>
    </div>

    <div class="row">
        <div class="col-lg-12">
            <div class="accordion" id="accordionExample">
                <div class="card">
                    <div class="card-header" id="headingOne">
                        <h2 class="mb-0">
                            <button class="btn btn-link" type="button" data-toggle="collapse" data-target="#collapseOne" aria-expanded="true" aria-controls="collapseOne">
                                Billing Information 
                            </button>
                        </h2>
                    </div>

                    <div id="collapseOne" class="collapse {{ !$errors->any() ? 'show' : '' }}" aria-labelledby="headingOne" data-parent="#accordionExample">
                        <div class="card-body">
                            <div class="row">
                                <div class="col-lg-6">
                                    <div class="address">
                                        @if ($errors->confirmation_errors->has('delivery_address'))
                                            <div class="help-block text-danger">
                                                <strong>Please add an address NOW</strong>
                                            </div>
                                        @endif

                                        @foreach($addresses as $address)
                                            @if(!empty($address->complex))
                                                {{ $address->complex }},
                                            @endif
                                            <div>{{ $address->address }},</div>
                                            <div>{{ $address->suburb }},</div>
                                            <div>{{ $address->city }},</div>
                                            <div>{{ $address->province }},</div>
                                            <div>{{ $address->postal_code }}</div>
                                            
                                            <div class="row edit-delete">
                                                <div class="col-lg-2">
                                                    <a class="btn btn-primary edit-button" href="{{ route('account.edit.delivery.address', [$address->id]) }}">Edit</a> 
                                                    <span>/</span>
                                                </div>

                                                <div class="col-lg-2">
                                                    <form action="{{ route('account.delete.delivery.address', [$address->id]) }}" method="post">
                                                        @csrf
                                                        {{ method_field('DELETE') }}
                                                        <button class="btn btn-danger delete-button"><i class="fa fa-pencil"></i> Delete</button>
                                                    </form>
                                                </div>
                                            </div>
                                        @endforeach
                                    </div>
                                </div>

                                <div class="col-lg-6">
                                    <a href="{{ route('account.add.address') }}" class="btn btn-dark float-right mt-15">Add Address</a>
                                </div>
                            </div>
                        </div>
                    </div>
                </div>

                <div class="card">
                    <div class="card-header" id="headingTwo">
                        <h2 class="mb-0">
                            <button class="btn btn-link collapsed" id="delivery-collection" type="button" data-toggle="collapse" data-target="#collapseTwo" aria-expanded="false" aria-controls="collapseTwo">
                                Delivery/Collection
                            </button>
                        </h2>
                    </div>

                    <div id="collapseTwo" class="collapse {{ $errors->confirmation_errors->any() ? 'show' : '' }}" aria-labelledby="headingTwo" data-parent="#accordionExample">
                        <div class="card-body">
                            <p>
                                Please select your delivery option
                            </p>

                            @if ($errors->confirmation_errors->has('delivery_collection'))
                                <div class="help-block text-danger">
                                    <strong>Please select your delivery option</strong>
                                </div>
                            @endif
    
                            <div class="delivery-option">
                                <input type="radio" class="form-check-input {{ $errors->confirmation_errors->has('delivery_collection') ? 'is-invalid' : '' }}" name="delivery-option" id="delivery" value="delivery">
                                <label for="delivery" class="form-check-label">
                                    Delivery
                                </label>

                                <input type="radio" class="form-check-input {{ $errors->confirmation_errors->has('delivery_collection') ? 'is-invalid' : '' }}" name="delivery-option" id="collection" value="collection">
                                <label for="collection" class="form-check-label">
                                    Collection
                                </label>
                            </div>
                        </div>
                    </div>
                </div>

                <div class="card">
                    <div class="card-header" id="headingThree">
                        <h2 class="mb-0">
                            <button class="btn btn-link collapsed" type="button" data-toggle="collapse" data-target="#collapseThree" aria-expanded="false" aria-controls="collapseThree">
                                Payment Options
                            </button>
                        </h2>
                    </div>

                    <div id="collapseThree" class="collapse {{ $errors->any() ? 'show' : '' }}" aria-labelledby="headingThree" data-parent="#accordionExample">
                        <div class="card-body">
                            @if ($errors->has('payment_option'))
                                <div class="help-block text-danger">
                                    <strong>Please select a payment option</strong>
                                </div>
                            @endif
                            
                            <div class="row">
                                <div class="col-lg-12">
                                    <div class="payment-option">
                                        <input type="radio" class="form-check-input {{ $errors->has('payment_method') ? 'is-invalid' : '' }}" name="payment_method" id="payfast-eft" value="payfast-eft">
                                        <label for="payfast-eft" class="form-check-label">
                                            EFT with PayFast
                                        </label>
                                    </div>
                                </div>
                            </div>
                        </div>
                    </div>
                </div>

                <div class="card">
                    <div class="card-header" id="headingThree">
                        <h2 class="mb-0">
                            <button class="btn btn-link collapsed" type="button" data-toggle="collapse" data-target="#collapseFour" aria-expanded="false" aria-controls="collapseThree">
                                Review Your Order
                            </button>
                        </h2>
                    </div>

                    <div id="collapseFour" class="collapse" aria-labelledby="collapseFour" data-parent="#accordionExample">
                        <div class="card-body">
                            <table class="table table-bordered">
                                <thead>
                                    <tr>
                                        <th scope="col">Product</th>
                                        <th scope="col">Code</th>
                                        <th scope="col">Quantity</th>
                                        <th scope="col">Unit Price</th>
                                        <th scope="col">Total</th>
                                    </tr>
                                </thead>

                                <tbody>
                                    @foreach($products as $product)
                                        <?php
                                            $image = getImagesArray($product['item']['image']);
                                        ?>
                                        <tr>
                                            <th>
                                                @if(!empty($image))
                                                    <img src={!! asset("product_images/thumbs/$image[0]") !!}>
                                                @endif

                                                {{ $product['item']['title'] }}
                                            </th>
                                            <td>{{ $product['item']['supplier_code'] }}</td>
                                            <td>{{ $product['qty'] }}</td>
                                            <td>R {{ $product['item']['price'] }}</td>
                                            <td>R {{ $product['price'] }}</td>
                                        </tr>
                                    @endforeach
                        
                                    <tr>
                                        <th colspan="4">
                                            <div class="float-right">
                                                Sub Total       
                                            </div>
                                        </th>

                                        <td id="totalPrice" data-price="{{ $totalPrice }}">
                                            R {{ $totalPrice }}
                                        </td>
                                    </tr>

                                    <tr class="delivery-fees">
                                        <th colspan="4">
                                            <div class="float-right">
                                                Delivery Fee
                                            </div>
                                        </th>

                                        <td id="delivery-price" data-price="{{ $delivery }}">
                                            R {{ $delivery }}
                                        </td>
                                    </tr>

                                    <?php
                                        $total = $totalPrice + $delivery;
                                    ?>

                                    <tr class="total-price">
                                        <th colspan="4">
                                            <div class="float-right">
                                                Total:      
                                            </div>
                                        </th>

                                        <td>
                                            R <span id="completePrice"></span>
                                        </td>
                                    </tr>
                                </tbody>
                            </table>

                            <div class="confirm-order-btn pb-15">
                                @foreach($products as $product)
                                    <!-- BEGIN PAYFAST EFT -->
                                    <div class="payfast-eft" style="display: none">
                                        <form action="{{ route('payment.gateway') }}" method="POST">
                                            @csrf
                                            <input type="hidden" name="merchant_id" value="merchant_id">
                                            <input type="hidden" name="merchant_key" value="merchant_key">
                                            <input type="hidden" name="return_url" value="{{ route('payfast.success') }}">
                                            <input type="hidden" name="cancel_url" value="{{ route('payfast.cancel') }}"> 
                                            <input type="hidden" name="m_payment_id" value="{{ $invoice_number }}">
                                            <input type="hidden" name="amount" class="completePrice" value="">
                                            <input type="hidden" name="item_name" value="{{ $product['item']['title'] }}">
                                            <input type="hidden" name="item_description" value="{{ $product['item']['description'] }}">
                                            <input type="hidden" name="email_confirmation" value="1">
                                            <input type="hidden" name="confirmation_address" value="">
                                            <input type="hidden" name="payment_method" value="payfast_eft">
                                            <input type="hidden" name="delivery_collection" class="delivery_collection" value="">
                                            <input type="hidden" name="delivery_fee" class="delivery_fee" value="{{ $delivery }}">
                                            <!-- THIS IS WHERE THE ADDRESS IS ADDED TO THE HIDDEN FORM -->
                                            <input type="hidden" name="delivery_address" class="delivery_address" value="{{ $address }}">

                                            <?php
                                                $success = url('payfast-success');
                                                $cancel = url('payfast-cancel');
                                                $notify = url('payfast-notify');

                                                $original_str = getAscii('merchant_id=merchant_id&merchant_key=merchant_key&return_url='.$success.'&cancel_url='.$cancel.'&notify_url='.$notify.'&m_payment_id=01AB&amount='.$totalPrice.'&item_name=Test Item&item_description=A test product&email_confirmation=1&[email protected]&payment_method=eft');
                                                $hash_str = hash('MD5', $original_str);
                                                $hash = strtolower($hash_str);
                                            ?>

                                            <input type="hidden" name="signature" value="{{ $hash }}">
                                            
                                            <button type="submit" class="btn btn-success float-right confirm-payfast-order">
                                                Confirm Order
                                            </button>
                                        </form>
                                    </div>
                                    <!-- END PAYFAST EFT -->
                                @endforeach
                            </div>
                        </div>
                    </div>
                </div>
            </div>
        </div>
    </div>
</div>

<script>
    $(document).ready(function(){
        var price = $("#totalPrice").data('price'); //get data-price by this syntax
        
        $('#completePrice').html(price);
        $('.completePrice').val(price);

        $('input[type="radio"]').click(function(){
            if($(this).attr("value")=="collection"){
                $(".delivery-fees").hide('slow');
                
                var price = $("#totalPrice").data('price'); //get data-price by this syntax
                var deliveryprice = 0;  //get data-price by this syntax
                var totalPrice = parseFloat(price) + parseFloat(deliveryprice);

                $('#completePrice').html(totalPrice);
                $('.completePrice').val(totalPrice);
                $('.delivery_collection').val('collection');
                $('.confirm-order').removeAttr('disabled');
                $('.confirm-payfast-order').removeAttr('disabled');
            }

            if($(this).attr("value")=="delivery"){
                $(".delivery-fees").show('slow');

                var price = $("#totalPrice").data('price'); //get data-price by this syntax
                var deliveryprice = $("#delivery-price").data('price');  //get data-price by this syntax
                var totalPrice = parseFloat(price) + parseFloat(deliveryprice);

                $('#completePrice').html(totalPrice);
                $('.completePrice').val(totalPrice);
                $('.delivery_collection').val('delivery');
            }
        });

        /* BEGIN EFT PAYFAST */
        $('input[type="radio"]').click(function(){
            if($(this).attr("value")=="payfast-eft"){
                $(".payfast-eft").show('slow');
                $(".payfast-card").hide();
                $(".i-pay").hide();
                $(".confirm-order").hide();
                $(".payfast-debit-card").hide();
            }       
        });
        /* END EFT PAYFAST */
    });
</script>   
@stop

When they click confirm they then get sent to a payment gateway. I'm using PayFast as my payment gateway.

If the payment is successfull then they get sent to another page that just says success. The section <input type="hidden" name="return_url" value="{{ route('payfast.success') }}"> passes the url to the controller

public function paymentGateway(Request $request)
{
    if($request->payment_method == 'payfast_eft')
    {
        $process = 'Order Paid';
        $paid = '1';
    }

    if($request->delivery_collection == 'collection')
    {
        $delivery_fee = null;
    }else{
        $delivery_fee = $request->delivery_fee;
    }

    $orders = Order::all();

    $oldCart = Session::get('cart');
    $cart = new Cart($oldCart);

    $validation = Validator::make($request->all(), $this->getRules());

    if($validation->fails())
    {
        return redirect()->route('cart.deliveryConfirmation')
                        ->withErrors($validation, 'confirmation_errors')
                        ->with('error', 'There were validation errors');
    }

    $merchant_id = $request->merchant_id;
    $merchant_key = $request->merchant_key;
    $return_url = $request->return_url;
    $cancel_url = $request->cancel_url;
    $m_payment_id = $request->m_payment_id;
    $amount = $request->amount;
    $item_name = $request->item_name;
    $item_description = $request->item_description;
    $email_confirmation = '1';
    $confirmation_address = '[email protected]';
    $payment_method = $request->payment_method;
    $signature = $request->signature;

    if($request->payment_method == 'payfast_eft')
    {
        $url = 'https://sandbox.payfast.co.za/eng/process?merchant_id='.$merchant_id.'&merchant_key='.$merchant_key.'&return_url='.$return_url.'&cancel_url='.$cancel_url.'&m_payment_id='.$m_payment_id.'&amount='.$amount.'&item_name='.$item_name.'&item_description='.$item_description.'&email_confirmation='.$email_confirmation.'&confirmation_address='.$confirmation_address.'&payment_method='.$payment_method;
    }elseif($request->payment_method == 'cc'){
        $url = 'https://sandbox.payfast.co.za/eng/process?merchant_id='.$merchant_id.'&merchant_key='.$merchant_key.'&return_url='.$return_url.'&cancel_url='.$cancel_url.'&m_payment_id='.$m_payment_id.'&amount='.$amount.'&item_name='.$item_name.'&item_description='.$item_description.'&email_confirmation='.$email_confirmation.'&confirmation_address='.$confirmation_address.'&payment_method='.$payment_method;
    }elseif($request->payment_method == 'dc'){
        $url = 'https://sandbox.payfast.co.za/eng/process?merchant_id='.$merchant_id.'&merchant_key='.$merchant_key.'&return_url='.$return_url.'&cancel_url='.$cancel_url.'&m_payment_id='.$m_payment_id.'&amount='.$amount.'&item_name='.$item_name.'&item_description='.$item_description.'&email_confirmation='.$email_confirmation.'&confirmation_address='.$confirmation_address.'&payment_method='.$payment_method;
    }

    return redirect()->to($url);
}

If I need to provide any other information please let me know

Please sign in or create an account to participate in this conversation.