module ActiveMerchant #:nodoc: module Billing #:nodoc: class Ipay88Gateway < Gateway TEST_URL = '' LIVE_URL = 'https://www.ipay88.com/recurringpayment/webservice/RecurringPayment.asmx/Subscription' # The countries the gateway supports merchants from as 2 digit ISO country codes self.supported_countries = ['MY'] # The card types supported by the payment gateway self.supported_cardtypes = [:visa, :master] # The homepage URL of the gateway self.homepage_url = 'https://www.ipay88.com/recurringpayment/webservice' # The name of the gateway self.display_name = 'iPay88' # Creates a new Ipay88Gateway # # The gateway requires that a valid login and password be passed # in the +options+ hash. # # ==== Options # # * <tt>:login</tt> -- The ipay88 Merchant Code (REQUIRED) # * <tt>:password</tt> -- The ipay88 Merchant Code (REQUIRED) def initialize(options = {}) requires!(options, :login, :password) @options = options super end def recurring(money, creditcard, options = {}) post = {} add_merchant_authentication(post, options) add_invoice(post, options) add_creditcard(post, creditcard, options) add_customer_data(post, options) add_address(post, options) add_signature(post, options) recurring_commit("subscribe", post) end private def add_merchant_authentication(post, options) post["MerchantCode"] = @options[:login] post["BackendURL"] = options[:backend_url] end def add_invoice(post, options) post["RefNo"] = options[:reference_no] post["FirstPaymentDate"] = options[:first_payment_date] post["Currency"] = "MYR" post["Amount"] = amount(options[:amount]) post["NumberOfPayments"] = options[:number_of_payments] post["Frequency"] = options[:frequency] post["Desc"] = options[:description] end def add_creditcard(post, creditcard, options) post["CC_PAN"] = creditcard.number post["CC_CVC"] = creditcard.verification_value if creditcard.verification_value? post["CC_ExpiryDate"] = expdate(creditcard) post["CC_Name"] = creditcard.name post["CC_Country"] = options[:cc_country] post["CC_Bank"] = options[:cc_bank] post["CC_Ic"] = options[:cc_ic] post["CC_Email"] = options[:cc_email] post["CC_Phone"] = options[:cc_phone] post["CC_Remark"] = options[:cc_remark] end def add_customer_data(post, options) post["P_Name"] = options[:name] post["P_Email"] = options[:email] post["P_Phone"]= options[:phone] end def add_address(post, options) post["P_Addrl1"] = options[:address_line1] post["P_Addrl2"] = options[:address_line2] post["P_City"] = options[:city] post["P_State"] = options[:state] post["P_Zip"] = options[:zipcode] post["P_Country"] = options[:country] end def add_signature(post, options) hash_components = [post["MerchantCode"]] hash_components << @options[:password] hash_components << post["RefNo"] hash_components << post["FirstPaymentDate"] hash_components << post["Currency"] hash_components << options[:amount] # Amount in cents hash_components << post["NumberOfPayments"] hash_components << post["Frequency"] hash_components << post["CC_PAN"] hash_string = hash_components.join post["Signature"] = [Digest::SHA1.digest(hash_string)].pack("m").chomp end def recurring_commit(action, parameters) request = post_data(action, parameters) xml = ssl_post LIVE_URL, request response = recurring_parse(xml) message = response[:errdesc] success = response[:status] == "1" Response.new(success, message, response, :authorization => response[:subscription_no] ) end def recurring_parse(xml) response = {} xml = REXML::Document.new(xml) root = REXML::XPath.first(xml, "//SubscriptionDetails") if root root.elements.to_a.each do |node| recurring_parse_element(response, node) end end response end def recurring_parse_element(response, node) if node.has_elements? node.elements.each{|e| recurring_parse_element(response, e) } else response[node.name.underscore.to_sym] = node.text end end def post_data(action, parameters = {}) post = {} request = post.merge(parameters).collect { |key, value| "#{key}=#{CGI.escape(value.to_s)}" }.join("&") request end def expdate(creditcard) year = sprintf("%.4i", creditcard.year) month = sprintf("%.2i", creditcard.month) "#{month}#{year}" end end end end