Created
July 21, 2010 16:25
-
-
Save matthodan/484715 to your computer and use it in GitHub Desktop.
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
module ActiveMerchant #:nodoc: | |
module Billing #:nodoc: | |
class PaypalGateway < Gateway | |
RECURRING_ACTIONS = Set.new([:add, :cancel, :inquiry, :suspend]) | |
@@API_VERSION = '50.0' | |
def recurring(money, credit_card, options = {}) | |
options[:name] = credit_card.name if options[:name].blank? && credit_card | |
request = build_recurring_request(options[:profile_id] ? :modify : :add, money, options) do |xml| | |
add_credit_card(xml, credit_card, options[:billing_address], options) if credit_card | |
end | |
commit('CreateRecurringPaymentsProfile', request) | |
end | |
# cancels an existing recurring profile | |
def cancel_recurring(profile_id) | |
request = build_recurring_request(:cancel, 0, :profile_id => profile_id) {} | |
commit('ManageRecurringPaymentsProfileStatus', request) | |
end | |
# retrieves information about a recurring profile | |
def recurring_inquiry(profile_id, options = {}) | |
request = build_recurring_request(:inquiry, nil, options.update( :profile_id => profile_id )) | |
commit('GetRecurringPaymentsProfileDetails', request) | |
end | |
# suspends a recurring profile | |
def suspend_recurring(profile_id) | |
request = build_recurring_request(:suspend, 0, :profile_id => profile_id) {} | |
commit('ManageRecurringPaymentsProfileStatus', request) | |
end | |
private | |
def build_recurring_request(action, money, options) | |
unless RECURRING_ACTIONS.include?(action) | |
raise StandardError, "Invalid Recurring Profile Action: #{action}" | |
end | |
xml = Builder::XmlMarkup.new :indent => 2 | |
ns2 = 'n2:' | |
if [:add].include?(action) | |
xml.tag! 'CreateRecurringPaymentsProfileReq', 'xmlns' => PAYPAL_NAMESPACE do | |
xml.tag! 'CreateRecurringPaymentsProfileRequest' do | |
xml.tag! 'Version', @@API_VERSION, 'xmlns' => EBAY_NAMESPACE | |
# NOTE: namespace prefix here is critical! | |
xml.tag! ns2 + 'CreateRecurringPaymentsProfileRequestDetails ', 'xmlns:n2' => EBAY_NAMESPACE do | |
# credit card and other information goes here | |
yield xml | |
xml.tag! ns2 + 'RecurringPaymentsProfileDetails' do | |
xml.tag! ns2 + 'BillingStartDate', options[:starting_at] | |
end | |
xml.tag! ns2 + 'ScheduleDetails' do | |
xml.tag! ns2 + 'Description', options[:comment] | |
unless options[:trial_payment].nil? | |
xml.tag! ns2 + 'TrialPeriod' do | |
xml.tag! ns2 + 'BillingPeriod', 'Month' | |
xml.tag! ns2 + 'BillingFrequency', 1 | |
xml.tag! ns2 + 'TotalBillingCycles', 1 | |
xml.tag! ns2 + 'Amount', amount(options[:trial_payment]), 'currencyID' => options[:currency] || currency(options[:trial_payment]) | |
end | |
end | |
unless options[:one_time_payment].nil? | |
xml.tag! ns2 + 'ActivationDetails' do | |
xml.tag! ns2 + 'InitialAmount', amount(options[:one_time_payment]), 'currencyID' => options[:currency] || currency(options[:one_time_payment]) | |
end | |
end | |
frequency, period = get_pay_period(options) | |
xml.tag! ns2 + 'PaymentPeriod' do | |
xml.tag! ns2 + 'BillingPeriod', period | |
xml.tag! ns2 + 'BillingFrequency', frequency.to_s | |
xml.tag! ns2 + 'TotalBillingCycles', options[:payments] unless options[:payments].nil? || options[:payments] == 0 | |
xml.tag! ns2 + 'Amount', amount(money), 'currencyID' => options[:currency] || currency(money) | |
end | |
xml.tag! ns2 + 'AutoBillOutstandingAmount', 'AddToNextBilling' | |
end | |
end | |
end | |
end | |
elsif [:cancel, :suspend].include?(action) | |
xml.tag! 'ManageRecurringPaymentsProfileStatusReq', 'xmlns' => PAYPAL_NAMESPACE do | |
xml.tag! 'ManageRecurringPaymentsProfileStatusRequest', 'xmlns:n2' => EBAY_NAMESPACE do | |
xml.tag! ns2 + 'Version', @@API_VERSION | |
xml.tag! ns2 + 'ManageRecurringPaymentsProfileStatusRequestDetails' do | |
xml.tag! 'ProfileID', options[:profile_id] | |
xml.tag! ns2 + 'Action', action == :cancel ? 'Cancel' : 'Suspend' | |
xml.tag! ns2 + 'Note', 'Canceling the action, no real comment here' | |
end | |
end | |
end | |
elsif [:inquiry].include?(action) | |
xml.tag! 'GetRecurringPaymentsProfileDetailsReq', 'xmlns' => PAYPAL_NAMESPACE do | |
xml.tag! 'GetRecurringPaymentsProfileDetailsRequest', 'xmlns:n2' => EBAY_NAMESPACE do | |
xml.tag! ns2 + 'Version', @@API_VERSION | |
xml.tag! 'ProfileID', options[:profile_id] | |
end | |
end | |
end | |
end | |
def get_pay_period(options) | |
requires!(options, [:periodicity, :bimonthly, :monthly, :biweekly, :weekly, :yearly, :daily, :semimonthly, :quadweekly, :quarterly, :semiyearly]) | |
case options[:periodicity] | |
when :weekly then [1, 'Week'] | |
when :biweekly then [2, 'Week'] | |
when :semimonthly then [1, 'SemiMonth'] | |
when :quadweekly then [4, 'Week'] | |
when :monthly then [1, 'Month'] | |
when :quarterly then [3, 'Month'] | |
when :semiyearly then [6, 'Month'] # broken! i think | |
when :yearly then [1, 'Year'] | |
end | |
end | |
end | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment