Level 2 and 3 Processing

Required Fieldsanchor

Level 2 dataanchor

To qualify for Level 2 processing on a given transaction, you should include the following fields in the Transaction: Sale call:

Interchange rates for Level 2 dataanchor

The values passed in the required Level 2 fields will determine whether you then qualify for lower interchange rates. In most cases, you will need to pass a tax_amount of 0.1%-22% for Visa transactions, and 0.1%-30% for Mastercard transactions.

tax_exempt transactions will not qualify for reduced rates.

Creating a transactionanchor

Below is a full example using the required fields for Level 2:

  1. Ruby
result = gateway.transaction.sale(
  :amount => "100.00",
  :payment_method_nonce => nonce_from_the_client,
  :purchase_order_number => "12345",
  :tax_amount => "5.00"
)

Level 3 dataanchor

To qualify for Level 3 processing on a given transaction, you must pass Level 2 data, along with specific additional Level 3 data and line items. Line items are similar to the details you would find on an itemized invoice.

Each time you create a transaction, include the following fields in the Transaction: Sale call:

Supported charactersanchor

To ensure all line items appear as expected on the cardholder's statement, use only a-z, A-Z, 0-9, ', ., -, and spaces in the following fields:

Line items that contain other characters may still qualify for Level 3 processing, but unsupported characters will be converted to a space on the cardholder's statement.

Amount validationanchor

Each processor validates that the sum of line item amounts matches the root transaction, and they may decline the transaction if a mismatch occurs. To reliably ensure these amounts match, it's a good idea to sum the per-item tax and subtotal amounts to calculate the total transaction amounts. Below is an example for doing so in Ruby.

  1. Ruby
currency = "USD"

# Calculate subtotal and tax amount
subtotal_amount = 0
tax_amount = 0
line_items = items.map do |item|
  item_subtotal_amount = item.unit_amount * item.quantity
  item_tax_amount = item.unit_tax_amount * item.quantity

  if item.kind == "debit"
    subtotal_amount += item_subtotal_amount
    tax_amount += item_tax_amount
  else
    subtotal_amount -= item_subtotal_amount
    tax_amount -= item_tax_amount
  end

  {
    :quantity => item.quantity,
    :name => item.name,
    :kind => item.kind,
    :unit_amount => Money.new(item.unit_amount, currency).to_s,
    :unit_tax_amount => Money.new(item.unit_tax_amount, currency).to_s,
    :tax_amount => Money.new(item_tax_amount, currency).to_s,
    :total_amount => Money.new(item_subtotal_amount, currency).to_s,
  }
end

# Define your shipping amount
shipping_amount = 2_00

# Calculate total amount charged to the customer
total_amount = subtotal_amount + shipping_amount + tax_amount

result = gateway.transaction.sale(
  :amount => Money.new(total_amount, currency).to_s,
  :shipping_amount => Money.new(shipping_amount, currency).to_s,
  :tax_amount => Money.new(tax_amount, currency).to_s,
  :payment_method_nonce => nonce_from_the_client,
  :line_items => line_items,
)

Creating a transactionanchor

Below is a full example using the minimum required fields for Level 3:

  1. Ruby
result = gateway.transaction.sale(
  :amount => "100.00",
  :payment_method_nonce => nonce_from_the_client,
  :purchase_order_number => "12345",
  :tax_amount => "5.00",
  :shipping_amount => "1.00",
  :discount_amount => "0.00",
  :ships_from_postal_code => "60654",
  :shipping => {
    :first_name => "Clinton",
    :last_name => "Ecker",
    :street_address => "1234 Main Street",
    :extended_address => "Unit 222",
    :locality => "Chicago",
    :region => "IL",
    :postal_code => "60654",
    :country_code_alpha3 => "USA"
  },
  :line_items => [
    {
      :name => "Product Name",
      :kind => "debit",
      :quantity => "10.0000",
      :unit_amount => "9.5000",
      :unit_of_measure => "unit",
      :total_amount => "95.00",
      :tax_amount => "5.00",
      :discount_amount => "0.00",
      :product_code => "54321",
      :commodity_code => "98765"
    }
  ]
)

Specifying level 2 and 3 data when submitting for settlementanchor

availability

Level 2 and 3 processing via submit for settlement requires internal approval. Please contact us if you’re interested in this functionality.

In some cases, transaction amounts, and by extension Level 2 and 3 parameters, are not finalized until the transaction is ready to be submitted for settlement. This functionality allows you to apply Level 2 and 3 parameters when submitting a transaction for settlement instead of specifying them in the transaction sale call.

note

Level 2 and 3 data provided via submit for settlement will override all Level 2 and 3 data previously provided in a sale request. If you wish to pass Level 2 and 3 data, we recommend utilizing either transaction.sale or transaction.submit_for_settlement, but not both at the same time.

  1. Ruby
result = gateway.transaction.submit_for_settlement("transaction_id", nil, {
  :purchase_order_number => "12345",
  :tax_amount => "1.23",
  :shipping_amount => "1.00",
  :discount_amount => "0.00",
  :ships_from_postal_code => "60654",
  :line_items => [
    {
      :name => "Product Name",
      :kind => "debit",
      :quantity => "10.0000",
      :unit_amount => "9.5000",
      :unit_of_measure => "unit",
      :total_amount => "95.00",
      :tax_amount => "5.00",
      :discount_amount => "0.00",
      :product_code => "54321",
      :commodity_code => "98765"
    }
  ]
})

if result.success?
  settled_transaction = result.transaction
else
  puts(result.message)
end

Validation errorsanchor

A transaction result may contain validation errors specifically for Level 3 fields or transaction line items, but only if the format or length of the value is outside expected bounds. This is to ensure the additional fields minimally interfere with the successful submission of transactions.

For a list of errors, see the Validation Errors reference page.