From 3ffac4e77a118ee6ec7d369b0250c11830c2f7e0 Mon Sep 17 00:00:00 2001 From: jessib Date: Tue, 12 Mar 2013 13:32:46 -0700 Subject: Basic functionality for one time transactions using Braintree's transparent redirect API based from https://github.com/braintree/braintree_ruby_examples/tree/master/rails3_tr_checkout (very little changes were required) --- billing/app/controllers/payments_controller.rb | 22 ++++++++++++ billing/app/helpers/braintree_helper.rb | 50 ++++++++++++++++++++++++++ billing/app/views/payments/confirm.html.erb | 16 +++++++++ billing/app/views/payments/new.html.erb | 38 ++++++++++++++++++++ billing/config/initializers/braintree.rb | 5 +++ billing/leap_web_billing.gemspec | 4 ++- billing/lib/leap_web_billing/engine.rb | 4 ++- billing/script/rails | 8 +++++ 8 files changed, 145 insertions(+), 2 deletions(-) create mode 100644 billing/app/controllers/payments_controller.rb create mode 100644 billing/app/helpers/braintree_helper.rb create mode 100644 billing/app/views/payments/confirm.html.erb create mode 100644 billing/app/views/payments/new.html.erb create mode 100644 billing/config/initializers/braintree.rb create mode 100755 billing/script/rails (limited to 'billing') diff --git a/billing/app/controllers/payments_controller.rb b/billing/app/controllers/payments_controller.rb new file mode 100644 index 0000000..2a76bb1 --- /dev/null +++ b/billing/app/controllers/payments_controller.rb @@ -0,0 +1,22 @@ +class PaymentsController < ApplicationController + def new + @amount = calculate_amount + end + + def confirm + @result = Braintree::TransparentRedirect.confirm(request.query_string) + if @result.success? + render :action => "confirm" + else + @amount = calculate_amount + render :action => "new" + end + end + + protected + + def calculate_amount + # in a real app this be calculated from a shopping cart, determined by the product, etc. + "100.00" + end +end diff --git a/billing/app/helpers/braintree_helper.rb b/billing/app/helpers/braintree_helper.rb new file mode 100644 index 0000000..3d6e887 --- /dev/null +++ b/billing/app/helpers/braintree_helper.rb @@ -0,0 +1,50 @@ +module BraintreeHelper + class BraintreeFormBuilder < ActionView::Helpers::FormBuilder + include ActionView::Helpers::AssetTagHelper + include ActionView::Helpers::TagHelper + + def initialize(object_name, object, template, options, proc) + super + @braintree_params = @options[:params] + @braintree_errors = @options[:errors] + end + + def fields_for(record_name, *args, &block) + options = args.extract_options! + options[:builder] = BraintreeFormBuilder + options[:params] = @braintree_params && @braintree_params[record_name] + options[:errors] = @braintree_errors && @braintree_errors.for(record_name) + new_args = args + [options] + super record_name, *new_args, &block + end + + def text_field(method, options = {}) + has_errors = @braintree_errors && @braintree_errors.on(method).any? + field = super(method, options.merge(:value => determine_value(method))) + result = content_tag("div", field, :class => has_errors ? "fieldWithErrors" : "") + result.safe_concat validation_errors(method) + result + end + + protected + + def determine_value(method) + if @braintree_params + @braintree_params[method] + else + nil + end + end + + def validation_errors(method) + if @braintree_errors && @braintree_errors.on(method).any? + @braintree_errors.on(method).map do |error| + content_tag("div", ERB::Util.h(error.message), {:style => "color: red;"}) + end.join + else + "" + end + end + end +end + diff --git a/billing/app/views/payments/confirm.html.erb b/billing/app/views/payments/confirm.html.erb new file mode 100644 index 0000000..5ab851e --- /dev/null +++ b/billing/app/views/payments/confirm.html.erb @@ -0,0 +1,16 @@ +

Payment Result

+ +
Thank you for your payment.
+ +

Transaction Details

+ + + + + + + + + +
Amount$<%= @result.transaction.amount %>
Transaction ID:<%= @result.transaction.id %>
First Name:<%= h @result.transaction.customer_details.first_name %>
Last Name:<%= h @result.transaction.customer_details.last_name %>
Email:<%= h @result.transaction.customer_details.email %>
Credit Card:<%= h @result.transaction.credit_card_details.masked_number %>
Card Type:<%= h @result.transaction.credit_card_details.card_type %>
+ diff --git a/billing/app/views/payments/new.html.erb b/billing/app/views/payments/new.html.erb new file mode 100644 index 0000000..092c518 --- /dev/null +++ b/billing/app/views/payments/new.html.erb @@ -0,0 +1,38 @@ +

Payment: $<%= h @amount %>

+ +<% if @result -%> +
<%= h @result.errors.size %> error(s)
+<% end -%> + +<%= form_for :transaction, + :params => @result && @result.params[:transaction], + :errors => @result && @result.errors.for(:transaction), + :builder => BraintreeHelper::BraintreeFormBuilder, + :url => Braintree::TransparentRedirect.url, + :html => {:autocomplete => "off"} do |f| -%> + <%= field_set_tag "Customer" do -%> + <%= f.fields_for :customer do |c| -%> +
<%= c.label :first_name, "First Name" %>
+
<%= c.text_field :first_name %>
+
<%= c.label :last_name, "Last Name" %>
+
<%= c.text_field :last_name %>
+
<%= c.label :email, "Email" %>
+
<%= c.text_field :email %>
+ <% end -%> + <% end -%> + <%= field_set_tag "Credit Card" do -%> + <%= f.fields_for :credit_card do |c| -%> +
<%= c.label :number, "Number" %>
+
<%= c.text_field :number %>
+
<%= c.label :expiration_date, "Expiration Date (MM/YY)" %>
+
<%= c.text_field :expiration_date %>
+
<%= c.label :cvv, "CVV" %>
+
<%= c.text_field :cvv %>
+ <% end -%> + <% end -%> + <%= hidden_field_tag :tr_data, Braintree::TransparentRedirect.transaction_data( + :redirect_url => confirm_payment_url, + :transaction => {:type => "sale", :amount => @amount} + ) %> + <%= f.submit "Submit" %> +<% end -%> diff --git a/billing/config/initializers/braintree.rb b/billing/config/initializers/braintree.rb new file mode 100644 index 0000000..ee21088 --- /dev/null +++ b/billing/config/initializers/braintree.rb @@ -0,0 +1,5 @@ +Braintree::Configuration.logger = Logger.new('log/braintree.log') +Braintree::Configuration.environment = :sandbox +Braintree::Configuration.merchant_id = "bwrdyczvjspmxjhb" +Braintree::Configuration.public_key = "jmw58nbmjg84prbp" +Braintree::Configuration.private_key = "SET_ME" diff --git a/billing/leap_web_billing.gemspec b/billing/leap_web_billing.gemspec index c3b4bdd..17f7f92 100644 --- a/billing/leap_web_billing.gemspec +++ b/billing/leap_web_billing.gemspec @@ -16,5 +16,7 @@ Gem::Specification.new do |s| s.test_files = Dir["test/**/*"] s.add_dependency "leap_web_core", LeapWeb::VERSION - s.add_dependency "braintree-rails", "~> 0.4.5" + # s.add_dependency "braintree-rails", "~> 0.4.5" + s.add_dependency "braintree" + #s.add_dependency "carmen-rails" end diff --git a/billing/lib/leap_web_billing/engine.rb b/billing/lib/leap_web_billing/engine.rb index acf63b0..6d76add 100644 --- a/billing/lib/leap_web_billing/engine.rb +++ b/billing/lib/leap_web_billing/engine.rb @@ -2,7 +2,9 @@ require "leap_web_core" require "leap_web_core/ui_dependencies" -require "braintree-rails" +#require "braintree-rails" +require "braintree" +#require "carmen-rails" module LeapWebBilling class Engine < ::Rails::Engine diff --git a/billing/script/rails b/billing/script/rails new file mode 100755 index 0000000..8bd9c0a --- /dev/null +++ b/billing/script/rails @@ -0,0 +1,8 @@ +#!/usr/bin/env ruby +# This command will automatically be run when you run "rails" with Rails 3 gems installed from the root of your application. + +ENGINE_ROOT = File.expand_path('../..', __FILE__) +ENGINE_PATH = File.expand_path('../../lib/leap_web_billing/engine', __FILE__) + +require 'rails/all' +require 'rails/engine/commands' -- cgit v1.2.3