0
votes

I'm building a two sided marketplace, where users are paid out when an item of theirs, sells.

I have a form that a user fills out when wanting to list an item on the marketplace. It includes many inputs, but the important ones for this question are the Stripe COUNTRY, ACCOUNT, and ROUTING inputs. This is so that they can be paid automatically after their items sells.

I'm storing a Stripe recipient ID in the user database, so that they don't have to enter their bank account info every time they post a new item. (Which can be seen in the #create action) Everything that I'm about to post below works perfectly, BUT ONLY ONCE. After posting an item the first time, the user Recipient ID successfully saves to my user database. BUT, if that user attempts to post another item, I get a Stripe error, saying that: "You must supply either a card, customer, or bank account to create a token.", when attempting to submit the form. This error is shown in my Stripe dashboard as well.

I am under the assumption that is has to do with Strong Params? At first, I did not have :Country, :Routing_number, or :Account_number in the params in the listing_controller, so I have added them in, but it did not fix the error. Am I close? Can anyone spot what I'm doing wrong?

_FORM.HTML.ERB:

<%= form_for @listing, :html => { :multipart => true } do |f| %>
<% if @listing.errors.any? %>
<div id="error_explanation" class="alert alert-danger alert-dismissable">
<button type="button" class="close" data-dismiss="alert" aria-hidden="true">&times;    </button>
  <h2><%= pluralize(@listing.errors.count, "error") %> prohibited this listing from being saved:</h2>

  <ul>
  <% @listing.errors.full_messages.each do |message| %>
    <li><%= message %></li>
  <% end %>
  </ul>
</div>
<% end %>

<div id="stripe_error" class="alert alert-danger" style="display:none">
<noscript> Javascript is disabled. Order cannot be placed. First enable it in your  browser.</noscript>

<% if current_user.recipient.blank? %>
<br>
<h1>Bank Account Information</h1>
<p class="sm-message">(You'll only need to enter this once.)</p>

<div class="form-group">
  <%= label_tag :country %>
  <%= text_field_tag :country, nil, { :name => nil, :'data-stripe' => "country", class:  "form-control" } %>
</div>
<div class="form-group">
  <%= label_tag :routing_number %>
  <%= text_field_tag :routing_number, nil, { :name => nil, :'data-stripe' => "routingNumber", class: "form-control" } %>
 </div>
 <div class="form-group">
  <%= label_tag :account_number %>
  <%= text_field_tag :account_number, nil, { :name => nil, :'data-stripe' => "accountNumber", class: "form-control" } %>
</div>
<% end %>



<div class="form-group">
<%= f.submit class: "btn btn-primary btn-lg" %>
</div>
<% end %>
</div>

LISTING_CONTROLLER.RB

class ListingsController < ApplicationController
before_action :set_listing, only: [:show, :edit, :update, :destroy]
before_filter :authenticate_user!, only: [:seller, :new, :create, :edit, :update,  :destroy]
before_filter :check_user, only: [:edit, :update, :destroy]

def seller
@listings = Listing.where(user: current_user).order("created_at DESC")
end

# GET /listings
# GET /listings.json
def index
@listings = Listing.all.order("created_at DESC")
end

# GET /listings/1
# GET /listings/1.json
def show
end

# GET /listings/new
def new
@listing = Listing.new

end

# GET /listings/1/edit
def edit
end

# POST /listings
# POST /listings.json
def create
@listing = Listing.new(listing_params)
@listing.user_id = current_user.id
if current_user.recipient.blank?
Stripe.api_key = ENV["STRIPE_API_KEY"]
token = params[:stripeToken]

recipient = Stripe::Recipient.create(
  :name => current_user.name,
  :type => "individual",
  :bank_account => token
)

 current_user.recipient = recipient.id
 current_user.save
 end

 respond_to do |format|
  if @listing.save
    format.html { redirect_to @listing, notice: 'Listing was successfully created.' }
    format.json { render :show, status: :created, location: @listing }
  else
    format.html { render :new }
    format.json { render json: @listing.errors, status: :unprocessable_entity }
  end
  end
  end

  # PATCH/PUT /listings/1
  # PATCH/PUT /listings/1.json
  def update
  respond_to do |format|
  if @listing.update(listing_params)
    format.html { redirect_to @listing, notice: 'Listing was successfully updated.' }
    format.json { render :show, status: :ok, location: @listing }
  else
    format.html { render :edit }
    format.json { render json: @listing.errors, status: :unprocessable_entity }
  end
  end
  end

  # DELETE /listings/1
  # DELETE /listings/1.json
  def destroy
   @listing.destroy
  respond_to do |format|
  format.html { redirect_to listings_url, notice: 'Listing was successfully destroyed.'  }
  format.json { head :no_content }
  end
  end

  private
  # Use callbacks to share common setup or constraints between actions.
  def set_listing
  @listing = Listing.find(params[:id])
  end

  # Never trust parameters from the scary internet, only allow the white list through.
  def listing_params
  params.require(:listing).permit(:name, :description, :price, :duration, :street, :city, :state, :image, :duration, :category, :terms,
   :country, :account_number, :routing_number, :stripeToken)
  end

 def check_user
  if current_user != @listing.user
    redirect_to root_url, alert: "Sorry, that is not your listing."
 end
 end
 end

LISTING.JS.COFFEE

jQuery ->
Stripe.setPublishableKey($('meta[name="stripe-key"]').attr('content'))
listing.setupForm()

listing =
setupForm: ->
$('#new_listing').submit ->
  if $('input').length > 8
    $('input[type=submit]').attr('disabled', true)
    Stripe.bankAccount.createToken($('#new_listing'), listing.handleStripeResponse)
    false

 handleStripeResponse: (status, response) ->
  if status == 200
  $('#new_listing').append($('<input type="hidden" name="stripeToken"  />').val(response.id))
  $('#new_listing')[0].submit()
 else
  $('#stripe_error').text(response.error.message).show()
  $('input[type=submit]').attr('disabled', false)

STRIPE DASHBOARD INFORMATION BEING RETURNED:

key: "pk_test_WgTil6dDhXN6JqzqZI4Gjw0M"
callback: "sjsonp1404518718631"
_method: "POST"

error:
type: "invalid_request_error"
message: "You must supply either a card, customer, or bank account to create a token."
1
Is this code all current? You've got some ungood things going on here, like quoted symbols and—more importantly—an <% end %> that isn't closing anything. That <% end %> will break things. I'd start there unless it's a typo.colinm
Hmmmm, I went back through it again, and I'm not seeing what <% end %> doesn't belong. I've got a few "IF" statements going on, where the extra <% end %>'s are needed. Am I missing something? Also, sorry I'm very new to this, so what exactly do you mean by "quoted symbols"? Thank you very much!Anthony Myers

1 Answers

0
votes

The problem might be here:

current_user.recipient = recipient.id
current_user.save

You're saving an ID where an object is expected. Try:

current_user.recipient = recipient
current_user.save