Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added WePay support #65

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -35,5 +35,8 @@ gem 'jquery-ui-rails'
# Kickstarter's awesome Amazon Flexible Payments gem
gem 'amazon_flex_pay'

# Wepay gem
gem 'wepay'

# Configuration File
gem 'rails_config'
2 changes: 2 additions & 0 deletions Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,7 @@ GEM
uglifier (2.2.1)
execjs (>= 0.3.0)
multi_json (~> 1.0, >= 1.0.2)
wepay (0.0.1)

PLATFORMS
ruby
Expand All @@ -158,3 +159,4 @@ DEPENDENCIES
sqlite3
thin
uglifier (>= 1.0.3)
wepay
84 changes: 74 additions & 10 deletions app/controllers/preorder_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -13,27 +13,91 @@ def prefill
if Settings.use_payment_options
payment_option_id = params['payment_option']
raise Exception.new("No payment option was selected") if payment_option_id.nil?
payment_option = PaymentOption.find(payment_option_id)
price = payment_option.amount
@payment_option = PaymentOption.find(payment_option_id)
@price = payment_option.amount
else
price = Settings.price
@price = Settings.price
end

@order = Order.prefill!(:name => Settings.product_name, :price => price, :user_id => @user.id, :payment_option => payment_option)
@payment_service = PaymentService.find_by_name(Settings.payment_service)

@order = Order.prefill!(:name => Settings.product_name, :price => @price, :user_id => @user.id, :payment_option => @payment_option, :payment_service => @payment_service)

port = Rails.env.production? ? "" : ":3000"
@callback_url = "#{request.scheme}://#{request.host}#{port}/preorder/#{Settings.payment_service}_postfill"

# Check payment service and decide what flow to follow do
if Settings.payment_service == 'wepay'
wepay_flow
else
amazon_flow
end

end

def wepay_flow
# create Wepay object
wepay = WePay.new(Settings.wepay_client_id, Settings.wepay_secret_key, _use_stage = (!Rails.env.production?))

# create the checkout
# https://www.wepay.com/developer/reference/preapproval#create
response = wepay.call('/preapproval/create', Settings.wepay_access_token, {
:require_shipping => true,
:period => 'once',
:amount => @price,
:mode => 'regular',
:fee_payer => 'payee',
:prefill_info => {email: @user.email},
:short_description => @payment_option.nil? ? Settings.payment_description : @payment_option.description ,
:redirect_uri => @callback_url
})

# store wepay response into order
@order.token = response['preapproval_id']
@order.save!

redirect_to response['preapproval_uri']
end

def amazon_flow
# This is where all the magic happens. We create a multi-use token with Amazon, letting us charge the user's Amazon account
# Then, if they confirm the payment, Amazon POSTs us their shipping details and phone number
# From there, we save it, and voila, we got ourselves a preorder!
port = Rails.env.production? ? "" : ":3000"
callback_url = "#{request.scheme}://#{request.host}#{port}/preorder/postfill"
redirect_to AmazonFlexPay.multi_use_pipeline(@order.uuid, callback_url,
:transaction_amount => price,
:global_amount_limit => price + Settings.charge_limit,
redirect_to AmazonFlexPay.multi_use_pipeline(@order.uuid, @callback_url,
:transaction_amount => @price,
:global_amount_limit => @price + Settings.charge_limit,
:collect_shipping_address => "True",
:payment_reason => Settings.payment_description)
end

def postfill
# If callback comes from Wepay
def wepay_postfill
# If the user approved the 'preapproval' and
if params.has_key?('preapproval_id')
@order = Order.find_by_token(params[:preapproval_id])
unless @order.nil?
wepay = WePay.new(Settings.wepay_client_id, Settings.wepay_access_token, _use_stage = (!Rails.env.production?))
# Let's find the user information on Wepay end..
response = wepay.call('/preapproval', Settings.wepay_access_token, {
:preapproval_id => params[:preapproval_id]
})

@order.wepay_postfill(response)
if params['status'] != 'approved'
redirect_to :action => :share, :uuid => @order.uuid
else
redirect_to root_url
end
else
redirect_to root_url
end
else
redirect_to root_url
end
end

# If callback comes from Amazon
def amazon_postfill
unless params[:callerReference].blank?
@order = Order.postfill!(params)
end
Expand Down
19 changes: 18 additions & 1 deletion app/models/order.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@ class Order < ActiveRecord::Base
before_validation :generate_uuid!, :on => :create
belongs_to :user
belongs_to :payment_option
scope :completed, -> { where("token != ? OR token != ?", "", nil) }
belongs_to :payment_service

scope :completed, where("token != ? OR token != ?", "", nil)
self.primary_key = 'uuid'

# This is where we create our Caller Reference for Amazon Payments, and prefill some other information.
Expand All @@ -13,11 +15,26 @@ def self.prefill!(options = {})
@order.price = options[:price]
@order.number = Order.next_order_number
@order.payment_option = options[:payment_option] if !options[:payment_option].nil?
@order.payment_service = options[:payment_service] unless options[:payment_service].nil?
@order.save!

@order
end

def wepay_postfill(options = {})
self.status = options['state']
if options.has_key?('shipping_address')
self.address_one = options['shipping_address']['address1']
self.address_two = options['shipping_address']['address2']
self.city = options['shipping_address']['city']
self.state = options['shipping_address']['state']
self.zip = options['shipping_address']['zip']
self.country = options['shipping_address']['country']
self.name = options['payer_name']
self.save!
end
end

# After authenticating with Amazon, we get the rest of the details
def self.postfill!(options = {})
@order = Order.find_by!(:uuid => options[:callerReference])
Expand Down
3 changes: 3 additions & 0 deletions app/models/payment_service.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
class PaymentService < ActiveRecord::Base
has_many :orders
end
6 changes: 4 additions & 2 deletions config/routes.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
get 'preorder/checkout'
match '/preorder/share/:uuid' => 'preorder#share', :via => :get
match '/preorder/ipn' => 'preorder#ipn', :via => :post
match '/preorder/prefill' => 'preorder#prefill', :via => [:get,:post]
match '/preorder/postfill' => 'preorder#postfill', :via => [:get,:post]
match '/preorder/prefill' => 'preorder#prefill', :via => [:get, :post]
match '/preorder/postfill' => 'preorder#postfill', :via => [:get, :post]
match '/preorder/amazon_postfill' => 'preorder#amazon_postfill', :via => [:get, :post]
match '/preorder/wepay_postfill' => 'preorder#wepay_postfill', :via => [:get, :post]
end
10 changes: 9 additions & 1 deletion config/settings.yml
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,14 @@ video_embed_url: "https://www.youtube.com/v/D1L3o88GKew"
# NOTE: this only works for youtube video at the moment. If its not for youtube, then just leave this property blank
use_video_placeholder: true

# Payment service
payment_service: 'amazon'

# Wepay settings
wepay_client_id: "YOUR_WEPAY_CLIENT_ID"
wepay_secret_key: "YOUR_WEPAY_SECRET_KEY"
wepay_access_token: "YOUR_WEPAY_ACCESS_TOKEN"

# Amazon settings -- you'll need an Amazon Payments account, sign up here --> http://bit.ly/SGksTv

# To find your access key and secret key, head over to here --> http://bit.ly/R4I4ky (Follow that guide in the Seller Central page)
Expand All @@ -48,7 +56,7 @@ price: 19.95
# put code in seeds.rb, then run rake db:seed
use_payment_options: false

payment_description: "You really should change this text because people will see it on Amazon's order page!!!!!"
payment_description: "You really should change this text because people will see it on Payment Service's order page!!!!!"

# Amazon limits how much we can charge people with their Multi-Use tokens.
# You probably should add some leeway to account for international shipping
Expand Down
9 changes: 9 additions & 0 deletions db/migrate/20131117213159_create_payment_services.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
class CreatePaymentServices < ActiveRecord::Migration
def change
create_table :payment_services do |t|
t.string :name

t.timestamps
end
end
end
5 changes: 5 additions & 0 deletions db/migrate/20131117213318_add_payment_service_id_to_orders.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
class AddPaymentServiceIdToOrders < ActiveRecord::Migration
def change
add_column :orders, :payment_service_id, :integer
end
end
9 changes: 8 additions & 1 deletion db/schema.rb
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
#
# It's strongly recommended that you check this file into your version control system.

ActiveRecord::Schema.define(version: 20130107010733) do
ActiveRecord::Schema.define(version: 20131117213318) do

create_table "orders", id: false, force: true do |t|
t.string "token"
Expand All @@ -35,6 +35,7 @@
t.datetime "created_at"
t.datetime "updated_at"
t.integer "payment_option_id"
t.integer "payment_service_id"
end

create_table "payment_options", force: true do |t|
Expand All @@ -48,6 +49,12 @@
t.datetime "updated_at"
end

create_table "payment_services", force: true do |t|
t.string "name"
t.datetime "created_at"
t.datetime "updated_at"
end

create_table "users", force: true do |t|
t.string "email"
t.datetime "created_at"
Expand Down
3 changes: 2 additions & 1 deletion db/seeds.rb
Original file line number Diff line number Diff line change
Expand Up @@ -71,4 +71,5 @@
delivery_desc: 'Estimated delivery: Oct 2013',
limit: -1
}
])
])
PaymentService.create([ {name: 'amazon'}, {name: 'wepay'}])