0.0
The project is in a healthy, maintained state
Ruby Client for Genesis Payment Processing Gateway
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
 Dependencies

Development

~> 2.1
~> 2.22
~> 0.11
~> 13.0
~> 3.0
~> 1.21
~> 3.0
~> 3.18

Runtime

~> 0.3.2
~> 1.14
 Project Readme

Genesis Ruby

Gem Version Software License

Ruby Client for Genesis Payment Processing Gateway

Overview

Client Library for processing payments through Genesis Payment Processing Gateway. Its highly recommended to checkout "Genesis Payment Gateway API Documentation" first, in order to get an overview of Genesis's Payment Gateway API and functionality.

Requirements

Installation

Add this line to your application's Gemfile:

gem 'genesis_ruby'

And then execute:

$ bundle

Or install it yourself as:

$ gem install genesis_ruby

Getting Started

Configuration

configuration             = GenesisRuby::Configuration.new
configuration.username    = '<YOUR USERNAME>'
configuration.password    = '<YOUR PASSWORD>'
configuration.token       = '<YOUR TOKEN>'
configuration.environment = GenesisRuby::Api::Constants::Environments::STAGING   # Support alias strings: 'test', 'testing', 'staging', 'live', 'prod', 'production'
configuration.endpoint    = GenesisRuby::Api::Constants::Endpoints::EMERCHANTPAY # Support alias strings: 'emp', 'emerchantpay', 'ecp', 'ecomprocessing', 'e-comprocessing'

Web Payment Form

require 'genesis_ruby'

begin
  genesis = GenesisRuby::Genesis.for(config: configuration, request: GenesisRuby::Api::Requests::Wpf::Create) do |request|
    # Common Attributes
    request.transaction_id     = '12345-67890'
    request.amount             = '0.99'
    request.currency           = 'EUR'
    request.usage              = 'Example usage'
    request.description        = 'You are about to complete you purchase'
    request.customer_email     = 'travis@example.com'
    request.customer_phone     = '+1987987987987'
    request.notification_url   = 'https://www.example.com/notification'
    request.return_success_url = 'https://www.example.com/success'
    request.return_cancel_url  = 'https://www.example.com/failure'
    request.return_failure_url = 'https://www.example.com/cancel.html'
    request.return_pending_url = 'https://www.example.com/payment-pending.html'

    # Transaction Types
    request.add_transaction_type('authorize3d')
    # Transaction Type with Customer Attribute 
    request.add_transaction_type('sale3d', { bin: '420000' })
    # Transaction Type with Recurring V2
    request.add_transaction_type('sale3d', { recurring_type: GenesisRuby::Api::Constants::Transactions::Parameters::Recurring::Types::INITIAL })

    # Tokenization Attributes
    request.consumer_id   = '123456789'
    request.remember_card = true

    # Billing Attributes
    request.billing_first_name = 'Travis'
    request.billing_last_name  = 'Pastrana'
    request.billing_address1   = 'Muster Str. 12'
    request.billing_zip_code   = '10178'
    request.billing_city       = 'Los Angeles'
    request.billing_state      = 'CA'
    request.billing_country    = 'US'

    # Shipping Attributes
    request.shipping_first_name = 'Travis'
    request.shipping_last_name  = 'Pastrana'
    request.shipping_address1   = 'Muster Str. 12'
    request.shipping_zip_code   = '10178'
    request.shipping_city       = 'Los Angeles'
    request.shipping_state      = 'CA'
    request.shipping_country    = 'US'

    # Internationalization
    request.locale = 'EN'

    # Other
    request.lifetime            = 30
    request.web_payment_form_id = '987654321'

    # Reminders
    request.pay_later           = true
    request.add_reminder channel: 'email', after: 10
    request.add_reminder channel: 'sms', after: 30
  end.execute
  
  puts genesis.response.response_object

rescue GenesisRuby::Error => error
  puts error.message
end

A full list of the Transaction Types and Custom Attributes can be found here.

Transactions

require 'genesis_ruby'

begin
  genesis = GenesisRuby::Genesis.for(config: configuration, request: GenesisRuby::Api::Requests::Financial::Cards::Sale) do |request|
    # Common Attributes
    request.transaction_id     = '12345-67890'
    request.amount             = '0.99'
    request.currency           = 'EUR'
    request.usage              = 'Example usage'
    request.customer_email     = 'travis@example.com'
    request.customer_phone     = '+1987987987987'

    # Credit Card Attributes
    request.card_holder      = 'Travis Pastrana'
    request.card_number      = '4200000000000000'
    request.expiration_month = '12'
    request.expiration_year  = '2040'
    request.cvv              = '834'

    # Billing Attributes
    request.billing_first_name = 'Travis'
    request.billing_last_name  = 'Pastrana'
    request.billing_address1   = 'Muster Str. 12'
    request.billing_zip_code   = '10178'
    request.billing_city       = 'Los Angeles'
    request.billing_state      = 'CA'
    request.billing_country    = 'US'
  end.execute

  puts genesis.response.response_object

rescue GenesisRuby::Error => error
  puts error.message
end

Smart Router

The Smart Routing API is a higher-level abstraction that allows for simpler and more efficient gateway Processing API integration. It does not require the terminal token (configuration.token). This by itself minimizes the need for complex customer-level manual routing to terminals set up on the gateway platform configuration layer.

By default the Smart Router is disabled. Contact your account manager to use the functionality.

Smart Router global definition for all requests

  • GenesisRuby::Configuration

    configuration.force_smart_routing = true
  • Smart Router definition per request

    request.use_smart_router = true

Example 3DSv2 Request

Sample request including all the conditionally required/optional params for initiating a 3DS transaction with the 3DSv2-Method authentication protocol.

Also, an example is provided for the 3DS-Method-continue API call that will have to be submitted after the 3DS-Method is initiated.

require 'genesis_ruby'

begin
  genesis_3ds_v2 = GenesisRuby::Genesis.for(config: configuration, request: GenesisRuby::Api::Requests::Financial::Cards::Sale3d) do |request|
    # Common Attributes
    request.transaction_id     = '12345-67890'
    request.remote_ip          = '127.0.0.1'
    request.amount             = '0.99'
    request.currency           = 'EUR'
    request.usage              = 'Example usage'
    request.customer_email     = 'travis@example.com'
    request.customer_phone     = '+1987987987987'

    # Credit Card Attributes
    request.card_holder      = 'Travis Pastrana'

    # Test Cases
    request.card_number = '4012000000060085' # Test Case: Synchronous 3DSv2 Request with Frictionless flow
    # request.card_number = '4066330000000004' # Test Case: Asynchronous 3DSv2 Request with 3DS-Method and Frictionless flow
    # request.card_number = '4918190000000002' # Test Case: Asynchronous 3DSv2 Request with Challenge flow
    # request.card_number = '4938730000000001' # Test Case: Asynchronous 3DSv2 Request with 3DS-Method Challenge flow
    # request.card_number = '4901170000000003' # Test Case: Asynchronous 3DSv2 Request with Fallback flow
    # request.card_number = '4901164281364345' # Test Case: Asynchronous 3DSv2 Request with 3DS-Method Fallback flow

    request.expiration_month = '12'
    request.expiration_year  = '2040'
    request.cvv              = '123'

    # Async Attributes
    request.notification_url   = 'https://example.com/notification'
    request.return_success_url = 'https://example.com/success'
    request.return_failure_url = 'https://example.com/failure'

    # Billing Attributes
    request.billing_first_name = 'Travis'
    request.billing_last_name  = 'Pastrana'
    request.billing_address1   = 'Kreisfreie Stadt Berlin'
    request.billing_zip_code   = '10115'
    request.billing_city       = 'Berlin'
    request.billing_country    = 'DE'

    # Threeds V2 Attributes

    ## Method Attributes
    request.threeds_v2_method_callback_url = 'https://www.example.com/threeds/threeds_method/callback'

    ## Control Attributes
    request.threeds_v2_control_device_type           =
            GenesisRuby::Api::Constants::Transactions::Parameters::Threeds::Version2::Control::DeviceTypes::BROWSER
    request.threeds_v2_control_challenge_window_size =
            GenesisRuby::Api::Constants::Transactions::Parameters::Threeds::Version2::Control::ChallengeWindowSizes::FULLSCREEN
    request.threeds_v2_control_challenge_indicator   =
            GenesisRuby::Api::Constants::Transactions::Parameters::Threeds::Version2::Control::ChallengeIndicators::MANDATE

    ## Browser Attributes
    ## When Control Device Type is Browser
    request.threeds_v2_browser_accept_header    = '*/*'
    request.threeds_v2_browser_java_enabled     = true
    request.threeds_v2_browser_language         = 'en-GB'
    request.threeds_v2_browser_color_depth      = 48
    request.threeds_v2_browser_screen_height    = 900
    request.threeds_v2_browser_screen_width     = 1440
    request.threeds_v2_browser_time_zone_offset = '+0'
    request.threeds_v2_browser_user_agent       = 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.97 Safari/537.36'

    ## SDK
    ## When Control Device Type is SDK
    request.threeds_v2_sdk_interface                 =
            GenesisRuby::Api::Constants::Transactions::Parameters::Threeds::Version2::Sdk::Interfaces::BOTH
    request.threeds_v2_sdk_ui_types                  =
            GenesisRuby::Api::Constants::Transactions::Parameters::Threeds::Version2::Sdk::UiTypes::TEXT
    request.threeds_v2_sdk_ui_types                  =
            GenesisRuby::Api::Constants::Transactions::Parameters::Threeds::Version2::Sdk::UiTypes::SINGLE_SELECT
    request.threeds_v2_sdk_ui_types                  =
            GenesisRuby::Api::Constants::Transactions::Parameters::Threeds::Version2::Sdk::UiTypes::MULTI_SELECT
    request.threeds_v2_sdk_application_id            = 'fc1650c0-5778-0138-8205-2cbc32a32d65'
    request.threeds_v2_sdk_encrypted_data            = 'encrypted-data-here'
    request.threeds_v2_sdk_ephemeral_public_key_pair = 'public-key-pair'
    request.threeds_v2_sdk_max_timeout               = 10
    request.threeds_v2_sdk_reference_number          = 'sdk-reference-number-her'


    ## Purchase Attributes
    request.threeds_v2_purchase_category =
            GenesisRuby::Api::Constants::Transactions::Parameters::Threeds::Version2::Purchase::Categories::GOODS

    ## Recurring
    request.threeds_v2_recurring_expiration_date = '12-12-2024'
    request.threeds_v2_recurring_frequency       = 30

    ## Merchant Risk Attributes
    request.threeds_v2_merchant_risk_shipping_indicator           =
            GenesisRuby::Api::Constants::Transactions::Parameters::Threeds::Version2::MerchantRisk::ShippingIndicators::SAME_AS_BILLING
    request.threeds_v2_merchant_risk_delivery_timeframe           =
            GenesisRuby::Api::Constants::Transactions::Parameters::Threeds::Version2::MerchantRisk::DeliveryTimeframes::ANOTHER_DAY
    request.threeds_v2_merchant_risk_reorder_items_indicator      =
            GenesisRuby::Api::Constants::Transactions::Parameters::Threeds::Version2::MerchantRisk::ReorderItemIndicators::FIRST_TIME
    request.threeds_v2_merchant_risk_pre_order_purchase_indicator =
            GenesisRuby::Api::Constants::Transactions::Parameters::Threeds::Version2::MerchantRisk::PreOrderPurchaseIndicators::MERCHANDISE_AVAILABLE
    request.threeds_v2_merchant_risk_pre_order_date               = '31-12-2030'
    request.threeds_v2_merchant_risk_gift_card                    = true
    request.threeds_v2_merchant_risk_gift_card_count              = 99

    ## Card Holder Account Attributes
    request.threeds_v2_card_holder_account_creation_date                       = '31-12-2022'
    request.threeds_v2_card_holder_account_update_indicator                    =
            GenesisRuby::Api::Constants::Transactions::Parameters::Threeds::Version2::CardHolderAccount::UpdateIndicators::MORE_THAN_60DAYS
    request.threeds_v2_card_holder_account_last_change_date                    = '31-12-2022'
    request.threeds_v2_card_holder_account_password_change_indicator           =
            GenesisRuby::Api::Constants::Transactions::Parameters::Threeds::Version2::CardHolderAccount::PasswordChangeIndicators::NO_CHANGE
    request.threeds_v2_card_holder_account_password_change_date                = '31-12-2022'
    request.threeds_v2_card_holder_account_shipping_address_usage_indicator    =
            GenesisRuby::Api::Constants::Transactions::Parameters::Threeds::Version2::CardHolderAccount::ShippingAddressUsageIndicators::MORE_THAN_60DAYS
    request.threeds_v2_card_holder_account_shipping_address_date_first_used    = '31-12-2022'
    request.threeds_v2_card_holder_account_transactions_activity_last24_hours  = 2
    request.threeds_v2_card_holder_account_transactions_activity_previous_year = 10
    request.threeds_v2_card_holder_account_provision_attempts_last24_hours     = 1
    request.threeds_v2_card_holder_account_purchases_count_last6_months        = 5
    request.threeds_v2_card_holder_account_suspicious_activity_indicator       =
            GenesisRuby::Api::Constants::Transactions::Parameters::Threeds::Version2::CardHolderAccount::SuspiciousActivityIndicators::NO_SUSPICIOUS_OBSERVED
    request.threeds_v2_card_holder_account_registration_indicator              =
            GenesisRuby::Api::Constants::Transactions::Parameters::Threeds::Version2::CardHolderAccount::RegistrationIndicators::MORE_THAN_60DAYS
    request.threeds_v2_card_holder_account_registration_date                   = '31-12-2022'

  end.execute

  response_3ds_v2 = genesis_3ds_v2.response

  if response_3ds_v2.approved?
    # Transaction approved no customer action required
    # Test Case: Synchronous 3DSv2 Request with Frictionless flow
    puts response_3ds_v2.response_object
  end

  if response_3ds_v2.declined? || response_3ds_v2.error?
    # Transaction declined no customer action required
    # Synchronous 3DSv2 Request with Frictionless flow
    puts response_3ds_v2.response_object
  end

  if response_3ds_v2.pending_async?
    # Additional Actions Required
    response_object_3ds_v2 = response_3ds_v2.response_object

    if response_object_3ds_v2[:redirect_url]
      # An interaction between consumer and issuer is required
      # 3DSv2 Challenge required
      # 3DSv1 payer authentication required - fallback from 3DSv2 to 3DSv1
      # Test Case: Asynchronous 3DSv2 Request with Challenge flow
      # Test Case: Asynchronous 3DSv2 Request with Fallback flow
      puts response_object_3ds_v2[:redirect_url_type]
      puts response_object_3ds_v2[:redirect_url]
    end

    if response_object_3ds_v2[:threeds_method_url]
      # 3DS-Method submission is required
      # Generate 3DSv2-Method Signature token used for Threeds Method Continue Request. It's not required when the 3DS-Method continue request is built by the initial request's response object.
      puts GenesisRuby::Utils::Threeds::V2.generate_signature(
              unique_id: response_object_3ds_v2[:unique_id],
              amount: response_object_3ds_v2[:amount],
              timestamp: response_object_3ds_v2[:timestamp].strftime(GenesisRuby::Api::Constants::DateTimeFormats::YYYY_MM_DD_H_I_S_ZULU),
              merchant_password: configuration.password
      )

      # Execute 3DS-Method Continue Request after initiating the 3DS-Method submission
      # The new request is loaded from the response object of the initial request
      genesis_3ds_v2_continue = GenesisRuby::Api::Requests::Financial::Cards::Threeds::V2::MethodContinue.build_from_response_object(
              configuration,
              genesis_3ds_v2.response.response_object
      )

      genesis_3ds_v2_continue.execute

      response_3ds_v2_continue = genesis_3ds_v2_continue.response

      if response_3ds_v2_continue.approved?
        # Transaction APPROVED no customer action required
        # Test Case: Asynchronous 3DSv2 Request with 3DS-Method and Frictionless flow
        puts response_3ds_v2_continue.response_object
      end

      if response_3ds_v2_continue.declined? || response_3ds_v2_continue.error?
        # Transaction declined no customer action required
        puts response_3ds_v2_continue.response_object
      end

      if response_3ds_v2_continue.pending_async?
        # Customer action required
        continue_response_object = response_3ds_v2_continue.response_object

        if continue_response_object[:redirect_url]
          # Test Case: Asynchronous 3DSv2 Request with 3DS-Method Challenge flow
          # Test Case: Asynchronous 3DSv2 Request with 3DS-Method Fallback flow
          puts continue_response_object[:redirect_url_type]
          puts continue_response_object[:redirect_url]
        end
      end
    end
  end

rescue GenesisRuby::Error => error
  puts error.message
end

Standalone ThreedsV2 Method Continue Request.

require 'genesis_ruby'

begin
  genesis = GenesisRuby::Genesis.for(config: configuration, request: GenesisRuby::Api::Requests::Financial::Cards::Threeds::V2::MethodContinue) do |request|
    # Amount in minor currency unit
    # If the AMOUNT is not in a minor currency unit then SET the CURRENCY. The AMOUNT will be converted into minor currency unit internally using the CURRENCY property.
    # Ex. amount = 10.00
    #     currency = 'EUR'
    #   The AMOUNT in that case for signature generation will be 1000
    # Amount is included in the response from the initial request in major currency unit genesis.response.response_object[:amount]
    request.amount = 10.00

    # If CURRENCY is set, AMOUNT value will be converted into MINOR currency unit
    # If you SET the AMOUNT in MINOR currency unit DO NOT set CURRENCY
    # Currency is included in the response from the initial request in major currency unit genesis.response.response_object[:currency]
    request.currency = 'EUR'

    # Set only one of the unique_id or url
    # request.url = 'https://staging.gate.emerchantpay.net/threeds/threeds_method/d6a6aa96292e4856d4a352ce634a4335'
    request.transaction_unique_id = 'd6a6aa96292e4856d4a352ce634a4335'

    # String representation of the timestamp
    # request.transaction_timestamp = genesis.response
    #   .response_object[:timestamp].strftime(GenesisRuby::Api::Constants::DateTimeFormats::YYYY_MM_DD_H_I_S_ZULU)
    request.transaction_timestamp = '2020-12-31T23:59:59Z'
  end.execute

  response = genesis.response

  if response.approved?
    # Asynchronous 3DSv2 Request with 3DS-Method and Frictionless flow
    # Transaction approved no customer action required
    puts response.response_object
  end

  if response.pending_async?
    # Customer action required
    response_object = response.response_object

    if response_object[:redirect_url]
      # Asynchronous 3DSv2 Request with 3DS-Method Challenge flow
      # Asynchronous 3DSv2 Request with 3DS-Method Fallback flow
      puts response_object[:redirect_url_type]
      puts response_object[:redirect_url]
    end
  end

rescue GenesisRuby::Error => error
  puts error.message
end

Apple Pay Request

Apple Pay is a mobile payment solution available on iOS devices with Touch ID / Face ID support. Apple Pay allows shoppers to purchase with credit and debit cards linked to their devices.

Apple Pay Transaction Example
require 'genesis_ruby'

begin
  genesis = GenesisRuby::Genesis.for(config:  configuration, request: GenesisRuby::Api::Requests::Financial::Mobile::ApplePay) do |request|
    # Common Attributes
    request.transaction_id     = '12345-67890'
    request.amount             = '0.99'
    request.currency           = 'EUR'
    request.usage              = 'Example usage'
    request.customer_email     = 'travis@example.com'
    request.customer_phone     = '+1987987987987'

    request.payment_subtype    = GenesisRuby::Api::Constants::Transactions::Parameters::Mobile::ApplePay::PaymentSubtypes::SALE

    # Billing Attributes
    request.billing_first_name = 'Travis'
    request.billing_last_name  = 'Pastrana'
    request.billing_address1   = 'Muster Str. 12'
    request.billing_zip_code   = '10178'
    request.billing_city       = 'Los Angeles'
    request.billing_state      = 'CA'
    request.billing_country    = 'US'

    # Apple Pay Payment Token
    json_token = '{"paymentData":{"version":"EC_v1","data":"MgcrhHr/uhfRy7zxMOvahhf5sp+ZfUsWADlG5OhvZ8vEAybEouyk4tT8oYaOqlfNTdkJZl2tmCgyLReibOjW2RiXzw5S9ZtA6ISnEBjNFla9Hju1KJnxQ+QFIdSlhEDOqN/Wk9kSFz2mnT8wajaG6mytpXhzCxvl5ElCp0gm0wMb82lvpf6my5TIu+CuANPZ2g/kslqKUGEjQHhO3FVqmiEj2YpkrlhXcvFu1GalTOWgjnLVCMz8l8DCQek/UIZQ3ZiJEoQTlEZRzXlwG8FlEp/QwbLiIlQfDLCtu3pBH0EaOeQ1OwupXs64EYfL+DEzYKdpi7dE9Y93zcXR6y2qsawBC8lCeI8zGc+kRFQJ5IrPd81BRZep3xsHwh1uki2dfx2taLyjxyCWWKaUWCzYI1p/u7YsypYEMj3np+MHfg==","signature":"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","header":{"wrappedKey": "wrapped key", "ephemeralPublicKey":"MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEJsaMBlzR3D0H7xKwDncLNGOEcsl6Jilx5d+MDI/1QFxuIf6a0fY5qgOwnuLgZepqc3AVeU1RV8enPCQSWfFKRg==","publicKeyHash":"QOmvMaoCNYk5tv+69KC1i2UCFQcOl6LYPIJfYAT+SLQ=","transactionId":"ccedaf3f32efcc971259694f0efd0dcaa0ed545e7a31a0f7ec8e1c110656c25b"}},"paymentMethod":{"displayName":"Visa 0225","network":"Visa","type":"debit"},"transactionIdentifier":"CCEDAF3F32EFCC971259694F0EFD0DCAA0ED545E7A31A0F7EC8E1C110656C25B"}'

    # Set Apple Pay token from a JSON string
    request.json_token = json_token

    # Alternatively you can set every token attributes
    # token = JSON.parse json_token
    # request.token_version                = token['paymentData']['version']
    # request.token_data                   = token['paymentData']['data']
    # request.token_signature              = token['paymentData']['signature']
    # request.token_ephemeral_public_key   = token['paymentData']['header']['ephemeralPublicKey']
    # request.token_public_key_hash        = token['paymentData']['header']['publicKeyHash']
    # request.token_transaction_id         = token['paymentData']['header']['transactionId']
    # request.token_display_name           = token['paymentMethod']['displayName']
    # request.token_network                = token['paymentMethod']['network']
    # request.token_type                   = token['paymentMethod']['type']
    # request.token_transaction_identifier = token['transactionIdentifier']
  end.execute

  puts genesis.response.response_object
rescue GenesisRuby::Error => error
  puts error.message
end
Apple Pay Web Payment Form Example
require 'genesis_ruby'

begin
  genesis = GenesisRuby::Genesis.for(config: configuration, request: GenesisRuby::Api::Requests::Wpf::Create) do |request|
    # Common Attributes
    request.transaction_id     = '12345-67890'
    request.amount             = '0.99'
    request.currency           = 'EUR'
    request.usage              = 'Example usage'
    request.description        = 'You are about to complete you purchase'
    request.customer_email     = 'travis@example.com'
    request.customer_phone     = '+1987987987987'
    request.notification_url   = 'https://www.example.com/notification'
    request.return_success_url = 'https://www.example.com/success'
    request.return_cancel_url  = 'https://www.example.com/failure'
    request.return_failure_url = 'https://www.example.com/cancel.html'
    request.return_pending_url = 'https://www.example.com/payment-pending.html'

    # Transaction Types
    request.add_transaction_type('apple_pay', { payment_subtype: GenesisRuby::Api::Constants::Transactions::Parameters::Mobile::ApplePay::PaymentSubtypes::AUTHORIZE })

    # Billing Attributes
    request.billing_first_name = 'Travis'
    request.billing_last_name  = 'Pastrana'
    request.billing_address1   = 'Muster Str. 12'
    request.billing_zip_code   = '10178'
    request.billing_city       = 'Los Angeles'
    request.billing_state      = 'CA'
    request.billing_country    = 'US'
  end.execute

  puts genesis.response.response_object

rescue GenesisRuby::Error => error
  puts error.message
end

Google Pay Request

Google Pay allows shoppers to purchase with credit and debit cards linked to their Google account.

Google Pay Transaction Example
require 'genesis_ruby'

begin
  genesis = GenesisRuby::Genesis.for(config:  configuration, request: GenesisRuby::Api::Requests::Financial::Mobile::GooglePay) do |request|
    # Common Attributes
    request.transaction_id     = '12345-67890'
    request.amount             = '0.99'
    request.currency           = 'EUR'
    request.usage              = 'Example usage'
    request.customer_email     = 'travis@example.com'
    request.customer_phone     = '+1987987987987'

    request.payment_subtype    = GenesisRuby::Api::Constants::Transactions::Parameters::Mobile::GooglePay::PaymentSubtypes::SALE

    # Billing Attributes
    request.billing_first_name = 'Travis'
    request.billing_last_name  = 'Pastrana'
    request.billing_address1   = 'Muster Str. 12'
    request.billing_zip_code   = '10178'
    request.billing_city       = 'Los Angeles'
    request.billing_state      = 'CA'
    request.billing_country    = 'US'

    # Google Pay Payment Token
    json_token = '{
            "protocolVersion":"ECv2",
            "signature":"MEQCIH6Q4OwQ0jAceFEkGF0JID6sJNXxOEi4r+mA7biRxqBQAiAondqoUpU/bdsrAOpZIsrHQS9nwiiNwOrr24RyPeHA0Q\u003d\u003d",
            "intermediateSigningKey":{
                    "signedKey": "{\"keyExpiration\":\"1542323393147\",\"keyValue\":\"MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE/1+3HBVSbdv+j7NaArdgMyoSAM43yRydzqdg1TxodSzA96Dj4Mc1EiKroxxunavVIvdxGnJeFViTzFvzFRxyCw\\u003d\\u003d\"}",
                    "signatures": ["MEYCIQCO2EIi48s8VTH+ilMEpoXLFfkxAwHjfPSCVED/QDSHmQIhALLJmrUlNAY8hDQRV/y1iKZGsWpeNmIP+z+tCQHQxP0v"]
            },
            "signedMessage":"{\"tag\":\"jpGz1F1Bcoi/fCNxI9n7Qrsw7i7KHrGtTf3NrRclt+U\\u003d\",\"ephemeralPublicKey\":\"BJatyFvFPPD21l8/uLP46Ta1hsKHndf8Z+tAgk+DEPQgYTkhHy19cF3h/bXs0tWTmZtnNm+vlVrKbRU9K8+7cZs\\u003d\",\"encryptedMessage\":\"mKOoXwi8OavZ\"}"
    }'

    # Set Google Pay token from a JSON string
    request.json_token = json_token

    # Alternatively you can set every token attributes
    # token = JSON.parse json_token
    # request.token_protocol_version = token['protocolVersion']
    # request.token_signature        = token['signature']
    # request.token_signed_key       = token['intermediateSigningKey']['signedKey']
    # request.token_signatures       = token['intermediateSigningKey']['signatures']
    # request.token_signed_message   = token['signedMessage']
  end.execute

  puts genesis.response.response_object
rescue GenesisRuby::Error => error
  puts error.message
end
Google Pay Web Payment Form Example
require 'genesis_ruby'

begin
  genesis = GenesisRuby::Genesis.for(config: configuration, request: GenesisRuby::Api::Requests::Wpf::Create) do |request|
    # Common Attributes
    request.transaction_id     = '12345-67890'
    request.amount             = '0.99'
    request.currency           = 'EUR'
    request.usage              = 'Example usage'
    request.description        = 'You are about to complete you purchase'
    request.customer_email     = 'travis@example.com'
    request.customer_phone     = '+1987987987987'
    request.notification_url   = 'https://www.example.com/notification'
    request.return_success_url = 'https://www.example.com/success'
    request.return_cancel_url  = 'https://www.example.com/failure'
    request.return_failure_url = 'https://www.example.com/cancel.html'
    request.return_pending_url = 'https://www.example.com/payment-pending.html'

    # Transaction Types
    request.add_transaction_type('google_pay', { payment_subtype: GenesisRuby::Api::Constants::Transactions::Parameters::Mobile::GooglePay::PaymentSubtypes::AUTHORIZE })

    # Billing Attributes
    request.billing_first_name = 'Travis'
    request.billing_last_name  = 'Pastrana'
    request.billing_address1   = 'Muster Str. 12'
    request.billing_zip_code   = '10178'
    request.billing_city       = 'Los Angeles'
    request.billing_state      = 'CA'
    request.billing_country    = 'US'
  end.execute

  puts genesis.response.response_object

rescue GenesisRuby::Error => error
  puts error.message
end

Recurring

A recurring transaction describes a payment where the cardholder’s account is periodically charged for a repeated delivery and use of a product or service (subscription, membership fee, etc.) over time. A recurring payment consists of an initial transaction and one or several repeated subsequent transactions.

request.recurring_type = GenesisRuby::Api::Constants::Transactions::Parameters::Recurring::Types::INITIAL

Managed Recurring

Managed Recurring provides the option to automatically schedule recurring transactions for a specific day and time. Managed Recurring is available after additional configuration. More info can be found here

request.recurring_type = GenesisRuby::Api::Constants::Transactions::Parameters::Recurring::Types::MANAGED
  • Web Payment Form
    request.add_transaction_type(
      'sale3d',
      {
        managed_recurring: {
          mode:        'automatic',
          interval:    'days',
          first_date:  ((Date.today) + 1).strftime('%Y-%d-%m'),
          time_of_day: 1,
          period:      1,
          amount:      GenesisRuby::Utils::MoneyFormat.amount_to_exponent('0.99', 'EUR'),
          max_count:   1
        }
      }
    )

Level 3 Travel Data

Level 3 travel data is supplied as optional data to the standard API request. If the supplied is valid travel data then the transaction will be processed as a travel transaction and will qualify for the travel Incentive rates. Otherwise the transaction will be processed normally as a regular transaction. Note that the travel data will be stored as part of the transaction in all cases.

Example Leg Data
GenesisRuby::Utils::Transactions::TravelData::AirlineItinerary::Leg.new departure_date:         '2034-12-31',
                                                                        arrival_date:           '2034-12-31',
                                                                        carrier_code:           12,
                                                                        service_class:          1,
                                                                        origin_city:            'VAR',
                                                                        destination_city:       'FRA',
                                                                        stopover_code:          0,
                                                                        fare_basis_code:        1,
                                                                        flight_number:          'W1234',
                                                                        departure_time:         '11:37',
                                                                        departure_time_segment: 'P'
Example Tax Data
GenesisRuby::Utils::Transactions::TravelData::AirlineItinerary::Tax.new fee_type: 'type', 
                                                                        fee_amount: 0.99 # will converted automatically to minor format based on the currency
Example Level 3 Travel Data
# Ticket attributes
request.travel_aid_ticket_number               = '123456789012345'
request.travel_aid_passenger_name              = 'Test Example'
request.travel_aid_customer_code               = 1
request.travel_aid_issuing_carrier             = 'AAAA'
request.travel_aid_total_fare                  = '0.99' # will converted automatically to minor format based on the currency
request.travel_aid_agency_name                 = 'Agency'
request.travel_aid_agency_code                 = 'AG001'
request.travel_aid_date_of_issue               = '2018-02-01'
request.travel_aid_restricted_ticket_indicator = 1
request.travel_aid_confirmation_information    = 'Confirmation'

request.add_travel_aid_leg leg
request.add_travel_aid_tax tax

# Car rental
request.travel_car_rental_purchase_identifier       = '12478'
request.travel_car_rental_class_id                  = 3
request.travel_car_rental_pickup_date               = '2034-12-31'
request.travel_car_rental_renter_name               = 'John Smith'
request.travel_car_rental_return_city               = 'Varna'
request.travel_car_rental_return_state              = 'VAR'
request.travel_car_rental_return_country            = 'BGR'
request.travel_car_rental_return_date               = '2034-12-31'
request.travel_car_rental_renter_return_location_id = '12478'
request.travel_car_rental_customer_code             = 1
request.travel_car_rental_extra_charges             = 2
request.travel_car_rental_no_show_indicator         = 1

# Hotel Rental attributes
request.travel_hotel_rental_purchase_identifier = '12478'
request.travel_hotel_rental_arrival_date        = '2034-12-31'
request.travel_hotel_rental_departure_date      = '2034-12-31'
request.travel_hotel_rental_customer_code       = '12478'
request.travel_hotel_rental_no_show_indicator   = 1

# Reference Ticket Attributes
request.travel_ac_ticket_reference_id       = '8b7e3575e5605ea7e1895707a3e92837'
request.travel_ac_ticket_document_number    = '1111'
request.travel_ac_issued_with_ticket_number = '12321'

# Ancillary Charges
request.travel_ac_type     = 'BF'
request.travel_ac_sub_type = 'BG'

Response

After Request execution (genesis.execute) a Response object can be accessed genesis.response.

The Response contains the original response from the Gateway:

genesis.response.response_raw

The Response contains the parsed response from the Gateway:

genesis.response.response_object

Success Request

You receive from the Response Object a Hash collection. The data contains a :status.

If the Transaction is Successful the status is one of the following:

  • new
  • approved
  • pending_async
Example Successful Transaction Execution
  {:status=>"new",
  :unique_id=>"2993ad9c2dd45ecfa9862b9eaf0ceb29",
  :transaction_id=>"9c8b862b-4f91-478b-8a14-87bffab7e55d",
  :timestamp=>
  #<DateTime: 2023-04-20T12:11:42+00:00 ((2460055j,43902s,0n),+0s,2299161j)>,
  :amount=>"0.99",
  :currency=>"EUR",
  :redirect_url=>
  "https://staging.wpf.emerchantpay.net/ja/v2/payment/2993ad9c2dd45ecfa9862b9eaf0ceb29"}

If an error occurs during the Transaction Execution the status is one of the following:

  • error
  • declined
Example Transaction Execution with Error
{:status=>"error",
 :unique_id=>"fc94d7cdebe5f81618785d1033948fcc",
 :transaction_id=>"8bf4556b-a6ba-4389-a2e8-b7efa9e384b3",
 :code=>"120",
 :technical_message=>
   "Lacking Terminal/MID setups for the currency 'USD' for the requested transaction types",
 :message=>"Transaction failed, please contact support!",
 :timestamp=>
   #<DateTime: 2023-04-20T12:13:52+00:00 ((2460055j,44032s,0n),+0s,2299161j)>,
   :amount=>"0.99",
 :currency=>"USD"}

Reference actions

The Reference transaction requests allow actions over an existing payment. The payment can be modified with:

  • Capture - settles a transaction that has been authorized before
  • Void - undo other transactions
  • Refund - allow to return already billed amounts to customers

! Void transaction request doesn't require amount and currency parameters

After a successful response of a payment, reference actions can be executed by using the unique_id.

require 'genesis_ruby'

begin
  genesis = GenesisRuby::Genesis.for(config: configuration, request: GenesisRuby::Api::Requests::Financial::Refund) do |request|
    request.transaction_id = '12345-67890'
    request.amount         = '0.99' # not available for GenesisRuby::Api::Requests::Financial::Void
    request.currency       = 'EUR' # not available for GenesisRuby::Api::Requests::Financial::Void
    request.usage          = 'Example usage'
    request.reference_id   = 'unique_id received upon successful payment transaction'
  end.execute

  puts genesis.response.response_object

rescue GenesisRuby::Error => error
  puts error.message
end

Gateway Notification

With the asynchronous payment flows like Web Payment Form the Gateway sends the transaction events upon status change on the defined notification_url. The library contains a Notification module that helps handle the received gateway notification and can provide easy reconciliation execution.

Initialization

The notification module requires notification data or any object that responds to to_h with a Hash return value. For example, with Ruby on Rails you can permit the params and to_h method can be executed without errors:

permitted_params = params.permit(:transaction_id, :terminal_token, :unique_id, :transaction_type, :status, :signature, :amount)

A full list of the available params that can be received upon notification can be found here.

begin
  notification = GenesisRuby::Api::Notification.new configuration, permitted_params

  # Helper methods
  notification.api_notification?
  notification.wpf_notification?
  notification.unique_id

  # Executes Gateway Transaction Reconciliation
  # This provides the latest information on the transaction from the Gateway
  notification.reconcile

  # Provides information if the given reconcile response contains transaction information
  notification.transaction_reconciliation?

  # Get the Reconcile Response Object in Hash data structure
  notification.reconciliation.response_object

  # Generate response document expected from the Gateway
  notification.generate_response
rescue GenesisRuby::ParameterError => error
  puts error.message
end

Reconcile

Minimum required data for execution of reconcile:

{
  unique_id: 'unique_id received from the gateway in the notification params',
  signature: 'the signature received in the notification'
}

If the signature can't be verified Genesis::Ruby::ParameterError will be raised.

Helpers

notification.reconcile returns GenesisRuby::Api::Response. The response object can be accessed via notification.reconciliation. The reconciliation object has every helper that Response contains like checking the status with error?, approved?, etc.

For checking if the reconciliation.response_object is a successful transaction response you can use notification.transaction_reconciliation?

Errors

Upon wrong data like configuration terminal token, reconciliation.response_object can be similar:

{
   status: 'error',
   code: '220',
   message: 'Reconcile request failed, please contact support!',
   technical_message: 'Invalid Terminal'
}

Respond to the Gateway

When receiving the notification, you are required to render an xml page containing the transaction’s unique id so that the gateway knows that you have accepted the notification. If the XML is not delivered, the notification is sent periodically until the XML is received.

GenesisRuby::Api::Notification provides helper method for generation of the expected xml content. The Gateway expects a response with:

  • Status 200
  • Content Type text/xml
notification.generate_response

Response Helpers

Sates

The Response object has predefined checks for validating the status of the received response. Every available status received from the Gateway can be checked in the following way.

genesis.response.new?
genesis.response.approved?
genesis.response.declined?
genesis.response.error?
...

Formatters

By default, the Response Object is formatted. For example, amounts are transformed in major currency format, timestamps in DateTime, etc. If you want to stop formatting you can do it by defining format_reponse in the Configuration.

configuration.format_response = false

Sanitization

By default, the Response Object is sanitized, and <empty/> values are removed. If you want to stop sanitization you can do it by defining configuration.sanitize_response in the Configuration.

configuration.sanitize_response = false

Requests

You can use the following request classes to initialize the Genesis client:

# Financial
## Cards
GenesisRuby::Api::Requests::Financial::Cards::Authorize
GenesisRuby::Api::Requests::Financial::Cards::Authorize3d
GenesisRuby::Api::Requests::Financial::Cards::Sale
GenesisRuby::Api::Requests::Financial::Cards::Sale3d

## Mobile
GenesisRuby::Api::Requests::Financial::Mobile::ApplePay
GenesisRuby::Api::Requests::Financial::Mobile::GooglePay

# Web Payment Form
## Create
GenesisRuby::Api::Requests::Wpf::Create
## WPF Reconcile
GenesisRuby::Api::Requests::Wpf::Reconcile

# Online Banking Payments
# PayIn
GenesisRuby::Api::Requests::Financial::OnlineBankingPayments::OnlineBanking::PayIn

# References
GenesisRuby::Api::Requests::Financial::Capture
GenesisRuby::Api::Requests::Financial::Void
GenesisRuby::Api::Requests::Financial::Refund

# Non Financial
## Reconcile
GenesisRuby::Api::Requests::NonFinancial::Reconcile::Transaction
GenesisRuby::Api::Requests::NonFinancial::Reconcile::DateRange

Manual initialization

Manual Client initialization
require 'genesis_ruby'

begin
  request = GenesisRuby::Api::Requests::Wpf::Create.new(configuration)

  request.transaction_id     = '12345-67890'
  request.amount             = '0.99'
  request.currency           = 'EUR'
  request.usage              = 'Example usage'
  request.description        = 'You are about to complete you purchase'
  request.customer_email     = 'travis@example.com'
  request.customer_phone     = '+1987987987987'
  request.notification_url   = 'https://www.example.com/notification'
  request.return_success_url = 'https://www.example.com/success'
  request.return_cancel_url  = 'https://www.example.com/failure'
  request.return_failure_url = 'https://www.example.com/cancel.html'
  request.return_pending_url = 'https://www.example.com/payment-pending.html'

  # Transaction Types
  request.add_transaction_type('authorize3d')
  
  genesis = GenesisRuby::Genesis.new(configuration, request)

  puts genesis.execute.response.response_object

rescue GenesisRuby::Error => error
  puts error.message
end

Running Specs

rake test

Running Linters

rake styles