#Stripe Laravel Tests

27 messages · Page 1 of 1 (latest)

sullen bronze
#
  public function checkout()
    {
        $user_id = Auth::id();
        $stripe = $this->stripe;

        // Creates an order table
        $order = new Order();
        $order->id = fake()->numerify('######');
        $order->status = 'unpaid';
        $order->total_price = $this->getTotalCartPrice();
        $order->user()->associate(Auth::user());
        $order->save();


        $carts = Cart::where('user_id', $user_id)->get();
        $listOfProducts = [];
        foreach($carts as $cart)
        {
            $listOfProducts[] = [
                'price_data' => [
                    'currency' => 'gbp',
                    'product_data' => [
                        'name' => $cart->product->name,
                    ],
                    'unit_amount' => $cart->product->price * 100,
                ],
                'quantity' => $cart->quantity,
            ]; 
        
            // Creates an orderItem table for each product in the cart and associates it with the order. This allows us to check what products are linked with the order
            $orderItem = new OrderItem();
            $orderItem->user()->associate(Auth::user());
            $orderItem->product()->associate($cart->product);
            $orderItem->quantity = $cart->quantity; 
            $orderItem->unit_price = $cart->product->price;
            $orderItem->order()->associate($order->id);
            $orderItem->save();
        }

        $sessionData = ([
            'line_items' => $listOfProducts,
            'mode' => 'payment',
            'success_url' => route('checkout.success', [], true)."?session_id={CHECKOUT_SESSION_ID}",
            'cancel_url' => route('checkout.cancel', [], true)."?session_id={CHECKOUT_SESSION_ID}",
        ]);
#
           // Conditionally add coupon if it exists in session
        if ($coupon = session('coupon.name')) {
            $sessionData['discounts'] = [
                [
                    'coupon' => $coupon,
                ],
            ];
        }

        $checkout_session = $stripe->checkout->sessions->create($sessionData);

        $order->session_id = $checkout_session->id;
        $order->save();

        return redirect()->away($checkout_session->url); // This will direct user to checkout page and they will either go to the checkout.success or checkout.cancel route after checkout depening on their action 
    }
#

My test currently:


        $user = User::factory()->create();
        $carts = Cart::factory()->count(4)->create(['user_id' => $user->id]);

        $this->actingAs($user);

        $response = $this->post(route('checkout'));

        $response->assertStatus(302);

        $response->assertRedirect()

So for $response->assertRedirect() I need to ensure it gets directed to a checkout session url i assume?

devout veldt
#

Can you format your code with syntax highlight, please? It’s difficult to follow when it’s just grey text.
```php
// Your PHP code here...

sullen bronze
devout veldt
#

Couple of notes: you shouldn’t be using the env() helper outside of configuration files. Map the STRIPE_SECRET environment variable to a configuration value instead. You can add an entry to your config/services.php file:

return [
    'stripe' => [
        'key' => env('STRIPE_KEY'),
        'secret' => env('STRIPE_SECRET'),
    ],
];

You can then reference these in your code as config('services.stripe.secret') etc.

#

Also, you’d be better off binding a well-configured instance of the StripeClient to the container in a service provider:

$this->app->singleton(StripeClient::class, function () {
    return new StripeClient([
        'api_key' => $this->app['config']['services.stripe.secret'],
    ]);
});

This way, you can just type-hint StripeClient in classes and methods that need it, and the already-configured instance will be injected instead of manually instantiating it in multiple places in your app:

class CheckoutController extends Controller
{
    protected $stripe;

    public function __construct(StripeClient $stripe)
    {
        $this->stripe = $stripe;
    }

    // Now all actions have access to StripeClient as $this->stripe
}
#

This is a lot of unnecessary duplication for the sake of adding a coupon:

if(!session()->get('coupon')) // Checks if the user has a coupon applied to cart
{
    $checkout_session = $stripe->checkout->sessions->create([
        'line_items' => $listOfProducts,
        'mode' => 'payment',
        'success_url' => route('checkout.success', [], true)."?session_id={CHECKOUT_SESSION_ID}",
        'cancel_url' => route('checkout.cancel', [], true)."?session_id={CHECKOUT_SESSION_ID}",
    ]);
} else {    
    $checkout_session = $stripe->checkout->sessions->create([
        'line_items' => $listOfProducts,
        'mode' => 'payment',
        'discounts' => [[
            'coupon' => session()->get('coupon')['name'],
        ]],
        'success_url' => route('checkout.success', [], true)."?session_id={CHECKOUT_SESSION_ID}",
        'cancel_url' => route('checkout.cancel', [], true)."?session_id={CHECKOUT_SESSION_ID}",
    ]);
}

You can simplify by creating your “base” array, and then conditionally adding a new key if there is a coupon in the session:

$sessionData = [
    'line_items' => $listOfProducts,
    'mode' => 'payment',
    'success_url' => route('checkout.success', [], true)."?session_id={CHECKOUT_SESSION_ID}",
    'cancel_url' => route('checkout.cancel', [], true)."?session_id={CHECKOUT_SESSION_ID}",
];

// Conditionally add coupon if it exists in session
if ($coupon = session('coupon.name')) {
    $sessionData['discounts'] = [
        [
            'coupon' => $coupon,
        ],
    ];
}

$checkout_session = $stripe->checkout->sessions->create($sessionData);
sullen bronze
#

Wow, thank you

sullen bronze
devout veldt
#

No, register method.

sullen bronze
#

I get an error of Target class [App\Http\Controllers\StripeClient] does not exist.

devout veldt
#
use Stripe\StripeClient;
sullen bronze
# devout veldt You need to actually import the class.

Sorry to keep bothering you but now I get an error of No API key provided. Set your API key when constructing the StripeClient instance, or provide it on a per-request basis using the `api_key` key in the $opts argument.

Aren't we passing the api_key here: 'api_key' => $this->app['config']['services.stripe.secret'],

#

The STRIPE_SECRET_KEY is in my .env file

devout veldt
sullen bronze
#

I have like this:

 'stripe' => [
        'key' => env('STRIPE_KEY'),
        'secret' => env('STRIPE_SECRET'),
    ]
young hamlet
sullen bronze
#

🤦‍♂️ I'm sorry

#

Thank you

#

Okay, based on Martin feedback (thank you vert much btw). I have updated the OP with the cleaned code. if anyone could by any chance help me out in writing a test for this, I would appreciate it as I am very confused on how to make it work.

delicate fractal
#

how can i withdraw amount stripe laravel

#

any body help?

devout veldt
#

From the #rules:

Help us help you - Search the documentation before posting your issue and explain what you're doing and include any error messages you have received.