class ActiveMerchant::Billing::CyberSourceGateway
Initial setup instructions can be found in apps.cybersource.com/library/documentation/dev_guides/SOAP_Toolkits/SOAP_toolkits.pdf
Important Notes
-
For checks you can purchase and store.
-
AVS and CVV only work against the production server. You will always get back X for AVS and no response for CVV against the test server.
-
Nexus is the list of states or provinces where you have a physical presence. Nexus is used to calculate tax. Leave blank to tax everyone.
-
If you want to calculate VAT for overseas customers you must supply a registration number in the options hash as vat_reg_number.
-
productCode is a value in the line_items hash that is used to tell CyberSource what kind of item you are selling. It is used when calculating tax/VAT.
-
All transactions use dollar values.
-
To process pinless debit cards through the pinless debit card network, your Cybersource merchant account must accept pinless debit card payments.
-
The order of the XML elements does matter, make sure to follow the order in the documentation exactly.
Constants
- PRODUCTION_XSD_VERSION
- TEST_XSD_VERSION
Schema files can be found here: ics2ws.ic3.com/commerce/1.x/transactionProcessor/
Public Class Methods
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
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
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 207 def calculate_tax(creditcard, options) requires!(options, :line_items) setup_address_hash(options) commit(build_tax_calculation_request(creditcard, options), :calculate_tax, nil, options) end
# File lib/active_merchant/billing/gateways/cyber_source.rb, line 122 def capture(money, authorization, options = {}) setup_address_hash(options) commit(build_capture_request(money, authorization, options), :capture, money, options) end
Adds credit to a card or subscription (stand alone credit).
# File lib/active_merchant/billing/gateways/cyber_source.rb, line 149 def credit(money, creditcard_or_reference, options = {}) setup_address_hash(options) commit(build_credit_request(money, creditcard_or_reference, options), :credit, money, options) end
options => true # attempts to process as pinless debit card
# File lib/active_merchant/billing/gateways/cyber_source.rb, line 128 def purchase(money, payment_method_or_reference, options = {}) setup_address_hash(options) commit(build_purchase_request(money, payment_method_or_reference, options), :purchase, money, options) end
# File lib/active_merchant/billing/gateways/cyber_source.rb, line 137 def refund(money, identification, options = {}) commit(build_refund_request(money, identification, options), :refund, money, options) end
Retrieves a customer subscription/profile
# File lib/active_merchant/billing/gateways/cyber_source.rb, line 176 def retrieve(reference, options = {}) requires!(options, :order_id) commit(build_retrieve_subscription_request(reference, options), :retrieve, nil, options) end
# File lib/active_merchant/billing/gateways/cyber_source.rb, line 223 def scrub(transcript) transcript. gsub(%r((<wsse:Password [^>]*>)[^<]*(</wsse:Password>))i, '\1[FILTERED]\2'). gsub(%r((<accountNumber>)[^<]*(</accountNumber>))i, '\1[FILTERED]\2'). gsub(%r((<cvNumber>)[^<]*(</cvNumber>))i, '\1[FILTERED]\2'). gsub(%r((<cavv>)[^<]*(</cavv>))i, '\1[FILTERED]\2'). gsub(%r((<xid>)[^<]*(</xid>))i, '\1[FILTERED]\2'). gsub(%r((<authenticationData>)[^<]*(</authenticationData>))i, '\1[FILTERED]\2') end
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 157 def store(payment_method, options = {}) setup_address_hash(options) commit(build_create_subscription_request(payment_method, options), :store, nil, options) end
# File lib/active_merchant/billing/gateways/cyber_source.rb, line 233 def supports_network_tokenization? true end
# File lib/active_merchant/billing/gateways/cyber_source.rb, line 219 def supports_scrubbing? true end
Removes a customer subscription/profile
# File lib/active_merchant/billing/gateways/cyber_source.rb, line 170 def unstore(reference, options = {}) requires!(options, :order_id) commit(build_delete_subscription_request(reference, options), :unstore, nil, options) end
Updates a customer subscription/profile
# File lib/active_merchant/billing/gateways/cyber_source.rb, line 163 def update(reference, creditcard, options = {}) requires!(options, :order_id) setup_address_hash(options) commit(build_update_subscription_request(reference, creditcard, options), :update, nil, options) end
Determines if a card can be used for Pinless Debit Card transactions
# File lib/active_merchant/billing/gateways/cyber_source.rb, line 214 def validate_pinless_debit_card(creditcard, options = {}) requires!(options, :order_id) commit(build_validate_pinless_debit_request(creditcard, options), :validate_pinless_debit_card, nil, options) end
# File lib/active_merchant/billing/gateways/cyber_source.rb, line 141 def verify(payment, options = {}) MultiResponse.run(:use_first_response) do |r| r.process { authorize(100, payment, options) } r.process(:ignore_result) { void(r.authorization, options) } end end
# File lib/active_merchant/billing/gateways/cyber_source.rb, line 237 def verify_credentials response = void('0') response.params['reasonCode'] == '102' end
# File lib/active_merchant/billing/gateways/cyber_source.rb, line 133 def void(identification, options = {}) commit(build_void_request(identification, options), :void, nil, options) end
Private Instance Methods
# File lib/active_merchant/billing/gateways/cyber_source.rb, line 455 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', lookup_country_code(address[:country]) unless address[:country].blank? 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] || 'null@cybersource.com' xml.tag! 'ipAddress', options[:ip] unless options[:ip].blank? || shipTo 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
# File lib/active_merchant/billing/gateways/cyber_source.rb, line 557 def add_auth_network_tokenization(xml, payment_method, options) return unless network_tokenization?(payment_method) case card_brand(payment_method).to_sym when :visa xml.tag! 'ccAuthService', {'run' => 'true'} do xml.tag!('cavv', payment_method.payment_cryptogram) xml.tag!('commerceIndicator', 'vbv') xml.tag!('xid', payment_method.payment_cryptogram) end when :master xml.tag! 'ucaf' do xml.tag!('authenticationData', payment_method.payment_cryptogram) xml.tag!('collectionIndicator', '2') end xml.tag! 'ccAuthService', {'run' => 'true'} do xml.tag!('commerceIndicator', 'spa') end when :american_express cryptogram = Base64.decode64(payment_method.payment_cryptogram) xml.tag! 'ccAuthService', {'run' => 'true'} do xml.tag!('cavv', Base64.encode64(cryptogram[0...20])) xml.tag!('commerceIndicator', 'aesk') xml.tag!('xid', Base64.encode64(cryptogram[20...40])) end end end
# File lib/active_merchant/billing/gateways/cyber_source.rb, line 614 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
# File lib/active_merchant/billing/gateways/cyber_source.rb, line 528 def add_auth_service(xml, payment_method, options) if network_tokenization?(payment_method) add_auth_network_tokenization(xml, payment_method, options) else xml.tag! 'ccAuthService', {'run' => 'true'} do check_for_stored_cred_commerce_indicator(xml, options) end end end
# File lib/active_merchant/billing/gateways/cyber_source.rb, line 410 def add_business_rules_data(xml, payment_method, options) prioritized_options = [options, @options] unless network_tokenization?(payment_method) xml.tag! 'businessRules' do xml.tag!('ignoreAVSResult', 'true') if extract_option(prioritized_options, :ignore_avs) xml.tag!('ignoreCVResult', 'true') if extract_option(prioritized_options, :ignore_cvv) end end end
# File lib/active_merchant/billing/gateways/cyber_source.rb, line 591 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
# File lib/active_merchant/billing/gateways/cyber_source.rb, line 513 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
# File lib/active_merchant/billing/gateways/cyber_source.rb, line 676 def add_check_payment_method(xml) xml.tag! 'subscription' do xml.tag! 'paymentMethod', 'check' end end
# File lib/active_merchant/billing/gateways/cyber_source.rb, line 628 def add_check_service(xml) xml.tag! 'ecDebitService', {'run' => 'true'} end
# File lib/active_merchant/billing/gateways/cyber_source.rb, line 621 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
# File lib/active_merchant/billing/gateways/cyber_source.rb, line 475 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
# File lib/active_merchant/billing/gateways/cyber_source.rb, line 670 def add_creditcard_payment_method(xml) xml.tag! 'subscription' do xml.tag! 'paymentMethod', 'credit card' end end
# File lib/active_merchant/billing/gateways/cyber_source.rb, line 485 def add_decision_manager_fields(xml, options) return unless options[:decision_manager_enabled] xml.tag! 'decisionManager' do xml.tag! 'enabled', options[:decision_manager_enabled] if options[:decision_manager_enabled] xml.tag! 'profile', options[:decision_manager_profile] if options[:decision_manager_profile] end end
# File lib/active_merchant/billing/gateways/cyber_source.rb, line 494 def add_issuer_additional_data(xml, options) return unless options[:issuer_additional_data] xml.tag! 'issuer' do xml.tag! 'additionalData', options[:issuer_additional_data] end end
# File lib/active_merchant/billing/gateways/cyber_source.rb, line 428 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', localized_amount(value[:declared_value].to_i, options[:currency] || default_currency) 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
# File lib/active_merchant/billing/gateways/cyber_source.rb, line 502 def add_mdd_fields(xml, options) return unless options.keys.any? { |key| key.to_s.start_with?('mdd_field') } xml.tag! 'merchantDefinedData' do (1..100).each do |each| key = "mdd_field_#{each}".to_sym xml.tag!("field#{each}", options[key]) if options[key] end end end
# File lib/active_merchant/billing/gateways/cyber_source.rb, line 440 def add_merchant_data(xml, options) xml.tag! 'merchantID', @options[:login] xml.tag! 'merchantReferenceCode', options[:order_id] || generate_unique_id xml.tag! 'clientLibrary', 'Ruby Active Merchant' xml.tag! 'clientLibraryVersion', VERSION xml.tag! 'clientEnvironment', RUBY_PLATFORM end
# File lib/active_merchant/billing/gateways/cyber_source.rb, line 682 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
# File lib/active_merchant/billing/gateways/cyber_source.rb, line 585 def add_payment_network_token(xml) xml.tag! 'paymentNetworkToken' do xml.tag!('transactionType', '1') end end
# File lib/active_merchant/billing/gateways/cyber_source.rb, line 448 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', localized_amount(money.to_i, options[:currency] || default_currency)) if include_grand_total end end
# File lib/active_merchant/billing/gateways/cyber_source.rb, line 598 def add_purchase_service(xml, payment_method, options) if options[:pinless_debit_card] xml.tag! 'pinlessDebitService', {'run' => 'true'} else add_auth_service(xml, payment_method, options) xml.tag! 'ccCaptureService', {'run' => 'true'} end end
# File lib/active_merchant/billing/gateways/cyber_source.rb, line 716 def add_stored_credential_options(xml, options={}) return unless options[:stored_credential] if options[:stored_credential][:initial_transaction] xml.tag! 'subsequentAuthFirst', 'true' elsif options[:stored_credential][:reason_type] == 'unscheduled' xml.tag! 'subsequentAuth', 'true' xml.tag! 'subsequentAuthTransactionID', options[:stored_credential][:network_transaction_id] else xml.tag! 'subsequentAuthTransactionID', options[:stored_credential][:network_transaction_id] end end
# File lib/active_merchant/billing/gateways/cyber_source.rb, line 648 def add_subscription(xml, options, reference = nil) options[:subscription] ||= {} xml.tag! 'recurringSubscriptionInfo' do if reference subscription_id = reference.split(';')[6] xml.tag! 'subscriptionID', subscription_id end xml.tag! 'status', options[:subscription][:status] if options[:subscription][:status] xml.tag! 'amount', localized_amount(options[:subscription][:amount].to_i, options[:currency] || default_currency) 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
# File lib/active_merchant/billing/gateways/cyber_source.rb, line 632 def add_subscription_create_service(xml, options) xml.tag! 'paySubscriptionCreateService', {'run' => 'true'} end
# File lib/active_merchant/billing/gateways/cyber_source.rb, line 640 def add_subscription_delete_service(xml, options) xml.tag! 'paySubscriptionDeleteService', {'run' => 'true'} end
# File lib/active_merchant/billing/gateways/cyber_source.rb, line 644 def add_subscription_retrieve_service(xml, options) xml.tag! 'paySubscriptionRetrieveService', {'run' => 'true'} end
# File lib/active_merchant/billing/gateways/cyber_source.rb, line 636 def add_subscription_update_service(xml, options) xml.tag! 'paySubscriptionUpdateService', {'run' => 'true'} end
# File lib/active_merchant/billing/gateways/cyber_source.rb, line 521 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
# File lib/active_merchant/billing/gateways/cyber_source.rb, line 702 def add_threeds_services(xml, options) xml.tag! 'payerAuthEnrollService', {'run' => 'true'} if options[:payer_auth_enroll_service] if options[:payer_auth_validate_service] xml.tag! 'payerAuthValidateService', {'run' => 'true'} do xml.tag! 'signedPARes', options[:pares] end end end
# File lib/active_merchant/billing/gateways/cyber_source.rb, line 698 def add_validate_pinless_debit_service(xml) xml.tag! 'pinlessDebitValidateService', {'run' => 'true'} end
# File lib/active_merchant/billing/gateways/cyber_source.rb, line 607 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
# File lib/active_merchant/billing/gateways/cyber_source.rb, line 258 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_decision_manager_fields(xml, options) add_mdd_fields(xml, options) add_auth_service(xml, creditcard_or_reference, options) add_threeds_services(xml, options) add_payment_network_token(xml) if network_tokenization?(creditcard_or_reference) add_business_rules_data(xml, creditcard_or_reference, options) add_stored_credential_options(xml, options) add_issuer_additional_data(xml, options) xml.target! end
# File lib/active_merchant/billing/gateways/cyber_source.rb, line 284 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, authorization, options) xml.target! end
# File lib/active_merchant/billing/gateways/cyber_source.rb, line 347 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) else add_purchase_service(xml, payment_method, options) add_payment_network_token(xml) if network_tokenization?(payment_method) end end add_subscription_create_service(xml, options) add_business_rules_data(xml, payment_method, options) xml.target! end
# File lib/active_merchant/billing/gateways/cyber_source.rb, line 338 def build_credit_request(money, creditcard_or_reference, options) xml = Builder::XmlMarkup.new :indent => 2 add_payment_method_or_subscription(xml, money, creditcard_or_reference, options) add_credit_service(xml) xml.target! end
# File lib/active_merchant/billing/gateways/cyber_source.rb, line 389 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
# File lib/active_merchant/billing/gateways/cyber_source.rb, line 295 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) add_decision_manager_fields(xml, options) add_mdd_fields(xml, 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_threeds_services(xml, options) add_payment_network_token(xml) if network_tokenization?(payment_method_or_reference) add_business_rules_data(xml, payment_method_or_reference, options) unless options[:pinless_debit_card] end add_issuer_additional_data(xml, options) xml.target! end
# File lib/active_merchant/billing/gateways/cyber_source.rb, line 327 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
Where we actually build the full SOAP request using builder
# File lib/active_merchant/billing/gateways/cyber_source.rb, line 729 def build_request(body, options) xsd_version = test? ? TEST_XSD_VERSION : PRODUCTION_XSD_VERSION 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
# File lib/active_merchant/billing/gateways/cyber_source.rb, line 396 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
# File lib/active_merchant/billing/gateways/cyber_source.rb, line 273 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, creditcard, options) xml.target! end
# File lib/active_merchant/billing/gateways/cyber_source.rb, line 377 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, creditcard, options) xml.target! end
# File lib/active_merchant/billing/gateways/cyber_source.rb, line 403 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
# File lib/active_merchant/billing/gateways/cyber_source.rb, line 313 def build_void_request(identification, options) order_id, request_id, request_token, action, money, currency = identification.split(';') options[:order_id] = order_id xml = Builder::XmlMarkup.new :indent => 2 if action == 'capture' add_void_service(xml, request_id, request_token) else add_purchase_data(xml, money, true, options.merge(:currency => currency || default_currency)) add_auth_reversal_service(xml, request_id, request_token) end xml.target! end
# File lib/active_merchant/billing/gateways/cyber_source.rb, line 538 def check_for_stored_cred_commerce_indicator(xml, options) return unless options[:stored_credential] if commerce_indicator(options) xml.tag!('commerceIndicator', commerce_indicator(options)) end end
# File lib/active_merchant/billing/gateways/cyber_source.rb, line 545 def commerce_indicator(options) return if options[:stored_credential][:initial_transaction] case options[:stored_credential][:reason_type] when 'installment' then 'install' when 'recurring' then 'recurring' end end
Contact CyberSource, make the SOAP request, and parse the reply into a Response
object
# File lib/active_merchant/billing/gateways/cyber_source.rb, line 755 def commit(request, action, amount, options) begin raw_response = ssl_post(test? ? self.test_url : self.live_url, build_request(request, options)) rescue ResponseError => e raw_response = e.response.body end begin response = parse(raw_response) rescue REXML::ParseException => e response = { message: e.to_s } end success = response[:decision] == 'ACCEPT' message = response[:message] authorization = success ? authorization_from(response, action, amount, options) : nil Response.new(success, message, response, :test => test?, :authorization => authorization, :avs_result => { :code => response[:avsCode] }, :cvv_result => response[:cvCode] ) end
# File lib/active_merchant/billing/gateways/cyber_source.rb, line 421 def extract_option(prioritized_options, option_name) options_matching_key = prioritized_options.detect do |options| options.has_key? option_name end options_matching_key[option_name] if options_matching_key end
# File lib/active_merchant/billing/gateways/cyber_source.rb, line 711 def lookup_country_code(country_field) country_code = Country.find(country_field) rescue nil country_code&.code(:alpha2) end
# File lib/active_merchant/billing/gateways/cyber_source.rb, line 553 def network_tokenization?(payment_method) payment_method.is_a?(NetworkTokenizationCreditCard) end
Parse the SOAP response Technique inspired by the Paypal Gateway
# File lib/active_merchant/billing/gateways/cyber_source.rb, line 783 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.expanded_name when 'c:reasonCode' reply[:reasonCode] = node.text reply[:message] = reason_message(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
# File lib/active_merchant/billing/gateways/cyber_source.rb, line 803 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 parent += '_' + node.parent.attributes['id'] if node.parent.attributes['id'] parent += '_' end reply["#{parent}#{node.name}".to_sym] ||= node.text end return reply end
# File lib/active_merchant/billing/gateways/cyber_source.rb, line 817 def reason_message(reason_code) return if reason_code.blank? @@response_codes[:"r#{reason_code}"] end
Create all address hash key value pairs so that we still function if we were only provided with one or two of them or even none
# File lib/active_merchant/billing/gateways/cyber_source.rb, line 246 def setup_address_hash(options) default_address = { :address1 => 'Unspecified', :city => 'Unspecified', :state => 'NC', :zip => '00000', :country => 'US' } options[:billing_address] = options[:billing_address] || options[:address] || default_address options[:shipping_address] = options[:shipping_address] || {} end