Laravel Cashier - Unit Tests With Creating Subscriptions With Payment Methods

- 1 answer

Looking deeper into this, I'm not sure it's even possible, which is a shame because I'm trying to learn TDD.

I would like to test my model with Billable being created and subscribed to a plan.

/** @test */
public function an_account_can_subscribe_to_a_plan() {
    $account = factory("App\Account")->create();

    $paymentMethod = PaymentMethod::create([
        'type' => 'card',
        'card' => [
            'number' => '4242424242424242',
            'exp_month' => '2',
            'exp_year' => '2021',
            'cvc' => '314'

    $subscription = $account->newSubscription('default', 'starter')->create($paymentMethod);
    $this->assertTrue( $subscription->valid() );  

The Laravel Cashier docs show how to send a token via Stripe.js, but that doesn't work for Unit Testing.

I've tried to include the Stripe library directly and create a PaymentMethod object, but this also requires me set an API key manually. Now the error I'm getting is that I have to verify my phone number to send raw credit card numbers to the stripe API.

I'm hoping there's a better way. How can I use Laravel Cashier in a TDD way and mock up fake subscriptions with fake payment methods?



Stripe provides not only test card numbers, but tokens and payment method's.

Click the PaymentMethods tab. The value (for example pm_card_visa) can be used directly on the server-side in your tests without the need of front-end payment-intent implementation.

This is an example of a feature test I have:

     * @test
    public function a_user_can_subscribe_to_a_paid_plan()


        $enterprise = Plan::where('name', 'Enterprise')->first()->stripe_plan_id;

        $response = $this->post(route('paywall.payment'), [
            'payment_method' => 'pm_card_visa',
            'stripe_plan_id' => $enterprise


Your tests may vary, but you can make a normal request to your billing controller with these test payment methods and it goes through just as it would if you do it on the front-end.