Class: Cardia::CreditCardTransaction
- Defined in:
- lib/cardia/credit_card_transaction.rb
Overview
This class represents a credit card transaction against Cardia These are created at Cardia using one of the register methods:
-
register, which keeps the control with us (we dont redirect the user away), but gives the merchant full responsibility
-
register_3d, which forces our user into foreign territory, hopefully returning to us afterwards; but limits the merchants liabilities
Minimal usage example
require 'cardia'
customer = Cardia::Customer.new("John","Doe")
amount = 1000
order = Cardia::Order.new(amount, "My test order")
order.customer = customer
merchant = Cardia::Merchant.test_merchant
transaction = Cardia::CreditCardTransaction.with_http_connection(order)
transaction.merchant = merchant
card = Cardia::CreditCard.valid_card_for_testing
For regular transactions, use:
status = transaction.register(card)
For 3d secure, use:
status = transaction.register_3d(card, "http://my.success.url/", "http://my.failure.url/")
This will return a URL that the user should be redirected to. When the user is sent to this address he will either be redirected to
either the success or failure URL, depending on whether the payment was successful.
Instance Attribute Summary collapse
-
#merchant ⇒ Object
Returns the value of attribute merchant.
-
#order ⇒ Object
readonly
Returns the value of attribute order.
-
#verification_address ⇒ Object
readonly
Returns the value of attribute verification_address.
Class Method Summary collapse
-
.server_name ⇒ Object
:nodoc:.
-
.with_http_connection(an_order) ⇒ Object
Creates a new instance.
Instance Method Summary collapse
-
#change_amount(new_amount) ⇒ Object
This method changes the amount on a transaction You should probably investigate about the terms around this before actually using it.
-
#check_status ⇒ Object
Returns the transaction status as a Cardia::TransactionStatus instance.
-
#confirm! ⇒ Object
This method confirms payments that are “on hold”.
-
#credit(amount = nil) ⇒ Object
(also: #refund)
Credits the transaction.
-
#do_invoke_web_service(base_url, method, values) ⇒ Object
:nodoc:.
- #http_connection ⇒ Object
-
#initialize(an_order, http_connection) ⇒ CreditCardTransaction
constructor
:nodoc:.
-
#invoke(method, values) ⇒ Object
Implements the vanilla plain calls to Cardia.
-
#invoke_teller_web_service(method, values) ⇒ Object
:nodoc:.
-
#invoke_transaction_web_service(method, values) ⇒ Object
:nodoc:.
-
#register(a_credit_card) ⇒ Object
Register the transaction with Cardia.
-
#register_3d(a_credit_card, success_url, failure_url) ⇒ Object
Register using 3DSecure.
-
#register_with_doc(a_credit_card) ⇒ Object
Register the payment, keeping our user with us.
-
#store_name ⇒ Object
:nodoc:.
-
#void ⇒ Object
Cancels a transaction.
-
#wait_until_approved ⇒ Object
:nodoc:.
Constructor Details
#initialize(an_order, http_connection) ⇒ CreditCardTransaction
:nodoc:
33 34 35 36 |
# File 'lib/cardia/credit_card_transaction.rb', line 33 def initialize(an_order, http_connection) #:nodoc: @order= an_order @http = http_connection end |
Instance Attribute Details
#merchant ⇒ Object
Returns the value of attribute merchant.
31 32 33 |
# File 'lib/cardia/credit_card_transaction.rb', line 31 def merchant @merchant end |
#order ⇒ Object (readonly)
Returns the value of attribute order.
30 31 32 |
# File 'lib/cardia/credit_card_transaction.rb', line 30 def order @order end |
#verification_address ⇒ Object (readonly)
Returns the value of attribute verification_address.
30 31 32 |
# File 'lib/cardia/credit_card_transaction.rb', line 30 def verification_address @verification_address end |
Class Method Details
.server_name ⇒ Object
:nodoc:
210 211 212 |
# File 'lib/cardia/credit_card_transaction.rb', line 210 def self.server_name #:nodoc: "secure.cardia.no" end |
.with_http_connection(an_order) ⇒ Object
Creates a new instance. Send along your Order as the parameter, see Cardia::Order for methods that should be implemented in your order
-
an_order The order
40 41 42 43 44 |
# File 'lib/cardia/credit_card_transaction.rb', line 40 def self.with_http_connection(an_order) http = Net::HTTP.new(self.server_name,"443") http.use_ssl = true return self.new(an_order, http) end |
Instance Method Details
#change_amount(new_amount) ⇒ Object
This method changes the amount on a transaction You should probably investigate about the terms around this before actually using it
185 186 187 |
# File 'lib/cardia/credit_card_transaction.rb', line 185 def change_amount(new_amount) return invoke("ChangeAmount", "merchantToken=#{@merchant.token}&amount=#{new_amount}&merchantReference=#{@order.reference}") end |
#check_status ⇒ Object
Returns the transaction status as a Cardia::TransactionStatus instance
190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 |
# File 'lib/cardia/credit_card_transaction.rb', line 190 def check_status status, doc = invoke_transaction_web_service("ReturnTransactionStatus", "merchantToken=#{@merchant.token}&merchantReference=#{@order.reference}") response_code = doc.root.elements["ResponseCode"].text currency_code = doc.root.elements["CurrencyCode"].text recurring_code = doc.root.elements["RecurringCode"].text amt = doc.root.elements["Amount"] s = TransactionStatus.new(status) unless amt.nil? s.amount = Money.kroner(amt.text.to_i) end s.response_code = response_code.to_i s.currency_code = currency_code s.recurring_code = recurring_code return s end |
#confirm! ⇒ Object
This method confirms payments that are “on hold”. Cardia calls this RevertOnHold
179 180 181 |
# File 'lib/cardia/credit_card_transaction.rb', line 179 def confirm! return invoke_transaction_web_service("RevertOnHoldTransaction", "merchantToken=#{@merchant.token}&merchantReference=#{@order.reference}") end |
#credit(amount = nil) ⇒ Object Also known as: refund
Credits the transaction. This is bank-speak for reversing it; giving the customer a full refund If you want to, you can supply the amount manually
172 173 174 175 |
# File 'lib/cardia/credit_card_transaction.rb', line 172 def credit(amount=nil) amount = @order.amount if amount.nil? return invoke("CreditTransaction", "merchantToken=#{@merchant.token}&amount=#{amount}&merchantReference=#{@order.reference}") end |
#do_invoke_web_service(base_url, method, values) ⇒ Object
:nodoc:
124 125 126 127 128 129 130 |
# File 'lib/cardia/credit_card_transaction.rb', line 124 def do_invoke_web_service(base_url, method, values) #:nodoc: http = http_connection url = base_url + method response, body = http.post(url, values, {"Content-Type" => "application/x-www-form-urlencoded"}) response.value return REXML::Document.new(response.body) end |
#http_connection ⇒ Object
120 121 122 |
# File 'lib/cardia/credit_card_transaction.rb', line 120 def http_connection @http end |
#invoke(method, values) ⇒ Object
Implements the vanilla plain calls to Cardia
67 68 69 70 |
# File 'lib/cardia/credit_card_transaction.rb', line 67 def invoke(method, values) #:nodoc: status, doc = invoke_transaction_web_service(method, values) return status end |
#invoke_teller_web_service(method, values) ⇒ Object
:nodoc:
60 61 62 63 64 |
# File 'lib/cardia/credit_card_transaction.rb', line 60 def invoke_teller_web_service(method, values) #:nodoc: doc = do_invoke_web_service("/Service/Card/Mpi/TellerMpi/1.2/TellerMpi.asmx/", method, values) status_code = doc.root.elements["ResponseCode"].text.to_i return status_code, doc end |
#invoke_transaction_web_service(method, values) ⇒ Object
:nodoc:
52 53 54 55 56 57 58 |
# File 'lib/cardia/credit_card_transaction.rb', line 52 def invoke_transaction_web_service(method, values) #:nodoc: doc = do_invoke_web_service("/Service/Card/Transaction/1.2/Transaction.asmx/", method, values) status_code = doc.root.elements["StatusCode"].text.to_i return status_code, doc end |
#register(a_credit_card) ⇒ Object
Register the transaction with Cardia. Once this has been done, the amount is reserved on the users credit card, given that the the returned status says so…
102 103 104 105 |
# File 'lib/cardia/credit_card_transaction.rb', line 102 def register(a_credit_card) status, doc = register_with_doc(a_credit_card) return status end |
#register_3d(a_credit_card, success_url, failure_url) ⇒ Object
Register using 3DSecure. Send along a card, a URL for redirection after successful payments and a URL to redirect to when the payment was unsuccessful.
133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 |
# File 'lib/cardia/credit_card_transaction.rb', line 133 def register_3d(a_credit_card, success_url, failure_url) raise "No verification code supplied" if a_credit_card.verification_value.nil? params = { :merchantToken => @merchant.token, :applicationIdentifier => "", # not in use :cardNumber => a_credit_card.number, :expiryDate => a_credit_card.expires, :cv2Code => a_credit_card.verification_value, :merchantReference => @order.reference, :successfulTransactionUrl => CGI::escape(success_url), :unsuccessfulTransactionUrl => CGI::escape(failure_url), :authorizedNotAuthenticatedUrl => "", # not in use :currencyCode => "NOK", :amount => @order.amount.to_i, :isOnHold => "true", :paymentType => a_credit_card.payment_type } opts = [] params.each{|k,v| opts << "#{k}=#{v}"} values = opts.join("&") status, doc = invoke_teller_web_service("PrepareTransaction", values) unless status == 1 raise doc.root.elements["Error"].text end address = doc.root.elements["Address"].text guid = doc.root.elements["ReferenceGuid"].text @verification_address = "#{address}?preparationGuid=#{guid}" return @verification_address end |
#register_with_doc(a_credit_card) ⇒ Object
Register the payment, keeping our user with us
73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 |
# File 'lib/cardia/credit_card_transaction.rb', line 73 def register_with_doc(a_credit_card) #:nodoc: raise "Invalid credit card" unless a_credit_card.valid? params = { :merchantToken => @merchant.token, :userToken => @order.customer.token, :merchantReference => @order.reference, :store => store_name, :orderDescription => @order.description, :cardNumber => a_credit_card.number, :expiryDate => a_credit_card.expires, :cvc2Code => a_credit_card.verification_value, :currencyCode => "NOK", :instanceId => "", :amount => @order.amount.to_i, # croaks on floating point :purchaseDate => Date.today.strftime("%Y-%m-%d"), :isOnHold => "true", :isPreRegistered => "false" } opts = [] params.each{|k,v| opts<<"#{k}=#{v}"} values = opts.join("&") method = "RegisterCardTransaction" status, doc = invoke_transaction_web_service(method, values) return status, doc end |
#store_name ⇒ Object
:nodoc:
206 207 208 |
# File 'lib/cardia/credit_card_transaction.rb', line 206 def store_name #:nodoc: "AS Juks og Bedrag" end |
#void ⇒ Object
Cancels a transaction. A good practice is probably to have a before_destroy filter in your order that does this
165 166 167 |
# File 'lib/cardia/credit_card_transaction.rb', line 165 def void return invoke("VoidTransaction", "merchantToken=#{@merchant.token}&userToken=#{@order.customer.token}&merchantReference=#{@order.reference}") end |
#wait_until_approved ⇒ Object
:nodoc:
107 108 109 110 111 112 113 114 115 116 117 118 |
# File 'lib/cardia/credit_card_transaction.rb', line 107 def wait_until_approved #:nodoc: (1..10).each do |n| status = check_status if status == TransactionStatus.approved yield return end puts n sleep(2) end raise "Out of retries, Order not approved" end |