Mocking Stripe in Laravel with Stripe Mock Server

Mocking Stripe in Laravel with Stripe Mock Server

Featured on Hashnode

If you've ever tried to test your Stripe integration, you'll know how challenging it can be. The Stripe SDK uses lots of static methods that are hard to fake.

I would rather not write my own stubs or dummy classes that get switched out in tests, that's a lot of work.

thankfully, Stripe has a Mock Server that you can install. The idea is you use Stripe's API endpoints in your application, and when tests run, they run using the Stripe Mock server endpoints and return a sample response from Stripe for each endpoint.

This lets you test your implementation without having to touch any actual Stripe code.

Installation

Install on MacOS with Homebrew

brew install stripe/stripe-mock/stripe-mock

# start a stripe-mock service at login
brew services start stripe-mock

# upgrade if you already have it
brew upgrade stripe-mock

# restart the service after upgrading
brew services restart stripe-mock

The Homebrew service listens on port 12111 for HTTP and 12112 for HTTPS and HTTP/2.

Docker

docker run --rm -it -p 12111-12112:12111-12112 stripe/stripe-mock:latest

The default Docker ENTRYPOINT listens on port 12111 for HTTP and 12112 for HTTPS and HTTP/2.

Laravel Setup

In config/services.php add environment variables for strip API base:

'stripe' => [
        'key' => env('STRIPE_KEY'),
        'secret' => env('STRIPE_SECRET'),
        'webhook' => env('STRIPE_WEBHOOK_SECRET'),
        'monthly' => env('STRIPE_MONTHLY'),
        'annually' => env('STRIPE_ANNUALLY'),
        'api_base' => env('STRIPE_API_BASE'),
],

I will use a .env.testing file so I can have different credentials for testing purposes.

Ensure the key and secret start with sk_test_ otherwise Stripe will complain.

Since I've installed Stripe Mock with Homebrew the URL will be http://localhost:12111

STRIPE_KEY=sk_test_4eHqC79LfsWDarjtT1zdp7dc
STRIPE_SECRET=sk_test_9eC37FqLyjWDarjtT1zdp9dc
STRIPE_WEBHOOK_SECRET=whsec_secret
STRIPE_MONTHLY=price_monthly
STRIPE_ANNUALLY=price_annual
STRIPE_API_BASE="http://localhost:12111"

Now we need a way for the base URL to switch with the Stripe_API_BASE is set.

Inside app/Providers/AppServiceProvider.php

Add this code. This tells Stripe to use the mock URL instead of the real one. By default, $apiBase inside Stripe is set to https://api.stripe.com

public function boot(): void
{
    if ($stripeApiBase = config('services.stripe.api_base')) {
        Stripe::$apiBase = $stripeApiBase;
    }
}

that's pretty much it. Now when config('services.stripe.api_base') is set Stripe will use the Mock URL instead of Stripes URL.

GitHub Actions

Now let's go over how-to set up Stripe Mock for GitHub Actions. Inside a GitHub actions .yml file install the Mock server in the services section:

services:

    stripemock:
      image: stripemock/stripe-mock:latest
      ports:
        - 12111:12111

Now set up the environment variables for the tests.

The key and secret don't need to be real, but they need to look like valid keys.

They must start with sk_test_

-   name: Run test suite
    env:
      STRIPE_KEY: "sk_test_4eC39HqLyjWDarjtT1zdp7dc"
      STRIPE_SECRET: "sk_test_6eC37HqLyjWDarjtT1zdp7dc"
      STRIPE_WEBHOOK_SECRET: "dummy"
      STRIPE_MONTHLY: "price_1Nb4hULiL14otffRI9TPcHo4"
      STRIPE_ANNUALLY: "price_1Nb4hULiL14otffRvPO2pt3b"
      STRIPE_API_BASE:  "localhost:12111"
    run: ./vendor/bin/pest --parallel

Did you find this article valuable?

Support David Carr by becoming a sponsor. Any amount is appreciated!