Class: Docdata::Response
- Inherits:
-
Object
- Object
- Docdata::Response
- Defined in:
- lib/docdata/response.rb
Overview
Object representing a "response" with attributes provided by Docdata
Constant Summary collapse
- @@success =
false
Instance Attribute Summary collapse
-
#amount ⇒ Integer
The captured amount in cents.
-
#currency ⇒ String
Currency ("EUR", "GBP", "USD", etc.).
-
#key ⇒ String
Payment key for future correspondence about this transaction.
-
#message ⇒ String
Response message from DocData.
- #paid ⇒ Boolean (also: #paid?)
-
#payment ⇒ Docdata::Payment
Object.
-
#report ⇒ Hash
The parsed report node of the reponse-xml.
-
#status ⇒ String
The status of this response (capture response).
-
#success ⇒ Boolean
(also: #success?)
True/false, depending of the API response.
-
#url ⇒ String
The return URL.
-
#xml ⇒ String
The raw XML returned by the API.
Class Method Summary collapse
-
.parse(method_name, response) ⇒ Object
Parses the returned response hash and turns it into a new Docdata::Response object.
-
.response_body(response) ⇒ Hash
plain XML files, in normal use, it uses a
Savon::Response
.
Instance Method Summary collapse
-
#amount_to_set ⇒ Object
[Integer] the amount to set, calculated from the multiple payment nodes.
- #authorized ⇒ Boolean (also: #authorized?)
- #canceled ⇒ Boolean (also: #canceled?)
-
#capture_status ⇒ String
The status of the capture, if exists.
-
#currency_to_set ⇒ String
The currency if this transaction.
-
#doc ⇒ Nokogiri::XML::Document
Object.
-
#initialize(args = nil) ⇒ Response
constructor
Initializer to transform a +Hash+ into an Response object.
-
#is_paid? ⇒ Boolean
There are several approaches to determine if a payment is paid, some slow and safe, other quick and unreliable.
-
#payment_method ⇒ String
The payment method of this transaction.
-
#payment_status ⇒ String
The status string provided by the API.
-
#pid ⇒ String
The PID of the transaction.
-
#set_attributes ⇒ Object
Set the attributes based on the API response.
-
#status_xml ⇒ Nokogiri::XML::Document
Object, containing only the status section.
Constructor Details
#initialize(args = nil) ⇒ Response
Initializer to transform a +Hash+ into an Response object
53 54 55 56 57 58 59 |
# File 'lib/docdata/response.rb', line 53 def initialize(args=nil) @report = {} return if args.nil? args.each do |k,v| instance_variable_set("@#{k}", v) unless v.nil? end end |
Instance Attribute Details
#amount ⇒ Integer
Returns the captured amount in cents.
35 36 37 |
# File 'lib/docdata/response.rb', line 35 def amount @amount end |
#currency ⇒ String
Returns Currency ("EUR", "GBP", "USD", etc.).
41 42 43 |
# File 'lib/docdata/response.rb', line 41 def currency @currency end |
#key ⇒ String
Returns Payment key for future correspondence about this transaction.
14 15 16 |
# File 'lib/docdata/response.rb', line 14 def key @key end |
#message ⇒ String
Returns Response message from DocData.
23 24 25 |
# File 'lib/docdata/response.rb', line 23 def @message end |
#paid ⇒ Boolean Also known as: paid?
32 33 34 |
# File 'lib/docdata/response.rb', line 32 def paid @paid end |
#payment ⇒ Docdata::Payment
Returns object.
44 45 46 |
# File 'lib/docdata/response.rb', line 44 def payment @payment end |
#report ⇒ Hash
Returns The parsed report node of the reponse-xml.
26 27 28 |
# File 'lib/docdata/response.rb', line 26 def report @report end |
#status ⇒ String
Returns the status of this response (capture response).
38 39 40 |
# File 'lib/docdata/response.rb', line 38 def status @status end |
#success ⇒ Boolean Also known as: success?
Returns true/false, depending of the API response.
16 17 18 |
# File 'lib/docdata/response.rb', line 16 def success @success end |
#url ⇒ String
Returns the return URL.
47 48 49 |
# File 'lib/docdata/response.rb', line 47 def url @url end |
#xml ⇒ String
Returns The raw XML returned by the API.
29 30 31 |
# File 'lib/docdata/response.rb', line 29 def xml @xml end |
Class Method Details
.parse(method_name, response) ⇒ Object
Parses the returned response hash and turns it into a new Docdata::Response object
90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 |
# File 'lib/docdata/response.rb', line 90 def self.parse(method_name, response) body, xml = self.response_body(response) if body["#{method_name}_response".to_sym] && body["#{method_name}_response".to_sym]["#{method_name}_error".to_sym] raise DocdataError.new(response), body["#{method_name}_response".to_sym]["#{method_name}_error".to_sym][:error] else m = body["#{method_name}_response".to_sym]["#{method_name}_success".to_sym] r = self.new(key: m[:key], message: m[:success], success: true) r.xml = xml #save the raw xml # puts m[:report] if m[:report] r.report = m[:report] end r.set_attributes return r end end |
.response_body(response) ⇒ Hash
plain XML files, in normal use, it uses a Savon::Response
109 110 111 112 113 114 115 116 117 118 119 |
# File 'lib/docdata/response.rb', line 109 def self.response_body(response) if response.is_a?(File) parser = Nori.new(:convert_tags_to => lambda { |tag| tag.snakecase.to_sym }) xml = response.read body = parser.parse(xml).first.last.first.last else body = response.body.to_hash xml = response.xml end return body, xml end |
Instance Method Details
#amount_to_set ⇒ Object
[Integer] the amount to set, calculated from the multiple payment nodes
63 64 65 66 67 68 69 70 71 72 73 74 |
# File 'lib/docdata/response.rb', line 63 def amount_to_set # if (report && Response.payment_node(report) && Response.payment_node(report)[:authorization] && Response.payment_node(report)[:authorization][:amount].present?) if (report && Response.payment_node(report) && Response.payment_node(report)[:authorization] && Response.payment_node(report)[:authorization][:amount].present?) if canceled return Response.payment_node(report)[:authorization][:amount].to_i else return total_acquirer_pending + total_acquirer_approved end else return false end end |
#authorized ⇒ Boolean Also known as:
213 214 215 |
# File 'lib/docdata/response.rb', line 213 def payment_status == "AUTHORIZED" end |
#canceled ⇒ Boolean Also known as: canceled?
219 220 221 222 |
# File 'lib/docdata/response.rb', line 219 def canceled (payment_status && payment_status == "CANCELED") || (capture_status && capture_status == "CANCELED") end |
#capture_status ⇒ String
Returns the status of the capture, if exists.
226 227 228 229 230 231 232 |
# File 'lib/docdata/response.rb', line 226 def capture_status if report && Response.payment_node(report) && Response.payment_node(report)[:authorization] && Response.payment_node(report)[:authorization][:capture] Response.payment_node(report)[:authorization][:capture][:status] else nil end end |
#currency_to_set ⇒ String
Returns the currency if this transaction.
236 237 238 239 240 241 242 |
# File 'lib/docdata/response.rb', line 236 def currency_to_set if status_xml && status_xml.xpath("//amount").any? status_xml.xpath("//amount").first.attributes["currency"].value else nil end end |
#doc ⇒ Nokogiri::XML::Document
Returns object.
245 246 247 248 249 250 |
# File 'lib/docdata/response.rb', line 245 def doc # remove returns and whitespaces between tags xml_string = xml.gsub("\n", "").gsub(/>\s+</, "><") # return Nokogiri::XML::Document @doc ||= Nokogiri.XML(xml_string) end |
#is_paid? ⇒ Boolean
Docdata doesn't explicitly say 'paid' or 'not paid', this is a little bit a gray area.
This method is never 100% reliable. If you need to finetune this, please implement your own method, using
There are several approaches to determine if a payment is paid, some slow and safe, other quick and unreliable. The reason for this is that some payment methods have a much longer processing time. For each payment method a different 'paid'. the available data (total_captured, total_registered, etc.) from the Docs: Safe route: The safest route to check whether all payments were made is for the merchants to refer to the “Total captured” amount to see whether this equals the “Total registered amount”. While this may be the safest indicator, the downside is that it can sometimes take a long time for acquirers or shoppers to actually have the money transferred and it can be captured. Quick route: Another option is to see whether the sum of “total shopper pending”, “total acquirer pending” and “total acquirer authorized” matches the “total registered sum”. This implies that everyone responsible has indicated that they are going to make the payment and that the merchant is trusting that everyone will indeed make this. While this route will be faster, it does also have the risk that some payments will actually not have been made. Balanced route: Depending on the merchant's situation, it can be a good option to only refer to certain totals. For instance, if the merchant only makes use of credit card payments it could be a good route to only look at “Total acquirer approved”, since this will be rather safe but quicker than looking at the captures.
185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 |
# File 'lib/docdata/response.rb', line 185 def is_paid? if payment_method case payment_method # ideal (dutch) when "IDEAL" (total_registered == total_captured) ## && (capture_status == "CAPTURED") # creditcard when "MASTERCARD", "VISA", "AMEX" (total_registered == total_acquirer_approved) # sofort überweisung (german) when "SOFORT_UEBERWEISUNG" (total_registered == total_acquirer_approved) # podium giftcard (dutch) when "PODIUM_GIFTCARD" (total_registered == total_captured) # fallback: if total_registered equals total_caputured, # we can assume that this order is paid. No 100% guarantee. else total_registered == total_acquirer_approved end else false end end |
#payment_method ⇒ String
Returns the payment method of this transaction.
129 130 131 132 133 134 135 136 137 138 139 |
# File 'lib/docdata/response.rb', line 129 def payment_method begin if report && Response.payment_node(report).present? && Response.payment_node(report)[:payment_method].present? Response.payment_node(report)[:payment_method].to_s else nil end rescue nil end end |
#payment_status ⇒ String
Returns the status string provided by the API. One of [AUTHORIZED, CANCELED].
143 144 145 146 147 148 149 |
# File 'lib/docdata/response.rb', line 143 def payment_status if report && Response.payment_node(report) && Response.payment_node(report)[:authorization] Response.payment_node(report)[:authorization][:status] else nil end end |
#pid ⇒ String
Returns the PID of the transaction.
152 153 154 155 156 157 158 |
# File 'lib/docdata/response.rb', line 152 def pid if report && Response.payment_node(report) && Response.payment_node(report)[:id] Response.payment_node(report)[:id] else nil end end |
#set_attributes ⇒ Object
Set the attributes based on the API response
77 78 79 80 81 82 |
# File 'lib/docdata/response.rb', line 77 def set_attributes self.paid = is_paid? self.amount = amount_to_set if amount_to_set self.status = capture_status if capture_status self.currency = currency_to_set end |
#status_xml ⇒ Nokogiri::XML::Document
This is a fix for Nokogiri's trouble finding xpath elements after 'xlmns' attribute in a node.
Returns object, containing only the status section.
254 255 256 |
# File 'lib/docdata/response.rb', line 254 def status_xml @status_xml ||= Nokogiri.XML(doc.xpath("//S:Body").first.children.first.children.first.to_xml) end |