forked from activemerchant/active_merchant
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
7 changed files
with
481 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,175 @@ | ||
require "nokogiri" | ||
|
||
module ActiveMerchant #:nodoc: | ||
module Billing #:nodoc: | ||
class IppGateway < Gateway | ||
self.live_url = 'https://www.ippayments.com.au/interface/api/dts.asmx' | ||
self.test_url = 'https://demo.ippayments.com.au/interface/api/dts.asmx' | ||
|
||
self.supported_countries = ['AU'] | ||
self.supported_cardtypes = [:visa, :master, :american_express, :diners_club, :jcb] | ||
|
||
self.homepage_url = 'http://www.ippayments.com.au/' | ||
self.display_name = 'IPP' | ||
|
||
self.money_format = :cents | ||
|
||
STANDARD_ERROR_CODE_MAPPING = { | ||
"05" => STANDARD_ERROR_CODE[:card_declined], | ||
"06" => STANDARD_ERROR_CODE[:processing_error], | ||
"14" => STANDARD_ERROR_CODE[:invalid_number], | ||
"54" => STANDARD_ERROR_CODE[:expired_card], | ||
} | ||
|
||
def initialize(options={}) | ||
requires!(options, :username, :password) | ||
super | ||
end | ||
|
||
def purchase(money, payment, options={}) | ||
commit("SubmitSinglePayment") do |xml| | ||
xml.Transaction do | ||
xml.CustRef options[:order_id] | ||
add_amount(xml, money) | ||
xml.TrnType "1" | ||
add_credit_card(xml, payment) | ||
add_credentials(xml) | ||
xml.TrnSource options[:ip] | ||
end | ||
end | ||
end | ||
|
||
def authorize(money, payment, options={}) | ||
commit("SubmitSinglePayment") do |xml| | ||
xml.Transaction do | ||
xml.CustRef options[:order_id] | ||
add_amount(xml, money) | ||
xml.TrnType "2" | ||
add_credit_card(xml, payment) | ||
add_credentials(xml) | ||
xml.TrnSource options[:ip] | ||
end | ||
end | ||
end | ||
|
||
def capture(money, authorization, options={}) | ||
commit("SubmitSingleCapture") do |xml| | ||
xml.Capture do | ||
xml.Receipt authorization | ||
add_amount(xml, money) | ||
add_credentials(xml) | ||
end | ||
end | ||
end | ||
|
||
def refund(money, authorization, options={}) | ||
commit("SubmitSingleRefund") do |xml| | ||
xml.Refund do | ||
xml.Receipt authorization | ||
add_amount(xml, money) | ||
add_credentials(xml) | ||
end | ||
end | ||
end | ||
|
||
def supports_scrubbing? | ||
true | ||
end | ||
|
||
def scrub(transcript) | ||
transcript. | ||
gsub(%r((<CardNumber>)[^<]+(<))i, '\1[FILTERED]\2'). | ||
gsub(%r((<CVN>)[^<]+(<))i, '\1[FILTERED]\2'). | ||
gsub(%r((<Password>)[^<]+(<))i, '\1[FILTERED]\2') | ||
end | ||
|
||
private | ||
|
||
def add_credentials(xml) | ||
xml.Security do | ||
xml.UserName @options[:username] | ||
xml.Password @options[:password] | ||
end | ||
end | ||
|
||
def add_amount(xml, money) | ||
xml.Amount amount(money) | ||
end | ||
|
||
def add_credit_card(xml, payment) | ||
xml.CreditCard :Registered => "False" do | ||
xml.CardNumber payment.number | ||
xml.ExpM format(payment.month, :two_digits) | ||
xml.ExpY format(payment.year, :four_digits) | ||
xml.CVN payment.verification_value | ||
xml.CardHolderName payment.name | ||
end | ||
end | ||
|
||
def parse(body) | ||
element = Nokogiri::XML(body).root.first_element_child.first_element_child | ||
|
||
response = {} | ||
doc = Nokogiri::XML(element) | ||
doc.root.elements.each do |e| | ||
response[e.name.underscore.to_sym] = e.inner_text | ||
end | ||
response | ||
end | ||
|
||
def commit(action, &block) | ||
headers = { | ||
"Content-Type" => "text/xml; charset=utf-8", | ||
"SOAPAction" => "http://www.ippayments.com.au/interface/api/dts/#{action}", | ||
} | ||
response = parse(ssl_post(commit_url, new_submit_xml(action, &block), headers)) | ||
|
||
Response.new( | ||
success_from(response), | ||
message_from(response), | ||
response, | ||
authorization: authorization_from(response), | ||
error_code: error_code_from(response), | ||
test: test?, | ||
) | ||
end | ||
|
||
def new_submit_xml(action) | ||
xml = Builder::XmlMarkup.new(indent: 2) | ||
xml.instruct! | ||
xml.soap :Envelope, "xmlns:xsi" => "http://www.w3.org/2001/XMLSchema-instance", "xmlns:xsd" => "http://www.w3.org/2001/XMLSchema", "xmlns:soap" => "http://schemas.xmlsoap.org/soap/envelope/" do | ||
xml.soap :Body do | ||
xml.__send__(action, "xmlns" => "http://www.ippayments.com.au/interface/api/dts") do | ||
xml.trnXML do | ||
inner_xml = Builder::XmlMarkup.new(indent: 2) | ||
yield(inner_xml) | ||
xml.cdata!(inner_xml.target!) | ||
end | ||
end | ||
end | ||
end | ||
xml.target! | ||
end | ||
|
||
def commit_url | ||
(test? ? test_url : live_url) | ||
end | ||
|
||
def success_from(response) | ||
(response[:response_code] == "0") | ||
end | ||
|
||
def error_code_from(response) | ||
STANDARD_ERROR_CODE_MAPPING[response[:declined_code]] | ||
end | ||
|
||
def message_from(response) | ||
response[:declined_message] | ||
end | ||
|
||
def authorization_from(response) | ||
response[:receipt] | ||
end | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,84 @@ | ||
require 'test_helper' | ||
|
||
class RemoteIppTest < Test::Unit::TestCase | ||
def setup | ||
@gateway = IppGateway.new(fixtures(:ipp)) | ||
|
||
@credit_card = credit_card('4005550000000001') | ||
|
||
@options = { | ||
order_id: '1', | ||
billing_address: address, | ||
description: 'Store Purchase', | ||
} | ||
end | ||
|
||
def test_dump_transcript | ||
skip("Transcript scrubbing for this gateway has been tested.") | ||
dump_transcript_and_fail(@gateway, @amount, @credit_card, @options) | ||
end | ||
|
||
def test_transcript_scrubbing | ||
transcript = capture_transcript(@gateway) do |gateway| | ||
gateway.purchase(@amount, @credit_card, @options) | ||
end | ||
transcript = @gateway.scrub(transcript) | ||
|
||
assert_scrubbed(@credit_card.number, transcript) | ||
assert_scrubbed(@credit_card.verification_value, transcript) | ||
assert_scrubbed(@gateway.options[:password], transcript) | ||
end | ||
|
||
def test_successful_purchase | ||
response = @gateway.purchase(200, @credit_card, @options) | ||
assert_success response | ||
assert_equal '', response.message | ||
end | ||
|
||
def test_failed_purchase | ||
response = @gateway.purchase(105, @credit_card, @options) | ||
assert_failure response | ||
assert_equal 'Do Not Honour', response.message | ||
assert_equal Gateway::STANDARD_ERROR_CODE[:card_declined], response.error_code | ||
end | ||
|
||
def test_successful_authorize_and_capture | ||
response = @gateway.authorize(200, @credit_card, @options) | ||
assert_success response | ||
response = @gateway.capture(200, response.authorization) | ||
assert_success response | ||
end | ||
|
||
def test_failed_authorize | ||
response = @gateway.authorize(105, @credit_card, @options) | ||
assert_failure response | ||
end | ||
|
||
def test_failed_capture | ||
response = @gateway.capture(200, '') | ||
assert_failure response | ||
end | ||
|
||
def test_successful_refund | ||
response = @gateway.purchase(200, @credit_card, @options) | ||
response = @gateway.refund(200, response.authorization, @options) | ||
assert_success response | ||
assert_equal '', response.message | ||
end | ||
|
||
def test_failed_refund | ||
response = @gateway.purchase(200, @credit_card, @options) | ||
response = @gateway.refund(105, response.authorization, @options) | ||
assert_failure response | ||
assert_equal 'Do Not Honour', response.message | ||
end | ||
|
||
def test_invalid_login | ||
gateway = IppGateway.new( | ||
username: '', | ||
password: '', | ||
) | ||
response = gateway.purchase(200, @credit_card, @options) | ||
assert_failure response | ||
end | ||
end |
Oops, something went wrong.