class ActiveMerchant::Billing::CyberSourceGateway

See the remote and mocked unit test files for example usage. Pay special attention to the contents of the options hash.

Initial setup instructions can be found in cybersource.com/support_center/implementation/downloads/soap_api/SOAP_toolkits.pdf

Debugging If you experience an issue with this gateway be sure to examine the transaction information from a general transaction search inside the CyberSource Business Center for the full error messages including field names.

Important Notes

Constants

XSD_VERSION

Public Class Methods

new(options = {}) click to toggle source

These are the options that can be used when creating a new CyberSource Gateway object.

:login => your username

:password => the transaction key you generated in the Business Center

:test => true sets the gateway to test mode

:vat_reg_number => your VAT registration number

:nexus => “WI CA QC” sets the states/provinces where you have a physical

presence for tax purposes

:ignore_avs => true don’t want to use AVS so continue processing even

if AVS would have failed

:ignore_cvv => true don’t want to use CVV so continue processing even

if CVV would have failed
Calls superclass method ActiveMerchant::Billing::Gateway::new
# File lib/active_merchant/billing/gateways/cyber_source.rb, line 112
def initialize(options = {})
  requires!(options, :login, :password)
  super
end

Public Instance Methods

auth_reversal(money, identification, options = {}) click to toggle source
# File lib/active_merchant/billing/gateways/cyber_source.rb, line 126
def auth_reversal(money, identification, options = {})
  commit(build_auth_reversal_request(money, identification, options), options)
end
authorize(money, creditcard_or_reference, options = {}) click to toggle source

Request an authorization for an amount from CyberSource

You must supply an :order_id in the options hash

# File lib/active_merchant/billing/gateways/cyber_source.rb, line 120
def authorize(money, creditcard_or_reference, options = {})
  requires!(options,  :order_id)
  setup_address_hash(options)
  commit(build_auth_request(money, creditcard_or_reference, options), options )
end
calculate_tax(creditcard, options) click to toggle source

CyberSource requires that you provide line item information for tax calculations. If you do not have prices for each item or want to simplify the situation then pass in one fake line item that costs the subtotal of the order

The line_item hash goes in the options hash and should look like

:line_items => [
  {
    :declared_value => '1',
    :quantity => '2',
    :code => 'default',
    :description => 'Giant Walrus',
    :sku => 'WA323232323232323'
  },
  {
    :declared_value => '6',
    :quantity => '1',
    :code => 'default',
    :description => 'Marble Snowcone',
    :sku => 'FAKE1232132113123'
  }
]

This functionality is only supported by this particular gateway may be changed at any time

# File lib/active_merchant/billing/gateways/cyber_source.rb, line 213
def calculate_tax(creditcard, options)
  requires!(options,  :line_items)
  setup_address_hash(options)
  commit(build_tax_calculation_request(creditcard, options), options)
end
capture(money, authorization, options = {}) click to toggle source

Capture an authorization that has previously been requested

# File lib/active_merchant/billing/gateways/cyber_source.rb, line 131
def capture(money, authorization, options = {})
  setup_address_hash(options)
  commit(build_capture_request(money, authorization, options), options)
end
credit(money, reference, options = {}) click to toggle source

Adds credit to a subscription (stand alone credit).

# File lib/active_merchant/billing/gateways/cyber_source.rb, line 154
def credit(money, reference, options = {})
  requires!(options, :order_id)
  commit(build_credit_request(money, reference, options), options)
end
purchase(money, payment_method_or_reference, options = {}) click to toggle source

Purchase is an auth followed by a capture You must supply an order_id in the options hash options => true # attempts to process as pinless debit card

# File lib/active_merchant/billing/gateways/cyber_source.rb, line 139
def purchase(money, payment_method_or_reference, options = {})
  requires!(options, :order_id)
  setup_address_hash(options)
  commit(build_purchase_request(money, payment_method_or_reference, options), options)
end
refund(money, identification, options = {}) click to toggle source
# File lib/active_merchant/billing/gateways/cyber_source.rb, line 149
def refund(money, identification, options = {})
  commit(build_refund_request(money, identification, options), options)
end
retrieve(reference, options = {}) click to toggle source

Retrieves a customer subscription/profile

# File lib/active_merchant/billing/gateways/cyber_source.rb, line 182
def retrieve(reference, options = {})
  requires!(options, :order_id)
  commit(build_retrieve_subscription_request(reference, options), options)
end
store(payment_method, options = {}) click to toggle source

Stores a customer subscription/profile with type “on-demand”. To charge the card while creating a profile, pass options => money

# File lib/active_merchant/billing/gateways/cyber_source.rb, line 162
def store(payment_method, options = {})
  requires!(options, :order_id)
  setup_address_hash(options)
  commit(build_create_subscription_request(payment_method, options), options)
end
unstore(reference, options = {}) click to toggle source

Removes a customer subscription/profile

# File lib/active_merchant/billing/gateways/cyber_source.rb, line 176
def unstore(reference, options = {})
  requires!(options, :order_id)
  commit(build_delete_subscription_request(reference, options), options)
end
update(reference, creditcard, options = {}) click to toggle source

Updates a customer subscription/profile

# File lib/active_merchant/billing/gateways/cyber_source.rb, line 169
def update(reference, creditcard, options = {})
  requires!(options, :order_id)
  setup_address_hash(options)
  commit(build_update_subscription_request(reference, creditcard, options), options)
end
validate_pinless_debit_card(creditcard, options = {}) click to toggle source

Determines if a card can be used for Pinless Debit Card transactions

# File lib/active_merchant/billing/gateways/cyber_source.rb, line 220
def validate_pinless_debit_card(creditcard, options = {})
  requires!(options, :order_id)
  commit(build_validate_pinless_debit_request(creditcard,options), options)
end
void(identification, options = {}) click to toggle source
# File lib/active_merchant/billing/gateways/cyber_source.rb, line 145
def void(identification, options = {})
  commit(build_void_request(identification, options), options)
end

Private Instance Methods

add_address(xml, payment_method, address, options, shipTo = false) click to toggle source
# File lib/active_merchant/billing/gateways/cyber_source.rb, line 414
def add_address(xml, payment_method, address, options, shipTo = false)
  xml.tag! shipTo ? 'shipTo' : 'billTo' do
    xml.tag! 'firstName',             payment_method.first_name             if payment_method
    xml.tag! 'lastName',              payment_method.last_name              if payment_method
    xml.tag! 'street1',               address[:address1]
    xml.tag! 'street2',               address[:address2]                unless address[:address2].blank?
    xml.tag! 'city',                  address[:city]
    xml.tag! 'state',                 address[:state]
    xml.tag! 'postalCode',            address[:zip]
    xml.tag! 'country',               address[:country]
    xml.tag! 'company',               address[:company]                 unless address[:company].blank?
    xml.tag! 'companyTaxID',          address[:companyTaxID]            unless address[:company_tax_id].blank?
    xml.tag! 'phoneNumber',           address[:phone]                   unless address[:phone].blank?
    xml.tag! 'email',                 options[:email]
    xml.tag! 'driversLicenseNumber',  options[:drivers_license_number]  unless options[:drivers_license_number].blank?
    xml.tag! 'driversLicenseState',   options[:drivers_license_state]   unless options[:drivers_license_state].blank?
  end
end
add_auth_reversal_service(xml, request_id, request_token) click to toggle source
# File lib/active_merchant/billing/gateways/cyber_source.rb, line 527
def add_auth_reversal_service(xml, request_id, request_token)
  xml.tag! 'ccAuthReversalService', {'run' => 'true'} do
    xml.tag! 'authRequestID', request_id
    xml.tag! 'authRequestToken', request_token
  end
end
add_auth_service(xml, payment_method_or_reference, options) click to toggle source
# File lib/active_merchant/billing/gateways/cyber_source.rb, line 458
def add_auth_service(xml, payment_method_or_reference, options)
  if token_based_card?(payment_method_or_reference, options)
    # Sadly, for each type of card there is different rules on how to send this
    # See http://apps.cybersource.com/library/documentation/dev_guides/tokenization/Tokenization.pdf
    if card_brand(payment_method_or_reference) == 'visa'
      xml.tag! 'ccAuthService', {'run' => 'true'} do
        # Cryptogram for payment network tokenization transactions. The value for this field must be 28-character base64 or 40-character hex binary
        xml.tag! 'cavv', options[:cryptogram]
        # Type of payer authentication fields that are being used for the payment network tokenization transaction
        xml.tag! 'commerceIndicator', 'vbv' # Verified by Visa
        # Cryptogram for payment network tokenization transactions. The value for this field must be 28-character base64 or 40-character hex binary
        xml.tag! 'xid', options[:cryptogram]
      end
    elsif card_brand(payment_method_or_reference) == 'master'
      xml.tag! 'ucaf' do
        # Cryptogram for payment network tokenization transactions with MasterCard
        xml.tag! 'authenticationData', options[:cryptogram]
        # Required field for payment network tokenization transactions with MasterCard
        xml.tag! 'collectionIndicator', '2'
      end
      xml.tag! 'ccAuthService', {'run' => 'true'} do
        # Type of payer authentication fields that are being used for the payment network tokenization transaction
        xml.tag! 'commerceIndicator', 'spa' # MasterCard SecureCode
      end
    elsif card_brand(payment_method_or_reference) == 'american_express'
      # For the American Express card type, the cryptogram is a 40-byte binary value that
      # you must split into two 20-byte binary values (block A and block B). Send the first
      # 20-byte value (block A) in the cardholder authentication verification value (CAVV)
      # field. Send the second 20-byte value (block B) in the transaction ID (XID) field.
      # The incoming cryptogram is base64 encoded, so we first decode it, then split it
      # then re-encode it for transmission (chomping off a trailing newline ruby adds).
      base64_decoded_cryptogram = Base64.decode64(options[:cryptogram])
      block_a                   = base64_decoded_cryptogram[0, 20]
      block_b                   = base64_decoded_cryptogram[20, 20]
      xml.tag! 'ccAuthService', {'run' => 'true'} do
        xml.tag! 'cavv', Base64.encode64(block_a).chomp
        # Type of payer authentication fields that are being used for the payment network tokenization transaction
        xml.tag! 'commerceIndicator', 'aesk' # American Express SafeKey
        xml.tag! 'xid', Base64.encode64(block_b).chomp
      end
    end
  else
    xml.tag! 'ccAuthService', {'run' => 'true'}
  end
end
add_business_rules_data(xml) click to toggle source
# File lib/active_merchant/billing/gateways/cyber_source.rb, line 380
def add_business_rules_data(xml)
  xml.tag! 'businessRules' do
    xml.tag!('ignoreAVSResult', 'true') if @options[:ignore_avs]
    xml.tag!('ignoreCVResult', 'true') if @options[:ignore_cvv]
  end
end
add_capture_service(xml, request_id, request_token) click to toggle source
# File lib/active_merchant/billing/gateways/cyber_source.rb, line 504
def add_capture_service(xml, request_id, request_token)
  xml.tag! 'ccCaptureService', {'run' => 'true'} do
    xml.tag! 'authRequestID', request_id
    xml.tag! 'authRequestToken', request_token
  end
end
add_check(xml, check) click to toggle source
# File lib/active_merchant/billing/gateways/cyber_source.rb, line 443
def add_check(xml, check)
  xml.tag! 'check' do
    xml.tag! 'accountNumber', check.account_number
    xml.tag! 'accountType', check.account_type[0]
    xml.tag! 'bankTransitNumber', check.routing_number
  end
end
add_check_payment_method(xml) click to toggle source
# File lib/active_merchant/billing/gateways/cyber_source.rb, line 589
def add_check_payment_method(xml)
  xml.tag! 'subscription' do
    xml.tag! 'paymentMethod', "check"
  end
end
add_check_service(xml) click to toggle source
# File lib/active_merchant/billing/gateways/cyber_source.rb, line 541
def add_check_service(xml)
  xml.tag! 'ecDebitService', {'run' => 'true'}
end
add_credit_service(xml, request_id = nil, request_token = nil) click to toggle source
# File lib/active_merchant/billing/gateways/cyber_source.rb, line 534
def add_credit_service(xml, request_id = nil, request_token = nil)
  xml.tag! 'ccCreditService', {'run' => 'true'} do
    xml.tag! 'captureRequestID', request_id if request_id
    xml.tag! 'captureRequestToken', request_token if request_token
  end
end
add_creditcard(xml, creditcard) click to toggle source
# File lib/active_merchant/billing/gateways/cyber_source.rb, line 433
def add_creditcard(xml, creditcard)
  xml.tag! 'card' do
    xml.tag! 'accountNumber', creditcard.number
    xml.tag! 'expirationMonth', format(creditcard.month, :two_digits)
    xml.tag! 'expirationYear', format(creditcard.year, :four_digits)
    xml.tag!('cvNumber', creditcard.verification_value) unless (@options[:ignore_cvv] || creditcard.verification_value.blank? )
    xml.tag! 'cardType', @@credit_card_codes[card_brand(creditcard).to_sym]
  end
end
add_creditcard_payment_method(xml) click to toggle source
# File lib/active_merchant/billing/gateways/cyber_source.rb, line 583
def add_creditcard_payment_method(xml)
  xml.tag! 'subscription' do
    xml.tag! 'paymentMethod', "credit card"
  end
end
add_line_item_data(xml, options) click to toggle source
# File lib/active_merchant/billing/gateways/cyber_source.rb, line 387
def add_line_item_data(xml, options)
  options[:line_items].each_with_index do |value, index|
    xml.tag! 'item', {'id' => index} do
      xml.tag! 'unitPrice', amount(value[:declared_value])
      xml.tag! 'quantity', value[:quantity]
      xml.tag! 'productCode', value[:code] || 'shipping_only'
      xml.tag! 'productName', value[:description]
      xml.tag! 'productSKU', value[:sku]
    end
  end
end
add_merchant_data(xml, options) click to toggle source
# File lib/active_merchant/billing/gateways/cyber_source.rb, line 399
def add_merchant_data(xml, options)
  xml.tag! 'merchantID', @options[:login]
  xml.tag! 'merchantReferenceCode', options[:order_id]
  xml.tag! 'clientLibrary' ,'Ruby Active Merchant'
  xml.tag! 'clientLibraryVersion',  VERSION
  xml.tag! 'clientEnvironment' , RUBY_PLATFORM
end
add_network_token(xml, payment_method_or_reference, options) click to toggle source
# File lib/active_merchant/billing/gateways/cyber_source.rb, line 615
def add_network_token(xml, payment_method_or_reference, options)
  xml.tag! 'paymentNetworkToken' do
    # Type of transaction that provided the token data. This value does not specify the token
    # service provider; it specifies the entity that provided you with information about the token.
    # 1: In-app transaction.
    #    An application on the customer’s mobile device provided the
    #    token data for an e-commerce transaction.
    #    For recurring transactions, use this value if the original transaction was an in-app
    #    e-commerce transaction.
    # See http://apps.cybersource.com/library/documentation/dev_guides/tokenization/Tokenization.pdf
    xml.tag! 'transactionType', '1'
  end
end
add_payment_method_or_subscription(xml, money, payment_method_or_reference, options) click to toggle source
# File lib/active_merchant/billing/gateways/cyber_source.rb, line 595
def add_payment_method_or_subscription(xml, money, payment_method_or_reference, options)
  if payment_method_or_reference.is_a?(String)
    add_purchase_data(xml, money, true, options)
    add_subscription(xml, options, payment_method_or_reference)
  elsif card_brand(payment_method_or_reference) == 'check'
    add_address(xml, payment_method_or_reference, options[:billing_address], options)
    add_purchase_data(xml, money, true, options)
    add_check(xml, payment_method_or_reference)
  else
    add_address(xml, payment_method_or_reference, options[:billing_address], options)
    add_address(xml, payment_method_or_reference, options[:shipping_address], options, true)
    add_purchase_data(xml, money, true, options)
    add_creditcard(xml, payment_method_or_reference)
  end
end
add_purchase_data(xml, money = 0, include_grand_total = false, options={}) click to toggle source
# File lib/active_merchant/billing/gateways/cyber_source.rb, line 407
def add_purchase_data(xml, money = 0, include_grand_total = false, options={})
  xml.tag! 'purchaseTotals' do
    xml.tag! 'currency', options[:currency] || currency(money)
    xml.tag!('grandTotalAmount', amount(money))  if include_grand_total
  end
end
add_purchase_service(xml, payment_method_or_reference, options) click to toggle source
# File lib/active_merchant/billing/gateways/cyber_source.rb, line 511
def add_purchase_service(xml, payment_method_or_reference, options)
  if options[:pinless_debit_card]
    xml.tag! 'pinlessDebitService', {'run' => 'true'}
  else
    add_auth_service(xml, payment_method_or_reference, options)
    xml.tag! 'ccCaptureService', {'run' => 'true'}
  end
end
add_subscription(xml, options, reference = nil) click to toggle source
# File lib/active_merchant/billing/gateways/cyber_source.rb, line 561
def add_subscription(xml, options, reference = nil)
  options[:subscription] ||= {}

  xml.tag! 'recurringSubscriptionInfo' do
    if reference
      _, subscription_id, _ = reference.split(";")
      xml.tag! 'subscriptionID',  subscription_id
    end

    xml.tag! 'status',            options[:subscription][:status]                         if options[:subscription][:status]
    xml.tag! 'amount',            amount(options[:subscription][:amount])                 if options[:subscription][:amount]
    xml.tag! 'numberOfPayments',  options[:subscription][:occurrences]                    if options[:subscription][:occurrences]
    xml.tag! 'automaticRenew',    options[:subscription][:automatic_renew]                if options[:subscription][:automatic_renew]
    xml.tag! 'frequency',         options[:subscription][:frequency]                      if options[:subscription][:frequency]
    xml.tag! 'startDate',         options[:subscription][:start_date].strftime("%Y%m%d")  if options[:subscription][:start_date]
    xml.tag! 'endDate',           options[:subscription][:end_date].strftime("%Y%m%d")    if options[:subscription][:end_date]
    xml.tag! 'approvalRequired',  options[:subscription][:approval_required] || false
    xml.tag! 'event',             options[:subscription][:event]                          if options[:subscription][:event]
    xml.tag! 'billPayment',       options[:subscription][:bill_payment]                   if options[:subscription][:bill_payment]
  end
end
add_subscription_create_service(xml, options) click to toggle source
# File lib/active_merchant/billing/gateways/cyber_source.rb, line 545
def add_subscription_create_service(xml, options)
  xml.tag! 'paySubscriptionCreateService', {'run' => 'true'}
end
add_subscription_delete_service(xml, options) click to toggle source
# File lib/active_merchant/billing/gateways/cyber_source.rb, line 553
def add_subscription_delete_service(xml, options)
  xml.tag! 'paySubscriptionDeleteService', {'run' => 'true'}
end
add_subscription_retrieve_service(xml, options) click to toggle source
# File lib/active_merchant/billing/gateways/cyber_source.rb, line 557
def add_subscription_retrieve_service(xml, options)
  xml.tag! 'paySubscriptionRetrieveService', {'run' => 'true'}
end
add_subscription_update_service(xml, options) click to toggle source
# File lib/active_merchant/billing/gateways/cyber_source.rb, line 549
def add_subscription_update_service(xml, options)
  xml.tag! 'paySubscriptionUpdateService', {'run' => 'true'}
end
add_tax_service(xml) click to toggle source
# File lib/active_merchant/billing/gateways/cyber_source.rb, line 451
def add_tax_service(xml)
  xml.tag! 'taxService', {'run' => 'true'} do
    xml.tag!('nexus', @options[:nexus]) unless @options[:nexus].blank?
    xml.tag!('sellerRegistration', @options[:vat_reg_number]) unless @options[:vat_reg_number].blank?
  end
end
add_validate_pinless_debit_service(xml) click to toggle source
# File lib/active_merchant/billing/gateways/cyber_source.rb, line 611
def add_validate_pinless_debit_service(xml)
  xml.tag!'pinlessDebitValidateService', {'run' => 'true'}
end
add_void_service(xml, request_id, request_token) click to toggle source
# File lib/active_merchant/billing/gateways/cyber_source.rb, line 520
def add_void_service(xml, request_id, request_token)
  xml.tag! 'voidService', {'run' => 'true'} do
    xml.tag! 'voidRequestID', request_id
    xml.tag! 'voidRequestToken', request_token
  end
end
build_auth_request(money, creditcard_or_reference, options) click to toggle source
# File lib/active_merchant/billing/gateways/cyber_source.rb, line 234
def build_auth_request(money, creditcard_or_reference, options)
  xml = Builder::XmlMarkup.new :indent => 2
  add_payment_method_or_subscription(xml, money, creditcard_or_reference, options)
  add_auth_service(xml, creditcard_or_reference, options)
  add_business_rules_data(xml)
  add_network_token(xml, creditcard_or_reference, options) if token_based_card?(creditcard_or_reference, options)
  xml.target!
end
build_auth_reversal_request(money, identification, options) click to toggle source
# File lib/active_merchant/billing/gateways/cyber_source.rb, line 287
def build_auth_reversal_request(money, identification, options)
  order_id, request_id, request_token = identification.split(";")
  options[:order_id] = order_id
  xml = Builder::XmlMarkup.new :indent => 2
  add_purchase_data(xml, money, true, options)
  add_auth_reversal_service(xml, request_id, request_token)
  xml.target!
end
build_capture_request(money, authorization, options) click to toggle source
# File lib/active_merchant/billing/gateways/cyber_source.rb, line 254
def build_capture_request(money, authorization, options)
  order_id, request_id, request_token = authorization.split(";")
  options[:order_id] = order_id

  xml = Builder::XmlMarkup.new :indent => 2
  add_purchase_data(xml, money, true, options)
  add_capture_service(xml, request_id, request_token)
  add_business_rules_data(xml)
  xml.target!
end
build_create_subscription_request(payment_method, options) click to toggle source
# File lib/active_merchant/billing/gateways/cyber_source.rb, line 317
def build_create_subscription_request(payment_method, options)
  default_subscription_params = {:frequency => "on-demand", :amount => 0, :automatic_renew => false}
  options[:subscription] = default_subscription_params.update(
    options[:subscription] || {}
  )

  xml = Builder::XmlMarkup.new :indent => 2
  add_address(xml, payment_method, options[:billing_address], options)
  add_purchase_data(xml, options[:setup_fee] || 0, true, options)
  if card_brand(payment_method) == 'check'
    add_check(xml, payment_method)
    add_check_payment_method(xml)
  else
    add_creditcard(xml, payment_method)
    add_creditcard_payment_method(xml)
  end
  add_subscription(xml, options)
  if options[:setup_fee]
    if card_brand(payment_method) == 'check'
      add_check_service(xml, options)
    else
      add_purchase_service(xml, payment_method, options)
    end
  end
  add_subscription_create_service(xml, options)
  add_business_rules_data(xml)
  add_network_token(xml, payment_method, options) if options[:setup_fee] and token_based_card?(payment_method, options)
  xml.target!
end
build_credit_request(money, reference, options) click to toggle source
# File lib/active_merchant/billing/gateways/cyber_source.rb, line 307
def build_credit_request(money, reference, options)
  xml = Builder::XmlMarkup.new :indent => 2

  add_purchase_data(xml, money, true, options)
  add_subscription(xml, options, reference)
  add_credit_service(xml)

  xml.target!
end
build_delete_subscription_request(reference, options) click to toggle source
# File lib/active_merchant/billing/gateways/cyber_source.rb, line 359
def build_delete_subscription_request(reference, options)
  xml = Builder::XmlMarkup.new :indent => 2
  add_subscription(xml, options, reference)
  add_subscription_delete_service(xml, options)
  xml.target!
end
build_purchase_request(money, payment_method_or_reference, options) click to toggle source
# File lib/active_merchant/billing/gateways/cyber_source.rb, line 265
def build_purchase_request(money, payment_method_or_reference, options)
  xml = Builder::XmlMarkup.new :indent => 2
  add_payment_method_or_subscription(xml, money, payment_method_or_reference, options)
  if !payment_method_or_reference.is_a?(String) && card_brand(payment_method_or_reference) == 'check'
    add_check_service(xml)
  else
    add_purchase_service(xml, payment_method_or_reference, options)
    add_business_rules_data(xml) unless options[:pinless_debit_card]
    add_network_token(xml, payment_method_or_reference, options) if token_based_card?(payment_method_or_reference, options)
  end
  xml.target!
end
build_refund_request(money, identification, options) click to toggle source
# File lib/active_merchant/billing/gateways/cyber_source.rb, line 296
def build_refund_request(money, identification, options)
  order_id, request_id, request_token = identification.split(";")
  options[:order_id] = order_id

  xml = Builder::XmlMarkup.new :indent => 2
  add_purchase_data(xml, money, true, options)
  add_credit_service(xml, request_id, request_token)

  xml.target!
end
build_request(body, options) click to toggle source

Where we actually build the full SOAP request using builder

# File lib/active_merchant/billing/gateways/cyber_source.rb, line 634
def build_request(body, options)
  xml = Builder::XmlMarkup.new :indent => 2
    xml.instruct!
    xml.tag! 's:Envelope', {'xmlns:s' => 'http://schemas.xmlsoap.org/soap/envelope/'} do
      xml.tag! 's:Header' do
        xml.tag! 'wsse:Security', {'s:mustUnderstand' => '1', 'xmlns:wsse' => 'http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd'} do
          xml.tag! 'wsse:UsernameToken' do
            xml.tag! 'wsse:Username', @options[:login]
            xml.tag! 'wsse:Password', @options[:password], 'Type' => 'http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText'
          end
        end
      end
      xml.tag! 's:Body', {'xmlns:xsi' => 'http://www.w3.org/2001/XMLSchema-instance', 'xmlns:xsd' => 'http://www.w3.org/2001/XMLSchema'} do
        xml.tag! 'requestMessage', {'xmlns' => "urn:schemas-cybersource-com:transaction-data-#{XSD_VERSION}"} do
          add_merchant_data(xml, options)
          xml << body
        end
      end
    end
  xml.target!
end
build_retrieve_subscription_request(reference, options) click to toggle source
# File lib/active_merchant/billing/gateways/cyber_source.rb, line 366
def build_retrieve_subscription_request(reference, options)
  xml = Builder::XmlMarkup.new :indent => 2
  add_subscription(xml, options, reference)
  add_subscription_retrieve_service(xml, options)
  xml.target!
end
build_tax_calculation_request(creditcard, options) click to toggle source
# File lib/active_merchant/billing/gateways/cyber_source.rb, line 243
def build_tax_calculation_request(creditcard, options)
  xml = Builder::XmlMarkup.new :indent => 2
  add_address(xml, creditcard, options[:billing_address], options, false)
  add_address(xml, creditcard, options[:shipping_address], options, true)
  add_line_item_data(xml, options)
  add_purchase_data(xml, 0, false, options)
  add_tax_service(xml)
  add_business_rules_data(xml)
  xml.target!
end
build_update_subscription_request(reference, creditcard, options) click to toggle source
# File lib/active_merchant/billing/gateways/cyber_source.rb, line 347
def build_update_subscription_request(reference, creditcard, options)
  xml = Builder::XmlMarkup.new :indent => 2
  add_address(xml, creditcard, options[:billing_address], options) unless options[:billing_address].blank?
  add_purchase_data(xml, options[:setup_fee], true, options) unless options[:setup_fee].blank?
  add_creditcard(xml, creditcard)    if creditcard
  add_creditcard_payment_method(xml) if creditcard
  add_subscription(xml, options, reference)
  add_subscription_update_service(xml, options)
  add_business_rules_data(xml)
  xml.target!
end
build_validate_pinless_debit_request(creditcard,options) click to toggle source
# File lib/active_merchant/billing/gateways/cyber_source.rb, line 373
def build_validate_pinless_debit_request(creditcard,options)
  xml = Builder::XmlMarkup.new :indent => 2
  add_creditcard(xml, creditcard)
  add_validate_pinless_debit_service(xml)
  xml.target!
end
build_void_request(identification, options) click to toggle source
# File lib/active_merchant/billing/gateways/cyber_source.rb, line 278
def build_void_request(identification, options)
  order_id, request_id, request_token = identification.split(";")
  options[:order_id] = order_id

  xml = Builder::XmlMarkup.new :indent => 2
  add_void_service(xml, request_id, request_token)
  xml.target!
end
commit(request, options) click to toggle source

Contact CyberSource, make the SOAP request, and parse the reply into a Response object

# File lib/active_merchant/billing/gateways/cyber_source.rb, line 658
def commit(request, options)
  response = parse(ssl_post(test? ? self.test_url : self.live_url, build_request(request, options)))

  success = response[:decision] == "ACCEPT"
  message = @@response_codes[('r' + response[:reasonCode]).to_sym] rescue response[:message]
  authorization = success ? [ options[:order_id], response[:requestID], response[:requestToken] ].compact.join(";") : nil

  Response.new(success, message, response,
    :test => test?,
    :authorization => authorization,
    :avs_result => { :code => response[:avsCode] },
    :cvv_result => response[:cvCode]
  )
end
parse(xml) click to toggle source

Parse the SOAP response Technique inspired by the Paypal Gateway

# File lib/active_merchant/billing/gateways/cyber_source.rb, line 675
def parse(xml)
  reply = {}
  xml = REXML::Document.new(xml)
  if root = REXML::XPath.first(xml, "//c:replyMessage")
    root.elements.to_a.each do |node|
      case node.name
      when 'c:reasonCode'
        reply[:message] = reply(node.text)
      else
        parse_element(reply, node)
      end
    end
  elsif root = REXML::XPath.first(xml, "//soap:Fault")
    parse_element(reply, root)
    reply[:message] = "#{reply[:faultcode]}: #{reply[:faultstring]}"
  end
  return reply
end
parse_element(reply, node) click to toggle source
# File lib/active_merchant/billing/gateways/cyber_source.rb, line 694
def parse_element(reply, node)
  if node.has_elements?
    node.elements.each{|e| parse_element(reply, e) }
  else
    if node.parent.name =~ /item/
      parent = node.parent.name + (node.parent.attributes["id"] ? "_" + node.parent.attributes["id"] : '')
      reply[(parent + '_' + node.name).to_sym] = node.text
    else
      reply[node.name.to_sym] = node.text
    end
  end
  return reply
end
setup_address_hash(options) click to toggle source

Create all address hash key value pairs so that we still function if we were only provided with one or two of them

# File lib/active_merchant/billing/gateways/cyber_source.rb, line 229
def setup_address_hash(options)
  options[:billing_address] = options[:billing_address] || options[:address] || {}
  options[:shipping_address] = options[:shipping_address] || {}
end
token_based_card?(payment_method_or_reference, options) click to toggle source
# File lib/active_merchant/billing/gateways/cyber_source.rb, line 629
def token_based_card?(payment_method_or_reference, options)
  !payment_method_or_reference.is_a?(String) && card_brand(payment_method_or_reference) && options[:cryptogram]
end