omnipay 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: c3c13dede2e2ea788ee716eb834b225b1cae1ca9
4
+ data.tar.gz: 949abeb3bde942deb0c11d8c011814b692f538f1
5
+ SHA512:
6
+ metadata.gz: afbd5ccc734ef955631e111ded2dbf447dc63ae3658069d7b72c1c8210dbee2eb707a989f5057dc0ec112f0a7dcfa43660b6f8d0aaa6b76a80155b6883331d09
7
+ data.tar.gz: d419fd51650c301b5c2a379fea3a11192921b1b585f146726af5ed2d933d0c1054afd28ac1c6d41cafb443e835e2075554048a85aa59faeddb8cb23af40934c3
@@ -0,0 +1,32 @@
1
+ require 'singleton'
2
+
3
+ module Omnipay
4
+
5
+ autoload :Gateway, 'omnipay/gateway'
6
+ autoload :Adapter, 'omnipay/adapter'
7
+ autoload :RequestPhase, 'omnipay/request_phase'
8
+ autoload :CallbackPhase, 'omnipay/callback_phase'
9
+ autoload :AutosubmitForm, 'omnipay/autosubmit_form'
10
+ autoload :Signer, 'omnipay/signer'
11
+
12
+ # Error codes
13
+ INVALID_RESPONSE = :invalid_response
14
+ CANCELATION = :cancelation
15
+ PAYMENT_REFUSED = :payment_refused
16
+ WRONG_SIGNATURE = :wrong_signature
17
+
18
+ # Configuration
19
+ class Configuration
20
+ include Singleton
21
+ attr_accessor :secret_token
22
+ end
23
+
24
+ def self.configuration
25
+ Configuration.instance
26
+ end
27
+
28
+ def self.configure
29
+ yield configuration
30
+ end
31
+
32
+ end
@@ -0,0 +1,62 @@
1
+ # Glue between the rack middleware and the adapter implementation
2
+ # Responsible for initializing, configuring the adapter, and formatting
3
+ # the responses for use in the middleware
4
+
5
+ module Omnipay
6
+
7
+ class Adapter
8
+
9
+ attr_reader :uid
10
+
11
+ def initialize(uid, callback_url, config, dynamic_config)
12
+ @uid = uid
13
+ @callback_url = callback_url
14
+ @config = config
15
+ @dynamic_config = dynamic_config
16
+
17
+ @strategy = build_strategy
18
+ end
19
+
20
+ def valid?
21
+ @strategy != nil
22
+ end
23
+
24
+ def request_phase(amount, opts)
25
+ @strategy.request_phase(amount, opts)
26
+ end
27
+
28
+ def callback_hash(params)
29
+ @strategy.callback_hash(params)
30
+ end
31
+
32
+
33
+ private
34
+
35
+ def build_strategy
36
+ return nil unless strategy_class
37
+
38
+ strategy_class.new(@callback_url, strategy_config)
39
+ end
40
+
41
+ def strategy_class
42
+ params[:adapter]
43
+ end
44
+
45
+ def strategy_config
46
+ params[:config] || {}
47
+ end
48
+
49
+ def params
50
+ return @params if @params
51
+
52
+ if @dynamic_config
53
+ @params = @dynamic_config.call(@uid) || {}
54
+ else
55
+ @params = @config || {}
56
+ end
57
+
58
+ @params ||= {}
59
+ end
60
+
61
+ end
62
+ end
@@ -0,0 +1,140 @@
1
+ # Omnipay adapter for mangopay
2
+ # documentation : http://docs.mangopay.com/api-references/
3
+ #
4
+ # Configuration :
5
+ # - client_id:string (mandatory) : client id of your mangopay account
6
+ # - client_passphrase:string (mandatory) : the passphrase for your account
7
+ # - wallet_id:string (mandatory) : the wallet to be credited with the payments
8
+
9
+ require_relative 'mangopay/client'
10
+
11
+
12
+ module Omnipay
13
+ module Adapters
14
+
15
+ class Mangopay
16
+
17
+ attr_reader :client
18
+
19
+ def initialize(callback_url, config = {})
20
+
21
+ raise ArgumentError.new("Missing client_id, client_passphrase, or wallet_id parameter") unless [config[:client_id], config[:client_passphrase], config[:wallet_id]].all?
22
+
23
+ @client = Client.new(config[:client_id], config[:client_passphrase], :sandbox => !!config[:sandbox])
24
+ @callback_url = callback_url
25
+ @wallet_id = config[:wallet_id]
26
+
27
+ end
28
+
29
+
30
+ def request_phase(amount, params = {})
31
+
32
+ transaction_id, redirect_url = create_web_payin(amount, params)
33
+
34
+ # Generate the path and query parameters from the returned redirect_url string
35
+ uri = URI(redirect_url)
36
+
37
+ return [
38
+ 'GET',
39
+ "#{uri.scheme}://#{uri.host}#{uri.path}",
40
+ Rack::Utils.parse_nested_query(uri.query),
41
+ transaction_id
42
+ ]
43
+
44
+ end
45
+
46
+
47
+ def callback_hash(params)
48
+
49
+ transaction_id = params[:transactionId]
50
+
51
+ begin
52
+ response = @client.get "/payins/#{transaction_id}"
53
+ rescue Mangopay::Client::Error => e
54
+ return {
55
+ :success => false,
56
+ :error => Omnipay::INVALID_RESPONSE,
57
+ :error_message => "Could not fetch details of transaction #{transaction_id}"
58
+ }
59
+ end
60
+
61
+ # Check if the response is valid
62
+ if response['code'] != 200
63
+ return {
64
+ :success => false,
65
+ :error => Omnipay::INVALID_RESPONSE
66
+ }
67
+ end
68
+
69
+
70
+ # Successful transaction
71
+ if response['Status'] == 'SUCCEEDED'
72
+ {
73
+ :success => true,
74
+ :amount => response['DebitedFunds']['Amount'],
75
+ :transaction_id => transaction_id
76
+ }
77
+ else
78
+
79
+ # Cancelation
80
+ if ['101001', '101002'].include? response['ResultCode']
81
+ {
82
+ :success => false,
83
+ :error => Omnipay::CANCELATION
84
+ }
85
+ else
86
+ {
87
+ :success => false,
88
+ :error => Omnipay::PAYMENT_REFUSED,
89
+ :error_message => "Refused payment for transaction #{transaction_id}.\nCode : #{response['ResultCode']}\nMessage : #{response['ResultMessage']}"
90
+ }
91
+ end
92
+ end
93
+ end
94
+
95
+
96
+ private
97
+
98
+ def create_web_payin(amount, params)
99
+
100
+ # Create a user
101
+ random_key = "#{Time.now.to_i}-#{(0...3).map { ('a'..'z').to_a[rand(26)] }.join}"
102
+ user_params = {
103
+ :Email => "user-#{random_key}@host.tld",
104
+ :FirstName => "User #{random_key}",
105
+ :LastName => "User #{random_key}",
106
+ :Birthday => Time.now.to_i,
107
+ :Nationality => "FR",
108
+ :CountryOfResidence => "FR"
109
+ }
110
+
111
+ user_id = (@client.post('/users/natural', user_params))["Id"]
112
+
113
+ # Create the web payin
114
+ payin_params = {
115
+ :AuthorId => user_id,
116
+ :DebitedFunds => {
117
+ :Currency => 'EUR',
118
+ :Amount => amount
119
+ },
120
+ :Fees => {
121
+ :Currency => 'EUR',
122
+ :Amount => 0
123
+ },
124
+ :CreditedWalletId => @wallet_id,
125
+ :ReturnURL => @callback_url,
126
+ :Culture => (params[:locale] || 'fr').upcase,
127
+ :CardType => 'CB_VISA_MASTERCARD',
128
+ :SecureMode => 'FORCE'
129
+ }
130
+
131
+ payin = @client.post '/payins/card/web', payin_params
132
+
133
+ # Return the transaction reference, and the full redirection url
134
+ return [payin["Id"], payin["RedirectURL"]]
135
+ end
136
+
137
+ end
138
+
139
+ end
140
+ end
@@ -0,0 +1,70 @@
1
+ # Client for the mangopay API
2
+
3
+ require 'httparty'
4
+
5
+ module Omnipay
6
+ module Adapters
7
+ class Mangopay
8
+
9
+ class Client
10
+
11
+ class Error < ::StandardError ; end
12
+
13
+ include HTTParty
14
+
15
+ format :json
16
+
17
+ headers 'Accept' => 'application/json'
18
+ headers 'Content-Type' => 'application/json'
19
+
20
+ def initialize(key, secret, opts = {})
21
+ @key = key
22
+ @secret = secret
23
+
24
+ if opts[:sandbox]
25
+ @base_uri = 'https://api.sandbox.mangopay.com/v2'
26
+ else
27
+ @base_uri = 'https://api.mangopay.com/v2'
28
+ end
29
+ end
30
+
31
+ def get(path)
32
+ response = self.class.get "/#{@key}#{path}",
33
+ :basic_auth => {:username => @key, :password => @secret},
34
+ :base_uri => @base_uri
35
+
36
+ check_errors(response)
37
+
38
+ response.parsed_response.merge("code" => response.code)
39
+ end
40
+
41
+ def post(path, params = {})
42
+ response = self.class.post "/#{@key}#{path}",
43
+ :body => params.to_json,
44
+ :basic_auth => {:username => @key, :password => @secret},
45
+ :base_uri => @base_uri
46
+
47
+ check_errors(response)
48
+
49
+ response.parsed_response.merge("code" => response.code)
50
+ end
51
+
52
+
53
+ private
54
+
55
+ def check_errors(response)
56
+ # nocommit, log the request :/
57
+ if response.code != 200
58
+ error_message = response.parsed_response.merge(
59
+ "code" => response.code
60
+ )
61
+
62
+ raise Error, error_message.inspect
63
+ end
64
+ end
65
+
66
+ end
67
+
68
+ end
69
+ end
70
+ end
@@ -0,0 +1,130 @@
1
+ # Omnipay adapter for oneclicpay
2
+ # documentation : docs.oneclicpay.com
3
+ #
4
+ # Configuration :
5
+ # - tpe_id:string (mandatory) : serial number of your virutal payment terminal
6
+ # - secret_key:string (mandatory) : security key for your account
7
+ # - sandbox:boolean (default: false) : use the sandbox or the production environment
8
+
9
+ require 'base64'
10
+ require 'digest'
11
+ require 'httparty'
12
+
13
+ module Omnipay
14
+ module Adapters
15
+
16
+ class Oneclicpay
17
+
18
+ HTTP_METHOD = 'POST'
19
+
20
+ REDIRECT_URLS = {
21
+ :sandbox => 'https://secure.homologation.oneclicpay.com',
22
+ :production => 'https://secure.oneclicpay.com'
23
+ }
24
+
25
+ VALIDATION_URLS = {
26
+ :sandbox => 'https://secure.homologation.oneclicpay.com:60000',
27
+ :production => 'https://secure.oneclicpay.com:60000'
28
+ }
29
+
30
+ def initialize(callback_url, config)
31
+ @callback_url = callback_url
32
+
33
+ @tpe_id = config[:tpe_id]
34
+ @secret_key = config[:secret_key]
35
+ @is_sandbox = config[:sandbox]
36
+
37
+ raise ArgumentError.new("Missing tpe_id or secret_key parameter") unless [@tpe_id, @secret_key].all?
38
+ end
39
+
40
+
41
+ def request_phase(amount, params={})
42
+ product_name = params[:title] || ''
43
+ transaction_id = params[:transaction_id] || random_transaction_id
44
+ locale = params[:locale] || 'fr'
45
+
46
+ [
47
+ HTTP_METHOD,
48
+ redirect_url,
49
+ redirect_params_for(amount, product_name, transaction_id, locale),
50
+ transaction_id
51
+ ]
52
+ end
53
+
54
+
55
+ def callback_hash(params)
56
+
57
+ if params[:result] == "NOK" && params[:reason] == "Abandon de la transaction."
58
+ return { :success => false, :error => Omnipay::CANCELATION }
59
+ end
60
+
61
+
62
+ if params[:result] == "OK"
63
+
64
+ # Validate the response via the API
65
+ transaction_id = params[:transactionId]
66
+ amount = get_transaction_amount(transaction_id)
67
+
68
+ if amount
69
+ { :success => true, :amount => amount, :transaction_id => transaction_id }
70
+ else
71
+ { :success => false, :error => Omnipay::INVALID_RESPONSE, :error_message => "Could not fetch the amount of the transaction #{transaction_id}" }
72
+ end
73
+
74
+
75
+ elsif params[:result] == "NOK"
76
+ { :success => false, :error => Omnipay::PAYMENT_REFUSED, :error_message => params[:reason] }
77
+
78
+ else
79
+ { :success => false, :error => Omnipay::INVALID_RESPONSE, :error_message => "No :result key in the params #{params.inspect}" }
80
+ end
81
+ end
82
+
83
+
84
+ private
85
+
86
+ def redirect_params_for(amount, product_name, transaction_id, locale)
87
+ {
88
+ :montant => (amount.to_f/100).to_s,
89
+ :idTPE => @tpe_id,
90
+ :idTransaction => transaction_id,
91
+ :devise => 'EUR',
92
+ :lang => locale,
93
+ :nom_produit => product_name,
94
+ :urlRetourOK => @callback_url,
95
+ :urlRetourNOK => @callback_url
96
+ }.tap{|params|
97
+ params[:sec] = signature(params)
98
+ }
99
+ end
100
+
101
+ def random_transaction_id
102
+ "#{Time.now.to_i}-#{@tpe_id}-#{random_token}"
103
+ end
104
+
105
+ def random_token
106
+ (0...3).map { ('a'..'z').to_a[rand(26)] }.join
107
+ end
108
+
109
+ def signature(params)
110
+ to_sign = (params.values + [@secret_key]).join('|')
111
+ Digest::SHA512.hexdigest(Base64.encode64(to_sign).gsub(/\n/, ''))
112
+ end
113
+
114
+ def get_transaction_amount(transaction_id)
115
+ response = HTTParty.post("#{validation_url}/rest/payment/find?serialNumber=#{@tpe_id}&key=#{@secret_key}&transactionRef=#{transaction_id}")
116
+ (response.parsed_response["transaction"][0]["ok"] != 0) && response.parsed_response["transaction"][0]["amount"]
117
+ end
118
+
119
+ def redirect_url
120
+ @is_sandbox ? REDIRECT_URLS[:sandbox] : REDIRECT_URLS[:production]
121
+ end
122
+
123
+ def validation_url
124
+ @is_sandbox ? VALIDATION_URLS[:sandbox] : VALIDATION_URLS[:production]
125
+ end
126
+
127
+ end
128
+
129
+ end
130
+ end
@@ -0,0 +1,43 @@
1
+ # Builds an html page with an autosubmitted form, to handle POST redirections
2
+ module Omnipay
3
+ class AutosubmitForm
4
+
5
+ HEADER = <<-HEADER
6
+ <!DOCTYPE html>
7
+ <html>
8
+ <head>
9
+ <script type="text/javascript">
10
+ window.onload=function(){
11
+ document.getElementById('autosubmit-form').submit();
12
+ }
13
+ </script>
14
+ </head>
15
+
16
+ <body>
17
+ <h1>Redirecting...</h1>
18
+ HEADER
19
+
20
+ FOOTER = <<-FOOTER
21
+ </body>
22
+ </html>
23
+ FOOTER
24
+
25
+ def initialize(action, fields)
26
+ @action = action
27
+ @fields = fields.map{|name, value| {:name => name, :value => value}}
28
+ end
29
+
30
+ def html
31
+ HEADER + form_html + FOOTER
32
+ end
33
+
34
+ def form_html
35
+ " <form method=\"POST\" id=\"autosubmit-form\" action=\"#{@action}\">\n" +
36
+ @fields.map{|field|
37
+ " <input type=\"hidden\" name=\"#{field[:name]}\" value=\"#{field[:value]}\"/>\n"
38
+ }.join +
39
+ " </form>\n"
40
+ end
41
+
42
+ end
43
+ end
@@ -0,0 +1,68 @@
1
+ # Class responsible for updating the request env in the callback phase
2
+
3
+ module Omnipay
4
+ class CallbackPhase
5
+
6
+ def initialize(request, adapter)
7
+ @request = request
8
+ @adapter = adapter
9
+ end
10
+
11
+
12
+ def update_env!
13
+
14
+ # The request params, keys symbolized
15
+ params = Hash[@request.params.map{|k,v|[k.to_sym,v]}]
16
+
17
+ # Get the callback hash
18
+ callback_hash = @adapter.callback_hash(params)
19
+
20
+ # Check the signature
21
+ if callback_hash[:success] && !valid_signature?(callback_hash)
22
+ callback_hash = {
23
+ :success => false,
24
+ :error => Omnipay::WRONG_SIGNATURE,
25
+ :error_message => "Signatures do not match."
26
+ }
27
+ end
28
+
29
+ # If not successful response, add informations to the error message
30
+ if !callback_hash[:success]
31
+ callback_hash[:error_message] = (callback_hash[:error_message] || callback_hash[:error].to_s) +
32
+ "\nAdapter : #{@adapter.uid}" +
33
+ "\nContext : #{context.inspect}" +
34
+ "\nStored signature : #{stored_signature}" +
35
+ "\nRequest : #{@request.inspect}"
36
+ end
37
+
38
+ # Store the response in the environment
39
+ @request.env['omnipay.response'] = callback_hash.merge(:raw => params, :context => context)
40
+
41
+ # Force GET request
42
+ @request.env['REQUEST_METHOD'] = 'GET'
43
+ end
44
+
45
+
46
+ private
47
+
48
+ def valid_signature?(callback_hash)
49
+ callback_signature = Signer.new(callback_hash[:transaction_id], callback_hash[:amount], context).signature
50
+
51
+ callback_signature == stored_signature
52
+ end
53
+
54
+ def stored_signature
55
+ @stored_signature ||= @request.session['omnipay.signature'] && @request.session['omnipay.signature'].delete(@adapter.uid)
56
+ end
57
+
58
+ def callback_signature
59
+ @callback_signatureSigner.new(callback_hash[:transaction_id], callback_hash[:amount], context).signature
60
+ end
61
+
62
+ def context
63
+ @context ||= @request.session['omnipay.context'] && @request.session['omnipay.context'].delete(@adapter.uid)
64
+ @context ||= {}
65
+ end
66
+
67
+ end
68
+ end
@@ -0,0 +1,85 @@
1
+ require 'rack'
2
+
3
+ module Omnipay
4
+
5
+ # Gateway middleware
6
+ class Gateway
7
+
8
+ BASE_PATH = '/pay'
9
+
10
+ def initialize(app, options={}, &block)
11
+ @app = app
12
+
13
+ @adapter_options = options
14
+ @adapter_config_block = block
15
+
16
+ # Refreshed at each request
17
+ @uid = nil
18
+ @request = nil
19
+ end
20
+
21
+
22
+ def call(env)
23
+
24
+ # Get the current request
25
+ @request = Rack::Request.new(env)
26
+
27
+ # Check if the path is good, and extract the uid
28
+ @uid = extract_uid_from_path(@request.path)
29
+ return @app.call(env) unless @uid
30
+
31
+ # Get the adapter config for this uid (to handle dynamic configuration)
32
+ adapter = Adapter.new(@uid, callback_url, @adapter_options, @adapter_config_block)
33
+ return @app.call(env) unless adapter.valid?
34
+
35
+ # Handle the request phase
36
+ if request_phase?
37
+ return RequestPhase.new(@request, adapter).response
38
+ end
39
+
40
+ # Handle the callback phase
41
+ if callback_phase?
42
+ CallbackPhase.new(@request, adapter).update_env!
43
+ end
44
+
45
+ # Forward to the app
46
+ @app.call(env)
47
+
48
+ end
49
+
50
+
51
+ private
52
+
53
+ # Check if the current request matches the request or callback phase
54
+ def request_phase?
55
+ @request.path == "#{BASE_PATH}/#{@uid}" && @request.request_method == 'GET'
56
+ end
57
+
58
+ def callback_phase?
59
+ @request.path == "#{BASE_PATH}/#{@uid}/callback"
60
+ end
61
+
62
+
63
+ # Extract the uid from the path
64
+ # If uid already defined, check if it matches
65
+ # "/pay/foobar/callback" => "foobar"
66
+ def extract_uid_from_path(path)
67
+ if path.start_with? BASE_PATH
68
+ uid = path.gsub(/^#{BASE_PATH}/, '').split('/')[1]
69
+ end
70
+
71
+ if !@adapter_options.empty?
72
+ uid = nil unless uid == @adapter_options[:uid]
73
+ end
74
+
75
+ uid
76
+ end
77
+
78
+
79
+ # The callback url for a uid in the current host
80
+ def callback_url
81
+ "#{@request.base_url}#{BASE_PATH}/#{@uid}/callback"
82
+ end
83
+
84
+ end
85
+ end
@@ -0,0 +1,76 @@
1
+ # Class responsible for formatting the redirection in the request phase
2
+
3
+ module Omnipay
4
+ class RequestPhase
5
+
6
+ def initialize(request, adapter)
7
+ @request = request
8
+ @adapter = adapter
9
+ end
10
+
11
+ def response
12
+ method, url, params, transaction_id = @adapter.request_phase(amount, adapter_params)
13
+
14
+ context = store_context!
15
+
16
+ signature = Signer.new(transaction_id, amount, context).signature
17
+ store_signature!(signature)
18
+
19
+ if method == 'GET'
20
+ get_redirect_response(url, params)
21
+ elsif method == 'POST'
22
+ post_redirect_response(url, params)
23
+ else
24
+ raise TypeError.new('request_phase returned http method must be \'GET\' or \'POST\'')
25
+ end
26
+ end
27
+
28
+
29
+ private
30
+
31
+ def amount
32
+ @request.params['amount'].tap{ |amount|
33
+ raise ArgumentError.new('No amount specified') unless amount
34
+ }.to_i
35
+ end
36
+
37
+ def adapter_params
38
+ params = @request.params.dup
39
+
40
+ params.delete 'amount'
41
+ params.delete 'context'
42
+
43
+ # Symbolize the keys
44
+ Hash[params.map{|k,v|[k.to_sym,v]}]
45
+ end
46
+
47
+ def get_redirect_response(url, params)
48
+ redirect_url = url + '?' + Rack::Utils.build_query(params)
49
+ Rack::Response.new.tap{|response| response.redirect(redirect_url)}
50
+ end
51
+
52
+ def post_redirect_response(url, params)
53
+ form = AutosubmitForm.new(url, params)
54
+ Rack::Response.new([form.html], 200, {'Content-Type' => 'text/html;charset=utf-8'})
55
+ end
56
+
57
+ # Store the request's context in session
58
+ def store_context!
59
+ context = @request.params.delete('context')
60
+
61
+ if context
62
+ @request.session['omnipay.context'] ||= {}
63
+ @request.session['omnipay.context'][@adapter.uid] = context
64
+ end
65
+
66
+ return context
67
+ end
68
+
69
+ # Store the requests signature in the session
70
+ def store_signature!(signature)
71
+ @request.session['omnipay.signature'] ||= {}
72
+ @request.session['omnipay.signature'][@adapter.uid] = signature
73
+ end
74
+
75
+ end
76
+ end
@@ -0,0 +1,34 @@
1
+ # Class responsible for signing the outgoing payments in the request phase,
2
+ # and validating them in the callback phase
3
+
4
+ require 'openssl'
5
+
6
+ module Omnipay
7
+ class Signer
8
+
9
+ def initialize(transaction_id, amount, context)
10
+ @transaction_id = transaction_id
11
+ @amount = amount
12
+ @context = context || {}
13
+ end
14
+
15
+ def signature
16
+ to_sign = "#{secret_token}:#{@transaction_id}:#{@amount}:#{self.class.hash_to_string @context}"
17
+ CGI.escape(Base64.encode64(OpenSSL::HMAC.digest('sha1', secret_token, to_sign)))
18
+ end
19
+
20
+
21
+ # Unique key : to configure globally
22
+ def secret_token
23
+ Omnipay.configuration.secret_token
24
+ end
25
+
26
+ private
27
+
28
+ def self.hash_to_string(hash)
29
+ # key/values appended by alphabetical key order
30
+ hash.sort_by{|k,_|k}.flatten.join('')
31
+ end
32
+
33
+ end
34
+ end
@@ -0,0 +1,3 @@
1
+ module Omnipay
2
+ VERSION = "0.0.1"
3
+ end
metadata ADDED
@@ -0,0 +1,83 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: omnipay
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - ClicRDV
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2014-01-10 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: rack
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - '>='
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - '>='
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: httparty
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - <
32
+ - !ruby/object:Gem::Version
33
+ version: '1.0'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - <
39
+ - !ruby/object:Gem::Version
40
+ version: '1.0'
41
+ description: Payment gateway abstraction for rack applications. Think omniauth for
42
+ off-site payment.
43
+ email:
44
+ - contact@clicrdv.com
45
+ executables: []
46
+ extensions: []
47
+ extra_rdoc_files: []
48
+ files:
49
+ - lib/omnipay.rb
50
+ - lib/omnipay/adapter.rb
51
+ - lib/omnipay/adapters/mangopay.rb
52
+ - lib/omnipay/adapters/mangopay/client.rb
53
+ - lib/omnipay/adapters/oneclicpay.rb
54
+ - lib/omnipay/autosubmit_form.rb
55
+ - lib/omnipay/callback_phase.rb
56
+ - lib/omnipay/gateway.rb
57
+ - lib/omnipay/request_phase.rb
58
+ - lib/omnipay/signer.rb
59
+ - lib/omnipay/version.rb
60
+ homepage: https://github.com/clicrdv/omnipay
61
+ licenses: []
62
+ metadata: {}
63
+ post_install_message:
64
+ rdoc_options: []
65
+ require_paths:
66
+ - lib
67
+ required_ruby_version: !ruby/object:Gem::Requirement
68
+ requirements:
69
+ - - '>='
70
+ - !ruby/object:Gem::Version
71
+ version: '0'
72
+ required_rubygems_version: !ruby/object:Gem::Requirement
73
+ requirements:
74
+ - - '>='
75
+ - !ruby/object:Gem::Version
76
+ version: '0'
77
+ requirements: []
78
+ rubyforge_project: '[none]'
79
+ rubygems_version: 2.0.6
80
+ signing_key:
81
+ specification_version: 4
82
+ summary: Payment gateway abstraction for rack applications.
83
+ test_files: []