activemerchant 1.27.0 → 1.28.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data.tar.gz.sig +3 -0
- data/CHANGELOG +13 -0
- data/README.md +4 -1
- data/lib/active_merchant/billing/gateways/authorize_net_cim.rb +3 -1
- data/lib/active_merchant/billing/gateways/banwire.rb +92 -0
- data/lib/active_merchant/billing/gateways/bogus.rb +35 -35
- data/lib/active_merchant/billing/gateways/elavon.rb +192 -23
- data/lib/active_merchant/billing/gateways/litle.rb +7 -2
- data/lib/active_merchant/billing/gateways/orbital.rb +229 -88
- data/lib/active_merchant/billing/gateways/paypal_express.rb +22 -2
- data/lib/active_merchant/billing/integrations/easy_pay/common.rb +1 -1
- data/lib/active_merchant/billing/integrations/easy_pay/helper.rb +1 -5
- data/lib/active_merchant/billing/integrations/easy_pay/notification.rb +10 -2
- data/lib/active_merchant/billing/integrations/paysbuy.rb +36 -0
- data/lib/active_merchant/billing/integrations/paysbuy/helper.rb +15 -0
- data/lib/active_merchant/billing/integrations/paysbuy/notification.rb +28 -0
- data/lib/active_merchant/billing/integrations/webmoney.rb +43 -0
- data/lib/active_merchant/billing/integrations/webmoney/common.rb +17 -0
- data/lib/active_merchant/billing/integrations/webmoney/helper.rb +39 -0
- data/lib/active_merchant/billing/integrations/webmoney/notification.rb +31 -0
- data/lib/active_merchant/version.rb +1 -1
- metadata +60 -25
- metadata.gz.sig +0 -0
| @@ -101,6 +101,10 @@ module ActiveMerchant #:nodoc: | |
| 101 101 | 
             
                    build_response(:registerToken, @litle.register_token_request(to_pass), %w(801 802))
         | 
| 102 102 | 
             
                  end
         | 
| 103 103 |  | 
| 104 | 
            +
                  def test?
         | 
| 105 | 
            +
                    super || @options[:test]
         | 
| 106 | 
            +
                  end
         | 
| 107 | 
            +
             | 
| 104 108 | 
             
                  private
         | 
| 105 109 |  | 
| 106 110 | 
             
                  CARD_TYPE = {
         | 
| @@ -148,10 +152,11 @@ module ActiveMerchant #:nodoc: | |
| 148 152 | 
             
                        {:litleOnlineResponse => response},
         | 
| 149 153 | 
             
                        :authorization => detail['litleTxnId'],
         | 
| 150 154 | 
             
                        :avs_result => {:code => fraud['avs']},
         | 
| 151 | 
            -
                        :cvv_result => fraud['cvv']
         | 
| 155 | 
            +
                        :cvv_result => fraud['cvv'],
         | 
| 156 | 
            +
                        :test => test?
         | 
| 152 157 | 
             
                      )
         | 
| 153 158 | 
             
                    else
         | 
| 154 | 
            -
                      Response.new(false, response['message'], :litleOnlineResponse => response)
         | 
| 159 | 
            +
                      Response.new(false, response['message'], :litleOnlineResponse => response, :test => test?)
         | 
| 155 160 | 
             
                    end
         | 
| 156 161 | 
             
                  end
         | 
| 157 162 |  | 
| @@ -4,32 +4,32 @@ require "rexml/document" | |
| 4 4 | 
             
            module ActiveMerchant #:nodoc:
         | 
| 5 5 | 
             
              module Billing #:nodoc:
         | 
| 6 6 | 
             
                # For more information on Orbital, visit the {integration center}[http://download.chasepaymentech.com]
         | 
| 7 | 
            -
                # | 
| 7 | 
            +
                #
         | 
| 8 8 | 
             
                # ==== Authentication Options
         | 
| 9 | 
            -
                # | 
| 9 | 
            +
                #
         | 
| 10 10 | 
             
                # The Orbital Gateway supports two methods of authenticating incoming requests:
         | 
| 11 11 | 
             
                # Source IP authentication and Connection Username/Password authentication
         | 
| 12 | 
            -
                # | 
| 13 | 
            -
                # In addition, these IP addresses/Connection Usernames must be affiliated with the Merchant IDs | 
| 12 | 
            +
                #
         | 
| 13 | 
            +
                # In addition, these IP addresses/Connection Usernames must be affiliated with the Merchant IDs
         | 
| 14 14 | 
             
                # for which the client should be submitting transactions.
         | 
| 15 | 
            -
                # | 
| 16 | 
            -
                # This does allow Third Party Hosting service organizations presenting on behalf of other | 
| 17 | 
            -
                # merchants to submit transactions.  However, each time a new customer is added, the | 
| 18 | 
            -
                # merchant or Third-Party hosting organization needs to ensure that the new Merchant IDs | 
| 15 | 
            +
                #
         | 
| 16 | 
            +
                # This does allow Third Party Hosting service organizations presenting on behalf of other
         | 
| 17 | 
            +
                # merchants to submit transactions.  However, each time a new customer is added, the
         | 
| 18 | 
            +
                # merchant or Third-Party hosting organization needs to ensure that the new Merchant IDs
         | 
| 19 19 | 
             
                # or Chain IDs are affiliated with the hosting companies IPs or Connection Usernames.
         | 
| 20 | 
            -
                # | 
| 21 | 
            -
                # If the merchant expects to have more than one merchant account with the Orbital | 
| 22 | 
            -
                # Gateway, it should have its IP addresses/Connection Usernames affiliated at the Chain | 
| 20 | 
            +
                #
         | 
| 21 | 
            +
                # If the merchant expects to have more than one merchant account with the Orbital
         | 
| 22 | 
            +
                # Gateway, it should have its IP addresses/Connection Usernames affiliated at the Chain
         | 
| 23 23 | 
             
                # level hierarchy within the Orbital Gateway.  Each time a new merchant ID is added, as
         | 
| 24 | 
            -
                # long as it is placed within the same Chain, it will simply work.  Otherwise, the additional | 
| 24 | 
            +
                # long as it is placed within the same Chain, it will simply work.  Otherwise, the additional
         | 
| 25 25 | 
             
                # MIDs will need to be affiliated with the merchant IPs or Connection Usernames respectively.
         | 
| 26 | 
            -
                # For example, we generally affiliate all Salem accounts [BIN 000001] with | 
| 27 | 
            -
                # their Company Number [formerly called MA #] number so all MIDs or Divisions under that | 
| 26 | 
            +
                # For example, we generally affiliate all Salem accounts [BIN 000001] with
         | 
| 27 | 
            +
                # their Company Number [formerly called MA #] number so all MIDs or Divisions under that
         | 
| 28 28 | 
             
                # Company will automatically be affiliated.
         | 
| 29 | 
            -
             | 
| 29 | 
            +
             | 
| 30 30 | 
             
                class OrbitalGateway < Gateway
         | 
| 31 | 
            -
                  API_VERSION = " | 
| 32 | 
            -
             | 
| 31 | 
            +
                  API_VERSION = "5.6"
         | 
| 32 | 
            +
             | 
| 33 33 | 
             
                  POST_HEADERS = {
         | 
| 34 34 | 
             
                    "MIME-Version" => "1.0",
         | 
| 35 35 | 
             
                    "Content-Type" => "Application/PTI46",
         | 
| @@ -38,27 +38,29 @@ module ActiveMerchant #:nodoc: | |
| 38 38 | 
             
                    "Document-type" => "Request",
         | 
| 39 39 | 
             
                    "Interface-Version" => "Ruby|ActiveMerchant|Proprietary Gateway"
         | 
| 40 40 | 
             
                  }
         | 
| 41 | 
            -
             | 
| 41 | 
            +
             | 
| 42 42 | 
             
                  SUCCESS, APPROVED = '0', '00'
         | 
| 43 | 
            -
             | 
| 43 | 
            +
             | 
| 44 44 | 
             
                  class_attribute :secondary_test_url, :secondary_live_url
         | 
| 45 | 
            -
             | 
| 45 | 
            +
             | 
| 46 46 | 
             
                  self.test_url = "https://orbitalvar1.paymentech.net/authorize"
         | 
| 47 47 | 
             
                  self.secondary_test_url = "https://orbitalvar2.paymentech.net/authorize"
         | 
| 48 | 
            -
             | 
| 48 | 
            +
             | 
| 49 49 | 
             
                  self.live_url = "https://orbital1.paymentech.net/authorize"
         | 
| 50 50 | 
             
                  self.secondary_live_url = "https://orbital2.paymentech.net/authorize"
         | 
| 51 | 
            -
             | 
| 51 | 
            +
             | 
| 52 52 | 
             
                  self.supported_countries = ["US", "CA"]
         | 
| 53 53 | 
             
                  self.default_currency = "CAD"
         | 
| 54 54 | 
             
                  self.supported_cardtypes = [:visa, :master, :american_express, :discover, :diners_club, :jcb]
         | 
| 55 | 
            -
             | 
| 55 | 
            +
             | 
| 56 56 | 
             
                  self.display_name = 'Orbital Paymentech'
         | 
| 57 57 | 
             
                  self.homepage_url = 'http://chasepaymentech.com/'
         | 
| 58 | 
            -
             | 
| 58 | 
            +
             | 
| 59 59 | 
             
                  self.money_format = :cents
         | 
| 60 | 
            -
             | 
| 61 | 
            -
                   | 
| 60 | 
            +
             | 
| 61 | 
            +
                  AVS_SUPPORTED_COUNTRIES = ['US', 'CA', 'UK', 'GB']
         | 
| 62 | 
            +
             | 
| 63 | 
            +
                  CURRENCY_CODES = {
         | 
| 62 64 | 
             
                    "AUD" => '036',
         | 
| 63 65 | 
             
                    "CAD" => '124',
         | 
| 64 66 | 
             
                    "CZK" => '203',
         | 
| @@ -77,42 +79,43 @@ module ActiveMerchant #:nodoc: | |
| 77 79 | 
             
                    "EUR" => '978'
         | 
| 78 80 | 
             
                  }
         | 
| 79 81 |  | 
| 80 | 
            -
                  AVS_SUPPORTED_COUNTRIES = ['US', 'CA', 'UK', 'GB']
         | 
| 81 | 
            -
             | 
| 82 82 | 
             
                  def initialize(options = {})
         | 
| 83 83 | 
             
                    requires!(options, :merchant_id)
         | 
| 84 84 | 
             
                    requires!(options, :login, :password) unless options[:ip_authentication]
         | 
| 85 85 | 
             
                    @options = options
         | 
| 86 86 | 
             
                    super
         | 
| 87 87 | 
             
                  end
         | 
| 88 | 
            -
             | 
| 88 | 
            +
             | 
| 89 89 | 
             
                  # A – Authorization request
         | 
| 90 90 | 
             
                  def authorize(money, creditcard, options = {})
         | 
| 91 91 | 
             
                    order = build_new_order_xml('A', money, options) do |xml|
         | 
| 92 | 
            -
                      add_creditcard(xml, creditcard, options[:currency]) | 
| 93 | 
            -
                      add_address(xml, creditcard, options) | 
| 92 | 
            +
                      add_creditcard(xml, creditcard, options[:currency]) unless creditcard.nil? && options[:profile_txn]
         | 
| 93 | 
            +
                      add_address(xml, creditcard, options)
         | 
| 94 | 
            +
                      add_customer_data(xml, options) if @options[:customer_profiles]
         | 
| 94 95 | 
             
                    end
         | 
| 95 96 | 
             
                    commit(order)
         | 
| 96 97 | 
             
                  end
         | 
| 97 | 
            -
             | 
| 98 | 
            +
             | 
| 98 99 | 
             
                  # AC – Authorization and Capture
         | 
| 99 100 | 
             
                  def purchase(money, creditcard, options = {})
         | 
| 100 101 | 
             
                    order = build_new_order_xml('AC', money, options) do |xml|
         | 
| 101 | 
            -
                      add_creditcard(xml, creditcard, options[:currency])
         | 
| 102 | 
            -
                      add_address(xml, creditcard, options) | 
| 102 | 
            +
                      add_creditcard(xml, creditcard, options[:currency]) unless creditcard.nil? && options[:profile_txn]
         | 
| 103 | 
            +
                      add_address(xml, creditcard, options)
         | 
| 104 | 
            +
                      add_customer_data(xml, options) if @options[:customer_profiles]
         | 
| 103 105 | 
             
                    end
         | 
| 104 106 | 
             
                    commit(order)
         | 
| 105 | 
            -
                  end | 
| 106 | 
            -
             | 
| 107 | 
            +
                  end
         | 
| 108 | 
            +
             | 
| 107 109 | 
             
                  # MFC - Mark For Capture
         | 
| 108 110 | 
             
                  def capture(money, authorization, options = {})
         | 
| 109 111 | 
             
                    commit(build_mark_for_capture_xml(money, authorization, options))
         | 
| 110 112 | 
             
                  end
         | 
| 111 | 
            -
             | 
| 113 | 
            +
             | 
| 112 114 | 
             
                  # R – Refund request
         | 
| 113 115 | 
             
                  def refund(money, authorization, options = {})
         | 
| 114 116 | 
             
                    order = build_new_order_xml('R', money, options.merge(:authorization => authorization)) do |xml|
         | 
| 115 117 | 
             
                      add_refund(xml, options[:currency])
         | 
| 118 | 
            +
                      xml.tag! :CustomerRefNum, options[:customer_ref_num] if @options[:customer_profiles] && options[:profile_txn]
         | 
| 116 119 | 
             
                    end
         | 
| 117 120 | 
             
                    commit(order)
         | 
| 118 121 | 
             
                  end
         | 
| @@ -121,31 +124,90 @@ module ActiveMerchant #:nodoc: | |
| 121 124 | 
             
                    deprecated CREDIT_DEPRECATION_MESSAGE
         | 
| 122 125 | 
             
                    refund(money, authorization, options)
         | 
| 123 126 | 
             
                  end
         | 
| 124 | 
            -
             | 
| 127 | 
            +
             | 
| 125 128 | 
             
                  # setting money to nil will perform a full void
         | 
| 126 | 
            -
                  def void(authorization, options = {})
         | 
| 127 | 
            -
                    order = build_void_request_xml(authorization, options)
         | 
| 129 | 
            +
                  def void(money, authorization, options = {})
         | 
| 130 | 
            +
                    order = build_void_request_xml(money, authorization, options)
         | 
| 131 | 
            +
                    commit(order)
         | 
| 132 | 
            +
                  end
         | 
| 133 | 
            +
             | 
| 134 | 
            +
             | 
| 135 | 
            +
                  # ==== Customer Profiles
         | 
| 136 | 
            +
                  # :customer_ref_num should be set unless your happy with Orbital providing one
         | 
| 137 | 
            +
                  #
         | 
| 138 | 
            +
                  # :customer_profile_order_override_ind can be set to map
         | 
| 139 | 
            +
                  # the CustomerRefNum to OrderID or Comments. Defaults to 'NO' - no mapping
         | 
| 140 | 
            +
                  #
         | 
| 141 | 
            +
                  #   'NO' - No mapping to order data
         | 
| 142 | 
            +
                  #   'OI' - Use <CustomerRefNum> for <OrderID>
         | 
| 143 | 
            +
                  #   'OD' - Use <CustomerRefNum> for <Comments>
         | 
| 144 | 
            +
                  #   'OA' - Use <CustomerRefNum> for <OrderID> and <Comments>
         | 
| 145 | 
            +
                  #
         | 
| 146 | 
            +
                  # :order_default_description can be set optionally. 64 char max.
         | 
| 147 | 
            +
                  #
         | 
| 148 | 
            +
                  # :order_default_amount can be set optionally. integer as cents.
         | 
| 149 | 
            +
                  #
         | 
| 150 | 
            +
                  # :status defaults to Active
         | 
| 151 | 
            +
                  #
         | 
| 152 | 
            +
                  #   'A' - Active
         | 
| 153 | 
            +
                  #   'I' - Inactive
         | 
| 154 | 
            +
                  #   'MS'  - Manual Suspend
         | 
| 155 | 
            +
             | 
| 156 | 
            +
                  def add_customer_profile(creditcard, options = {})
         | 
| 157 | 
            +
                    options.merge!(:customer_profile_action => 'C')
         | 
| 158 | 
            +
                    order = build_customer_request_xml(creditcard, options)
         | 
| 159 | 
            +
                    commit(order)
         | 
| 160 | 
            +
                  end
         | 
| 161 | 
            +
             | 
| 162 | 
            +
                  def update_customer_profile(creditcard, options = {})
         | 
| 163 | 
            +
                    options.merge!(:customer_profile_action => 'U')
         | 
| 164 | 
            +
                    order = build_customer_request_xml(creditcard, options)
         | 
| 165 | 
            +
                    commit(order)
         | 
| 166 | 
            +
                  end
         | 
| 167 | 
            +
             | 
| 168 | 
            +
                  def retrieve_customer_profile(customer_ref_num)
         | 
| 169 | 
            +
                    options = {:customer_profile_action => 'R', :customer_ref_num => customer_ref_num}
         | 
| 170 | 
            +
                    order = build_customer_request_xml(nil, options)
         | 
| 171 | 
            +
                    commit(order)
         | 
| 172 | 
            +
                  end
         | 
| 173 | 
            +
             | 
| 174 | 
            +
                  def delete_customer_profile(customer_ref_num)
         | 
| 175 | 
            +
                    options = {:customer_profile_action => 'D', :customer_ref_num => customer_ref_num}
         | 
| 176 | 
            +
                    order = build_customer_request_xml(nil, options)
         | 
| 128 177 | 
             
                    commit(order)
         | 
| 129 178 | 
             
                  end
         | 
| 130 | 
            -
             | 
| 131 | 
            -
                  private | 
| 132 | 
            -
             | 
| 179 | 
            +
             | 
| 180 | 
            +
                  private
         | 
| 181 | 
            +
             | 
| 182 | 
            +
                  def authorization_string(*args)
         | 
| 183 | 
            +
                    args.compact.join(";")
         | 
| 184 | 
            +
                  end
         | 
| 185 | 
            +
             | 
| 186 | 
            +
                  def split_authorization(authorization)
         | 
| 187 | 
            +
                    authorization.split(';')
         | 
| 188 | 
            +
                  end
         | 
| 189 | 
            +
             | 
| 133 190 | 
             
                  def add_customer_data(xml, options)
         | 
| 134 | 
            -
                    if options[: | 
| 135 | 
            -
                      xml.tag! :CustomerProfileFromOrderInd, 'S'
         | 
| 191 | 
            +
                    if options[:profile_txn]
         | 
| 136 192 | 
             
                      xml.tag! :CustomerRefNum, options[:customer_ref_num]
         | 
| 137 193 | 
             
                    else
         | 
| 138 | 
            -
                       | 
| 194 | 
            +
                      if options[:customer_ref_num]
         | 
| 195 | 
            +
                        xml.tag! :CustomerProfileFromOrderInd, 'S'
         | 
| 196 | 
            +
                        xml.tag! :CustomerRefNum, options[:customer_ref_num]
         | 
| 197 | 
            +
                      else
         | 
| 198 | 
            +
                        xml.tag! :CustomerProfileFromOrderInd, 'A'
         | 
| 199 | 
            +
                      end
         | 
| 200 | 
            +
                      xml.tag! :CustomerProfileOrderOverrideInd, options[:customer_profile_order_override_ind] || 'NO'
         | 
| 139 201 | 
             
                    end
         | 
| 140 202 | 
             
                  end
         | 
| 141 | 
            -
             | 
| 203 | 
            +
             | 
| 142 204 | 
             
                  def add_soft_descriptors(xml, soft_desc)
         | 
| 143 | 
            -
                    xml.tag! :SDMerchantName, soft_desc.merchant_name
         | 
| 144 | 
            -
                    xml.tag! :SDProductDescription, soft_desc.product_description
         | 
| 145 | 
            -
                    xml.tag! :SDMerchantCity, soft_desc.merchant_city
         | 
| 146 | 
            -
                    xml.tag! :SDMerchantPhone, soft_desc.merchant_phone
         | 
| 147 | 
            -
                    xml.tag! :SDMerchantURL, soft_desc.merchant_url
         | 
| 148 | 
            -
                    xml.tag! :SDMerchantEmail, soft_desc.merchant_email
         | 
| 205 | 
            +
                    xml.tag! :SDMerchantName, soft_desc.merchant_name             if soft_desc.merchant_name
         | 
| 206 | 
            +
                    xml.tag! :SDProductDescription, soft_desc.product_description if soft_desc.product_description
         | 
| 207 | 
            +
                    xml.tag! :SDMerchantCity, soft_desc.merchant_city             if soft_desc.merchant_city
         | 
| 208 | 
            +
                    xml.tag! :SDMerchantPhone, soft_desc.merchant_phone           if soft_desc.merchant_phone
         | 
| 209 | 
            +
                    xml.tag! :SDMerchantURL, soft_desc.merchant_url               if soft_desc.merchant_url
         | 
| 210 | 
            +
                    xml.tag! :SDMerchantEmail, soft_desc.merchant_email           if soft_desc.merchant_email
         | 
| 149 211 | 
             
                  end
         | 
| 150 212 |  | 
| 151 213 | 
             
                  def add_address(xml, creditcard, options)
         | 
| @@ -165,24 +227,48 @@ module ActiveMerchant #:nodoc: | |
| 165 227 | 
             
                    end
         | 
| 166 228 | 
             
                  end
         | 
| 167 229 |  | 
| 230 | 
            +
                  # For Profile requests
         | 
| 231 | 
            +
                  def add_customer_address(xml, options)
         | 
| 232 | 
            +
                    if address = options[:billing_address] || options[:address]
         | 
| 233 | 
            +
                      xml.tag! :CustomerAddress1, address[:address1]
         | 
| 234 | 
            +
                      xml.tag! :CustomerAddress2, address[:address2]
         | 
| 235 | 
            +
                      xml.tag! :CustomerCity, address[:city]
         | 
| 236 | 
            +
                      xml.tag! :CustomerState, address[:state]
         | 
| 237 | 
            +
                      xml.tag! :CustomerZIP, address[:zip]
         | 
| 238 | 
            +
                      xml.tag! :CustomerPhone, address[:phone] ? address[:phone].scan(/\d/).to_s : nil
         | 
| 239 | 
            +
                      xml.tag! :CustomerCountryCode, address[:country]
         | 
| 240 | 
            +
                    end
         | 
| 241 | 
            +
                  end
         | 
| 242 | 
            +
             | 
| 168 243 | 
             
                  def add_creditcard(xml, creditcard, currency=nil)
         | 
| 169 244 | 
             
                    xml.tag! :AccountNum, creditcard.number
         | 
| 170 245 | 
             
                    xml.tag! :Exp, expiry_date(creditcard)
         | 
| 171 | 
            -
             | 
| 246 | 
            +
             | 
| 172 247 | 
             
                    xml.tag! :CurrencyCode, currency_code(currency)
         | 
| 173 248 | 
             
                    xml.tag! :CurrencyExponent, '2' # Will need updating to support currencies such as the Yen.
         | 
| 174 | 
            -
             | 
| 175 | 
            -
                     | 
| 249 | 
            +
             | 
| 250 | 
            +
                    # If you are trying to collect a Card Verification Number
         | 
| 251 | 
            +
                    # (CardSecVal) for a Visa or Discover transaction, pass one of these values:
         | 
| 252 | 
            +
                    #   1 Value is Present
         | 
| 253 | 
            +
                    #   2 Value on card but illegible
         | 
| 254 | 
            +
                    #   9 Cardholder states data not available
         | 
| 255 | 
            +
                    # If the transaction is not a Visa or Discover transaction:
         | 
| 256 | 
            +
                    #   Null-fill this attribute OR
         | 
| 257 | 
            +
                    #   Do not submit the attribute at all.
         | 
| 258 | 
            +
                    # - http://download.chasepaymentech.com/docs/orbital/orbital_gateway_xml_specification.pdf
         | 
| 259 | 
            +
                    if %w( visa discover ).include?(creditcard.brand)
         | 
| 260 | 
            +
                      xml.tag! :CardSecValInd, creditcard.verification_value? ? '1' : '9'
         | 
| 261 | 
            +
                    end
         | 
| 176 262 | 
             
                    xml.tag! :CardSecVal,  creditcard.verification_value if creditcard.verification_value?
         | 
| 177 263 | 
             
                  end
         | 
| 178 | 
            -
             | 
| 264 | 
            +
             | 
| 179 265 | 
             
                  def add_refund(xml, currency=nil)
         | 
| 180 266 | 
             
                    xml.tag! :AccountNum, nil
         | 
| 181 | 
            -
             | 
| 267 | 
            +
             | 
| 182 268 | 
             
                    xml.tag! :CurrencyCode, currency_code(currency)
         | 
| 183 269 | 
             
                    xml.tag! :CurrencyExponent, '2' # Will need updating to support currencies such as the Yen.
         | 
| 184 270 | 
             
                  end
         | 
| 185 | 
            -
             | 
| 271 | 
            +
             | 
| 186 272 |  | 
| 187 273 | 
             
                  def parse(body)
         | 
| 188 274 | 
             
                    response = {}
         | 
| @@ -195,8 +281,8 @@ module ActiveMerchant #:nodoc: | |
| 195 281 | 
             
                      end
         | 
| 196 282 | 
             
                    end
         | 
| 197 283 | 
             
                    response
         | 
| 198 | 
            -
                  end | 
| 199 | 
            -
             | 
| 284 | 
            +
                  end
         | 
| 285 | 
            +
             | 
| 200 286 | 
             
                  def recurring_parse_element(response, node)
         | 
| 201 287 | 
             
                    if node.has_elements?
         | 
| 202 288 | 
             
                      node.elements.each{|e| recurring_parse_element(response, e) }
         | 
| @@ -204,23 +290,24 @@ module ActiveMerchant #:nodoc: | |
| 204 290 | 
             
                      response[node.name.underscore.to_sym] = node.text
         | 
| 205 291 | 
             
                    end
         | 
| 206 292 | 
             
                  end
         | 
| 207 | 
            -
             | 
| 293 | 
            +
             | 
| 208 294 | 
             
                  def commit(order)
         | 
| 209 295 | 
             
                    headers = POST_HEADERS.merge("Content-length" => order.size.to_s)
         | 
| 210 296 | 
             
                    request = lambda {return parse(ssl_post(remote_url, order, headers))}
         | 
| 211 | 
            -
             | 
| 297 | 
            +
             | 
| 212 298 | 
             
                    # Failover URL will be used in the event of a connection error
         | 
| 213 299 | 
             
                    begin response = request.call; rescue ConnectionError; retry end
         | 
| 214 | 
            -
             | 
| 300 | 
            +
             | 
| 215 301 | 
             
                    Response.new(success?(response), message_from(response), response,
         | 
| 216 | 
            -
                      { | 
| 217 | 
            -
             | 
| 218 | 
            -
             | 
| 219 | 
            -
             | 
| 302 | 
            +
                      {
         | 
| 303 | 
            +
                         :authorization => authorization_string(response[:tx_ref_num], response[:order_id]),
         | 
| 304 | 
            +
                         :test => self.test?,
         | 
| 305 | 
            +
                         :avs_result => {:code => response[:avs_resp_code]},
         | 
| 306 | 
            +
                         :cvv_result => response[:cvv2_resp_code]
         | 
| 220 307 | 
             
                      }
         | 
| 221 308 | 
             
                    )
         | 
| 222 309 | 
             
                  end
         | 
| 223 | 
            -
             | 
| 310 | 
            +
             | 
| 224 311 | 
             
                  def remote_url
         | 
| 225 312 | 
             
                    unless $!.class == ActiveMerchant::ConnectionError
         | 
| 226 313 | 
             
                      self.test? ? self.test_url : self.live_url
         | 
| @@ -230,18 +317,20 @@ module ActiveMerchant #:nodoc: | |
| 230 317 | 
             
                  end
         | 
| 231 318 |  | 
| 232 319 | 
             
                  def success?(response)
         | 
| 233 | 
            -
                    if response[:message_type] | 
| 320 | 
            +
                    if response[:message_type] == "R"
         | 
| 234 321 | 
             
                      response[:proc_status] == SUCCESS
         | 
| 322 | 
            +
                    elsif response[:customer_profile_action]
         | 
| 323 | 
            +
                      response[:profile_proc_status] == SUCCESS
         | 
| 235 324 | 
             
                    else
         | 
| 236 325 | 
             
                      response[:proc_status] == SUCCESS &&
         | 
| 237 | 
            -
             | 
| 326 | 
            +
                      response[:resp_code] == APPROVED
         | 
| 238 327 | 
             
                    end
         | 
| 239 328 | 
             
                  end
         | 
| 240 | 
            -
             | 
| 329 | 
            +
             | 
| 241 330 | 
             
                  def message_from(response)
         | 
| 242 | 
            -
                     | 
| 331 | 
            +
                    response[:resp_msg] || response[:status_msg] || response[:customer_profile_message]
         | 
| 243 332 | 
             
                  end
         | 
| 244 | 
            -
             | 
| 333 | 
            +
             | 
| 245 334 | 
             
                  def ip_authentication?
         | 
| 246 335 | 
             
                    @options[:ip_authentication] == true
         | 
| 247 336 | 
             
                  end
         | 
| @@ -255,30 +344,46 @@ module ActiveMerchant #:nodoc: | |
| 255 344 | 
             
                        xml.tag! :IndustryType, parameters[:industry_type] || "EC"
         | 
| 256 345 | 
             
                        xml.tag! :MessageType, action
         | 
| 257 346 | 
             
                        add_bin_merchant_and_terminal(xml, parameters)
         | 
| 258 | 
            -
             | 
| 347 | 
            +
             | 
| 259 348 | 
             
                        yield xml if block_given?
         | 
| 260 | 
            -
             | 
| 261 | 
            -
                        xml.tag! :Comments, parameters[:comments] if parameters[:comments]
         | 
| 349 | 
            +
             | 
| 262 350 | 
             
                        xml.tag! :OrderID, format_order_id(parameters[:order_id])
         | 
| 263 351 | 
             
                        xml.tag! :Amount, amount(money)
         | 
| 264 | 
            -
                        
         | 
| 352 | 
            +
                        xml.tag! :Comments, parameters[:comments] if parameters[:comments]
         | 
| 353 | 
            +
             | 
| 354 | 
            +
                        if parameters[:soft_descriptors].is_a?(OrbitalSoftDescriptors)
         | 
| 355 | 
            +
                          add_soft_descriptors(xml, parameters[:soft_descriptors])
         | 
| 356 | 
            +
                        end
         | 
| 357 | 
            +
             | 
| 358 | 
            +
                        set_recurring_ind(xml, parameters)
         | 
| 359 | 
            +
             | 
| 265 360 | 
             
                        # Append Transaction Reference Number at the end for Refund transactions
         | 
| 266 361 | 
             
                        if action == "R"
         | 
| 267 | 
            -
                          tx_ref_num, _ = parameters[:authorization] | 
| 362 | 
            +
                          tx_ref_num, _ = split_authorization(parameters[:authorization])
         | 
| 268 363 | 
             
                          xml.tag! :TxRefNum, tx_ref_num
         | 
| 269 364 | 
             
                        end
         | 
| 270 365 | 
             
                      end
         | 
| 271 366 | 
             
                    end
         | 
| 272 367 | 
             
                    xml.target!
         | 
| 273 368 | 
             
                  end
         | 
| 274 | 
            -
             | 
| 369 | 
            +
             | 
| 370 | 
            +
                  # For Canadian transactions on PNS Tampa on New Order
         | 
| 371 | 
            +
                  # RF - First Recurring Transaction
         | 
| 372 | 
            +
                  # RS - Subsequent Recurring Transactions
         | 
| 373 | 
            +
                  def set_recurring_ind(xml, parameters)
         | 
| 374 | 
            +
                    if parameters[:recurring_ind]
         | 
| 375 | 
            +
                      raise "RecurringInd must be set to either \"RF\" or \"RS\"" unless %w(RF RS).include?(parameters[:recurring_ind])
         | 
| 376 | 
            +
                      xml.tag! :RecurringInd, parameters[:recurring_ind]
         | 
| 377 | 
            +
                    end
         | 
| 378 | 
            +
                  end
         | 
| 379 | 
            +
             | 
| 275 380 | 
             
                  def build_mark_for_capture_xml(money, authorization, parameters = {})
         | 
| 276 | 
            -
                    tx_ref_num, order_id = authorization | 
| 381 | 
            +
                    tx_ref_num, order_id = split_authorization(authorization)
         | 
| 277 382 | 
             
                    xml = xml_envelope
         | 
| 278 383 | 
             
                    xml.tag! :Request do
         | 
| 279 384 | 
             
                      xml.tag! :MarkForCapture do
         | 
| 280 385 | 
             
                        add_xml_credentials(xml)
         | 
| 281 | 
            -
                        xml.tag! :OrderID, order_id
         | 
| 386 | 
            +
                        xml.tag! :OrderID, format_order_id(order_id)
         | 
| 282 387 | 
             
                        xml.tag! :Amount, amount(money)
         | 
| 283 388 | 
             
                        add_bin_merchant_and_terminal(xml, parameters)
         | 
| 284 389 | 
             
                        xml.tag! :TxRefNum, tx_ref_num
         | 
| @@ -286,26 +391,27 @@ module ActiveMerchant #:nodoc: | |
| 286 391 | 
             
                    end
         | 
| 287 392 | 
             
                    xml.target!
         | 
| 288 393 | 
             
                  end
         | 
| 289 | 
            -
             | 
| 290 | 
            -
                  def build_void_request_xml(authorization, parameters = {})
         | 
| 291 | 
            -
                    tx_ref_num, order_id = authorization | 
| 394 | 
            +
             | 
| 395 | 
            +
                  def build_void_request_xml(money, authorization, parameters = {})
         | 
| 396 | 
            +
                    tx_ref_num, order_id = split_authorization(authorization)
         | 
| 292 397 | 
             
                    xml = xml_envelope
         | 
| 293 398 | 
             
                    xml.tag! :Request do
         | 
| 294 399 | 
             
                      xml.tag! :Reversal do
         | 
| 295 400 | 
             
                        add_xml_credentials(xml)
         | 
| 296 401 | 
             
                        xml.tag! :TxRefNum, tx_ref_num
         | 
| 297 402 | 
             
                        xml.tag! :TxRefIdx, parameters[:transaction_index]
         | 
| 298 | 
            -
                        xml.tag! : | 
| 403 | 
            +
                        xml.tag! :AdjustedAmt, amount(money)
         | 
| 404 | 
            +
                        xml.tag! :OrderID, format_order_id(order_id || parameters[:order_id])
         | 
| 299 405 | 
             
                        add_bin_merchant_and_terminal(xml, parameters)
         | 
| 300 406 | 
             
                      end
         | 
| 301 407 | 
             
                    end
         | 
| 302 408 | 
             
                    xml.target!
         | 
| 303 409 | 
             
                  end
         | 
| 304 | 
            -
             | 
| 410 | 
            +
             | 
| 305 411 | 
             
                  def currency_code(currency)
         | 
| 306 412 | 
             
                    CURRENCY_CODES[(currency || self.default_currency)].to_s
         | 
| 307 413 | 
             
                  end
         | 
| 308 | 
            -
             | 
| 414 | 
            +
             | 
| 309 415 | 
             
                  def expiry_date(credit_card)
         | 
| 310 416 | 
             
                    "#{format(credit_card.month, :two_digits)}#{format(credit_card.year, :two_digits)}"
         | 
| 311 417 | 
             
                  end
         | 
| @@ -346,6 +452,41 @@ module ActiveMerchant #:nodoc: | |
| 346 452 | 
             
                    order_id.gsub!(illegal_characters, '')
         | 
| 347 453 | 
             
                    order_id[0...22]
         | 
| 348 454 | 
             
                  end
         | 
| 455 | 
            +
             | 
| 456 | 
            +
                  def build_customer_request_xml(creditcard, options = {})
         | 
| 457 | 
            +
                    xml = xml_envelope
         | 
| 458 | 
            +
                    xml.tag! :Request do
         | 
| 459 | 
            +
                      xml.tag! :Profile do
         | 
| 460 | 
            +
                        xml.tag! :OrbitalConnectionUsername, @options[:login] unless ip_authentication?
         | 
| 461 | 
            +
                        xml.tag! :OrbitalConnectionPassword, @options[:password] unless ip_authentication?
         | 
| 462 | 
            +
                        xml.tag! :CustomerBin, bin
         | 
| 463 | 
            +
                        xml.tag! :CustomerMerchantID, @options[:merchant_id]
         | 
| 464 | 
            +
                        xml.tag! :CustomerName, creditcard.name if creditcard
         | 
| 465 | 
            +
                        xml.tag! :CustomerRefNum, options[:customer_ref_num] if options[:customer_ref_num]
         | 
| 466 | 
            +
             | 
| 467 | 
            +
                        add_customer_address(xml, options)
         | 
| 468 | 
            +
             | 
| 469 | 
            +
                        xml.tag! :CustomerProfileAction, options[:customer_profile_action] # C, R, U, D
         | 
| 470 | 
            +
                        xml.tag! :CustomerProfileOrderOverrideInd, options[:customer_profile_order_override_ind] || 'NO'
         | 
| 471 | 
            +
             | 
| 472 | 
            +
                        if options[:customer_profile_action] == 'C'
         | 
| 473 | 
            +
                          xml.tag! :CustomerProfileFromOrderInd, options[:customer_ref_num] ? 'S' : 'A'
         | 
| 474 | 
            +
                        end
         | 
| 475 | 
            +
             | 
| 476 | 
            +
                        xml.tag! :OrderDefaultDescription, options[:order_default_description][0..63] if options[:order_default_description]
         | 
| 477 | 
            +
                        xml.tag! :OrderDefaultAmount, options[:order_default_amount] if options[:order_default_amount]
         | 
| 478 | 
            +
             | 
| 479 | 
            +
                        if ['C', 'U'].include? options[:customer_profile_action]
         | 
| 480 | 
            +
                          xml.tag! :CustomerAccountType, 'CC' # Only credit card supported
         | 
| 481 | 
            +
                          xml.tag! :Status, options[:status] || 'A' # Active
         | 
| 482 | 
            +
                        end
         | 
| 483 | 
            +
             | 
| 484 | 
            +
                        xml.tag! :CCAccountNum, creditcard.number if creditcard
         | 
| 485 | 
            +
                        xml.tag! :CCExpireDate, creditcard.expiry_date.expiration.strftime("%m%y") if creditcard
         | 
| 486 | 
            +
                      end
         | 
| 487 | 
            +
                    end
         | 
| 488 | 
            +
                    xml.target!
         | 
| 489 | 
            +
                  end
         | 
| 349 490 | 
             
                end
         | 
| 350 491 | 
             
              end
         | 
| 351 492 | 
             
            end
         |