class Docdata::Payment

Object representing a “WSDL” object with attributes provided by Docdata

@example

Payment.new({
  :amount => 2500,
  :currency => "EUR",
  :order_reference => "TJ123"
  :profile => "MyProfile"
  :shopper => @shopper
})

@return [Array] Errors @param :amount [Integer] The total price in cents @param :currency [String] ISO currency code (USD, EUR, GBP, etc.) @param :order_reference [String] A unique order reference @param :profile [String] The DocData payment profile (e.g. ‘MyProfile’) @param :description [String] Description for this payment @param :receipt_text [String] A receipt text @param :shopper [Docdata::Shopper] A shopper object (instance of Docdata::Shopper) @param :bank_id [String] (optional) in case you want to redirect the consumer directly to the bank page (iDeal), you can set the bank id (‘0031’ for ABN AMRO for example.) @param :prefered_payment_method [String] (optional) set a prefered payment method. any of: [IDEAL, AMAX, VISA, etc.] @param :line_items [Array] (optional) Array of objects of type Docdata::LineItem @param :default_act [Boolean] (optional) Should the redirect URL contain a default_act=true parameter?

Attributes

amount[RW]
bank_id[RW]
canceled[RW]
currency[RW]
default_act[RW]
description[RW]
errors[RW]
id[RW]
key[RW]
line_items[RW]
order_reference[RW]
prefered_payment_method[RW]
profile[RW]
receipt_text[RW]
shopper[RW]

Public Class Methods

cancel(api_key) click to toggle source

This method makes it possible to find and cancel a payment with only the key It combines

# File lib/docdata/payment.rb, line 148
def self.cancel(api_key)
  p = self.find(api_key)
  p.cancel
end
find(api_key) click to toggle source

Initialize a Payment object with the key set

# File lib/docdata/payment.rb, line 162
def self.find(api_key)
  p = self.new(key: api_key)
  if p.status.success
    return p
  else
    raise DocdataError.new(p), p.status.message
  end
end
new(args=nil) click to toggle source

Initializer to transform a Hash into an Payment object

@param [Hash] args

# File lib/docdata/payment.rb, line 64
def initialize(args=nil)
  @line_items = []
  return if args.nil?
  args.each do |k,v|
    instance_variable_set("@#{k}", v) unless v.nil?
  end
end
refund(api_key, amount_to_refund, refund_description="") click to toggle source

This method makes it possible to find and refund a payment with only the key exmaple usage: Docdata::Payment.refund(“APIT0K3N”, 250)

# File lib/docdata/payment.rb, line 155
def self.refund(api_key, amount_to_refund, refund_description="")
  p = self.find(api_key)
  p.refund(amount_to_refund, refund_description)
end

Public Instance Methods

cancel() click to toggle source

This calls the ‘cancel’ method of the SOAP API It cancels the payment and returns a Docdata::Response object

# File lib/docdata/payment.rb, line 111
def cancel
  # make the SOAP API call
  response        = Docdata.client.call(:cancel, xml: cancel_xml)
  response_object = Docdata::Response.parse(:cancel, response)
  if response_object.success?
    self.key = response_object.key
  end

  # set `self` as the value of the `payment` attribute in the response object
  response_object.payment = self
  self.canceled = true
  return true
end
cancel_xml() click to toggle source

@return [String] the xml to send in the SOAP API

# File lib/docdata/payment.rb, line 245
def cancel_xml
  xml_file        = "#{File.dirname(__FILE__)}/xml/cancel.xml.erb"
  template        = File.read(xml_file)      
  namespace       = OpenStruct.new(payment: self)
  xml             = ERB.new(template).result(namespace.instance_eval { binding })
end
check()
Alias for: status
cleaned_up_description() click to toggle source

@return [String] a cleaned up version of the description string where forbidden characters are filtered out and limit is 50 chars.

# File lib/docdata/payment.rb, line 75
def cleaned_up_description
  description.gsub("&", "and")[0..49]
end
create() click to toggle source

This is the most importent method. It uses all the attributes and performs a ‘create` action on Docdata Payments SOAP API. @return [Docdata::Response] response object with `key`, `message` and `success?` methods

# File lib/docdata/payment.rb, line 90
def create
  # if there are any line items, they should all be valid.
  validate_line_items

  # make the SOAP API call
  response        = Docdata.client.call(:create, xml: create_xml)
  response_object = Docdata::Response.parse(:create, response)
  if response_object.success?
    self.key = response_object.key
  end

  # set `self` as the value of the `payment` attribute in the response object
  response_object.payment = self
  response_object.url     = redirect_url

  return response_object
end
create_xml() click to toggle source

@return [String] the xml to send in the SOAP API

# File lib/docdata/payment.rb, line 236
def create_xml
  xml_file        = "#{File.dirname(__FILE__)}/xml/create.xml.erb"
  template        = File.read(xml_file)      
  namespace       = OpenStruct.new(payment: self, shopper: shopper)
  xml             = ERB.new(template).result(namespace.instance_eval { binding })
end
redirect_url() click to toggle source

@return [String] The URI where the consumer can be redirected to in order to pay

# File lib/docdata/payment.rb, line 197
def redirect_url
  url = {}
  
  base_url = Docdata::Config.return_url
  if Docdata::Config.test_mode
    redirect_base_url = 'https://test.docdatapayments.com/ps/menu'
  else
    redirect_base_url = 'https://secure.docdatapayments.com/ps/menu'
  end
  url[:command]             = "show_payment_cluster"
  url[:payment_cluster_key] = key
  url[:merchant_name]       = Docdata::Config.username
  # only include return URL if present
  if base_url.present?
    url[:return_url_success]  = "#{base_url}/success?key=#{url[:payment_cluster_key]}"
    url[:return_url_pending]  = "#{base_url}/pending?key=#{url[:payment_cluster_key]}"
    url[:return_url_canceled] = "#{base_url}/canceled?key=#{url[:payment_cluster_key]}"
    url[:return_url_error]    = "#{base_url}/error?key=#{url[:payment_cluster_key]}"
  end
  if shopper && shopper.language_code
    url[:client_language]      = shopper.language_code
  end
  if default_act
    url[:default_act]     = "yes"
  end
  if bank_id.present?
    url[:ideal_issuer_id] = bank_id
    url[:default_pm]      = "IDEAL"
  end
  if prefered_payment_method.present?
    url[:default_pm]      = prefered_payment_method
  end
  params = URI.encode_www_form(url)
  uri = "#{redirect_base_url}?#{params}"
end
Also aliased as: url
refund(amount_to_refund, refund_description="") click to toggle source

This calls the ‘refund’ method of the SOAP API It refunds (part of) the amount paid

# File lib/docdata/payment.rb, line 128
def refund(amount_to_refund, refund_description="")
  p = Docdata::Payment.new(key: key)
  p = p.status.payment
  refund_object = Docdata::Refund.new(
    currency: p.currency,
    amount: amount_to_refund,
    description: refund_description,
    payment: p
  )
  if refund_object.valid?
    refund_object.perform_refund
  else
    raise DocdataError.new(refund_object), refund_object.errors.full_messages.join(", ")
  end
end
status() click to toggle source

This is one of the other native SOAP API methods. @return [Docdata::Response]

# File lib/docdata/payment.rb, line 174
def status
  # read the xml template
  xml_file        = "#{File.dirname(__FILE__)}/xml/status.xml.erb"
  template        = File.read(xml_file)      
  namespace       = OpenStruct.new(payment: self)
  xml             = ERB.new(template).result(namespace.instance_eval { binding })

  # puts xml

  response        = Docdata.client.call(:status, xml: xml)
  response_object = Docdata::Response.parse(:status, response)

  response_object.set_attributes

  self.id                 = response_object.pid
  self.currency           = response_object.currency
  response_object.key     = key
  response_object.payment = self
  return response_object # Docdata::Response
end
Also aliased as: check
url()
Alias for: redirect_url
valid?() click to toggle source

@return [Boolean] true/false, depending if this instanciated object is valid

# File lib/docdata/payment.rb, line 80
def valid?
  validator = PaymentValidator.new
  validator.valid?(self)
end

Private Instance Methods

validate_line_items() click to toggle source

In case there are any line_items, validate them all and raise an error for the first invalid LineItem

# File lib/docdata/payment.rb, line 257
def validate_line_items
  if @line_items.any?
    for line_item in @line_items
      if line_item.valid?
        # do nothing, this line_item seems okay
      else
        raise DocdataError.new(line_item), line_item.error_message
      end
    end
  end
end
vat_rates() click to toggle source

@return [Hash] list of VAT-rates and there respective totals

# File lib/docdata/payment.rb, line 270
def vat_rates
  rates = {}
  for item in @line_items
    rates["vat_#{item.vat_rate.to_s}"] ||= {}
    rates["vat_#{item.vat_rate.to_s}"][:rate] ||= item.vat_rate
    rates["vat_#{item.vat_rate.to_s}"][:total] ||= 0
    rates["vat_#{item.vat_rate.to_s}"][:total] += item.vat
  end
  return rates
end