Last edited 06:33AM, Oct 07, 2007

Jasper Bryant-Greene Member

Integrate with SecurePayTech (NZ credit card gateway) This post is outdated

I'm a Shopify user based in New Zealand, and I've recently set my father's business up on Shopify too. We both use SecurePayTech for processing credit cards - a New Zealand-based gateway. There's a bunch of other people that I'd refer to Shopify too, but currently it has no support for this gateway, which is pretty popular in NZ. SecurePayTech's documentation is public, and the API's a pretty simple SOAP one: http://www.securepaytech.com/developers/documentation/SPT-Developer-Documentation.pdf Is there any chance integration with this could be written? I could potentially do it myself, as I'm reasonably experienced with Ruby, but last time I looked I couldn't find any documentation for Shopify's payment gateway API at all. Given that there's already two stores wanting to use it, and I will refer at least two more once it's available as a gateway, it could be worth your time anyway :) Thanks, Jasper
Jasper Bryant-Greene

02:26AM, Oct 08, 2007

danW Shopify Advisor

http://www.activemerchant.org/

10:57AM, Oct 08, 2007

Jasper Bryant-Greene Member

Yep, I know that’s the home of Shopify’s payment gateway code. But there’s (as far as I can see) zero documentation on writing new gateway classes. All the documentation is centred on using ActiveMerchant, rather than on extending it.

I can probably work from an example; does anyone know if any of the currently implemented gateways use SOAP? This could be interesting as I’ve generally found SOAP client support in Ruby to be terrible.

Jasper Bryant-Greene

11:24AM, Oct 08, 2007

Jasper Bryant-Greene Member

One SecurePayTech class for Active Merchant below. I based this on the HttpsPostPurchase interface rather than SOAP, and it only supports purchase currently.

module ActiveMerchant
  module Billing
    class SecurePayTechGateway < Gateway
      class SecurePayTechPostData < PostData
        # Fields that will be sent even if they are blank
        self.required_fields = [ :OrderReference, :CardNumber, :CardExpiry, :CardHolderName, :CardType, :MerchantID, :MerchantKey, :Amount, :Currency ]
      end                                                  

      URL = 'https://tx.securepaytech.com/web/HttpPostPurchase'

      PAYMENT_GATEWAY_RESPONSES = {
        1 => "Transaction OK",
        2 => "Insufficient funds",
        3 => "Card expired",
        4 => "Card declined",
        5 => "Server error occurred",
        6 => "Communications error",
        7 => "Unsupported transaction type",
        8 => "Bad or malformed request",
        9 => "Invalid card number" 
      }

      # URL
      attr_reader :response
      attr_reader :options

      self.default_currency = 'NZD'
      self.supported_countries = ['NZ']
      self.supported_cardtypes = [:visa, :master, :american_express, :diners_club]
      self.homepage_url = 'http://www.securepaytech.com/'
      self.display_name = "SecurePayTech" 

      def initialize(options = {})
        requires!(options, :merchant_id, :merchant_key)
        @options = options
        super
      end

      def purchase(money, creditcard, options = {})
        post = SecurePayTechPostData.new

        add_amount(post, money, options)
        add_creditcard(post, creditcard)
        add_invoice_data(post, options)

        commit(:purchase, post)
      end  

      private                                 
      def commit(action, post)
        if result = test_result_from_cc_number(post[:card_number])
          return result
        end

        data = ssl_post(URL, post_data(action, post))

        @response = parse(data)

        success = (@response[:result_code] == 1)
        message = success ? 'Success' : message_from(@response)

        Response.new(success, message, @response, 
          :test => test?, 
          :authorization => @response[:merchant_transation_reference]
        )
      end

      def parse(body)
        response = CGI.unescape(body).split(',')

        result = {}
        result[:result_code] = response[0]

        if response.length == 2
          result[:fail_reason] = response[1]
        else
          result[:merchant_transaction_reference] = response[1]
          result[:receipt_number]                 = response[2]
          result[:transaction_number]             = response[3]
          result[:authorisation_id]               = response[4]
          result[:batch_number]                   = response[5]
        end

        result
      end     

      def post_data(action, post)
        post[:MerchantID]  = @options[:merchant_id]
        post[:MerchantKey] = @options[:merchant_key]
        post.to_s
      end

      def add_creditcard(post, creditcard)      
        post[:CardNumber]     = creditcard.number
        post[:CardExpiry]     = expdate(creditcard)
        post[:CardHolderName] = creditcard.name

        # SecurePayTech always autodetects this
        post[:CardType]       = 0
      end

      def add_invoice_data(post, options)
        post[:OrderReference] = options[:order_id]
      end

      def add_amount(post, money, options)
        post[:Amount] = amount(money)

        # SecurePayTech currently only supports NZD anyway, but for possible future expansion...
        post[:Currency] = options[:currency] || currency(money)
      end

      # Make a ruby type out of the response string
      def normalize(field)
        case field
        when "true"   then true
        when "false"  then false
        when ""       then nil
        when "null"   then nil
        else field
        end        
      end          

      def message_from(result)
        PAYMENT_GATEWAY_RESPONSES[result[:result_code]]
      end

      def expdate(creditcard)
        year  = sprintf("%.4i", creditcard.year)
        month = sprintf("%.2i", creditcard.month)

        "#{month}#{year[-2..-1]}" 
      end
    end
  end
end
Jasper Bryant-Greene

Last edited 02:04AM, Oct 15, 2007

cody Shopify

Nice work. Can you create a patch as described in the contribution guide, preferably with some tests :)

Cody Fauser Shopify – CTO

08:20PM, Oct 17, 2007

Jasper Bryant-Greene Member

I’ve created a patch, including tests, and posted it to your bug tracker as issue #77.

Jasper Bryant-Greene

01:48PM, Oct 18, 2007

tobi Shopify

awesome Jasper!

Tobias Lütke - Shopify CEO // http://twitter.com/tobi

05:48PM, Oct 23, 2007

cody Shopify

Jasper,

SecurePayTech is now available in Shopify. Great job on the gateway.

Cody Fauser Shopify – CTO

This thread has been closed! You will not be able to reply.