activemerchant 1.66.0 → 1.67.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.
- checksums.yaml +4 -4
- data/CHANGELOG +28 -0
- data/lib/active_merchant/billing/gateways/authorize_net.rb +74 -7
- data/lib/active_merchant/billing/gateways/checkout_v2.rb +1 -0
- data/lib/active_merchant/billing/gateways/credorax.rb +8 -1
- data/lib/active_merchant/billing/gateways/cyber_source.rb +14 -7
- data/lib/active_merchant/billing/gateways/ebanx.rb +234 -0
- data/lib/active_merchant/billing/gateways/elavon.rb +23 -92
- data/lib/active_merchant/billing/gateways/fat_zebra.rb +1 -27
- data/lib/active_merchant/billing/gateways/firstdata_e4.rb +5 -3
- data/lib/active_merchant/billing/gateways/jetpay_v2.rb +410 -0
- data/lib/active_merchant/billing/gateways/nmi.rb +10 -1
- data/lib/active_merchant/billing/gateways/opp.rb +124 -114
- data/lib/active_merchant/billing/gateways/orbital.rb +15 -4
- data/lib/active_merchant/billing/gateways/payeezy.rb +9 -6
- data/lib/active_merchant/billing/gateways/quickpay/quickpay_v10.rb +19 -14
- data/lib/active_merchant/billing/gateways/realex.rb +2 -5
- data/lib/active_merchant/billing/gateways/safe_charge.rb +2 -1
- data/lib/active_merchant/billing/gateways/wepay.rb +11 -6
- data/lib/active_merchant/version.rb +1 -1
- metadata +4 -2
| @@ -116,7 +116,12 @@ module ActiveMerchant #:nodoc: | |
| 116 116 | 
             
                      gsub(%r((ccnumber=)\d+), '\1[FILTERED]').
         | 
| 117 117 | 
             
                      gsub(%r((cvv=)\d+), '\1[FILTERED]').
         | 
| 118 118 | 
             
                      gsub(%r((checkaba=)\d+), '\1[FILTERED]').
         | 
| 119 | 
            -
                      gsub(%r((checkaccount=)\d+), '\1[FILTERED]')
         | 
| 119 | 
            +
                      gsub(%r((checkaccount=)\d+), '\1[FILTERED]').
         | 
| 120 | 
            +
                      gsub(%r((cryptogram=)[^&]+(&?)), '\1[FILTERED]\2')
         | 
| 121 | 
            +
                  end
         | 
| 122 | 
            +
             | 
| 123 | 
            +
                  def supports_network_tokenization?
         | 
| 124 | 
            +
                    true
         | 
| 120 125 | 
             
                  end
         | 
| 121 126 |  | 
| 122 127 | 
             
                  private
         | 
| @@ -135,6 +140,10 @@ module ActiveMerchant #:nodoc: | |
| 135 140 | 
             
                  def add_payment_method(post, payment_method, options)
         | 
| 136 141 | 
             
                    if(payment_method.is_a?(String))
         | 
| 137 142 | 
             
                      post[:customer_vault_id] = payment_method
         | 
| 143 | 
            +
                    elsif (payment_method.is_a?(NetworkTokenizationCreditCard))
         | 
| 144 | 
            +
                      post[:ccnumber] = payment_method.number
         | 
| 145 | 
            +
                      post[:ccexp] = exp_date(payment_method)
         | 
| 146 | 
            +
                      post[:token_cryptogram] = payment_method.payment_cryptogram
         | 
| 138 147 | 
             
                    elsif(card_brand(payment_method) == 'check')
         | 
| 139 148 | 
             
                      post[:payment] = 'check'
         | 
| 140 149 | 
             
                      post[:checkname] = payment_method.name
         | 
| @@ -1,26 +1,26 @@ | |
| 1 1 | 
             
            module ActiveMerchant #:nodoc:
         | 
| 2 2 | 
             
              module Billing #:nodoc:
         | 
| 3 3 | 
             
                class OppGateway < Gateway
         | 
| 4 | 
            -
            # = Open Payment Platform
         | 
| 4 | 
            +
                # = Open Payment Platform
         | 
| 5 5 | 
             
                #
         | 
| 6 | 
            -
                #  The Open Payment Platform includes a powerful omni-channel transaction processing API, | 
| 7 | 
            -
                #   enabling you to quickly and flexibly build new applications and services on the platform. | 
| 8 | 
            -
                # | 
| 9 | 
            -
                #   This plugin enables connectivity to the Open Payment Platform for activemerchant. | 
| 6 | 
            +
                #  The Open Payment Platform includes a powerful omni-channel transaction processing API,
         | 
| 7 | 
            +
                #   enabling you to quickly and flexibly build new applications and services on the platform.
         | 
| 8 | 
            +
                #
         | 
| 9 | 
            +
                #   This plugin enables connectivity to the Open Payment Platform for activemerchant.
         | 
| 10 10 | 
             
                #
         | 
| 11 11 | 
             
                # For any questions or comments please contact support@payon.com
         | 
| 12 12 | 
             
                #
         | 
| 13 13 | 
             
                # == Usage
         | 
| 14 14 | 
             
                #
         | 
| 15 15 | 
             
                #   gateway = ActiveMerchant::Billing::OppGateway.new(
         | 
| 16 | 
            -
                #      user_id: 'merchant user id', | 
| 16 | 
            +
                #      user_id: 'merchant user id',
         | 
| 17 17 | 
             
                #      password: 'password',
         | 
| 18 | 
            -
                #      entity_id: 'entity id', | 
| 18 | 
            +
                #      entity_id: 'entity id',
         | 
| 19 19 | 
             
                #   )
         | 
| 20 20 | 
             
                #
         | 
| 21 21 | 
             
                #   # set up credit card object as in main ActiveMerchant example
         | 
| 22 22 | 
             
                #   creditcard = ActiveMerchant::Billing::CreditCard.new(
         | 
| 23 | 
            -
             | 
| 23 | 
            +
                #     :type       => 'visa',
         | 
| 24 24 | 
             
                #     :number     => '4242424242424242',
         | 
| 25 25 | 
             
                #     :month      => 8,
         | 
| 26 26 | 
             
                #     :year       => 2009,
         | 
| @@ -30,7 +30,7 @@ module ActiveMerchant #:nodoc: | |
| 30 30 | 
             
                #
         | 
| 31 31 | 
             
                #   # Request: complete example, including address, billing address, shipping address
         | 
| 32 32 | 
             
                #    complete_request_options = {
         | 
| 33 | 
            -
                #      order_id: "your merchant/shop order id", # alternative is to set merchantInvoiceId | 
| 33 | 
            +
                #      order_id: "your merchant/shop order id", # alternative is to set merchantInvoiceId
         | 
| 34 34 | 
             
                #      merchant_transaction_id: "your merchant/shop transaction id",
         | 
| 35 35 | 
             
                #      address: address,
         | 
| 36 36 | 
             
                #      description: 'Store Purchase - Books',
         | 
| @@ -67,34 +67,34 @@ module ActiveMerchant #:nodoc: | |
| 67 67 | 
             
                #        ip:  101.102.103.104,
         | 
| 68 68 | 
             
                #      },
         | 
| 69 69 | 
             
                #    }
         | 
| 70 | 
            -
                # | 
| 70 | 
            +
                #
         | 
| 71 71 | 
             
                #    # Request: minimal example
         | 
| 72 72 | 
             
                #    minimal_request_options = {
         | 
| 73 | 
            -
                #      order_id: "your merchant/shop order id", # alternative is to set merchantInvoiceId | 
| 73 | 
            +
                #      order_id: "your merchant/shop order id", # alternative is to set merchantInvoiceId
         | 
| 74 74 | 
             
                #      description: 'Store Purchase - Books',
         | 
| 75 75 | 
             
                #    }
         | 
| 76 76 | 
             
                #
         | 
| 77 | 
            -
                #   options = | 
| 77 | 
            +
                #   options =
         | 
| 78 78 | 
             
                #   # run request
         | 
| 79 79 | 
             
                #   response = gateway.purchase(754, creditcard, options) # charge 7,54 EUR
         | 
| 80 80 | 
             
                #
         | 
| 81 81 | 
             
                #   response.success?                   # Check whether the transaction was successful
         | 
| 82 | 
            -
                #   response.error_code                 # Retrieve the error message - it's mapped to Gateway::STANDARD_ERROR_CODE | 
| 82 | 
            +
                #   response.error_code                 # Retrieve the error message - it's mapped to Gateway::STANDARD_ERROR_CODE
         | 
| 83 83 | 
             
                #   response.message                    # Retrieve the message returned by opp
         | 
| 84 84 | 
             
                #   response.authorization              # Retrieve the unique transaction ID returned by opp
         | 
| 85 85 | 
             
                #   response.params['result']['code']   # Retrieve original return code returned by opp server
         | 
| 86 86 | 
             
                #
         | 
| 87 87 | 
             
                # == Errors
         | 
| 88 | 
            -
                #   If transaction is not successful, response.error_code contains mapped to Gateway::STANDARD_ERROR_CODE error message. | 
| 89 | 
            -
                #   Complete list of opp error codes can be viewed on https://docs.oppwa.com/ | 
| 90 | 
            -
                #   Because this list is much bigger than Gateway::STANDARD_ERROR_CODE, only fraction is mapped to Gateway::STANDARD_ERROR_CODE. | 
| 91 | 
            -
                #   All other codes are mapped as Gateway::STANDARD_ERROR_CODE[:processing_error], so if this is the case, | 
| 88 | 
            +
                #   If transaction is not successful, response.error_code contains mapped to Gateway::STANDARD_ERROR_CODE error message.
         | 
| 89 | 
            +
                #   Complete list of opp error codes can be viewed on https://docs.oppwa.com/
         | 
| 90 | 
            +
                #   Because this list is much bigger than Gateway::STANDARD_ERROR_CODE, only fraction is mapped to Gateway::STANDARD_ERROR_CODE.
         | 
| 91 | 
            +
                #   All other codes are mapped as Gateway::STANDARD_ERROR_CODE[:processing_error], so if this is the case,
         | 
| 92 92 | 
             
                #   you may check the original result code from OPP that can be found in response.params['result']['code']
         | 
| 93 | 
            -
                # | 
| 93 | 
            +
                #
         | 
| 94 94 | 
             
                # == Special features
         | 
| 95 | 
            -
                #   For purchase method risk check can be forced when options[:risk_workflow] = true | 
| 96 | 
            -
                #   This will split (on OPP server side) the transaction into two separate transactions: authorize and capture, | 
| 97 | 
            -
                #   but capture will be executed only if risk checks are successful. | 
| 95 | 
            +
                #   For purchase method risk check can be forced when options[:risk_workflow] = true
         | 
| 96 | 
            +
                #   This will split (on OPP server side) the transaction into two separate transactions: authorize and capture,
         | 
| 97 | 
            +
                #   but capture will be executed only if risk checks are successful.
         | 
| 98 98 | 
             
                #
         | 
| 99 99 | 
             
                #   For testing you may use the test account details listed fixtures.yml under opp. It is important to note that there are two test modes available:
         | 
| 100 100 | 
             
                #     options[:test_mode]='EXTERNAL' causes test transactions to be forwarded to the processor's test system for 'end-to-end' testing
         | 
| @@ -102,10 +102,10 @@ module ActiveMerchant #:nodoc: | |
| 102 102 | 
             
                #   If no test_mode parameter is sent, test_mode=INTERNAL is the default behaviour.
         | 
| 103 103 | 
             
                #
         | 
| 104 104 | 
             
                #   Billing Address, Shipping Address, Custom Parameters are supported as described under https://docs.oppwa.com/parameters
         | 
| 105 | 
            -
                #   See complete example above for details. | 
| 105 | 
            +
                #   See complete example above for details.
         | 
| 106 106 | 
             
                #
         | 
| 107 107 | 
             
                #   == Tokenization
         | 
| 108 | 
            -
                #  When create_registration is set to true, the payment details will be stored and a token will be returned in registrationId response field, | 
| 108 | 
            +
                #  When create_registration is set to true, the payment details will be stored and a token will be returned in registrationId response field,
         | 
| 109 109 | 
             
                #  which can subsequently be used to reference the stored payment.
         | 
| 110 110 |  | 
| 111 111 | 
             
                  self.test_url = 'https://test.oppwa.com/v1/payments'
         | 
| @@ -113,7 +113,7 @@ module ActiveMerchant #:nodoc: | |
| 113 113 |  | 
| 114 114 | 
             
                  self.supported_countries = %w(AD AI AG AR AU AT BS BB BE BZ BM BR BN BG CA HR CY CZ DK DM EE FI FR DE GR GD GY HK HU IS IN IL IT JP LV LI LT LU MY MT MX MC MS NL PA PL PT KN LC MF VC SM SG SK SI ZA ES SR SE CH TR GB US UY)
         | 
| 115 115 | 
             
                  self.default_currency = 'EUR'
         | 
| 116 | 
            -
                  self.supported_cardtypes = [:visa, :master, :american_express, :diners_club, :discover, :jcb, :maestro, :dankort] | 
| 116 | 
            +
                  self.supported_cardtypes = [:visa, :master, :american_express, :diners_club, :discover, :jcb, :maestro, :dankort]
         | 
| 117 117 |  | 
| 118 118 | 
             
                  self.homepage_url = 'https://docs.oppwa.com'
         | 
| 119 119 | 
             
                  self.display_name = 'Open Payment Platform'
         | 
| @@ -125,7 +125,7 @@ module ActiveMerchant #:nodoc: | |
| 125 125 |  | 
| 126 126 | 
             
                  def purchase(money, payment, options={})
         | 
| 127 127 | 
             
                    # debit
         | 
| 128 | 
            -
                    execute_dbpa(options[:risk_workflow] ? 'PA.CP': 'DB', | 
| 128 | 
            +
                    execute_dbpa(options[:risk_workflow] ? 'PA.CP': 'DB',
         | 
| 129 129 | 
             
                      money, payment, options)
         | 
| 130 130 | 
             
                  end
         | 
| 131 131 |  | 
| @@ -133,7 +133,7 @@ module ActiveMerchant #:nodoc: | |
| 133 133 | 
             
                    # preauthorization PA
         | 
| 134 134 | 
             
                    execute_dbpa('PA', money, payment, options)
         | 
| 135 135 | 
             
                  end
         | 
| 136 | 
            -
             | 
| 136 | 
            +
             | 
| 137 137 | 
             
                  def capture(money, authorization, options={})
         | 
| 138 138 | 
             
                    # capture CP
         | 
| 139 139 | 
             
                    execute_referencing('CP', money, authorization, options)
         | 
| @@ -163,8 +163,6 @@ module ActiveMerchant #:nodoc: | |
| 163 163 | 
             
                  def scrub(transcript)
         | 
| 164 164 | 
             
                    transcript.
         | 
| 165 165 | 
             
                      gsub(%r((authentication\.password=)\w+), '\1[FILTERED]').
         | 
| 166 | 
            -
                      gsub(%r((authentication\.userId=)\w+), '\1[FILTERED]').
         | 
| 167 | 
            -
                      gsub(%r((authentication\.entityId=)\w+), '\1[FILTERED]').
         | 
| 168 166 | 
             
                      gsub(%r((card\.number=)\d+), '\1[FILTERED]').
         | 
| 169 167 | 
             
                      gsub(%r((card\.cvv=)\d+), '\1[FILTERED]')
         | 
| 170 168 | 
             
                  end
         | 
| @@ -173,12 +171,13 @@ module ActiveMerchant #:nodoc: | |
| 173 171 |  | 
| 174 172 | 
             
                  def execute_dbpa(txtype, money, payment, options)
         | 
| 175 173 | 
             
                    post = {}
         | 
| 176 | 
            -
                    post[:paymentType] = txtype | 
| 174 | 
            +
                    post[:paymentType] = txtype
         | 
| 177 175 | 
             
                    add_invoice(post, money, options)
         | 
| 178 176 | 
             
                    add_payment_method(post, payment, options)
         | 
| 179 177 | 
             
                    add_address(post, options)
         | 
| 180 | 
            -
                    add_customer_data(post, options)
         | 
| 178 | 
            +
                    add_customer_data(post, payment, options)
         | 
| 181 179 | 
             
                    add_options(post, options)
         | 
| 180 | 
            +
                    add_3d_secure(post, options)
         | 
| 182 181 | 
             
                    commit(post, nil, options)
         | 
| 183 182 | 
             
                  end
         | 
| 184 183 |  | 
| @@ -189,76 +188,86 @@ module ActiveMerchant #:nodoc: | |
| 189 188 | 
             
                    commit(post, authorization, options)
         | 
| 190 189 | 
             
                  end
         | 
| 191 190 |  | 
| 192 | 
            -
                  def add_authentication(post) | 
| 193 | 
            -
                      post[:authentication] = { entityId: @options[:entity_id], password: @options[:password], userId: @options[:user_id]} | 
| 191 | 
            +
                  def add_authentication(post)
         | 
| 192 | 
            +
                      post[:authentication] = { entityId: @options[:entity_id], password: @options[:password], userId: @options[:user_id]}
         | 
| 194 193 | 
             
                  end
         | 
| 195 194 |  | 
| 196 | 
            -
                  def add_customer_data(post, options)
         | 
| 195 | 
            +
                  def add_customer_data(post, payment, options)
         | 
| 197 196 | 
             
                    if options[:customer]
         | 
| 198 197 | 
             
                      post[:customer] = {
         | 
| 199 198 | 
             
                        merchantCustomerId:  options[:customer][:merchant_customer_id],
         | 
| 200 | 
            -
                        givenName:  options[:customer][:givenname],
         | 
| 201 | 
            -
                        surname:  options[:customer][:surname],
         | 
| 199 | 
            +
                        givenName:  options[:customer][:givenname] || payment.first_name,
         | 
| 200 | 
            +
                        surname:  options[:customer][:surname] || payment.last_name,
         | 
| 202 201 | 
             
                        birthDate:  options[:customer][:birth_date],
         | 
| 203 202 | 
             
                        phone:  options[:customer][:phone],
         | 
| 204 203 | 
             
                        mobile:  options[:customer][:mobile],
         | 
| 205 | 
            -
                        email:  options[:customer][:email],
         | 
| 204 | 
            +
                        email:  options[:customer][:email] || options[:email],
         | 
| 206 205 | 
             
                        companyName:  options[:customer][:company_name],
         | 
| 207 206 | 
             
                        identificationDocType:  options[:customer][:identification_doctype],
         | 
| 208 207 | 
             
                        identificationDocId:  options[:customer][:identification_docid],
         | 
| 209 | 
            -
                        ip:  options[:customer][:ip] | 
| 208 | 
            +
                        ip:  options[:customer][:ip] || options[:ip]
         | 
| 210 209 | 
             
                      }
         | 
| 211 210 | 
             
                    end
         | 
| 212 211 | 
             
                  end
         | 
| 213 212 |  | 
| 214 213 | 
             
                  def add_address(post, options)
         | 
| 215 | 
            -
                    if billing_address = options[:billing_address]
         | 
| 214 | 
            +
                    if billing_address = options[:billing_address] || options[:address]
         | 
| 216 215 | 
             
                      address(post, billing_address, 'billing')
         | 
| 217 216 | 
             
                    end
         | 
| 218 217 | 
             
                    if shipping_address = options[:shipping_address]
         | 
| 219 | 
            -
                      address(post,  | 
| 218 | 
            +
                      address(post, shipping_address, 'shipping')
         | 
| 220 219 | 
             
                      if shipping_address[:name]
         | 
| 221 | 
            -
                        firstname, lastname = shipping_address[:name].split(' ') | 
| 222 | 
            -
                        post[:shipping] = { givenName: firstname, surname: lastname } | 
| 223 | 
            -
                      end | 
| 220 | 
            +
                        firstname, lastname = shipping_address[:name].split(' ')
         | 
| 221 | 
            +
                        post[:shipping] = { givenName: firstname, surname: lastname }
         | 
| 222 | 
            +
                      end
         | 
| 224 223 | 
             
                    end
         | 
| 225 224 | 
             
                  end
         | 
| 226 225 |  | 
| 227 226 | 
             
                  def address(post, address, prefix)
         | 
| 228 | 
            -
             | 
| 229 | 
            -
             | 
| 230 | 
            -
             | 
| 231 | 
            -
             | 
| 232 | 
            -
             | 
| 233 | 
            -
             | 
| 234 | 
            -
             | 
| 235 | 
            -
             | 
| 227 | 
            +
                    post[prefix] = {
         | 
| 228 | 
            +
                      street1: address[:address1],
         | 
| 229 | 
            +
                      street2: address[:address2],
         | 
| 230 | 
            +
                      city: address[:city],
         | 
| 231 | 
            +
                      state: address[:state],
         | 
| 232 | 
            +
                      postcode: address[:zip],
         | 
| 233 | 
            +
                      country: address[:country],
         | 
| 234 | 
            +
                    }
         | 
| 236 235 | 
             
                  end
         | 
| 237 236 |  | 
| 238 237 | 
             
                  def add_invoice(post, money, options)
         | 
| 239 | 
            -
             | 
| 240 | 
            -
             | 
| 241 | 
            -
             | 
| 242 | 
            -
             | 
| 243 | 
            -
             | 
| 238 | 
            +
                    post[:amount] = amount(money)
         | 
| 239 | 
            +
                    post[:currency] = options[:currency] || currency(money) unless post[:paymentType] == 'RV'
         | 
| 240 | 
            +
                    post[:descriptor] = options[:description] || options[:descriptor]
         | 
| 241 | 
            +
                    post[:merchantInvoiceId] = options[:merchantInvoiceId] || options[:order_id]
         | 
| 242 | 
            +
                    post[:merchantTransactionId] = options[:merchant_transaction_id] || generate_unique_id
         | 
| 244 243 | 
             
                  end
         | 
| 245 244 |  | 
| 246 245 | 
             
                  def add_payment_method(post, payment, options)
         | 
| 247 | 
            -
             | 
| 248 | 
            -
             | 
| 249 | 
            -
             | 
| 250 | 
            -
             | 
| 251 | 
            -
             | 
| 252 | 
            -
             | 
| 253 | 
            -
             | 
| 254 | 
            -
             | 
| 255 | 
            -
             | 
| 256 | 
            -
             | 
| 257 | 
            -
             | 
| 258 | 
            -
             | 
| 259 | 
            -
             | 
| 260 | 
            -
             | 
| 261 | 
            -
             | 
| 246 | 
            +
                    if options[:registrationId]
         | 
| 247 | 
            +
                      #post[:recurringType] = 'REPEATED'
         | 
| 248 | 
            +
                      post[:card] = {
         | 
| 249 | 
            +
                        cvv: payment.verification_value,
         | 
| 250 | 
            +
                      }
         | 
| 251 | 
            +
                    else
         | 
| 252 | 
            +
                      post[:paymentBrand] = payment.brand.upcase
         | 
| 253 | 
            +
                      post[:card] = {
         | 
| 254 | 
            +
                        holder: payment.name,
         | 
| 255 | 
            +
                        number: payment.number,
         | 
| 256 | 
            +
                        expiryMonth: "%02d" % payment.month,
         | 
| 257 | 
            +
                        expiryYear: payment.year,
         | 
| 258 | 
            +
                        cvv: payment.verification_value,
         | 
| 259 | 
            +
                      }
         | 
| 260 | 
            +
                    end
         | 
| 261 | 
            +
                  end
         | 
| 262 | 
            +
             | 
| 263 | 
            +
                  def add_3d_secure(post, options)
         | 
| 264 | 
            +
                    return unless options[:eci] && options[:cavv] && options[:xid]
         | 
| 265 | 
            +
             | 
| 266 | 
            +
                    post[:threeDSecure] = {
         | 
| 267 | 
            +
                      eci: options[:eci],
         | 
| 268 | 
            +
                      verificationId: options[:cavv],
         | 
| 269 | 
            +
                      xid: options[:xid]
         | 
| 270 | 
            +
                    }
         | 
| 262 271 | 
             
                  end
         | 
| 263 272 |  | 
| 264 273 | 
             
                  def add_options(post, options)
         | 
| @@ -266,36 +275,38 @@ module ActiveMerchant #:nodoc: | |
| 266 275 | 
             
                    post[:testMode] = options[:test_mode] if test? && options[:test_mode]
         | 
| 267 276 | 
             
                    options.each {|key, value| post[key] = value if key.to_s.match('customParameters\[[a-zA-Z0-9\._]{3,64}\]') }
         | 
| 268 277 | 
             
                    post['customParameters[SHOPPER_pluginId]'] = 'activemerchant'
         | 
| 278 | 
            +
                    post['customParameters[custom_disable3DSecure]'] = options[:disable_3d_secure] if options[:disable_3d_secure]
         | 
| 269 279 | 
             
                  end
         | 
| 270 280 |  | 
| 271 281 | 
             
                  def build_url(url, authorization, options)
         | 
| 272 282 | 
             
                    if options[:registrationId]
         | 
| 273 283 | 
             
                      "#{url.gsub(/payments/, 'registrations')}/#{options[:registrationId]}/payments"
         | 
| 274 | 
            -
                    elsif authorization | 
| 284 | 
            +
                    elsif authorization
         | 
| 275 285 | 
             
                      "#{url}/#{authorization}"
         | 
| 276 286 | 
             
                    else
         | 
| 277 287 | 
             
                      url
         | 
| 278 288 | 
             
                    end
         | 
| 279 289 | 
             
                  end
         | 
| 280 | 
            -
             | 
| 290 | 
            +
             | 
| 281 291 | 
             
                  def commit(post, authorization, options)
         | 
| 282 | 
            -
                    url = (test? ? test_url : live_url)
         | 
| 292 | 
            +
                    url = build_url(test? ? test_url : live_url, authorization, options)
         | 
| 283 293 | 
             
                    add_authentication(post)
         | 
| 284 294 | 
             
                    post = flatten_hash(post)
         | 
| 285 295 |  | 
| 286 | 
            -
                     | 
| 287 | 
            -
             | 
| 288 | 
            -
                         | 
| 289 | 
            -
             | 
| 290 | 
            -
             | 
| 291 | 
            -
             | 
| 292 | 
            -
             | 
| 293 | 
            -
             | 
| 294 | 
            -
             | 
| 295 | 
            -
             | 
| 296 | 
            -
                      response = json_error(response)
         | 
| 296 | 
            +
                    response = begin
         | 
| 297 | 
            +
                      parse(
         | 
| 298 | 
            +
                        ssl_post(
         | 
| 299 | 
            +
                          url,
         | 
| 300 | 
            +
                          post.collect { |key, value| "#{key}=#{CGI.escape(value.to_s)}" }.join("&"),
         | 
| 301 | 
            +
                          "Content-Type" => "application/x-www-form-urlencoded;charset=UTF-8"
         | 
| 302 | 
            +
                        )
         | 
| 303 | 
            +
                      )
         | 
| 304 | 
            +
                    rescue ResponseError => e
         | 
| 305 | 
            +
                      parse(e.response.body)
         | 
| 297 306 | 
             
                    end
         | 
| 298 307 |  | 
| 308 | 
            +
                    success = success_from(response)
         | 
| 309 | 
            +
             | 
| 299 310 | 
             
                    Response.new(
         | 
| 300 311 | 
             
                      success,
         | 
| 301 312 | 
             
                      message_from(response),
         | 
| @@ -306,11 +317,34 @@ module ActiveMerchant #:nodoc: | |
| 306 317 | 
             
                    )
         | 
| 307 318 | 
             
                  end
         | 
| 308 319 |  | 
| 309 | 
            -
                  def  | 
| 310 | 
            -
                     | 
| 320 | 
            +
                  def parse(body)
         | 
| 321 | 
            +
                    begin
         | 
| 322 | 
            +
                      JSON.parse(body)
         | 
| 323 | 
            +
                    rescue JSON::ParserError
         | 
| 324 | 
            +
                      json_error(body)
         | 
| 325 | 
            +
                    end
         | 
| 326 | 
            +
                  end
         | 
| 327 | 
            +
             | 
| 328 | 
            +
                  def json_error(body)
         | 
| 329 | 
            +
                    message = "Invalid response received #{body.inspect}"
         | 
| 330 | 
            +
                    { 'result' => {'description' => message, 'code' => 'unknown' } }
         | 
| 331 | 
            +
                  end
         | 
| 332 | 
            +
             | 
| 333 | 
            +
                  def success_from(response)
         | 
| 334 | 
            +
                    return false unless response['result']
         | 
| 335 | 
            +
             | 
| 336 | 
            +
                    success_regex = /^(000\.000\.|000\.100\.1|000\.[36])/
         | 
| 337 | 
            +
             | 
| 338 | 
            +
                    if success_regex =~ response['result']['code']
         | 
| 339 | 
            +
                      true
         | 
| 340 | 
            +
                    else
         | 
| 341 | 
            +
                      false
         | 
| 342 | 
            +
                    end
         | 
| 311 343 | 
             
                  end
         | 
| 312 344 |  | 
| 313 345 | 
             
                  def message_from(response)
         | 
| 346 | 
            +
                    return 'Failed' unless response['result']
         | 
| 347 | 
            +
             | 
| 314 348 | 
             
                    response['result']['description']
         | 
| 315 349 | 
             
                  end
         | 
| 316 350 |  | 
| @@ -319,44 +353,20 @@ module ActiveMerchant #:nodoc: | |
| 319 353 | 
             
                  end
         | 
| 320 354 |  | 
| 321 355 | 
             
                  def error_code_from(response)
         | 
| 322 | 
            -
             | 
| 323 | 
            -
                      when '100.100.101' 
         | 
| 324 | 
            -
                          Gateway::STANDARD_ERROR_CODE[:incorrect_number]
         | 
| 325 | 
            -
                      when '100.400.317' 
         | 
| 326 | 
            -
                          Gateway::STANDARD_ERROR_CODE[:invalid_number]
         | 
| 327 | 
            -
                      when '100.100.600', '100.100.601', '800.100.153', '800.100.192' 
         | 
| 328 | 
            -
                          Gateway::STANDARD_ERROR_CODE[:invalid_cvc]
         | 
| 329 | 
            -
                      when '100.100.303' 
         | 
| 330 | 
            -
                          Gateway::STANDARD_ERROR_CODE[:expired_card]
         | 
| 331 | 
            -
                      when '100.800.200', '100.800.201', '100.800.202', '800.800.202' 
         | 
| 332 | 
            -
                          Gateway::STANDARD_ERROR_CODE[:incorrect_zip]
         | 
| 333 | 
            -
                      when '100.400.000', '100.400.086', '100.400.305', '800.400.150' 
         | 
| 334 | 
            -
                          Gateway::STANDARD_ERROR_CODE[:incorrect_address]
         | 
| 335 | 
            -
                      when '800.100.159' 
         | 
| 336 | 
            -
                          Gateway::STANDARD_ERROR_CODE[:pickup_card]
         | 
| 337 | 
            -
                      when '800.100.151', '800.100.158', '800.100.160' 
         | 
| 338 | 
            -
                          Gateway::STANDARD_ERROR_CODE[:card_declined]
         | 
| 339 | 
            -
                        else
         | 
| 340 | 
            -
                          Gateway::STANDARD_ERROR_CODE[:processing_error]
         | 
| 341 | 
            -
                      end
         | 
| 356 | 
            +
                    response['result']['code']
         | 
| 342 357 | 
             
                  end
         | 
| 343 | 
            -
             | 
| 344 | 
            -
                  def json_error(raw_response)
         | 
| 345 | 
            -
                    message = "Invalid response received #{raw_response.inspect}"
         | 
| 346 | 
            -
                    { 'result' => {'description' => message, 'code' => 'unknown' } }
         | 
| 347 | 
            -
                  end
         | 
| 348 | 
            -
                  
         | 
| 358 | 
            +
             | 
| 349 359 | 
             
                  def flatten_hash(hash)
         | 
| 350 360 | 
             
                    hash.each_with_object({}) do |(k, v), h|
         | 
| 351 361 | 
             
                      if v.is_a? Hash
         | 
| 352 362 | 
             
                        flatten_hash(v).map do |h_k, h_v|
         | 
| 353 363 | 
             
                          h["#{k}.#{h_k}".to_sym] = h_v
         | 
| 354 364 | 
             
                        end
         | 
| 355 | 
            -
                      else | 
| 365 | 
            +
                      else
         | 
| 356 366 | 
             
                        h[k] = v
         | 
| 357 367 | 
             
                      end
         | 
| 358 368 | 
             
                     end
         | 
| 359 | 
            -
                  end | 
| 369 | 
            +
                  end
         | 
| 360 370 | 
             
                end
         | 
| 361 371 | 
             
              end
         | 
| 362 372 | 
             
            end
         | 
| @@ -65,11 +65,11 @@ module ActiveMerchant #:nodoc: | |
| 65 65 |  | 
| 66 66 | 
             
                  class_attribute :secondary_test_url, :secondary_live_url
         | 
| 67 67 |  | 
| 68 | 
            -
                  self.test_url = "https://orbitalvar1. | 
| 69 | 
            -
                  self.secondary_test_url = "https://orbitalvar2. | 
| 68 | 
            +
                  self.test_url = "https://orbitalvar1.chasepaymentech.com/authorize"
         | 
| 69 | 
            +
                  self.secondary_test_url = "https://orbitalvar2.chasepaymentech.com/authorize"
         | 
| 70 70 |  | 
| 71 | 
            -
                  self.live_url = "https://orbital1. | 
| 72 | 
            -
                  self.secondary_live_url = "https://orbital2. | 
| 71 | 
            +
                  self.live_url = "https://orbital1.chasepaymentech.com/authorize"
         | 
| 72 | 
            +
                  self.secondary_live_url = "https://orbital2.chasepaymentech.com/authorize"
         | 
| 73 73 |  | 
| 74 74 | 
             
                  self.supported_countries = ["US", "CA"]
         | 
| 75 75 | 
             
                  self.default_currency = "CAD"
         | 
| @@ -345,6 +345,15 @@ module ActiveMerchant #:nodoc: | |
| 345 345 | 
             
                    xml.tag! :SDMerchantEmail, soft_desc.merchant_email           if soft_desc.merchant_email
         | 
| 346 346 | 
             
                  end
         | 
| 347 347 |  | 
| 348 | 
            +
                  def add_soft_descriptors_from_hash(xml, soft_desc)
         | 
| 349 | 
            +
                    xml.tag! :SDMerchantName, soft_desc[:merchant_name] || nil
         | 
| 350 | 
            +
                    xml.tag! :SDProductDescription, soft_desc[:product_description] || nil
         | 
| 351 | 
            +
                    xml.tag! :SDMerchantCity, soft_desc[:merchant_city] || nil
         | 
| 352 | 
            +
                    xml.tag! :SDMerchantPhone, soft_desc[:merchant_phone] || nil
         | 
| 353 | 
            +
                    xml.tag! :SDMerchantURL, soft_desc[:merchant_url] || nil
         | 
| 354 | 
            +
                    xml.tag! :SDMerchantEmail, soft_desc[:merchant_email] || nil
         | 
| 355 | 
            +
                  end
         | 
| 356 | 
            +
             | 
| 348 357 | 
             
                  def add_address(xml, creditcard, options)
         | 
| 349 358 | 
             
                    if(address = (options[:billing_address] || options[:address]))
         | 
| 350 359 | 
             
                      avs_supported = AVS_SUPPORTED_COUNTRIES.include?(address[:country].to_s) || empty?(address[:country])
         | 
| @@ -560,6 +569,8 @@ module ActiveMerchant #:nodoc: | |
| 560 569 |  | 
| 561 570 | 
             
                        if parameters[:soft_descriptors].is_a?(OrbitalSoftDescriptors)
         | 
| 562 571 | 
             
                          add_soft_descriptors(xml, parameters[:soft_descriptors])
         | 
| 572 | 
            +
                        elsif parameters[:soft_descriptors].is_a?(Hash)
         | 
| 573 | 
            +
                          add_soft_descriptors_from_hash(xml, parameters[:soft_descriptors])
         | 
| 563 574 | 
             
                        end
         | 
| 564 575 |  | 
| 565 576 | 
             
                        set_recurring_ind(xml, parameters)
         |