|
class PaymentReceipt < ActiveRecord::Base |
|
belongs_to :user |
|
serialize :pipeline_response_params |
|
|
|
default_value_for :amount, 5.00 |
|
|
|
def caller_reference |
|
[user.id, (created_at || Time.now).to_s(:number)].join(':') |
|
end |
|
|
|
def status=(status) |
|
write_attribute(:status, status.to_s.downcase) |
|
end |
|
|
|
def successful? |
|
status == "success" |
|
end |
|
|
|
def self.remit |
|
@remit ||= Remit::API.new(FPS_ACCESS_KEY, FPS_SECRET_KEY, FPS_SANDBOX) |
|
end |
|
|
|
def remit |
|
self.class.remit |
|
end |
|
|
|
# Returns a URI object with localhost replaced with 127.0.0.1 |
|
# For whatever reason FPS can't validate localhost urls. |
|
# Also the URI object is useful for remit calls that require |
|
# the host/path to get passed separate from the query. |
|
def self.sanitize(url) |
|
uri = URI.parse(url) |
|
uri.host = "127.0.0.1" if uri.host == "localhost" |
|
uri |
|
end |
|
|
|
def sanitize(url) |
|
self.class.sanitize(url) |
|
end |
|
|
|
def payment_url(return_url) |
|
remit.get_recurring_use_pipeline( |
|
:caller_reference => caller_reference, |
|
:payment_reason => "CallMe - Monthly Subscription", |
|
:recurring_period => "1 Month", |
|
:return_url => sanitize(return_url).to_s, |
|
:transaction_amount => amount |
|
).url |
|
end |
|
|
|
def process_pipeline_response(url) |
|
uri = sanitize(url) |
|
# Note that you can't use controller params since they might |
|
# also contain an :id from the URI path. |
|
query = uri.query |
|
uri.query = nil |
|
|
|
update_attribute(:pipeline_response_params, query) |
|
|
|
pipeline_response = Remit::PipelineResponse.new(uri.to_s, query, remit) |
|
raise "Invalid pipeline response" unless pipeline_response.valid? |
|
raise "Unsuccessful pipeline" unless pipeline_response.successful? |
|
|
|
update_attribute(:token_id, pipeline_response.tokenID) |
|
end |
|
|
|
def pay |
|
return if transaction_id |
|
|
|
pay_request = Remit::Pay::Request.new( |
|
:caller_reference => caller_reference, |
|
:charge_fee_to => "Caller", |
|
:sender_description => "CALLME", |
|
:sender_token_id => token_id, |
|
:transaction_amount => Remit::RequestTypes::Amount.new( |
|
:value => amount, |
|
:currency_code => "USD")) |
|
|
|
pay_response = remit.pay(pay_request) |
|
pay_result = pay_response.pay_result |
|
update_attributes(:request_id => pay_response.request_id, |
|
:transaction_id => pay_result.transaction_id, |
|
:status => pay_result.transaction_status) |
|
|
|
raise "Payment error" unless pay_result.pending? || pay_response.successful? |
|
end |
|
|
|
def pay_from_pipeline(url) |
|
process_pipeline_response(url) |
|
pay |
|
end |
|
|
|
def self.update_from_ipn(url, params) |
|
uri = sanitize(url) |
|
|
|
ipn_request = Remit::IpnRequest.new(uri.to_s, params, remit) |
|
raise "Invalid IPN signature" unless ipn_request.valid? |
|
|
|
transaction_id = ipn_request.transactionId |
|
status = ipn_request.transactionStatus |
|
|
|
receipt = PaymentReceipt.find_by_transaction_id(transaction_id) |
|
raise "Receipt for #{transaction_id} was not found" unless receipt |
|
|
|
receipt.update_attribute(:status, status) unless receipt.successful? |
|
receipt |
|
end |
|
end |