Created
August 4, 2013 14:12
-
-
Save anonymous/6150447 to your computer and use it in GitHub Desktop.
Bips.me Payment and IPN handler for Ruby on Rails (3.2.11)
Modify to your own needs. Functionality is tested. I ripped some application specific stuff out and put some stuff back in. So expect some no_method errors
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
def change | |
create_table :payments do |t| | |
t.integer :order_id | |
t.string :token | |
t.string :ip_address | |
t.string :bitcoin_address | |
t.integer :bitcoin_amount_satoshi | |
t.integer :euro_amount_ct | |
t.text :payment_notification_request | |
t.datetime :payment_completed | |
t.timestamps | |
end | |
add_index :payments, :token, :unique => true | |
add_index :payments, :order_id | |
end |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
gem "rest-client", "~> 1.6.7" |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class Order < ActiveRecord::Base | |
has_many :payments | |
end |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class Payment < ActiveRecord::Base | |
belongs_to :order | |
serialize :payment_notification_request | |
before_create :generate_token | |
after_save :set_order_payed | |
def set_order_payed | |
order.update_attribute(:payed, payment_completed) if payment_completed | |
end | |
def generate_token | |
self.token = loop do | |
random_token = SecureRandom.uuid | |
break random_token unless Payment.where(token: random_token).exists? | |
end | |
end | |
end |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class PaymentsController < ApplicationController | |
# GET /payment/new | |
# Routes: payment | |
def new | |
@order = Order.find(params[:order_id]) | |
redirect_to @order, :notice => 'invalid order!' and return if not @order | |
redirect_to @order, :notice => 'Order already payed!' and return if @order.payed | |
@payment = @order.payments.build | |
end | |
# POST /payment | |
# POST /payment.json | |
# Routes: payments, direct_payment | |
def create | |
@order = Order.find(payment_params[:order_id]) | |
@payment = @order.payments.build(payment_params) | |
# set price in cents | |
@payment.euro_amount_ct = @order.price_in_cents | |
@payment.ip_address = request.remote_ip.to_s | |
if @payment.save | |
redirect_to get_bitcoin_redirect(@payment) | |
else | |
render action: "new" | |
end | |
end | |
# POST /payments/confirm/bitcoin | |
def bitcoin_notification | |
# set/change secret on https://bips.me/merchant | |
secret = "mioEJcyTgj0BeYbMVA5XphdZOFzNuKvUHtrxQwnGkPsfaLRIDq" | |
hash = Digest::SHA512.hexdigest(params[:transaction][:hash] + secret) | |
@payment = Payment.find_by_token(params[:custom][:payment_token]) | |
if @payment && (hash == params[:hash]) && (params[:status] == "1") | |
@payment.payment_notification_request = params # store complete request in DB for future reference | |
@payment.bitcoin_address = params[:transaction][:address] # Bitcoin address of sender | |
@payment.bitcoin_amount_satoshi = (params[:btc][:amount].to_f * 100000000).to_i # Store recieved bitcoin amount as satoshi integer | |
@payment.payment_completed = Time.now # set payment completed | |
@payment.save | |
# | |
# Here goes the stuf to do when payment is succesfull | |
# Send email, change order status etcetera. | |
# You might want to do that in a background job. | |
# Maybe use the awesome Spawnling gem?! | |
# | |
head :ok | |
else | |
head :not_acceptable | |
end | |
end | |
def finish | |
@payment = Payment.where(:token => params[:payment_token]).first | |
# do some finish stuff | |
# BEWARE: payment process not completed / recieved until an IPN is sent to your server. | |
# Wait with sending payment confirmations until IPN is recieved. | |
end | |
def cancel | |
@payment = Payment.where(:token => params[:payment_token]).first | |
# do some cancel stuff | |
# maybe display page to try again | |
end | |
private | |
def get_bitcoin_redirect(payment) | |
# set/change Api Key on https://bips.me/merchant | |
api_key = "MySecretApiKey" | |
# Log RestClient requests to the standard Rails logger | |
RestClient.log = | |
Object.new.tap do |proxy| | |
def proxy.<<(message) | |
Rails.logger.info message | |
end | |
end | |
base_url = "https://bips.me" | |
uri = "#{base_url}/api/v1/invoice" | |
custom_parameters = { "payment_token" => payment.token, | |
"returnurl" => finish_payment_url(:payment_token => payment.token), | |
"cancelurl" => cancel_payment_url(:payment_token => payment.token) | |
}.to_json | |
parameters = { "price" => payment.euro_amount_ct/100.0, | |
"currency" => 'EUR', | |
"item" => "Order #{payment.order.id}", | |
"custom" => custom_parameters | |
} | |
resource = RestClient::Resource.new( uri, { :user => api_key }) | |
response = resource.post parameters | |
return response.to_str | |
end | |
end |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
resources :payments do | |
collection do | |
post 'confirm/bitcoin' => 'payments#bitcoin_notification' | |
post 'finish/:payment_token' => 'payments#finish' | |
post 'cancel/:payment_token' => 'payments#cancel' | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Forgot to login before placing this Gist.
This comment serves as a find-back-post.
I used this code on www.udid-registration.net to make bitcoin payments available.
I thought this might be helpful to others since documentation from Bips.me is a little lacking.
Oh, and yes: I changed my secret on bips.me quickly after realizing I forgot to take it out of my code :D