0

I set up Laravel Cashier and it fails to connect to Stripe.

I've isolated the bug to the point where this simple line fails:

$user = new User();
$user->subscription()->create('test');

The error is nondescript:

Stripe_ApiConnectionError in vendor/stripe/stripe-php/lib/Stripe/ApiRequestor.php

Could not connect to Stripe (https://api.stripe.com). Please check your internet connection and try again. If this problem persists, you should check Stripe's service status at https://twitter.com/stripestatus. Reason was:

As you can see, $errstr, used to display the reason, is null.

My research so far...

$errstr can be null because of an unfixed PHP bug when the certificate check fails.

I found this StackOverflow question which mentions that it's because the CAPath is not specified.

This indeed seems to be the case in Homestead / Vagrant. I suspect something is wrong in the default VagrantBox config.

When I run this command from my Mac I get a return code 0 (working):

openssl s_client -connect api.stripe.com:443

When I run the same command from Homestead I get a return code 20 (unable to get local issuer certificate):

To make it work in Homestead, I have to manually specify the CAPath like so:

openssl s_client -CApath /etc/ssl/certs/ -connect api.stripe.com:443

Then I get return code 0.

How can I fix this for good so my Cashier calls work?

Community
  • 1
  • 1
Lazlo
  • 8,518
  • 14
  • 77
  • 116

2 Answers2

1

I had this issue as well, and running vagrant provision didn't help.

My Homestead box has a habit of the clock going slightly or sometimes very out of time. It seemed that updating the time on Homestead to the correct time fixed it. Perhaps this is why running the provision command fixed it in your case.

You can do this by running:

sudo service ntp stop
sudo ntpdate -s time.nist.gov
sudo service ntp start

As I had to do this relatively often (it also caused issues with Scout) I ran:

php artisan make:command UpdateClock

and then edited app/Console/Commands/UpdateClock.php to the following:

<?php

namespace App\Console\Commands;

use Illuminate\Console\Command;

class UpdateClock extends Command
{
    /** The name and signature of the console command. */
    protected $signature = 'clock:update';

    /** The console command description */
    protected $description = 'Updates vagrants clock';

    /** Create a new command instance */
    public function __construct()
    {
        parent::__construct();
    }

    /** Execute the console command. */
    public function handle()
    {
        exec("sudo service ntp stop");
        exec("sudo ntpdate -s time.nist.gov");
        exec("sudo service ntp start");
    }
}

Now whenever it goes out of time I just run:

php artisan clock:update
Djave
  • 8,595
  • 8
  • 70
  • 124
0

Seems like running vagrant provision fixed the problem. Odd...

Lazlo
  • 8,518
  • 14
  • 77
  • 116