wirecard-elastic 0.2.0 → 0.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/Gemfile.lock +58 -0
- data/lib/wirecard/elastic/configuration.rb +4 -2
- data/lib/wirecard/elastic/error.rb +2 -0
- data/lib/wirecard/elastic/request/base.rb +36 -0
- data/lib/wirecard/elastic/request/body/builder/xml.rb +53 -0
- data/lib/wirecard/elastic/request/body/builder.rb +35 -0
- data/lib/wirecard/elastic/request/body/params/refund.rb +58 -0
- data/lib/wirecard/elastic/request/body/templates/refund.xml +13 -0
- data/lib/wirecard/elastic/request/refund.rb +49 -0
- data/lib/wirecard/elastic/request/transaction.rb +33 -0
- data/lib/wirecard/elastic/request.rb +112 -0
- data/lib/wirecard/elastic/response/base.rb +85 -0
- data/lib/wirecard/elastic/response/refund.rb +15 -0
- data/lib/wirecard/elastic/response/transaction.rb +15 -0
- data/lib/wirecard/elastic/response.rb +46 -0
- data/lib/wirecard/elastic/version.rb +2 -1
- data/lib/wirecard/elastic.rb +23 -20
- data/pkg/wirecard-elastic-0.1.0.gem +0 -0
- data/pkg/wirecard-elastic-0.1.1.gem +0 -0
- data/pkg/wirecard-elastic-0.2.0.gem +0 -0
- metadata +18 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 7dfbfe4ac51493be85c504c280f35891dd271ed0
|
4
|
+
data.tar.gz: 2aca41a8ad720d5b29d7527d6f7640a434a63a68
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 22b83d0b615cc40bae13f7e2ec6404ad6f4383021a60075e60deec803ca23964dbc00ee636e2f49119bf4d01e55bb9d3c00ad9e685e9b7ce10e73e8e9853cb9c
|
7
|
+
data.tar.gz: 6237450ae7354ea5e9a49bc9e082a096b9936aef2b29d7c7ae8cc8f2d0d39e1fe64bb18a9dbfea65878b944bee598e9928c02d4c544ad73234a236fac78c0ffd
|
data/Gemfile.lock
ADDED
@@ -0,0 +1,58 @@
|
|
1
|
+
PATH
|
2
|
+
remote: .
|
3
|
+
specs:
|
4
|
+
wirecard-elastic (0.2.1)
|
5
|
+
activesupport
|
6
|
+
|
7
|
+
GEM
|
8
|
+
remote: https://rubygems.org/
|
9
|
+
specs:
|
10
|
+
activesupport (4.2.6)
|
11
|
+
i18n (~> 0.7)
|
12
|
+
json (~> 1.7, >= 1.7.7)
|
13
|
+
minitest (~> 5.1)
|
14
|
+
thread_safe (~> 0.3, >= 0.3.4)
|
15
|
+
tzinfo (~> 1.1)
|
16
|
+
coderay (1.1.1)
|
17
|
+
diff-lcs (1.2.5)
|
18
|
+
i18n (0.7.0)
|
19
|
+
json (1.8.3)
|
20
|
+
method_source (0.8.2)
|
21
|
+
minitest (5.8.4)
|
22
|
+
pry (0.10.4)
|
23
|
+
coderay (~> 1.1.0)
|
24
|
+
method_source (~> 0.8.1)
|
25
|
+
slop (~> 3.4)
|
26
|
+
pry-rails (0.3.4)
|
27
|
+
pry (>= 0.9.10)
|
28
|
+
rake (10.4.2)
|
29
|
+
rspec (3.4.0)
|
30
|
+
rspec-core (~> 3.4.0)
|
31
|
+
rspec-expectations (~> 3.4.0)
|
32
|
+
rspec-mocks (~> 3.4.0)
|
33
|
+
rspec-core (3.4.4)
|
34
|
+
rspec-support (~> 3.4.0)
|
35
|
+
rspec-expectations (3.4.0)
|
36
|
+
diff-lcs (>= 1.2.0, < 2.0)
|
37
|
+
rspec-support (~> 3.4.0)
|
38
|
+
rspec-mocks (3.4.1)
|
39
|
+
diff-lcs (>= 1.2.0, < 2.0)
|
40
|
+
rspec-support (~> 3.4.0)
|
41
|
+
rspec-support (3.4.1)
|
42
|
+
slop (3.6.0)
|
43
|
+
thread_safe (0.3.5)
|
44
|
+
tzinfo (1.2.2)
|
45
|
+
thread_safe (~> 0.1)
|
46
|
+
|
47
|
+
PLATFORMS
|
48
|
+
ruby
|
49
|
+
|
50
|
+
DEPENDENCIES
|
51
|
+
bundler (~> 1.12)
|
52
|
+
pry-rails
|
53
|
+
rake (~> 10.0)
|
54
|
+
rspec
|
55
|
+
wirecard-elastic!
|
56
|
+
|
57
|
+
BUNDLED WITH
|
58
|
+
1.12.4
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# configuration of the gem and
|
2
|
+
# default values set here
|
1
3
|
module Wirecard
|
2
4
|
module Elastic
|
3
5
|
class Configuration
|
@@ -6,8 +8,8 @@ module Wirecard
|
|
6
8
|
attr_accessor :upop
|
7
9
|
|
8
10
|
def initialize
|
9
|
-
@upop
|
10
|
-
@creditcard = {}
|
11
|
+
@upop = { }
|
12
|
+
@creditcard = { }
|
11
13
|
end
|
12
14
|
|
13
15
|
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
module Wirecard
|
2
|
+
module Elastic
|
3
|
+
class Request
|
4
|
+
class Base
|
5
|
+
|
6
|
+
VALID_STATUS_LIST = [:success, :failed].freeze
|
7
|
+
|
8
|
+
# calling #safe will check if the transaction was successful or/and valid
|
9
|
+
# and raise an error if not ; this is a useful shortcut
|
10
|
+
# when manipulating the datas at a upper level
|
11
|
+
def safe
|
12
|
+
unless valid_status?
|
13
|
+
raise Wirecard::Elastic::Error, "The status of the transaction is not correct (#{response.request_status})"
|
14
|
+
end
|
15
|
+
if negative_response?
|
16
|
+
raise Wirecard::Elastic::Error, "The transaction could not be verified. API access refused."
|
17
|
+
end
|
18
|
+
self
|
19
|
+
end
|
20
|
+
|
21
|
+
alias :raise_response_issues :safe # retro compatibility v0.1.1
|
22
|
+
|
23
|
+
private
|
24
|
+
|
25
|
+
def valid_status?
|
26
|
+
VALID_STATUS_LIST.include? response.transaction_state
|
27
|
+
end
|
28
|
+
|
29
|
+
def negative_response?
|
30
|
+
response.transaction_state == :failed && response.request_status == :error
|
31
|
+
end
|
32
|
+
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,53 @@
|
|
1
|
+
require 'rexml/text'
|
2
|
+
|
3
|
+
# build a XML from a template and some variables
|
4
|
+
# output a string to be transmitted to the API
|
5
|
+
module Wirecard
|
6
|
+
module Elastic
|
7
|
+
class Request
|
8
|
+
module Body
|
9
|
+
class Builder
|
10
|
+
class Xml
|
11
|
+
|
12
|
+
TEMPLATE_FORMAT = "UTF-8".freeze
|
13
|
+
TEMPLATE_PATH = "../../templates/".freeze
|
14
|
+
|
15
|
+
attr_reader :template_name, :request
|
16
|
+
|
17
|
+
# template_name is contained in /templates/
|
18
|
+
# the request matches the variables to convert (in hash) e.g. :refund
|
19
|
+
def initialize(template_name, request)
|
20
|
+
@template_name = template_name
|
21
|
+
@request = request
|
22
|
+
end
|
23
|
+
|
24
|
+
# actually convert the file into a full XML with processed variables
|
25
|
+
def build!
|
26
|
+
xml_template = File.open(template_path, "r:#{TEMPLATE_FORMAT}", &:read)
|
27
|
+
xml_template.gsub(/{{\w+}}/, request_params)
|
28
|
+
end
|
29
|
+
|
30
|
+
private
|
31
|
+
|
32
|
+
# convert the current {{VARIABLES}}
|
33
|
+
# into their real values
|
34
|
+
def request_params
|
35
|
+
request.each_with_object({}) do |(key,value), hash|
|
36
|
+
hash["{{#{key.upcase}}}"] = REXML::Text.new(value.to_s)
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
def template_path
|
41
|
+
File.expand_path "#{TEMPLATE_PATH}#{template_file}", __FILE__
|
42
|
+
end
|
43
|
+
|
44
|
+
def template_file
|
45
|
+
"#{template_name}.xml"
|
46
|
+
end
|
47
|
+
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
# build the template, this system is type agnostic
|
2
|
+
# which means any type of file could be output from this point
|
3
|
+
module Wirecard
|
4
|
+
module Elastic
|
5
|
+
class Request
|
6
|
+
module Body
|
7
|
+
class Builder
|
8
|
+
|
9
|
+
attr_reader :origin, :template
|
10
|
+
|
11
|
+
# set the template and the origin instance
|
12
|
+
# the origin will be used to setup the params
|
13
|
+
# by using the different datas of the class asking
|
14
|
+
# for a body content
|
15
|
+
def initialize(origin, template)
|
16
|
+
@origin = origin
|
17
|
+
@template = template
|
18
|
+
end
|
19
|
+
|
20
|
+
# conversion into XML format
|
21
|
+
def to_xml
|
22
|
+
Xml.new(template, params).build!
|
23
|
+
end
|
24
|
+
|
25
|
+
# generation of the parameters used in the template
|
26
|
+
# through the origin instance
|
27
|
+
def params
|
28
|
+
Params.const_get(template.capitalize).new(origin).deliver!
|
29
|
+
end
|
30
|
+
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,58 @@
|
|
1
|
+
# setup the parameters that will be transmitted to the body builder
|
2
|
+
# which will convert the template into real values
|
3
|
+
module Wirecard
|
4
|
+
module Elastic
|
5
|
+
class Request
|
6
|
+
module Body
|
7
|
+
module Params
|
8
|
+
class Refund
|
9
|
+
|
10
|
+
# the request IP address is for now a static local address
|
11
|
+
REQUEST_IP_ADDRESS = "127.0.0.1".freeze
|
12
|
+
|
13
|
+
# each transaction its symetric refund term
|
14
|
+
REFUND_MAP = {:purchase => :'refund-purchase', :debit => :'refund-debit'}.freeze
|
15
|
+
|
16
|
+
attr_reader :origin
|
17
|
+
|
18
|
+
def initialize(origin)
|
19
|
+
@origin = origin
|
20
|
+
end
|
21
|
+
|
22
|
+
# output the hash
|
23
|
+
def deliver!
|
24
|
+
local.merge(remote)
|
25
|
+
end
|
26
|
+
|
27
|
+
private
|
28
|
+
|
29
|
+
# params we will use to fill the XML format request
|
30
|
+
def local
|
31
|
+
{
|
32
|
+
:merchant_account_id => origin.merchant_id,
|
33
|
+
:request_id => origin.request_id,
|
34
|
+
:parent_transaction_id => origin.parent_transaction_id,
|
35
|
+
:ip_address => REQUEST_IP_ADDRESS
|
36
|
+
}
|
37
|
+
end
|
38
|
+
|
39
|
+
# get some body params from the remote elastic API itself rather than our database (safer)
|
40
|
+
def remote
|
41
|
+
{
|
42
|
+
:currency => origin.parent_transaction.response.requested_amount_currency,
|
43
|
+
:amount => origin.parent_transaction.response.requested_amount,
|
44
|
+
:payment_method => origin.parent_transaction.response.payment_method,
|
45
|
+
:transaction_type => refund_transaction_type
|
46
|
+
}
|
47
|
+
end
|
48
|
+
|
49
|
+
def refund_transaction_type
|
50
|
+
REFUND_MAP[origin.parent_transaction.response.transaction_type]
|
51
|
+
end
|
52
|
+
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
<payment xmlns="http://www.elastic-payments.com/schema/payment">
|
2
|
+
<merchant-account-id>{{MERCHANT_ACCOUNT_ID}}</merchant-account-id>
|
3
|
+
<request-id>{{REQUEST_ID}}</request-id>
|
4
|
+
<transaction-type>{{TRANSACTION_TYPE}}</transaction-type>
|
5
|
+
<parent-transaction-id>{{PARENT_TRANSACTION_ID}}</parent-transaction-id>
|
6
|
+
|
7
|
+
<requested-amount currency="{{CURRENCY}}">{{AMOUNT}}</requested-amount>
|
8
|
+
<payment-methods>
|
9
|
+
<payment-method name="{{PAYMENT_METHOD}}"/>
|
10
|
+
</payment-methods>
|
11
|
+
|
12
|
+
<ip-address>{{IP_ADDRESS}}</ip-address>
|
13
|
+
</payment>
|
@@ -0,0 +1,49 @@
|
|
1
|
+
# refund a customer via the API
|
2
|
+
# this will make a double API call
|
3
|
+
# to first recover the original payment transaction
|
4
|
+
module Wirecard
|
5
|
+
module Elastic
|
6
|
+
class Request
|
7
|
+
class Refund < Base
|
8
|
+
|
9
|
+
PAYMENT_QUERY_MAP = {:purchase => "payments", :debit => "paymentmethods"}.freeze
|
10
|
+
|
11
|
+
attr_reader :merchant_id, :parent_transaction_id, :request_id, :payment_method
|
12
|
+
|
13
|
+
def initialize(merchant_id, parent_transaction_id, payment_method)
|
14
|
+
@merchant_id = merchant_id
|
15
|
+
@parent_transaction_id = parent_transaction_id
|
16
|
+
@request_id = SecureRandom.uuid
|
17
|
+
@payment_method = payment_method
|
18
|
+
end
|
19
|
+
|
20
|
+
# calling request
|
21
|
+
def request
|
22
|
+
@request ||= Request.new(query_uri: query, payment_method: payment_method, method: :post, body: body).dispatch!
|
23
|
+
end
|
24
|
+
|
25
|
+
# processed response
|
26
|
+
def response
|
27
|
+
@response ||= Response.new(request: request, action: :refund).dispatch!
|
28
|
+
end
|
29
|
+
|
30
|
+
# address we want to access on the API
|
31
|
+
def query
|
32
|
+
@query ||= PAYMENT_QUERY_MAP[parent_transaction.response.transaction_type]
|
33
|
+
end
|
34
|
+
|
35
|
+
# XML body we will send to the elastic API
|
36
|
+
def body
|
37
|
+
@body ||= Body::Builder.new(self, :refund).to_xml
|
38
|
+
end
|
39
|
+
|
40
|
+
# original transaction of the refund
|
41
|
+
# requested remotely to elastic API
|
42
|
+
def parent_transaction
|
43
|
+
@parent_transaction ||= Transaction.new(merchant_id, parent_transaction_id, payment_method)
|
44
|
+
end
|
45
|
+
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
# recover a transaction details from the Wirecard API
|
2
|
+
module Wirecard
|
3
|
+
module Elastic
|
4
|
+
class Request
|
5
|
+
class Transaction < Base
|
6
|
+
|
7
|
+
attr_reader :merchant_id, :transaction_id, :payment_method
|
8
|
+
|
9
|
+
def initialize(merchant_id, transaction_id, payment_method)
|
10
|
+
@merchant_id = merchant_id
|
11
|
+
@transaction_id = transaction_id
|
12
|
+
@payment_method = payment_method
|
13
|
+
end
|
14
|
+
|
15
|
+
# calling request
|
16
|
+
def request
|
17
|
+
@request ||= Request.new(query_uri: query, payment_method: payment_method).dispatch!
|
18
|
+
end
|
19
|
+
|
20
|
+
# processed response
|
21
|
+
def response
|
22
|
+
@response ||= Response.new(request: request, action: :transaction).dispatch!
|
23
|
+
end
|
24
|
+
|
25
|
+
# address we want to access on the API
|
26
|
+
def query
|
27
|
+
@query ||= "merchants/#{merchant_id}/payments/#{transaction_id}"
|
28
|
+
end
|
29
|
+
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,112 @@
|
|
1
|
+
require 'net/http'
|
2
|
+
|
3
|
+
# entry point of the request system
|
4
|
+
# this is where the API call is produced
|
5
|
+
module Wirecard
|
6
|
+
module Elastic
|
7
|
+
class Request
|
8
|
+
|
9
|
+
# content type might be flexible in the future
|
10
|
+
# for now it's a simple constant as the API
|
11
|
+
# is still simple
|
12
|
+
CONTENT_TYPE = 'text/xml'.freeze
|
13
|
+
|
14
|
+
# allowed methods to communicate to the API
|
15
|
+
# a get is usually without body
|
16
|
+
# a post will be with XML datas transmitted
|
17
|
+
ALLOWED_METHODS = [:get, :post]
|
18
|
+
|
19
|
+
# checking of the URL validity via REGEX
|
20
|
+
URL_PATTERN = /\A#{URI::regexp(['http', 'https'])}\z/
|
21
|
+
|
22
|
+
attr_reader :method, :body, :query_uri, :payment_method
|
23
|
+
|
24
|
+
# prepare the request datas and check the query URL on the fly
|
25
|
+
def initialize(query_uri:, payment_method:, method: :get, body: '')
|
26
|
+
@payment_method = payment_method
|
27
|
+
@method = method
|
28
|
+
@body = body
|
29
|
+
@query_uri = query_uri
|
30
|
+
raise Wirecard::Elastic::ConfigError, "Invalid engine URL. Please check your configuration." unless valid_query?
|
31
|
+
end
|
32
|
+
|
33
|
+
# process the actual call and return the instance
|
34
|
+
# raise an error if the server didn't answer anything
|
35
|
+
def dispatch!
|
36
|
+
@dispatch ||= begin
|
37
|
+
if feedback.nil?
|
38
|
+
raise Wirecard::Elastic::Error, "The request was not successful"
|
39
|
+
else
|
40
|
+
self
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
# compose the query via configuration and transmitted URI
|
46
|
+
def query
|
47
|
+
@query ||= "#{gateway[:engine_url]}#{query_uri}.json"
|
48
|
+
end
|
49
|
+
|
50
|
+
# get the http raw response from the API
|
51
|
+
# it's supposed to be a simple string
|
52
|
+
# we might parse as JSON later on
|
53
|
+
def feedback
|
54
|
+
@feedback ||= Net::HTTP.start(query_url.host, query_url.port,
|
55
|
+
:use_ssl => https_request?,
|
56
|
+
:verify_mode => OpenSSL::SSL::VERIFY_NONE) { |connection| send(connection) }
|
57
|
+
end
|
58
|
+
|
59
|
+
private
|
60
|
+
|
61
|
+
# connect and authenticate
|
62
|
+
# the client to the remote API
|
63
|
+
def send(connection)
|
64
|
+
request.basic_auth gateway[:username], gateway[:password] # authentification here
|
65
|
+
request.body = body # body (XML for instance)
|
66
|
+
request.content_type = CONTENT_TYPE # XML
|
67
|
+
connection.request request # give a response
|
68
|
+
end
|
69
|
+
|
70
|
+
# prepare the request by instanting Net::HTTP::Get/Post
|
71
|
+
# and manage it depending on the method
|
72
|
+
def request
|
73
|
+
@request ||= begin
|
74
|
+
if ALLOWED_METHODS.include?(method)
|
75
|
+
Net::HTTP.const_get(method.capitalize).new(query_url.request_uri)
|
76
|
+
else
|
77
|
+
raise Wirecard::Elastic::Error, "Request method not recognized"
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
# simple query URL checker
|
83
|
+
def valid_query?
|
84
|
+
(query =~ URL_PATTERN) != nil
|
85
|
+
end
|
86
|
+
|
87
|
+
# encapsulate the query into URI(*)
|
88
|
+
def query_url
|
89
|
+
@query_url ||= URI(query)
|
90
|
+
end
|
91
|
+
|
92
|
+
# check if the request is SSL or not
|
93
|
+
def https_request?
|
94
|
+
query_url.scheme == 'https'
|
95
|
+
end
|
96
|
+
|
97
|
+
# get the details from the configuration
|
98
|
+
# will fail if there's no valid configuration
|
99
|
+
def gateway
|
100
|
+
@gateway ||= begin
|
101
|
+
@gateway = Wirecard::Elastic.configuration.instance_variable_get("@#{payment_method}")
|
102
|
+
if @gateway.nil?
|
103
|
+
raise Wirecard::Elastic::ConfigError, "Can't recover #{payment_method} details. Please check your configuration."
|
104
|
+
else
|
105
|
+
@gateway
|
106
|
+
end
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
110
|
+
end
|
111
|
+
end
|
112
|
+
end
|
@@ -0,0 +1,85 @@
|
|
1
|
+
require 'rexml/text'
|
2
|
+
|
3
|
+
# format the response and handle / convert the result hash
|
4
|
+
# it's used throughout the whole ElasticApi library when a `response`
|
5
|
+
# has to be returned
|
6
|
+
module Wirecard
|
7
|
+
module Elastic
|
8
|
+
class Response
|
9
|
+
class Base
|
10
|
+
|
11
|
+
# will force symbol conversion for those specific methods calls
|
12
|
+
# *method.transaction_state will return a symbol
|
13
|
+
# *method.anything will return the raw value from the API
|
14
|
+
SYMBOLS_MAP = [:request_status, :transaction_type, :transaction_state, :payment_method]
|
15
|
+
|
16
|
+
# `transaction_type` isn't here because we don't want
|
17
|
+
# to turn `refund-purchase` into `refund_purchase`
|
18
|
+
# we use UNDERSCORE_MAP for that
|
19
|
+
UNDERSCORE_MAP = [:request_status, :transaction_state, :payment_method]
|
20
|
+
|
21
|
+
attr_reader :origin, :raw
|
22
|
+
|
23
|
+
def initialize(origin, raw)
|
24
|
+
@origin = origin
|
25
|
+
@raw = raw
|
26
|
+
end
|
27
|
+
|
28
|
+
def method_missing(method_symbol, *arguments, &block)
|
29
|
+
if map.include?(method_symbol)
|
30
|
+
response = cycle(*map[method_symbol])
|
31
|
+
if SYMBOLS_MAP.include?(method_symbol)
|
32
|
+
if UNDERSCORE_MAP.include?(method_symbol)
|
33
|
+
symbolize_data(underscore_data(response))
|
34
|
+
else
|
35
|
+
symbolize_data(response)
|
36
|
+
end
|
37
|
+
else
|
38
|
+
response
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
# general mapping for automatic method recovery
|
44
|
+
# when you basically ask for MyResponse.request_id it will go through the hash
|
45
|
+
# following the map and return the value at the end of the loop
|
46
|
+
# each response class can extend easily the map for its own specific use
|
47
|
+
def map
|
48
|
+
{
|
49
|
+
:request_id => [:"request-id"],
|
50
|
+
:request_status => [:statuses, :status, 0, :severity],
|
51
|
+
:requested_amount => [:"requested-amount", :value],
|
52
|
+
:requested_amount_currency => [:"requested-amount", :currency],
|
53
|
+
:transaction_id => [:"requested-id"],
|
54
|
+
:transaction_type => [:"transaction-type"],
|
55
|
+
:transaction_state => [:"transaction-state"],
|
56
|
+
:payment_method => [:"payment-methods", :"payment-method", 0, :name]
|
57
|
+
}
|
58
|
+
end
|
59
|
+
|
60
|
+
private
|
61
|
+
|
62
|
+
# navigate through the hash without crashing
|
63
|
+
def cycle(*elements)
|
64
|
+
position = raw[:payment] || raw[:payment]&.[](:"merchant-account-id")
|
65
|
+
elements.each do |element|
|
66
|
+
position = position&.[](element)
|
67
|
+
return position if position.nil?
|
68
|
+
end
|
69
|
+
position
|
70
|
+
end
|
71
|
+
|
72
|
+
# convert the data into a symbol
|
73
|
+
def symbolize_data(data)
|
74
|
+
data.to_s.to_sym
|
75
|
+
end
|
76
|
+
|
77
|
+
# convert - into _
|
78
|
+
def underscore_data(data)
|
79
|
+
data.to_s.gsub("-", "_")
|
80
|
+
end
|
81
|
+
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
module Wirecard
|
2
|
+
module Elastic
|
3
|
+
class Response
|
4
|
+
class Transaction < Base
|
5
|
+
|
6
|
+
# lots of transaction specific mapping can be added below
|
7
|
+
# you just have to do `super.merge(whatever)`
|
8
|
+
def map
|
9
|
+
super.merge({})
|
10
|
+
end
|
11
|
+
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
# after the request comes the processing of the response
|
2
|
+
# it checks the actual feedback from the API and react accordingly
|
3
|
+
module Wirecard
|
4
|
+
module Elastic
|
5
|
+
class Response
|
6
|
+
|
7
|
+
attr_reader :request, :action
|
8
|
+
|
9
|
+
def initialize(request:, action:)
|
10
|
+
@request = request
|
11
|
+
@action = action
|
12
|
+
end
|
13
|
+
|
14
|
+
# check the response and parse it if possible via JSON
|
15
|
+
# transmit the process to one of the Response subclasses (e.g. Refund, Transaction)
|
16
|
+
def dispatch!
|
17
|
+
if response.nil?
|
18
|
+
raise Wirecard::Elastic::Error, "The request failed."
|
19
|
+
else
|
20
|
+
Wirecard::Elastic::Response.const_get(action.capitalize).new(request, response)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
# process the API feedback by converting it into JSON
|
25
|
+
def response
|
26
|
+
@response ||= JSON.parse(request.feedback.body).deep_symbolize_keys if valid_body?
|
27
|
+
end
|
28
|
+
|
29
|
+
private
|
30
|
+
|
31
|
+
# is the API feedback valid ?
|
32
|
+
def valid_body?
|
33
|
+
request.feedback.body && valid_json?(request.feedback.body)
|
34
|
+
end
|
35
|
+
|
36
|
+
# check it's a parsable JSON
|
37
|
+
def valid_json?(json)
|
38
|
+
JSON.parse(json)
|
39
|
+
true
|
40
|
+
rescue JSON::ParserError
|
41
|
+
false
|
42
|
+
end
|
43
|
+
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
data/lib/wirecard/elastic.rb
CHANGED
@@ -1,28 +1,29 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
require "wirecard/elastic/request/base"
|
4
|
-
require "wirecard/elastic/request/refund" # should be dynamically loaded ?
|
5
|
-
require "wirecard/elastic/request/transaction" # should be dynamically loaded ? -> method missing
|
6
|
-
require "wirecard/elastic/response/builder"
|
7
|
-
require "wirecard/elastic/configuration"
|
8
|
-
require "wirecard/elastic/error"
|
9
|
-
require "wirecard/elastic/request"
|
10
|
-
require "wirecard/elastic/response"
|
11
|
-
require "wirecard/elastic/version"
|
1
|
+
# classes auto loader
|
2
|
+
Dir[File.expand_path "lib/**/*.rb"].each { |file| require_relative(file) }
|
12
3
|
|
4
|
+
# this is the entry point of the gem, here goes the configuration system
|
5
|
+
# also the different methods that should be publicly called
|
6
|
+
# such as Wirecard::Elastic.transaction(*) or Wirecard::Elastic.refund(*)
|
13
7
|
module Wirecard
|
14
8
|
module Elastic
|
15
9
|
|
16
|
-
|
10
|
+
# this restrict the actions available via the library to avoid crashes
|
11
|
+
# adding `:whatever` will allow to call Elastic.whatever
|
12
|
+
# and try to load Request::Whatever.new(*args) with it
|
13
|
+
METHODS_MAP = [:transaction, :refund]
|
17
14
|
|
18
|
-
|
19
|
-
Request::Transaction.new(merchant_id, transaction_id, payment_method)
|
20
|
-
end
|
15
|
+
class << self
|
21
16
|
|
22
|
-
def
|
23
|
-
|
17
|
+
def method_missing(method, *args)
|
18
|
+
unless METHODS_MAP.include?(method)
|
19
|
+
raise Error, "Invalid action. Please use the methods available (#{METHODS_MAP.join(', ')})"
|
20
|
+
end
|
21
|
+
Request.const_get(method.capitalize).new(*args)
|
24
22
|
end
|
25
23
|
|
24
|
+
# access and define configuration
|
25
|
+
# this is used while loading
|
26
|
+
# your environment (initializers)
|
26
27
|
def configuration
|
27
28
|
@configuration ||= Configuration.new
|
28
29
|
if block_given?
|
@@ -32,13 +33,15 @@ module Wirecard
|
|
32
33
|
end
|
33
34
|
end
|
34
35
|
|
36
|
+
alias :config :configuration
|
37
|
+
|
38
|
+
# simply reset the configuration
|
39
|
+
# NOTE : avoid to use this if you're
|
40
|
+
# not resetting anything afterwards
|
35
41
|
def reset
|
36
42
|
@configuration = Configuration.new
|
37
43
|
end
|
38
44
|
|
39
|
-
alias :config :configuration
|
40
|
-
|
41
45
|
end
|
42
|
-
|
43
46
|
end
|
44
47
|
end
|
Binary file
|
Binary file
|
Binary file
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: wirecard-elastic
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.2.
|
4
|
+
version: 0.2.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Loschcode
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2016-10-
|
11
|
+
date: 2016-10-27 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -90,6 +90,7 @@ files:
|
|
90
90
|
- ".gitignore"
|
91
91
|
- ".rspec"
|
92
92
|
- Gemfile
|
93
|
+
- Gemfile.lock
|
93
94
|
- README.md
|
94
95
|
- Rakefile
|
95
96
|
- bin/console
|
@@ -97,7 +98,22 @@ files:
|
|
97
98
|
- lib/wirecard/elastic.rb
|
98
99
|
- lib/wirecard/elastic/configuration.rb
|
99
100
|
- lib/wirecard/elastic/error.rb
|
101
|
+
- lib/wirecard/elastic/request.rb
|
102
|
+
- lib/wirecard/elastic/request/base.rb
|
103
|
+
- lib/wirecard/elastic/request/body/builder.rb
|
104
|
+
- lib/wirecard/elastic/request/body/builder/xml.rb
|
105
|
+
- lib/wirecard/elastic/request/body/params/refund.rb
|
106
|
+
- lib/wirecard/elastic/request/body/templates/refund.xml
|
107
|
+
- lib/wirecard/elastic/request/refund.rb
|
108
|
+
- lib/wirecard/elastic/request/transaction.rb
|
109
|
+
- lib/wirecard/elastic/response.rb
|
110
|
+
- lib/wirecard/elastic/response/base.rb
|
111
|
+
- lib/wirecard/elastic/response/refund.rb
|
112
|
+
- lib/wirecard/elastic/response/transaction.rb
|
100
113
|
- lib/wirecard/elastic/version.rb
|
114
|
+
- pkg/wirecard-elastic-0.1.0.gem
|
115
|
+
- pkg/wirecard-elastic-0.1.1.gem
|
116
|
+
- pkg/wirecard-elastic-0.2.0.gem
|
101
117
|
- wirecard-elastic.gemspec
|
102
118
|
homepage: https://github.com/Loschcode/wirecard-elastic
|
103
119
|
licenses: []
|