payex 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
data/Gemfile ADDED
@@ -0,0 +1,3 @@
1
+ source :rubygems
2
+ ruby '1.9.3'
3
+ gemspec
data/Gemfile.lock ADDED
@@ -0,0 +1,76 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ payex (0.0.1)
5
+ nori (~> 1.1)
6
+ savon (~> 1.1)
7
+
8
+ GEM
9
+ remote: http://rubygems.org/
10
+ specs:
11
+ akami (1.2.0)
12
+ gyoku (>= 0.4.0)
13
+ nokogiri (>= 1.4.0)
14
+ builder (3.0.0)
15
+ diff-lcs (1.1.3)
16
+ ffi (1.1.5)
17
+ guard (1.3.2)
18
+ listen (>= 0.4.2)
19
+ thor (>= 0.14.6)
20
+ guard-bundler (1.0.0)
21
+ bundler (~> 1.0)
22
+ guard (~> 1.1)
23
+ guard-rspec (1.2.1)
24
+ guard (>= 1.1)
25
+ gyoku (0.4.6)
26
+ builder (>= 2.1.2)
27
+ httpi (1.1.1)
28
+ rack
29
+ listen (0.4.7)
30
+ rb-fchange (~> 0.0.5)
31
+ rb-fsevent (~> 0.9.1)
32
+ rb-inotify (~> 0.8.8)
33
+ nokogiri (1.5.5)
34
+ nori (1.1.3)
35
+ rack (1.4.1)
36
+ rb-fchange (0.0.5)
37
+ ffi
38
+ rb-fsevent (0.9.1)
39
+ rb-inotify (0.8.8)
40
+ ffi (>= 0.5.0)
41
+ rspec (2.11.0)
42
+ rspec-core (~> 2.11.0)
43
+ rspec-expectations (~> 2.11.0)
44
+ rspec-mocks (~> 2.11.0)
45
+ rspec-core (2.11.1)
46
+ rspec-expectations (2.11.2)
47
+ diff-lcs (~> 1.1.3)
48
+ rspec-mocks (2.11.2)
49
+ savon (1.1.0)
50
+ akami (~> 1.2.0)
51
+ builder (>= 2.1.2)
52
+ gyoku (~> 0.4.5)
53
+ httpi (~> 1.1.0)
54
+ nokogiri (>= 1.4.0)
55
+ nori (~> 1.1.0)
56
+ wasabi (~> 2.5.0)
57
+ savon_spec (1.3.0)
58
+ rspec (>= 2.0.0)
59
+ savon (~> 1.0)
60
+ terminal-notifier-guard (1.5.3)
61
+ thor (0.16.0)
62
+ wasabi (2.5.1)
63
+ httpi (~> 1.0)
64
+ nokogiri (>= 1.4.0)
65
+
66
+ PLATFORMS
67
+ ruby
68
+
69
+ DEPENDENCIES
70
+ guard (~> 1.3)
71
+ guard-bundler (~> 1.0)
72
+ guard-rspec (~> 1.2)
73
+ payex!
74
+ rspec (~> 2.11)
75
+ savon_spec (~> 1.3)
76
+ terminal-notifier-guard (~> 1.5)
data/Guardfile ADDED
@@ -0,0 +1,10 @@
1
+ # -*- ruby -*-
2
+
3
+ guard :bundler do
4
+ watch 'Gemfile'
5
+ watch 'payex.gemspec'
6
+ end
7
+
8
+ guard :rspec, cli: '--color', bundler: false do
9
+ watch(%r'^(lib|spec)/') { 'spec' }
10
+ end
data/README ADDED
@@ -0,0 +1,34 @@
1
+ # -*- ruby -*-
2
+ require 'payex'
3
+
4
+ # This is how a basic PayEx transaction works:
5
+
6
+ PayEx.account_number = 123456789
7
+ PayEx.encryption_key = 'e4939be3910ebu194'
8
+
9
+ PayEx.return_url = 'http://example.com/payex-return'
10
+ PayEx.cancel_url = 'http://example.com/payex-cancel'
11
+
12
+ local_order_id = 'c704acc45a4bec4c8cd50b73fb01a7c7'
13
+
14
+ payment_url = PayEx.authorize_transaction! local_order_id,
15
+ product_number: '123456',
16
+ product_description: 'Brief product description',
17
+ price: 14900, # Price in cents
18
+ customer_ip: '12.34.56.78'
19
+
20
+ # After sending the customer to `payment_url`, they will enter their
21
+ # payment details before being redirected back to `PayEx.return_url`
22
+ # with an `orderRef` parameter appended to the query string:
23
+ #
24
+ # <http://example.com/payex-return?orderRef=9b4031c19960da92d>
25
+ #
26
+ # By giving the `orderRef` value to `PayEx.complete_transaction!` you
27
+ # retreive your local order ID and your app can proceed from there.
28
+
29
+ begin
30
+ local_order_id = PayEx.complete_transaction! '9b4031c19960da92d'
31
+ # [transaction successful]
32
+ rescue PayEx::Error => error
33
+ # [transaction unsucessful]
34
+ end
data/Rakefile ADDED
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env rake
2
+
3
+ require 'bundler/gem_tasks'
data/lib/payex/api.rb ADDED
@@ -0,0 +1,101 @@
1
+ require 'nori'
2
+ require 'savon'
3
+
4
+ module PayEx::API
5
+ extend self
6
+
7
+ class ParamError < StandardError; end
8
+
9
+ def invoke! wsdl, name, params, specs
10
+ body = get_request_body(params, specs)
11
+ response = invoke_raw! wsdl, name, body
12
+
13
+ # Unwrap e.g. <Initialize8Response>
14
+ response = response[response.keys.first]
15
+ # Unwrap e.g. <Initialize8Result>
16
+ response = response[response.keys.first]
17
+ # Parse embedded XML document
18
+ response = Nori.parse(response)
19
+ # Unwrap <payex>
20
+ response = response[response.keys.first]
21
+
22
+ if ok = response[:status][:code] == 'OK' rescue false
23
+ response
24
+ elsif defined? response[:status][:description]
25
+ raise PayEx::Error, response[:status][:description]
26
+ else
27
+ raise PayEx::Error, %{invalid response: #{response.inspect}}
28
+ end
29
+ end
30
+
31
+ def invoke_raw! wsdl, name, body
32
+ Savon.client(wsdl).request(name, body: body) {
33
+ http.headers.delete('SOAPAction')
34
+ }.body
35
+ end
36
+
37
+ def signed_hash(string)
38
+ Digest::MD5.hexdigest(string + PayEx.encryption_key!)
39
+ end
40
+
41
+ def get_request_body(params, specs)
42
+ parse_params(params, specs).tap do |params|
43
+ params['hash'] = sign_params(params, specs)
44
+ end
45
+ end
46
+
47
+ def sign_params(params, specs)
48
+ signed_hash(hashed_params(params, specs).join)
49
+ end
50
+
51
+ def hashed_params(params, specs)
52
+ specs.select { |key, options| options[:signed] }.
53
+ keys.map { |key| params[key] }
54
+ end
55
+
56
+ def parse_params(params, specs)
57
+ stringify_keys(params).tap do |result|
58
+ _parse_params! result, specs
59
+ result.select! { |k, v| v != nil }
60
+ end
61
+ end
62
+
63
+ def stringify_keys(hash)
64
+ Hash[*hash.map { |k, v| [k.to_s, v] }.flatten]
65
+ end
66
+
67
+ def _parse_params!(params, specs)
68
+ for name, options in specs
69
+ begin
70
+ params[name] = parse_param(params[name], options)
71
+ rescue PayEx::API::ParamError => error
72
+ param_error! %{#{name.inspect}: #{error.message}}
73
+ end
74
+ end
75
+ end
76
+
77
+ def parse_param(param, options)
78
+ unless options.is_a? Hash
79
+ raise ArgumentError, %{expected Hash, got #{options.inspect}}
80
+ end
81
+
82
+ if param != nil
83
+ result = param
84
+ elsif options.include? :default
85
+ result = options[:default]
86
+ result = result.call if result.is_a? Proc
87
+ else
88
+ param_error! 'parameter required'
89
+ end
90
+
91
+ if options.include?(:format) and not options[:format] === result
92
+ param_error! %{must match #{options[:format].inspect}}
93
+ else
94
+ result
95
+ end
96
+ end
97
+
98
+ def param_error! message
99
+ raise ParamError, message
100
+ end
101
+ end
@@ -0,0 +1,94 @@
1
+ module PayEx::PxOrder
2
+ extend self
3
+
4
+ def wsdl
5
+ '%s/pxorder/pxorder.asmx?WSDL' % PayEx.base_url
6
+ end
7
+
8
+ def Initialize7(params)
9
+ PayEx::API.invoke! wsdl, 'Initialize7', params, {
10
+ 'accountNumber' => {
11
+ signed: true,
12
+ default: proc { PayEx.account_number! }
13
+ },
14
+ 'purchaseOperation' => {
15
+ signed: true
16
+ },
17
+ 'price' => {
18
+ signed: true,
19
+ format: Integer
20
+ },
21
+ 'priceArgList' => {
22
+ signed: true,
23
+ default: ''
24
+ },
25
+ 'currency' => {
26
+ signed: true,
27
+ default: proc { PayEx.default_currency }
28
+ },
29
+ 'vat' => {
30
+ signed: true,
31
+ format: Integer,
32
+ default: 0
33
+ },
34
+ 'orderID' => {
35
+ signed: true,
36
+ format: /^[a-z0-9]{,50}$/i
37
+ },
38
+ 'productNumber' => {
39
+ signed: true,
40
+ format: /^[A-Z0-9]{,50}$/
41
+ },
42
+ 'description' => {
43
+ signed: true,
44
+ format: /^.{,160}$/
45
+ },
46
+ 'clientIPAddress' => {
47
+ signed: true
48
+ },
49
+ 'clientIdentifier' => {
50
+ signed: true,
51
+ default: ''
52
+ },
53
+ 'additionalValues' => {
54
+ signed: true,
55
+ default: ''
56
+ },
57
+ 'externalID' => {
58
+ signed: true,
59
+ default: ''
60
+ },
61
+ 'returnUrl' => {
62
+ signed: true
63
+ },
64
+ 'view' => {
65
+ signed: true,
66
+ default: 'CREDITCARD'
67
+ },
68
+ 'agreementRef' => {
69
+ signed: true,
70
+ default: ''
71
+ },
72
+ 'cancelUrl' => {
73
+ signed: true,
74
+ default: ''
75
+ },
76
+ 'clientLanguage' => {
77
+ signed: true,
78
+ default: ''
79
+ }
80
+ }
81
+ end
82
+
83
+ def Complete(params)
84
+ PayEx::API.invoke! wsdl, 'Complete', params, {
85
+ 'accountNumber' => {
86
+ signed: true,
87
+ default: proc { PayEx.account_number! }
88
+ },
89
+ 'orderRef' => {
90
+ signed: true
91
+ }
92
+ }
93
+ end
94
+ end
data/lib/payex.rb ADDED
@@ -0,0 +1,78 @@
1
+ module PayEx
2
+ extend self
3
+
4
+ TEST_URL = 'https://test-external.payex.com'
5
+ LIVE_URL = 'https://external.payex.com'
6
+
7
+ class Error < StandardError; end
8
+
9
+ attr_accessor :default_currency
10
+ attr_accessor :base_url
11
+
12
+ attr_accessor :account_number
13
+ attr_accessor :encryption_key
14
+
15
+ attr_accessor :return_url
16
+ attr_accessor :cancel_url
17
+ end
18
+
19
+ PayEx.default_currency = 'SEK'
20
+ PayEx.base_url = PayEx::TEST_URL
21
+
22
+ require 'payex/api'
23
+ require 'payex/pxorder'
24
+
25
+ def PayEx.account_number!
26
+ PayEx.account_number or fail 'Please set PayEx.account_number'
27
+ end
28
+
29
+ def PayEx.encryption_key!
30
+ PayEx.encryption_key or fail 'Please set PayEx.encryption_key'
31
+ end
32
+
33
+ def PayEx.authorize_transaction! order_id, params
34
+ response = PayEx::PxOrder.Initialize7 \
35
+ orderID: order_id,
36
+ purchaseOperation: 'AUTHORIZATION',
37
+ productNumber: params[:product_number],
38
+ description: params[:product_description],
39
+ price: params[:price],
40
+ clientIPAddress: params[:customer_ip],
41
+ returnUrl: PayEx.return_url,
42
+ cancelUrl: PayEx.cancel_url
43
+
44
+ response[:redirect_url]
45
+ end
46
+
47
+ def PayEx.complete_transaction! id
48
+ response = PayEx::PxOrder.Complete(orderRef: id)
49
+
50
+ status = response[:transaction_status]
51
+ status = PayEx.parse_transaction_status(status)
52
+
53
+ case status
54
+ when :sale, :authorize
55
+ response[:order_id]
56
+ when :initialize
57
+ raise PayEx::Error, 'Transaction not completed'
58
+ when :failure
59
+ message = response[:error_details][:third_party_error] rescue nil
60
+ raise PayEx::Error, message
61
+ else
62
+ raise PayEx::Error, 'Unexpected transaction status: ' +
63
+ status.to_s.upcase
64
+ end
65
+ end
66
+
67
+ def PayEx.parse_transaction_status(status)
68
+ case status.to_s
69
+ when '0' then :sale
70
+ when '1' then :initialize
71
+ when '2' then :credit
72
+ when '3' then :authorize
73
+ when '4' then :cancel
74
+ when '5' then :failure
75
+ when '6' then :capture
76
+ else status.to_s
77
+ end
78
+ end
data/payex.gemspec ADDED
@@ -0,0 +1,19 @@
1
+ # -*- ruby; coding: utf-8 -*-
2
+
3
+ Gem::Specification.new do |gem|
4
+ gem.name = 'payex'
5
+ gem.version = '0.0.1'
6
+ gem.summary = 'PayEx SOAP API glue'
7
+ gem.author = 'Daniel Brockman'
8
+ gem.files = `git ls-files 2>/dev/null`.split($\)
9
+
10
+ gem.add_dependency 'nori', '~> 1.1'
11
+ gem.add_dependency 'savon', '~> 1.1'
12
+
13
+ gem.add_development_dependency 'guard', '~> 1.3'
14
+ gem.add_development_dependency 'guard-bundler', '~> 1.0'
15
+ gem.add_development_dependency 'guard-rspec', '~> 1.2'
16
+ gem.add_development_dependency 'rspec', '~> 2.11'
17
+ gem.add_development_dependency 'savon_spec', '~> 1.3'
18
+ gem.add_development_dependency 'terminal-notifier-guard', '~> 1.5'
19
+ end
@@ -0,0 +1,60 @@
1
+ # -*- coding: utf-8 -*-
2
+ require 'payex'
3
+ require 'spec_helper'
4
+
5
+ describe PayEx::API do
6
+ before {
7
+ PayEx.encryption_key = 'foo'
8
+ }
9
+
10
+ it 'should know how to stringify keys' do
11
+ PayEx::API.stringify_keys(a: 1, b: 2).
12
+ should == { 'a' => 1, 'b' => 2 }
13
+ end
14
+
15
+ it 'should know how to sign params' do
16
+ param_hash, specs, param_array = {}, {}, []
17
+
18
+ for name in 'a'..'z'
19
+ if rand < 0.5
20
+ param_hash[name] = rand
21
+ param_array << param_hash[name]
22
+ specs[name] = { signed: true }
23
+ else
24
+ param_hash[name] = rand
25
+ end
26
+ end
27
+
28
+ actual = PayEx::API.sign_params(param_hash, specs)
29
+
30
+ to_sign = param_array.join + PayEx.encryption_key
31
+ expected = Digest::MD5.hexdigest(to_sign)
32
+
33
+ actual.should == expected
34
+ end
35
+
36
+ it 'should know how to add defaults' do
37
+ PayEx::API.parse_param(nil, { default: 2 }).should == 2
38
+ end
39
+
40
+ it 'should know how to call default procs' do
41
+ PayEx::API.parse_param(nil, { default: proc { 2 } }).should == 2
42
+ end
43
+
44
+ it 'should reject wrong type of value' do
45
+ proc {
46
+ PayEx::API.parse_param('foobar', { format: Integer })
47
+ }.should raise_error PayEx::API::ParamError
48
+ end
49
+
50
+ it 'should reject strings based on regular expressions' do
51
+ proc {
52
+ PayEx::API.parse_param('foobar', { format: /^.{,3}$/ })
53
+ }.should raise_error PayEx::API::ParamError
54
+ end
55
+
56
+ it 'should stringify keys when parsing params' do
57
+ PayEx::API.parse_params({ a: 1 }, { 'b' => { default: 2 } }).
58
+ should == { 'a' => 1, 'b' => 2 }
59
+ end
60
+ end
@@ -0,0 +1,30 @@
1
+ <?xml version="1.0" encoding="utf-8"?>
2
+ <env:Envelope xmlns:env="http://schemas.xmlsoap.org/soap/envelope/"
3
+ xmlns:xsd="http://www.w3.org/2001/XMLSchema"
4
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
5
+ <env:Body>
6
+ <Initialize7Response xmlns="http://external.payex.com/PxOrder/">
7
+ <Initialize7Result>
8
+ <![CDATA[
9
+ <?xml version="1.0" encoding="utf-8"?>
10
+ <payex>
11
+ <header name="Payex Header v1.0">
12
+ <id>4e0fbe36b146452b8ce7b87e6186a3e3</id>
13
+ <date>2010-11-10 06:13:48</date>
14
+ </header>
15
+ <status>
16
+ <code>OK</code>
17
+ <description>OK</description>
18
+ <errorCode>OK</errorCode>
19
+ <paramName/>
20
+ <thirdPartyError/>
21
+ </status>
22
+ <orderRef>b93d29bf7df3424cac23407a987c0be9</orderRef>
23
+ <sessionRef>7807accc0e7e4d069e1d92ec5680d0cc</sessionRef>
24
+ <redirectUrl>https://test-confined.payex.com/PxOrderCC.aspx?orderRef=b93d29bf7df3424cac23407a987c0be9</redirectUrl>
25
+ </payex>
26
+ ]]>
27
+ </Initialize7Result>
28
+ </Initialize7Response>
29
+ </env:Body>
30
+ </env:Envelope>
@@ -0,0 +1,45 @@
1
+ # -*- coding: utf-8 -*-
2
+ require 'payex'
3
+ require 'spec_helper'
4
+
5
+ describe PayEx do
6
+ before {
7
+ PayEx.account_number = 'foo-account'
8
+ PayEx.encryption_key = 'foo-secret'
9
+ PayEx.return_url = 'http://example.com/payex-callback'
10
+ }
11
+
12
+ it 'should send request and parse response' do
13
+ expected = {
14
+ 'accountNumber' => 'foo-account',
15
+ 'purchaseOperation' => 'AUTHORIZATION',
16
+ 'price' => 12300,
17
+ 'priceArgList' => '',
18
+ 'currency' => 'SEK',
19
+ 'vat' => 0,
20
+ 'orderID' => 'order123',
21
+ 'productNumber' => 'PRODUCT123',
22
+ 'description' => 'Product description',
23
+ 'clientIPAddress' => '12.34.56.78',
24
+ 'clientIdentifier' => '',
25
+ 'additionalValues' => '',
26
+ 'externalID' => '',
27
+ 'returnUrl' => 'http://example.com/payex-callback',
28
+ 'view' => 'CREDITCARD',
29
+ 'agreementRef' => '',
30
+ 'cancelUrl' => '',
31
+ 'clientLanguage' => ''
32
+ }
33
+
34
+ expected['hash'] = PayEx::API.signed_hash(expected.values.join)
35
+ savon.expects('Initialize7').with(expected).returns(:initialize_ok)
36
+
37
+ href = PayEx.authorize_transaction! 'order123',
38
+ product_number: 'PRODUCT123',
39
+ product_description: 'Product description',
40
+ price: 12300,
41
+ customer_ip: '12.34.56.78'
42
+
43
+ href.should include 'http'
44
+ end
45
+ end
@@ -0,0 +1,8 @@
1
+ require 'savon_spec'
2
+
3
+ Savon::Spec::Fixture.path =
4
+ File.expand_path('../fixtures', __FILE__)
5
+
6
+ RSpec.configure do |config|
7
+ config.include Savon::Spec::Macros
8
+ end
metadata ADDED
@@ -0,0 +1,185 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: payex
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Daniel Brockman
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2012-09-04 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: nori
16
+ requirement: !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ~>
20
+ - !ruby/object:Gem::Version
21
+ version: '1.1'
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ~>
28
+ - !ruby/object:Gem::Version
29
+ version: '1.1'
30
+ - !ruby/object:Gem::Dependency
31
+ name: savon
32
+ requirement: !ruby/object:Gem::Requirement
33
+ none: false
34
+ requirements:
35
+ - - ~>
36
+ - !ruby/object:Gem::Version
37
+ version: '1.1'
38
+ type: :runtime
39
+ prerelease: false
40
+ version_requirements: !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ~>
44
+ - !ruby/object:Gem::Version
45
+ version: '1.1'
46
+ - !ruby/object:Gem::Dependency
47
+ name: guard
48
+ requirement: !ruby/object:Gem::Requirement
49
+ none: false
50
+ requirements:
51
+ - - ~>
52
+ - !ruby/object:Gem::Version
53
+ version: '1.3'
54
+ type: :development
55
+ prerelease: false
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ none: false
58
+ requirements:
59
+ - - ~>
60
+ - !ruby/object:Gem::Version
61
+ version: '1.3'
62
+ - !ruby/object:Gem::Dependency
63
+ name: guard-bundler
64
+ requirement: !ruby/object:Gem::Requirement
65
+ none: false
66
+ requirements:
67
+ - - ~>
68
+ - !ruby/object:Gem::Version
69
+ version: '1.0'
70
+ type: :development
71
+ prerelease: false
72
+ version_requirements: !ruby/object:Gem::Requirement
73
+ none: false
74
+ requirements:
75
+ - - ~>
76
+ - !ruby/object:Gem::Version
77
+ version: '1.0'
78
+ - !ruby/object:Gem::Dependency
79
+ name: guard-rspec
80
+ requirement: !ruby/object:Gem::Requirement
81
+ none: false
82
+ requirements:
83
+ - - ~>
84
+ - !ruby/object:Gem::Version
85
+ version: '1.2'
86
+ type: :development
87
+ prerelease: false
88
+ version_requirements: !ruby/object:Gem::Requirement
89
+ none: false
90
+ requirements:
91
+ - - ~>
92
+ - !ruby/object:Gem::Version
93
+ version: '1.2'
94
+ - !ruby/object:Gem::Dependency
95
+ name: rspec
96
+ requirement: !ruby/object:Gem::Requirement
97
+ none: false
98
+ requirements:
99
+ - - ~>
100
+ - !ruby/object:Gem::Version
101
+ version: '2.11'
102
+ type: :development
103
+ prerelease: false
104
+ version_requirements: !ruby/object:Gem::Requirement
105
+ none: false
106
+ requirements:
107
+ - - ~>
108
+ - !ruby/object:Gem::Version
109
+ version: '2.11'
110
+ - !ruby/object:Gem::Dependency
111
+ name: savon_spec
112
+ requirement: !ruby/object:Gem::Requirement
113
+ none: false
114
+ requirements:
115
+ - - ~>
116
+ - !ruby/object:Gem::Version
117
+ version: '1.3'
118
+ type: :development
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ none: false
122
+ requirements:
123
+ - - ~>
124
+ - !ruby/object:Gem::Version
125
+ version: '1.3'
126
+ - !ruby/object:Gem::Dependency
127
+ name: terminal-notifier-guard
128
+ requirement: !ruby/object:Gem::Requirement
129
+ none: false
130
+ requirements:
131
+ - - ~>
132
+ - !ruby/object:Gem::Version
133
+ version: '1.5'
134
+ type: :development
135
+ prerelease: false
136
+ version_requirements: !ruby/object:Gem::Requirement
137
+ none: false
138
+ requirements:
139
+ - - ~>
140
+ - !ruby/object:Gem::Version
141
+ version: '1.5'
142
+ description:
143
+ email:
144
+ executables: []
145
+ extensions: []
146
+ extra_rdoc_files: []
147
+ files:
148
+ - Gemfile
149
+ - Gemfile.lock
150
+ - Guardfile
151
+ - README
152
+ - Rakefile
153
+ - lib/payex.rb
154
+ - lib/payex/api.rb
155
+ - lib/payex/pxorder.rb
156
+ - payex.gemspec
157
+ - spec/api_unit_spec.rb
158
+ - spec/fixtures/Initialize7/initialize_ok.xml
159
+ - spec/integration_spec.rb
160
+ - spec/spec_helper.rb
161
+ homepage:
162
+ licenses: []
163
+ post_install_message:
164
+ rdoc_options: []
165
+ require_paths:
166
+ - lib
167
+ required_ruby_version: !ruby/object:Gem::Requirement
168
+ none: false
169
+ requirements:
170
+ - - ! '>='
171
+ - !ruby/object:Gem::Version
172
+ version: '0'
173
+ required_rubygems_version: !ruby/object:Gem::Requirement
174
+ none: false
175
+ requirements:
176
+ - - ! '>='
177
+ - !ruby/object:Gem::Version
178
+ version: '0'
179
+ requirements: []
180
+ rubyforge_project:
181
+ rubygems_version: 1.8.24
182
+ signing_key:
183
+ specification_version: 3
184
+ summary: PayEx SOAP API glue
185
+ test_files: []