lib/paynow_sdk.rb in paynow_sdk-0.1.8 vs lib/paynow_sdk.rb in paynow_sdk-0.1.9
- old
+ new
@@ -1,9 +1,11 @@
require "paynow_sdk/version"
-require "httparty"
require "cgi"
require "digest"
+require "httparty"
+require "uri"
+require "rest-client"
#throws error when hash from Paynow does not match locally generated hash
class HashMismatchException < Exception
def initialize(message)
@@ -11,22 +13,22 @@
end
end
class StatusResponse
@@paid = true
- @@status = String
+ @@status = ""
@@amount = Float
- @@reference = String
- @@paynow_reference = String
- @@hash = String
+ @@reference = ""
+ @@paynow_reference = ""
+ @@hash = ""
def __status_update(data)
return "Not implemented"
end
def initialize(data, update)
- if is_bool(update)
+ if update
__status_update(data)
else
@status = data["status"].downcase
@paid = @status == "paid"
if data.include?("amount")
@@ -81,30 +83,29 @@
def hash=(val); @hash = val; end
end
class InitResponse
@@success = true
- @@instructions = String
+ @@instructions = ""
@@has_redirect = true
- @@hash = String
- @@redirect_url = String
- @@error = String
- @@poll_url = String
+ @@hash = ""
+ @@redirect_url = ""
+ @@error = ""
+ @@poll_url = ""
def initialize(data)
@status = data["status"]
@success = data["status"].downcase != "error"
@has_redirect = data.include?("browserurl")
@hash = data.include?("hash")
- if is_bool(!@success)
- return
+ if !@success
+ @poll_url = data["pollurl"]
end
- @poll_url = data["pollurl"]
- if is_bool(!@success)
+ if !@success
@error = data["error"]
end
- if is_bool(@has_redirect)
+ if @has_redirect
@redirect_url = data["browserurl"]
end
if data.include?("instructions")
@instruction = data["instructions"]
end
@@ -152,39 +153,39 @@
def poll_url; @poll_url = @@poll_url if @poll_url.nil?; @poll_url; end
def poll_url=(val); @poll_url = val; end
end
class Payment
- @@reference = String
+ @@reference = ""
@@items = []
- @@auth_email = String
+ @@auth_email = ""
def initialize(reference, auth_email)
@reference = reference
@auth_email = auth_email
end
def add(title, amount)
@items = []
@items.push([title, amount])
- return self
+ self
end
- def total()
+ def total
total = 0.0
for item in @items
total += item[1].to_f
end
- return total
+ total
end
- def info()
+ def info
out = ""
for item in @items
out += item[0] + ", "
end
- return out
+ out
end
def self.reference; @@reference; end
def self.reference=(val); @@reference = val; end
@@ -203,14 +204,14 @@
def auth_email; @auth_email = @@auth_email if @auth_email.nil?; @auth_email; end
def auth_email=(val); @auth_email = val; end
end
class Paynow
- @@url_initiate_transaction = URI("https://www.paynow.co.zw/interface/initiatetransaction")
- @@url_initiate_mobile_transaction = "https://www.paynow.co.zw/interface/remotetransaction"
- @@integration_id = String
- @@integration_key = String
+ @@url_initiate_transaction = "https://www.paynow.co.zw/interface/initiatetransaction/"
+ @@url_initiate_mobile_transaction = "https://www.paynow.co.zw/interface/remotetransaction/"
+ @@integration_id = ""
+ @@integration_key = ""
@@return_url = ""
@@result_url = ""
def initialize(integration_id, integration_key, return_url, result_url)
@integration_id = integration_id
@@ -226,127 +227,117 @@
def set_return_url(url)
@return_url = url
end
def create_payment(reference, auth_email)
- return Payment.new(reference, auth_email)
+ Payment.new(reference, auth_email)
end
def send(payment)
- return __init(payment)
+ init(payment)
end
def send_mobile(payment, phone, method)
- return __init_mobile(payment, phone, method)
+ init_mobile(payment, phone, method)
end
def process_status_update(data)
- return StatusResponse.new(data, true)
+ StatusResponse.new(data, true)
end
- def qs_to_hash(querystring)
- keyvals = querystring.split("&").inject({}) do |result, q|
- k, v = q.split("=")
- if !v.nil?
- result.merge({ k => v })
- elsif !result.key?(k)
- result.merge({ k => true })
- else
- result
- end
- end
- keyvals
- end
+ # def qs_to_hash(querystring)
+ # keyvals = querystring.split("&").inject({}) do |result, q|
+ # k, v = q.split("=")
+ # if !v.nil?
+ # result.merge({ k => v })
+ # elsif !result.key?(k)
+ # result.merge({ k => true })
+ # else
+ # result
+ # end
+ # end
+ # keyvals
+ # end
- def __init(payment)
- if payment.total() <= 0
+ def init(payment)
+ if payment.total <= 0
raise TypeError, "Transaction total cannot be less than 1"
end
- data = __build(payment)
- response = HTTParty.post(@url_initiate_transaction, data)
- response_object = __rebuild_response(CGI.parse(response))
- if response_object["status"].to_s.downcase == "error"
- return InitResponse.new(response_object)
- end
- if is_bool(!__verify_hash(response_object, @integration_key))
- raise HashMismatchException, "Hashes do not match"
- end
- return InitResponse.new(response_object)
- end
+ data = build(payment)
- def __init_mobile(payment, phone, method)
- if payment.total() <= 0
- raise TypeError, "Transaction total cannot be less than 1"
- end
- if is_bool(!payment.auth_email || payment.auth_email.size <= 0)
- raise TypeError, "Auth email is required for mobile transactions. You can pass the auth email as the second parameter in the create_payment method call"
- end
- data = __build_mobile(payment, phone, method)
- response = HTTParty.post(@url_initiate_mobile_transaction, data)
- response_object = __rebuild_response(CGI.parse(response))
+ response = RestClient.post("https://www.paynow.co.zw/interface/initiatetransaction/", data)
+ response_object = rebuild_response(response)
+
if response_object["status"].to_s.downcase == "error"
- return InitResponse.new(response_object)
+ InitResponse.new(response_object)
end
- if is_bool(!__verify_hash(response_object, @integration_key))
- raise HashMismatchException, "Hashes do not match"
- end
- return InitResponse.new(response_object)
+ # if !verify_hash(response_object, @integration_key)
+ # raise HashMismatchException, "Hashes do not match"
+ # end
+ InitResponse.new(response_object)
end
+ # def init_mobile(payment, phone, method)
+ # if payment.total <= 0
+ # raise TypeError, "Transaction total cannot be less than 1"
+ # end
+ # if is_bool(!payment.auth_email || payment.auth_email.size <= 0)
+ # raise TypeError, "Auth email is required for mobile transactions. You can pass the auth email as the second parameter in the create_payment method call"
+ # end
+ # data = build_mobile(payment, phone, method)
+ # response = HTTParty.post(@url_initiate_mobile_transaction, data)
+ # response_object = rebuild_response(response)
+ # if response_object["status"].to_s.downcase == "error"
+ # InitResponse.new(response_object)
+ # end
+ # if is_bool(!verify_hash(response_object, @integration_key))
+ # raise HashMismatchException, "Hashes do not match"
+ # end
+ # InitResponse.new(response_object)
+ # end
+
def check_transaction_status(poll_url)
response = HTTParty.post(poll_url, data: {})
- response_object = __rebuild_response(CGI.parse(response))
- return StatusResponse.new(response_object, false)
+ response_object = rebuild_response(response)
+ StatusResponse.new(response_object, false)
end
- def __build(payment)
- body = { "resulturl" => @result_url, "returnurl" => @return_url, "reference" => payment.reference, "amount" => payment.total(), "id" => @integration_id, "additionalinfo" => payment.info(), "authemail" => payment.auth_email || "", "status" => "Message" }
- for (key, value) in body
- body[key] = CGI::escape(value.to_s)
- end
- body["hash"] = __hash(body, @integration_key)
+ def build(payment)
+ body = { "resulturl": @result_url, "returnurl": @return_url, "reference": payment.reference, "amount": payment.total, "id": @integration_id, "additionalinfo": payment.info, "authemail": payment.auth_email || "", "status": "Message" }
+ joined = body.values.join.to_s
+ add_key = joined += @integration_key
+ body["hash"] = createdhash(add_key)
+ body = URI.encode_www_form(body)
body
end
- def __build_mobile(payment, phone, method)
- body = { "resulturl" => @result_url, "returnurl" => @return_url, "reference" => payment.reference, "amount" => payment.total(), "id" => @integration_id, "additionalinfo" => payment.info(), "authemail" => payment.auth_email, "phone" => phone, "method" => method, "status" => "Message" }
- for (key, value) in body
- if key == "authemail"
- next
- end
- body[key] = CGI::escape(value.to_s)
- end
- body["hash"] = __hash(body, @integration_key)
+ def build_mobile(payment, phone, method)
+ body = { "resulturl": @result_url, "returnurl": @return_url, "reference": payment.reference, "amount": payment.total, "id": @integration_id, "additionalinfo": payment.info, "authemail": payment.auth_email, "phone": phone, "method": method, "status": "Message" }
+ joined = body.values.join.to_s
+ add_key = joined += @integration_key
+ body["hash"] = createdhash(add_key)
+ body = URI.encode_www_form(body)
body
end
- def __hash(items, integration_key)
- out = ""
- for (key, value) in items
- if key.to_s.downcase == "hash"
- next
- end
- out += value.to_s
- end
- out += integration_key.downcase
+ def createdhash(out)
Digest::SHA2.new(512).hexdigest(out).upcase
end
- def __verify_hash(response, integration_key)
- if !response.include?("hash")
- raise TypeError, "Response from Paynow does not contain a hash"
- end
- old_hash = response["hash"]
- new_hash = __hash(response, integration_key)
- return old_hash == new_hash
- end
+ #verify the hash send to paynow is equal to the hash from paynow
+ # def verify_hash(response)
+ # # if !response.include?("hash")
+ # # raise TypeError, "Response from Paynow does not contain a hash"
+ # # end
+ # old_hash = response["hash"]
+ # new_hash = createdhash(response)
+ # old_hash == new_hash
+ # end
- def __rebuild_response(response)
- res = {}
- for (key, value) in response.to_a
- res[key] = value[0].to_s
- end
- return res
+ # rebuild a response from paynow into hash like the we send
+
+ def rebuild_response(response)
+ URI.decode_www_form(response).to_h
end
def self.url_initiate_transaction; @@url_initiate_transaction; end
def self.url_initiate_transaction=(val); @@url_initiate_transaction = val; end