user8331511
user8331511

Reputation:

Get Stripe charge information rails 5 create order

So I'm implementing Stripe and users are able to purchase successfully, however, I would like to get the charge information, last 4 card numbers, card type etc so I can generate receipts using https://github.com/excid3/receipts.

Here is what I have so far:

PaymentsController

class PaymentsController < ApplicationController
  before_action :authenticate_user!

  def create
    token = params[:stripeToken]
    @course = Course.find(params[:course_id])
    @user = current_user

    begin
      charge = Stripe::Charge.create(
        amount: (@course.price*100).to_i,
        currency: "gbp",
        source: token,
        description: params[:stripeEmail],
        receipt_email: params[:stripeEmail]
      )

      if charge.paid
        Order.create(
          course_id: @course.id,
          user_id: @user.id,
          Amount: @course.price
        )
      end

    flash[:success] = "Your payment was processed successfully"

    rescue Stripe::CardError => e
      body = e.json_body
      err = body[:error]
      flash[:error] = "Unfortunately, there was an error processing your payment: #{err[:message]}"
    end

    redirect_to course_path(@course)
  end
end

OrdersController

class OrdersController < ApplicationController
  layout proc { user_signed_in? ? "dashboard" : "application" }

  before_action :authenticate_user!

  def index
    @orders = Order.includes(:course).all
  end

  def show
    @order = Order.find(params[:id])

    respond_to do |format|
      format.pdf {
        send_data @order.receipt.render,
        filename: "#{@order.created_at.strftime("%Y-%m-%d")}-aurameir-courses-receipt.pdf",
        type: "application/pdf",
        disposition: :inline
      }
    end
  end

  def create
  end

  def destroy
  end
end

Order.rb

class Order < ApplicationRecord
  belongs_to :course
  belongs_to :user

  validates :stripe_id, uniqueness: true

  def receipt
    Receipts::Receipt.new(
      id: id,
      subheading: "RECEIPT FOR CHARGE #%{id}",
      product: "####",
      company: {
        name: "####",
        address: "####",
        email: "####",
        logo: "####"
      },
      line_items: [
        ["Date",           created_at.to_s],
        ["Account Billed", "#{user.full_name} (#{user.email})"],
        ["Product",        "####"],
        ["Amount",         "£#{amount / 100}.00"],
        ["Charged to",     "#{card_type} (**** **** **** #{card_last4})"],
        ["Transaction ID", uuid]
      ],
      font: {
        normal: Rails.root.join('app/assets/fonts-converted/font-files/AvenirBook.ttf')
      }
    )
  end
end

schema.rb

create_table "orders", force: :cascade do |t|
    t.integer "user_id"
    t.integer "course_id"
    t.integer "stripe_id"
    t.integer "amount"
    t.string "card_last4"
    t.string "card_type"
    t.integer "card_exp_month"
    t.integer "card_exp_year"
    t.string "uuid"
    t.index ["course_id"], name: "index_orders_on_course_id"
    t.index ["user_id"], name: "index_orders_on_user_id"
  end

How would I go about getting the charge information?

Upvotes: 2

Views: 469

Answers (2)

SteveTurczyn
SteveTurczyn

Reputation: 36880

All the information you need is in the charge object you created.

  if charge.paid
    Order.create(
      course_id: @course.id,
      user_id: @user.id,
      amount: @course.price, 
      card_last4: charge.source.last4,
      card_type: charge.source.brand,
      card_exp_month: charge.source.exp_month,
      card_exp_year: charge.source.exp_year
    )
  end

See https://stripe.com/docs/api/ruby#charge_object for all the information available to you about a charge.

Upvotes: 1

Ravi Teja Dandu
Ravi Teja Dandu

Reputation: 476

I guess you are not storing the Stripe Charge ID anywhere on successful payment.

My suggestion, store the charge ID in your Order record

if charge.paid
  Order.create(
    course_id: @course.id,
    user_id: @user.id,
    amount: @course.price,
    stripe_charge_id: charge.id
  )
end

In your receipt method you can fetch the stripe charge as follows:

def receipt
  stripe_charge = Stripe::Charge.retrieve(stripe_charge_id)
  ...

end

The stripe_charge objects contains all the information and you can use whatever data you need.

Hope this helped.

Upvotes: 0

Related Questions