Ask A Question


You’re not receiving notifications from this thread.

Rails Braintree couldn't update

Lee Terng Gio asked in Rails

I'm implementing Braintree Subscription Payment into my rails app. I've encounter some issue when trying to update subscription information in my database. When I make a payment, it's successfully created and saved into Braintree. The transaction was also created and saved into my database. The only problem is it couldn't update the payment information such as braintree_id, braintree_subscription_id etc in the User.

Below is my Subscriptions Controller:

class SubscriptionsController < ApplicationController
  before_action :logged_in_user, only: [:new, :create]

  def new
    @plans = Braintree::Plan.all

  def create
    if current_user.braintree_id?
      customer = Braintree::Customer.find(current_user.braintree_id)
      result = Braintree::Customer.create(
        email: current_user.company_email,
        payment_method_nonce: params[:payment_method_nonce]
      customer = result.customer


    result = Braintree::Subscription.create(
      payment_method_token: customer.payment_methods.find{ |pm| pm.default? }.token,
      plan_id: params[:plan_id],

    result.subscription.transactions.each do |transaction|
        plan_name: params[:plan_name],
        price: transaction.amount.to_f,
        start_date: transaction.subscription_details.billing_period_start_date,
        end_date: transaction.subscription_details.billing_period_end_date,

    current_user.update(braintree_subscription_id:, next_billing_date: result.subscription.next_billing_date,
    billing_period_start_date: result.subscription.billing_period_start_date,
    billing_period_end_date: result.subscription.billing_period_end_date,
    status: result.subscription.status,
    next_billing_period_amount: result.subscription.next_billing_period_amount,
    paid_through_date: result.subscription.paid_through_date,
    plan_id: params[:plan_id],
    plan_name: params[:plan_name])

    redirect_to @current_user, notice: "You have been subscribed"

I've tried to manually update the information in the console, and everything works well. Below are the output that when making a new payment, it rollback and couldn't update the User. While the Transaction was created and saved into database.

Started POST "/subscription.213" for at 2017-12-14 07:57:55 +0000
Processing by SubscriptionsController#create as 
  Parameters: {"utf8"=>"✓", "authenticity_token"=>"FHwbQSfiinjfskBG3Iec8C0gKuGIeOQDmBnjJu4fpEQwsrmsewHYvgAFIpKVguehm+TZAjHrfd8Ya6CWYPX1Rw==", "plan_id"=>"monthly", "plan_name"=>"monthly", "payment_method_nonce"=>"0986895d-aab4-01b3-5829-778101fa0ebb"}
  User Load (0.1ms)  SELECT  "users".* FROM "users" WHERE "users"."id" = ? LIMIT 1  [["id", 213]]
I, [2017-12-14T07:57:56.724260 #10346]  INFO -- : [Braintree] [14/Dec/2017 07:57:56 UTC] POST /merchants/wt92v8tk2hn8j7kg/customers 201
   (0.1ms)  begin transaction
  User Exists (0.3ms)  SELECT  1 AS one FROM "users" WHERE (LOWER("users"."company_email") = LOWER('') AND "users"."id" != 213) LIMIT 1
   (0.1ms)  rollback transaction
I, [2017-12-14T07:57:57.747920 #10346]  INFO -- : [Braintree] [14/Dec/2017 07:57:57 UTC] POST /merchants/wt92v8tk2hn8j7kg/subscriptions 201
   (0.0ms)  begin transaction
  SQL (0.3ms)  INSERT INTO "transactions" ("braintree_transaction_id", "plan_name", "price", "start_date", "end_date", "subscription_id", "user_id", "created_at", "updated_at") VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)  [["braintree_transaction_id", "38273ws4"], ["plan_name", "monthly"], ["price", 9.0], ["start_date", "2017-12-14"], ["end_date", "2018-01-13"], ["subscription_id", "7882v6"], ["user_id", 213], ["created_at", "2017-12-14 07:57:57.780968"], ["updated_at", "2017-12-14 07:57:57.780968"]]
   (8.8ms)  commit transaction
   (0.1ms)  begin transaction
  User Exists (0.3ms)  SELECT  1 AS one FROM "users" WHERE (LOWER("users"."company_email") = LOWER('') AND "users"."id" != 213) LIMIT 1
   (0.1ms)  rollback transaction
Redirected to
Completed 302 Found in 2257ms (ActiveRecord: 10.4ms)

This thing works perfectly in my other app which using Devise. I didn't use Devise in this app and I'm not sure what really cause this issue. It really appreciated if somebody point me some direction.


Hi Lee,

You probably have a validation on the user model or transaction model that's not being satisfied. Can you post any validations you have on your user and transaction model?

You can also use the byebug gem and place byebug right before the transaction that fails. Then try another subscription and this time when byebug is triggered, try creating the transaction there manually and see what error is raised.


Below is the User model:

    validates :company_name, presence: true, length: {maximum: 50}
    VALID_EMAIL_REGEX = /\A[\w+\-.]+@[a-z\d\-]+(\.[a-z\d\-]+)*\.[a-z]+\z/i
        validates :company_email, presence: true, length: {maximum: 255}, format: { with: VALID_EMAIL_REGEX }, uniqueness: { case_sensitive: false }
    validates :company_contact, presence: true, length: {maximum: 15}
    validates :term, presence: true
    validates :password, presence: true, length: { minimum: 6 }
    validates_confirmation_of :password

Below is my db/seed

User.create!(company_name:  "Example User",
             company_email: "",
             company_contact: "011999484",
             password:              "foobar",
             password_confirmation: "foobar",
             term:     true,
             activated: true,

99.times do |n|
  company_name  = "Example user"
  company_email = "example-#{n+1}"
  company_contact = "0119999494"
  password = "password"
  User.create!(company_name:  company_name,
              company_email: company_email,
              company_contact: company_contact,
              password:              password,
              password_confirmation: password,
              term: true,
              activated: true,

When I run rake db:seed, everything works well, and I can login using the password as "password", but when run user.valid?, it gives false and the errors messages show {:password=>["can't be blank", "is too short (minimum is 6 characters)"]}


What are you using to authenticate your users in this app if you're not using Devise? The error shown is clearly that it's expecting a password, and your validations on your user model also state you need password info when saving/updating a user.

I think you need to restructure your models some... your user model really needs to be focused on just the users information needed to login. Everything else needs to be in their own model that is associated with the user model.

So instead of putting a users company in the user model, create a company model and then depending on your needs, either do a has_one or has_many association between the user and company.

You also need a subscription model that will take care of keeping track of a users subscription. You may also consider a payment_source model that will keep track of the braintree_id.

Ideally, for what you're wanting to accomplish, you shouldn't need to save anything to the user model when you're creating a transaction.

Join the discussion
Create an account Log in

Want to stay up-to-date with Ruby on Rails?

Join 84,256+ developers who get early access to new tutorials, screencasts, articles, and more.

    We care about the protection of your data. Read our Privacy Policy.