Browse files

Implement statusRequest

  • Loading branch information...
1 parent 118b9c7 commit 837aaf04844bf08ade1b07ed6664771c54469236 @exviva committed Sep 26, 2012
View
6 README.md
@@ -40,6 +40,12 @@ The `response` hash will contain amongst other keys two important ones: `transac
The `transactionID` identifies the transaction at ClickandBuy, make sure you store it together with your order.
The `redirectURL` is where you redirect the user so that they can confirm the purchase.
+After a user lands on `success_url`, you can check whether or not the transaction had been confirmed:
+
+ transaction = gateway.check_status(transaction_id)
+
+The `transaction` variable is a hash containing the response details, amongst others a `transactionStatus` key.
+
## Running specs
Copy `spec/support/clickand_buy.yml.example` to `spec/support/clickand_buy.yml`. Now run:
View
5 lib/active_merchant/billing/clickand_buy_gateway.rb
@@ -1,4 +1,5 @@
require 'active_merchant/clickand_buy/request/pay_request'
+require 'active_merchant/clickand_buy/request/status_request'
module ActiveMerchant
module Billing
@@ -13,6 +14,10 @@ def setup_purchase(amount, options)
perform(ClickandBuy::Request::PayRequest.new(@auth, amount, options))
end
+ def check_status(transaction_id)
+ perform(ClickandBuy::Request::StatusRequest.new(@auth, transaction_id))
+ end
+
private
def perform(request)
response_string = ssl_post(endpoint_url, request.body, headers)
View
58 lib/active_merchant/clickand_buy/request/base.rb
@@ -0,0 +1,58 @@
+module ActiveMerchant::ClickandBuy::Request
+ class Base
+ def initialize(auth)
+ @auth = auth
+ end
+
+ def body
+ xml = Builder::XmlMarkup.new
+ xml.instruct!
+
+ xml.SOAP :Envelope, 'xmlns:SOAP' => 'http://schemas.xmlsoap.org/soap/envelope/' do
+ xml.SOAP :Body do
+ xml.tag! request_tag, xmlns: 'http://api.clickandbuy.com/webservices/pay_1_1_0/' do
+ xml.authentication do
+ xml.merchantID @auth[:merchant_id]
+ xml.projectID @auth[:project_id]
+ xml.token token
+ end
+
+ xml.details do
+ details(xml)
+ end
+ end
+ end
+ end
+
+ xml.target!
+ end
+
+ def handle_response(response_string)
+ response = Hash.from_xml(response_string)
+ extract_response_details(response['Envelope']['Body'][response_tag])
+ end
+
+ private
+ def details; raise NotImplementedError end
+ def extract_response_details(response); raise NotImplementedError end
+
+ def token
+ timestamp = Time.now.utc.strftime('%Y%m%d%H%M%S')
+ hash_input = [@auth[:project_id], @auth[:secret_key], timestamp].join('::')
+ hash = Digest::SHA1.hexdigest(hash_input)
+ [timestamp, hash].join('::')
+ end
+
+ def request_name
+ self.class.name.demodulize.camelize(:lower)
+ end
+
+ def request_tag
+ "#{request_name}_Request"
+ end
+
+ def response_tag
+ "#{request_name}_Response"
+ end
+ end
+end
View
79 lib/active_merchant/clickand_buy/request/pay_request.rb
@@ -1,60 +1,31 @@
-module ActiveMerchant
- module ClickandBuy
- module Request
- class PayRequest
- def initialize(auth, amount, options)
- @auth = auth
- @amount = amount
- @options = options
- end
+require 'active_merchant/clickand_buy/request/base'
- def body
- xml = Builder::XmlMarkup.new
- xml.instruct!
-
- xml.SOAP :Envelope, 'xmlns:SOAP' => 'http://schemas.xmlsoap.org/soap/envelope/' do
- xml.SOAP :Body do
- xml.payRequest_Request xmlns: 'http://api.clickandbuy.com/webservices/pay_1_1_0/' do
- xml.authentication do
- xml.merchantID @auth[:merchant_id]
- xml.projectID @auth[:project_id]
- xml.token token
- end
-
- xml.details do
- xml.amount do
- xml.amount sprintf('%.2f', @amount.to_f)
- xml.currency @amount.currency_as_string
- end
- xml.orderDetails do
- xml.text @options[:order_description]
- end
- xml.successURL @options[:success_url]
- xml.failureURL @options[:failure_url]
- xml.externalID @options[:order_id]
- xml.consumerIPAddress @options[:ip]
- xml.consumerLanguage @options[:locale]
- end
- end
- end
- end
-
- xml.target!
- end
-
- def handle_response(response_string)
- response = Hash.from_xml(response_string)
- response['Envelope']['Body']['payRequest_Response']['transaction']
- end
+module ActiveMerchant::ClickandBuy::Request
+ class PayRequest < Base
+ def initialize(auth, amount, options)
+ super(auth)
+ @amount = amount
+ @options = options
+ end
- private
- def token
- timestamp = Time.now.utc.strftime('%Y%m%d%H%M%S')
- hash_input = [@auth[:project_id], @auth[:secret_key], timestamp].join('::')
- hash = Digest::SHA1.hexdigest(hash_input)
- [timestamp, hash].join('::')
- end
+ private
+ def details(xml)
+ xml.amount do
+ xml.amount sprintf('%.2f', @amount.to_f)
+ xml.currency @amount.currency_as_string
+ end
+ xml.orderDetails do
+ xml.text @options[:order_description]
end
+ xml.successURL @options[:success_url]
+ xml.failureURL @options[:failure_url]
+ xml.externalID @options[:order_id]
+ xml.consumerIPAddress @options[:ip]
+ xml.consumerLanguage @options[:locale]
+ end
+
+ def extract_response_details(response)
+ response['transaction']
end
end
end
View
21 lib/active_merchant/clickand_buy/request/status_request.rb
@@ -0,0 +1,21 @@
+require 'active_merchant/clickand_buy/request/base'
+
+module ActiveMerchant::ClickandBuy::Request
+ class StatusRequest < Base
+ def initialize(auth, transaction_id)
+ super(auth)
+ @transaction_id = transaction_id
+ end
+
+ private
+ def details(xml)
+ xml.transactionIDList do
+ xml.transactionID @transaction_id
+ end
+ end
+
+ def extract_response_details(response)
+ response['transactionList']['transaction']
+ end
+ end
+end
View
35 spec/active_merchant/billing/clickand_buy_gateway_spec.rb
@@ -3,6 +3,13 @@
describe ActiveMerchant::Billing::ClickandBuyGateway do
let(:auth) { YAML.load_file(File.expand_path('../../../support/clickand_buy.yml', __FILE__)) }
let(:gateway) { described_class.new(auth) }
+ let(:amount) { Money.new(1000, 'EUR') }
+ let(:order_id) { Time.now.to_i }
+ let(:setup_purchase_options) { {success_url: 'http://example.com', failure_url: 'http://example.com', order_id: order_id, ip: '1.2.3.4', order_description: '', locale: 'en'} }
+
+ def perform_setup_purchase
+ gateway.setup_purchase(amount, setup_purchase_options)
+ end
describe '#initialize' do
[:project_id, :merchant_id, :secret_key].each do |key|
@@ -13,14 +20,11 @@
end
describe '#setup_purchase' do
- let(:amount) { Money.new(1000, 'EUR') }
- let(:order_id) { Time.now.to_i }
- let(:options) { {success_url: 'http://example.com', failure_url: 'http://example.com', order_id: order_id, ip: '1.2.3.4', order_description: '', locale: 'en'} }
- subject { gateway.setup_purchase(amount, options) }
+ subject { perform_setup_purchase }
[:success_url, :failure_url, :order_id, :ip, :order_description, :locale].each do |key|
context "without #{key} in options" do
- subject { gateway.setup_purchase(amount, options.except(key)) }
+ subject { gateway.setup_purchase(amount, setup_purchase_options.except(key)) }
it 'raises an argument error' do
expect { subject }.to raise_error(ArgumentError)
@@ -43,4 +47,25 @@
end
end
end
+
+ describe '#check_status', :remote do
+ let(:transaction_id) { '123' }
+ subject { gateway.check_status(transaction_id) }
+
+ it 'returns the transaction ID' do
+ subject['transactionID'].should eq('123')
+ end
+
+ it 'returns an error if transaction not found' do
+ subject['errorDetails']['code'].should eq('3')
+ end
+
+ context 'with a valid transaction ID' do
+ let(:transaction_id) { perform_setup_purchase['transactionID'] }
+
+ it 'returns the transaction status' do
+ subject['transactionStatus'].should eq('CREATED')
+ end
+ end
+ end
end

0 comments on commit 837aaf0

Please sign in to comment.