Integrate with SecurePayTech (NZ credit card gateway)

by Jasper Bryant-Greene - Member - 06:32AM, Oct 07, 2007

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

Last edited 06:33AM, Oct 07, 2007

danW

Shopify Advisor

02:26AM, Oct 08, 2007

http://www.activemerchant.org/

Jasper Bryant-Greene

Member

10:57AM, Oct 08, 2007

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

Member

11:24AM, Oct 08, 2007

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

cody

jaded Pixel

02:02AM, Oct 15, 2007

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

Jasper Bryant-Greene

Member

08:20PM, Oct 17, 2007

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

tobi

jaded Pixel

01:48PM, Oct 18, 2007

awesome Jasper!

---

Tobias Lütke
Shopify – Founder, CTO

cody

jaded Pixel

05:48PM, Oct 23, 2007

Jasper,

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

You must login to post a comment!

Don't have an account yet? Sign up for one.