lib/pesapal/merchant.rb in pesapal-1.8.0 vs lib/pesapal/merchant.rb in pesapal-2.0.0
- old
+ new
@@ -62,11 +62,11 @@
@order_details ||= {}
end
private
- attr_reader :api_domain, :api_endpoints, :env
+ attr_reader :env
def params
@params ||= nil
end
@@ -85,75 +85,26 @@
# Initialize Pesapal object and choose the environment, there are two
# environments; `:development` and `:production`. They determine if the code
# will interact with the testing or the live Pesapal API. Like so ...
#
# ```ruby
- # # Sets environment intelligently to 'Rails.env' (if Rails) or :development (if non-Rails)
- # pesapal = Pesapal::Merchant.new
- #
- # # Sets environment to :development
+ # # Sets environment to :development explicitly
# pesapal = Pesapal::Merchant.new(:development)
#
# # Sets environment to :production
# pesapal = Pesapal::Merchant.new(:production)
# ```
#
- # A few things to note about the constructor as it behaves differently
- # depending on the context within which it is called i.e. _Rails_ app vs
- # _non-Rails_ app ...
- #
- # ### Case 1: Rails app
- #
- # The constructor attempts to set configuration details that should be
- # available at runtime from `Rails.application.config.pesapal_credentials`.
- # This contains values loaded at application start from a YAML file located
- # at `config/pesapal.yml` which typically looks like this:
- #
- # ```yaml
- # development:
- # callback_url: 'http://0.0.0.0:3000/pesapal/callback'
- # consumer_key: '<YOUR_DEV_CONSUMER_KEY>'
- # consumer_secret: '<YOUR_DEV_CONSUMER_SECRET>'
- #
- # production:
- # callback_url: 'http://1.2.3.4:3000/pesapal/callback'
- # consumer_key: '<YOUR_PROD_CONSUMER_KEY>'
- # consumer_secret: '<YOUR_PROD_CONSUMER_SECRET>'
- # ```
- #
- # The appropriate credentials are picked and set to {#config} instance
- # attribute depending on set environment. The setting of environment is
- # explained above. It's worth nothing that if for some reason the YAML file
- # could not be read, then it fallbacks to setting {#config} instance
- # attribute with default values. The exact definition of default values is
- # shown below.
- #
- # ### Case 2: Non-Rails app
- #
- # Since (and if) no predefined configuration files are available, the
- # constructor sets the {#config} instance attribute up with default values
- # as shown below:
- #
- # ```
- # { :callback_url => 'http://0.0.0.0:3000/pesapal/callback',
- # :consumer_key => '<YOUR_CONSUMER_KEY>',
- # :consumer_secret => '<YOUR_CONSUMER_SECRET>'
- # }
- # ```
- #
- # @note You can change the environment at runtime using {#change_env}
- #
# @param env [Symbol] the environment we want to use i.e. `:development` or
- # `:production`. Leaving it blank sets environment intelligently to
- # `Rails.env` (if Rails) or `:development` (if non-Rails).
- def initialize(env = false)
- change_env env
- if defined?(Rails)
- configure Rails.application.config.pesapal_credentials
- else
- configure
- end
+ # `:production`.
+ def initialize(env = :development)
+ @env = env.to_s.downcase
+ @config = {
+ callback_url: 'http://0.0.0.0:3000/pesapal/callback',
+ consumer_key: '<YOUR_CONSUMER_KEY>',
+ consumer_secret: '<YOUR_CONSUMER_SECRET>'
+ }
end
# Generate URL that's used to post a transaction to PesaPal.
#
# PesaPal will present the user with a page which contains the available
@@ -183,21 +134,24 @@
# @return [String] URL of the Pesapal post order form
def generate_order_url
# build xml with input data, the format is standard so no editing is
# required
@post_xml = Pesapal::Helper::Post.generate_post_xml @order_details
-
# initialize setting of @params (oauth_signature left empty)
@params = Pesapal::Helper::Post.set_parameters(@config[:callback_url], @config[:consumer_key], @post_xml)
-
# generate oauth signature and add signature to the request parameters
- @params[:oauth_signature] = Pesapal::Oauth.generate_oauth_signature('GET', @api_endpoints[:postpesapaldirectorderv4], @params, @config[:consumer_secret], @token_secret)
-
+ @params[:oauth_signature] = Pesapal::Oauth.generate_oauth_signature(
+ 'GET',
+ postpesapaldirectorderv4_url,
+ @params,
+ @config[:consumer_secret],
+ @token_secret
+ )
# change params (with signature) to a query string
query_string = Pesapal::Oauth.generate_encoded_params_query_string @params
- "#{@api_endpoints[:postpesapaldirectorderv4]}?#{query_string}"
+ "#{postpesapaldirectorderv4_url}?#{query_string}"
end
# Same as {#query_payment_status}, but additional information is returned in
# a Hash.
#
@@ -235,27 +189,32 @@
#
# @return [Hash] transaction payment details
def query_payment_details(merchant_reference, transaction_tracking_id)
# initialize setting of @params (oauth_signature left empty)
@params = Pesapal::Helper::Details.set_parameters(@config[:consumer_key], merchant_reference, transaction_tracking_id)
-
# generate oauth signature and add signature to the request parameters
- @params[:oauth_signature] = Pesapal::Oauth.generate_oauth_signature('GET', @api_endpoints[:querypaymentdetails], @params, @config[:consumer_secret], @token_secret)
-
+ @params[:oauth_signature] = Pesapal::Oauth.generate_oauth_signature(
+ 'GET',
+ querypaymentdetails_url,
+ @params,
+ @config[:consumer_secret],
+ @token_secret
+ )
# change params (with signature) to a query string
query_string = Pesapal::Oauth.generate_encoded_params_query_string @params
# get status response
- uri = URI.parse "#{@api_endpoints[:querypaymentdetails]}?#{query_string}"
+ uri = URI.parse "#{querypaymentdetails_url}?#{query_string}"
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true
http.verify_mode = OpenSSL::SSL::VERIFY_PEER
response = http.request(Net::HTTP::Get.new(uri.request_uri))
response = CGI.parse response.body
response = response['pesapal_response_data'][0].split(',')
- { method: response[1],
+ {
+ method: response[1],
status: response[2],
merchant_reference: response[3],
transaction_tracking_id: response[0]
}
end
@@ -288,71 +247,31 @@
# @return [String] the status of the transaction. Possible values include
# PENDING | COMPLETED | FAILED | INVALID
def query_payment_status(merchant_reference, transaction_tracking_id = nil)
# initialize setting of @params (oauth_signature left empty)
@params = Pesapal::Helper::Status.set_parameters(@config[:consumer_key], merchant_reference, transaction_tracking_id)
-
# generate oauth signature and add signature to the request parameters
- @params[:oauth_signature] = Pesapal::Oauth.generate_oauth_signature('GET', @api_endpoints[:querypaymentstatus], @params, @config[:consumer_secret], @token_secret)
-
+ @params[:oauth_signature] = Pesapal::Oauth.generate_oauth_signature(
+ 'GET',
+ querypaymentstatus_url,
+ @params,
+ @config[:consumer_secret],
+ @token_secret
+ )
# change params (with signature) to a query string
query_string = Pesapal::Oauth.generate_encoded_params_query_string @params
# get status response
- uri = URI.parse "#{@api_endpoints[:querypaymentstatus]}?#{query_string}"
+ uri = URI.parse "#{querypaymentstatus_url}?#{query_string}"
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true
http.verify_mode = OpenSSL::SSL::VERIFY_PEER
response = http.request(Net::HTTP::Get.new(uri.request_uri))
response = CGI.parse response.body
response['pesapal_response_data'][0]
end
- # Set the environment in use.
- #
- # Useful especially if you want to change the environment at runtime from
- # what was set during initialization in the constructor. It also makes sure
- # that we use the appropriate endpoints when making calls to Pesapal. See
- # below:
- #
- # ```
- # # endpoint values set if :development
- # {
- # :postpesapaldirectorderv4 => "http://demo.pesapal.com/API/PostPesapalDirectOrderV4",
- # :querypaymentstatus => "http://demo.pesapal.com/API/QueryPaymentStatus",
- # :querypaymentdetails => "http://demo.pesapal.com/API/QueryPaymentDetails"
- # }
- #
- # # endpoint values set if :production
- # {
- # :postpesapaldirectorderv4 => "https://www.pesapal.com/API/PostPesapalDirectOrderV4",
- # :querypaymentstatus => "https://www.pesapal.com/API/QueryPaymentStatus",
- # :querypaymentdetails => "https://www.pesapal.com/API/QueryPaymentDetails"
- # }
- # ```
- #
- # @note For a Rails app, you'd expect that calling this would also flip the
- # credentials if there was a YAML file containing both environment
- # credentials but that's not the case. It could be something that we can
- # add later.
- #
- # @param env [Symbol] the environment we want to use i.e. :development or
- # :production
- #
- # @return [Hash] contains Pesapal endpoints appropriate for the set
- # environment
- def change_env(env = false)
- env = env.to_s.downcase
- if env == 'production'
- @env = 'production'
- else
- @env = 'development'
- @env = Rails.env if defined?(Rails)
- end
- assign_endpoints
- end
-
# Generates the appropriate IPN response depending on the status of the
# transaction.
#
# ```ruby
# # pass in the notification type, merchant reference and transaction id
@@ -391,45 +310,40 @@
def ipn_listener(notification_type, merchant_reference, transaction_tracking_id)
notification_type = 'CHANGE'
status = query_payment_status(merchant_reference, transaction_tracking_id)
output = { status: status, response: nil }
+ response = "pesapal_notification_type=#{notification_type}"
+ response += "&pesapal_transaction_tracking_id=#{transaction_tracking_id}"
+ response += "&pesapal_merchant_reference=#{merchant_reference}"
+
case status
- when 'COMPLETED' then output[:response] = "pesapal_notification_type=#{notification_type}&pesapal_transaction_tracking_id=#{transaction_tracking_id}&pesapal_merchant_reference=#{merchant_reference}"
- when 'FAILED' then output[:response] = "pesapal_notification_type=#{notification_type}&pesapal_transaction_tracking_id=#{transaction_tracking_id}&pesapal_merchant_reference=#{merchant_reference}"
+ when 'COMPLETED' then output[:response] = response
+ when 'FAILED' then output[:response] = response
end
output
end
private
- # Assign API endpoints depending on the environment.
- def assign_endpoints
- if @env == 'production'
- @api_domain = 'https://www.pesapal.com'
- else
- @api_domain = 'https://demo.pesapal.com'
- end
+ def api_domain
+ @env == 'production' ? 'www.pesapal.com' : 'demo.pesapal.com'
+ end
- @api_endpoints = {}
- @api_endpoints[:postpesapaldirectorderv4] = "#{@api_domain}/API/PostPesapalDirectOrderV4"
- @api_endpoints[:querypaymentstatus] = "#{@api_domain}/API/QueryPaymentStatus"
- @api_endpoints[:querypaymentdetails] = "#{@api_domain}/API/QueryPaymentDetails"
+ def api_endpoint
+ 'https://' + api_domain
+ end
- @api_endpoints
+ def postpesapaldirectorderv4_url
+ api_endpoint + '/API/PostPesapalDirectOrderV4'
end
- # Configure credentials through hash that passed in (does a little
- # processing to remove unwanted data & uses default if nothing is input).
- def configure(consumer_details = {})
- @config = { callback_url: 'http://0.0.0.0:3000/pesapal/callback',
- consumer_key: '<YOUR_CONSUMER_KEY>',
- consumer_secret: '<YOUR_CONSUMER_SECRET>'
- }
+ def querypaymentstatus_url
+ api_endpoint + '/API/QueryPaymentStatus'
+ end
- valid_config_keys = @config.keys
-
- consumer_details.each { |k, v| @config[k.to_sym] = v if valid_config_keys.include? k.to_sym }
+ def querypaymentdetails_url
+ api_endpoint + '/API/QueryPaymentDetails'
end
end
end