Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

JillzTom's avatar

Payment with Stripe gives an error

I'm trying to use stripe to make a small payment form in my application using Laravel. I followed even the tutorials from Laracast. But I'm getting this error

Stripe_InvalidRequestError You must supply either a card or a customer id

I even tried to take the code from the Github repository, but still getting the same error. Is it a general error or what might be the cause?

Should I provide all my code here? (It's the same as Github)

0 likes
4 replies
MThomas's avatar

What is the code that results in this error, probably you're not passing the card_id to stripe.

JillzTom's avatar

billing.js

(function(){
    var StripeBilling = {
        init: function(){
            this.form=$('#billing-form');
            this.submitButton = this.form.find('input[type=submit]');
            this.submitButtonValue = this.submitButton.val();

            var stripeKey=$('meta[name="publishable-key"]').attr('content');

            Stripe.setPublishableKey(stripeKey);

            this.bindEvents();
        },

        bindEvents: function(){
            this.form.on('submit', $.proxy(this.sendToken, this));
        },

        sendToken: function(event){
            this.submitButton.val('One Moment').prop('disabled', true);
            Stripe.createToken(this.form, $.proxy(this.stripeResponseHandler, this) );

            event.preventDefault();

        },

        stripeResponseHandler: function(status, response){
            if(response.error){
                this.form.find('.payment-errors').show().text(response.error.message);
                return this.submitButton.prop('disabled', false).val(this.submitButtonValue);
            }


            $('<div>', {
                type: 'hidden',
                name: 'stripe-token',
                value: response.id
            }).appendTo(this.form);

            this.form[0].submit();
        }
    };

    StripeBilling.init();

})();

BillingInterface.php

<?php
namespace Acme\Billing;

use Stripe;
use Stripe_Charge;
use Config;

class StripeBilling implements BillingInterface {
    public function __construct()
    {
        Stripe::setApiKey(Config::get('stripe.secrete_key'));
    }
    public function charge(array $data)
    {
        try
        {
            return Stripe_Charge::create([
                'amount' => 1000, // $10
                'currency' => 'usd',
                'description' => $data['email'],
                'card'=>$data['token']
            ]);
        }
        catch(Stripe_CardError $e)
        {
           dd('Card was declined');
        }
    }
}

Route.php

 Route::post('/payment', function(){

            $billing = App::make('Acme\Billing\BillingInterface');
            $billing->charge([
                'email'=> Input::get('email'),
                'token'=>Input::get('stripe-token')
            ]);

            return 'Charge was successful';
        });

Error ->

Stripe_InvalidRequestError 
You must supply either a card or a customer id
Open: C:\wamp\www\lc2\laravel\vendor\stripe\stripe-php\lib\Stripe\ApiRequestor.php
    case 400:
        if ($code == 'rate_limit') {
          throw new Stripe_RateLimitError(
              $msg, $param, $rcode, $rbody, $resp
          );
        }
    case 404:
        throw new Stripe_InvalidRequestError(
            $msg, $param, $rcode, $rbody, $resp
        );
MThomas's avatar

If you dump all the input values in the payment post route is stripe-token present there? Otherwise your JS script is not posting the value correctly I think.

theUnforgiven's avatar

I presume you will have seen this - https://gist.github.com/briancollins/6365455 ? I then had this setup:

class StripeBilling implements BillingInterface {

    public function __construct()
    {
        Stripe::setApiKey(Config::get('stripe.secret_key'));
    }
    // Set up customer and charge
    public function charge(array $data)
    {
        try
        {

              $customer = Stripe_Customer::create(array(
                    "card"        => $data['token'],
                    "plan"        => "standard",
                    "email"       => $data['email'],
                    "description" => $data['email']

              ));


              $charge = Stripe_Charge::create(array(
                    'customer' => $customer->id,
                    'amount'   => 699,
                    'currency' => 'GBP'
              ));

               $payment = new Payment;
               $payment->payment_token = $data['token'];
               $payment->user_id = $data['user_id'];
               $payment->payment_amount = '699';
               $payment->trial_start = $customer->subscription->trial_start;
               $payment->trial_end = $customer->subscription->trial_end;
               $payment->plan = $customer->subscription->plan;
               $payment->status = $customer->subscription->status;
               $payment->plan_created = $customer->subscription->current_period_start; 
               $payment->plan_active = 1;
               $payment->customer_id = $customer->id;
               $payment->save();


               $user = User::find($data['user_id']);
               $user->billing_id = $customer->id;
               $user->save();


               return $customer;

        }

        catch (Stripe_InvalidRequestError $e)
        {
            // Invalid parameters were supplied to Stripe's API
            return \App::make('redirect')->to('dashboard')->with('flash_error', $e->getMessage());
        }


        catch(Stripe_CardError $e)
        {
            return \App::make('redirect')->to('dashboard')->with('flash_error', $e->getMessage());
        }
        catch (Stripe_Error $e) 
        { 
            return \App::make('redirect')->to('dashboard')->with('flash_error', $e->getMessage());
        }
     }

Hope this helps and give you some indication on what's wrong or missing.

Please or to participate in this conversation.