Search code examples
phplaravellaravel-5stripe-connectintervention

How to upload image file to Stripe from Amazon S3 using Laravel 5.5 and Intervention Image


Laravel 5.5 app. I need to retrieve images of driver's licenses from Amazon S3 (already working) and then upload it to Stripe using their api for identity verification (not working).

Stripe's documents give this example:

\Stripe\Stripe::setApiKey(PLATFORM_SECRET_KEY);
\Stripe\FileUpload::create(
    array(
        "purpose" => "identity_document",
        "file" => fopen('/path/to/a/file.jpg', 'r')
    ),
    array("stripe_account" => CONNECTED_STRIPE_ACCOUNT_ID)
);

However, I am not retrieving my files using fopen(). When I retrieve my image from Amazon S3 (using my own custom methods), I end up with an instance of Intervention\Image -- essentially, Image::make($imageFromS3) -- and I don't know how to convert this to the equivalent of the call to fopen('/path/to/a/file.jpg', 'r'). I have tried the following:

$image->stream()

$image->stream()->__toString()

$image->stream('data-url')

$image->stream('data-url')->__toString()

I have also tried skipping intervention image and just using Laravel's storage retrieval, for example:

$image = Storage::disk('s3')->get('path/to/file.jpg');

All of these approaches result in getting an Invalid hash exception from Stripe.

What is the proper way to get a file from S3 and convert it to the equivalent of the fopen() call?


Solution

  • If the file on S3 is public, you could just pass the URL to Stripe:

    \Stripe\FileUpload::create(
        array(
            "purpose" => "identity_document",
            "file" => fopen(Storage::disk('s3')->url($file)),
        ),
        array("stripe_account" => CONNECTED_STRIPE_ACCOUNT_ID)
    );
    

    Note that this requires allow_url_fopen to be turned on in your php.ini file.

    If not, then you could grab the file from S3 first, write it to a temporary file, and then use the fopen() method that the Stripe documentation speaks of:

    // Retrieve file from S3...
    $image = Storage::disk('s3')->get($file);
    
    // Create temporary file with image content...
    $tmp = tmpfile();
    fwrite($tmp, $image);
    
    // Reset file pointer to first byte so that we can read from it from the beginning...
    fseek($tmp, 0);
    
    // Upload temporary file to S3...
    \Stripe\FileUpload::create(
        array(
            "purpose" => "identity_document",
            "file" => $tmp
        ),
        array("stripe_account" => CONNECTED_STRIPE_ACCOUNT_ID)
    );
    
    // Close temporary file and remove it...
    fclose($tmp);
    

    See https://secure.php.net/manual/en/function.tmpfile.php for more information.