William Holt William Holt - 2 months ago 18
jQuery Question

Possible to create Token with Stripe JS with no payment information

I have a client that wants to have a Stripe subscription that does not cost anything. Currently, their application is set up to take CC info because their older plan did require a monthly fee.

I want to know if it is possible to create a Stripe customer token via Stripe JS without taking any kind of CC info/bank account etc from the user?

I tried removing the CC fields with jQuery, but I keep getting a Stripe Invalid Request error because it cannot find the payment information.

So to summarize, when a user selects the 'free' plan from the dropdown, they should not see the CC fields and they should be able to progress through the sign up page without any Stripe validations while also creating their customer token.

Is this possible?

Relevant files

Hosts Controller #create

def create
@host = User.new(host_params)

if @host.valid?
customer = Stripe::Customer.create(
stripe_params.merge(email: host_params[:email], coupon: coupon)
)

@host.update(
stripe_customer_id: customer[:id],
subscription_plan: stripe_params[:plan]
)

sign_in(:user, @host)

redirect_to dashboard_path, notice: t('notices.hosts.created')
else
render :new
end
rescue Stripe::CardError, Stripe::InvalidRequestError => error
render :new, alert: error.message
end


Stripe JS code

$(document).on 'ready page:load', ->
$cardFields = $('#credit-card-fields')
$parentForm = $cardFields.parents('form')
$parentBtn = $('.js-payment-btn', $parentForm)

return unless $parentForm.length

$parentBtn.on 'click', (event) ->
event.preventDefault()

pub_key = $('meta[name=stripe-publishable-key]').attr('content')

$parentBtn.prop('disabled', true)

Stripe.setPublishableKey(pub_key)

Stripe.card.createToken $parentForm, (status, response) ->
if response.error
$parentForm.find('.payment-errors').text(response.error.message)
$parentBtn.prop('disabled', false)
else
token = response.id
S> $parentForm.append($('<input type="hidden" name="stripe[source]" />').val(token))
$parentForm.get(0).submit()


Stripe JS Form

<script type="text/javascript" src="https://js.stripe.com/v2/" data-turbolinks-track="true"></script>

<div class="clearfix" id="credit-card-fields">
<span class="payment-errors"></span>

<div class="form-group">
<div class="input-group">
<span class="input-group-addon icon icon-credit-card"></span>
<input id="card-number" class="form-control input-cc" required placeholder="Card Number" type="text" size="16" maxlength=16 data-stripe="number" />
</div>
</div>

<div class="form-group side-by-side">
<div class="input-group">
<span class="input-group-addon icon icon-calendar"></span>
<input id="card-month" class="form-control input-exp" required placeholder="MM" type="text" size="2" maxlength="2" data-stripe="exp-month" />
<input id="card-year" class="form-control input-exp" required placeholder="YY" type="text" size="2" maxlength="2" data-stripe="exp-year" />
</div>
</div>

<div class="form-group side-by-side">
<div class="input-group">
<span class="input-group-addon icon icon-lock"></span>
<input id="card-cvc" class="form-control input-cvv" required placeholder="CVC" type="text" size="4" maxlength="4" data-stripe="cvc" />
</div>
</div>
</div>

Answer

It would not make sense to create a card token without any card details so this is not possible. As you mentioned, if you try to create a token without the required parameters such as the card number or the expiration date you get an invalid_request_error back.

If you don't want to require card details then you should just not create a token. When someone attempts to subscribe to a free plan, you would bypass the need to create a token and simply collect the rest of the information you want such as the customer's email address or name. Then server-side, you'd call the Create Customer API and pass the plan id in the plan parameter to subscribe them.

If the plan is free then there's no need to pass a token and you can simply ignore the source parameter completely.

Comments