so_paid 0.0.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 ADDED
@@ -0,0 +1,15 @@
1
+ ---
2
+ !binary "U0hBMQ==":
3
+ metadata.gz: !binary |-
4
+ ZDhlYThjZWZjMGY5ODM0ZmI0NDNkNTBhMjhmMTY3OTE1NzUzNmM4Mw==
5
+ data.tar.gz: !binary |-
6
+ NTEzNzU1MDhhMTZiMzFjMGUyYTBmZTZkMmQ3NTRkZDFjYTc3ZDQ4YQ==
7
+ SHA512:
8
+ metadata.gz: !binary |-
9
+ ZGE0MWQ2MWYxYWVhODUyMTNkOWViOTU2NWFmZDBmYzY2NjAwMzRlNWZmODdi
10
+ YjM1NjA4YzYyNDFhZDI1MGM5YTYwMjhmZWQ4ZDRiMDMyZWU2YWFkZjdiYjMz
11
+ YWIzZjM4M2I5Mjc4NDBkYmU2NWRhNDY4Yzc2ODA4NzRmYzZkMGY=
12
+ data.tar.gz: !binary |-
13
+ MjJjOWVkOWM4NzgyZTRkMTE1NmY5OGZmNzczOTMxMDI0MWFmOWE5OWRkOTQw
14
+ NDAwMjdlNDI5ZmMwMDk0MDM4NTBmZmJhZmNjNjJmOTExMzlkOGIzM2Y4ZGM0
15
+ Y2ExZjdiNzZiZWM5Yjk4YTg1NDdhYmE4MTAwNjI3NzlmZTk5MjI=
data/.gitignore ADDED
@@ -0,0 +1,17 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in so_paid.gemspec
4
+ gemspec
data/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2014 Mike
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2014 mkralla11
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,47 @@
1
+ # SoPaid
2
+
3
+ A no-nonsense, fully configurable Rails credit card/payment vendor gem.
4
+
5
+ ## Installation
6
+
7
+ Add this line to your application's Gemfile:
8
+
9
+ gem 'so_paid'
10
+
11
+ And then execute:
12
+
13
+ $ bundle
14
+
15
+ Or install it yourself as:
16
+
17
+ $ gem install so_paid
18
+
19
+ ## Usage
20
+
21
+ See examples folder for instructions and copy/pastable files. More will be added here when time is available (...rare).
22
+
23
+ ## Currently supported payment vendors:
24
+
25
+ 1. cybersource
26
+ * request field info and doc:
27
+ * http://apps.cybersource.com/library/documentation/dev_guides/Secure_Acceptance_WM/Secure_Acceptance_WM.pdf
28
+ 2. no more yet...
29
+
30
+
31
+ ## Call To Lead<sup>TM</sup>
32
+
33
+ Want to make this gem more awesome? Even though everything works, maybe you have some good ideas that you want incorporated, whether it be performance-wise, or extension-wise. Hense, the following list is for you to easily view and will be ammended for large ideas.
34
+
35
+ ### The List<sup>TM</sup>:
36
+ 1. Support for paypal.
37
+ 2. Support for stripe (wrapping the gem that already exists).
38
+
39
+
40
+ ## Contributing
41
+
42
+ 1. Fork it
43
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
44
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
45
+ 4. Push to the branch (`git push origin my-new-feature`)
46
+ 5. Create new Pull Request
47
+
data/Rakefile ADDED
@@ -0,0 +1 @@
1
+ require "bundler/gem_tasks"
Binary file
@@ -0,0 +1,65 @@
1
+ class PaymentsController < ApplicationController
2
+
3
+ # Vendor will post to this post url (which can no longer be passed in at run time)
4
+ # set up this route in your cybersource/paypal/vendor's 'profile' panel on
5
+ # their website. http://yourdomain.com/payments/
6
+ def create
7
+ # process the response how you see fit,
8
+ # verify the transaction signature in the OrderProcessor class
9
+ # you have defined to process the returning post request from vendor,
10
+ # use public methods available to you using SoPaid.vendor,
11
+ # ex: SoPaid.vendor(:cybersource).verify_transaction_signature(params)
12
+ @order_processor = OrderProcessor.new(params)
13
+ @order_processor.process_transaction
14
+ render :nothing=>true, :status=>:ok
15
+ end
16
+
17
+ def confirm
18
+ get_cart_order
19
+ # Need to check if payment post is going to fail
20
+ # because the order can't save or is invalid! So, try to SAVE IT
21
+ # or else it will fail on return from Cybersource POST #notgood
22
+ # and the user won't know what happened
23
+ if @order.save
24
+ # specific payment vendor, ex: cybersource...
25
+ #...or not if you only have one defined in config
26
+ #ex: @payment_vendor = SoPaid.vendor(:cybersource).new(@order, {override_defaults_hash}, {override_config_defaults_hash})
27
+ @payment_vendor = SoPaid.vendor.new(@order)
28
+ else
29
+ flash[:error] = "Please fix all errors with your account and your order. If you are having trouble making a purchase, contact the administrator."
30
+ redirect_back_or_default root_path
31
+ end
32
+ end
33
+
34
+ # should show the list of payments/invoices
35
+ def index
36
+ # #payments are paid orders
37
+ @payments = @user.payments
38
+ render :layout=>"accounts"
39
+ end
40
+
41
+
42
+ # This is the return_url (which can no longer be passed in at run time)
43
+ # set up this route in your cybersource/paypal/vendor's 'profile' panel on
44
+ # their website. http://yourdomain.com/redirect_from_hop
45
+ def redirect_from_hop
46
+ if session[:pay_post_made]
47
+ if current_user and current_user.orders.order('created_at DESC').first
48
+ order = current_user.orders.order('created_at DESC').first
49
+ if order.paid?
50
+ flash[:success] = "You successfully purchased, " # + fill in what user purchased
51
+ else
52
+ flash[:fail] = "Uh oh, your purchase was not completed. Your credit card was not charged. Your cart will retain the items you original wanted to purchase.<br><br><b>Please verify that you entered your credit card information correctly and try again.</b> If the Problem persists please contact the administrator.".html_safe
53
+ end
54
+ end
55
+ session[:pay_post_made] = nil
56
+ end
57
+ #redirect to index of all payments
58
+ redirect_to payments_path
59
+ end
60
+
61
+ private
62
+ def get_cart_order
63
+ @order = current_user.cart
64
+ end
65
+ end
@@ -0,0 +1,6 @@
1
+ <form action="<%=@payment_vendor.hop_url(current_user)%>" method="post" >
2
+ <% @payment_vendor.generate_params.each_pair do |key, value| %>
3
+ <input type="hidden" name="<%=key%>" value="<%=value%>" >
4
+ <%end%>
5
+ <%= submit_tag "Complete Credit Card Payment", :class=>"btn btn-success btn-large" %>
6
+ </form>
@@ -0,0 +1,70 @@
1
+ SoPaid.configure do |config|
2
+ config.add_payment_vendor 'cybersource', # Name of your payment vendor
3
+ :vendor_options=>{
4
+ # The only options that need to be placed
5
+ # in this file are:
6
+
7
+ # secret_key, access_key, profile_id
8
+
9
+ # All others will be passed/filled
10
+ # by the default-defaults or by the Order object
11
+ # you pass in at instantiation time.
12
+
13
+ # NOTE: 'live' and 'test' hashes ALWAYS
14
+ # trump any 'defaults' which are outside
15
+ # of both of those hashes
16
+ # you do not need to include live or test
17
+ # hash if you don't want, and just use the default
18
+ # outer hash
19
+
20
+ :live=>{
21
+ :secret_key=>"your_key",
22
+ :access_key=>"your_key"
23
+ #...any other live options
24
+ },
25
+ :test=>{
26
+ :secret_key=>"your_key",
27
+ :access_key=>"your_key"
28
+ #...any other test options
29
+ },
30
+ #...any other DEFAULT options
31
+ :secret_key=>"",
32
+ :profile_id=>"",
33
+ :access_key=>"",
34
+ :transaction_uuid=>"",
35
+ :locale=>"en-US",
36
+ :transaction_type=>"sale",
37
+ :reference_number=>"",
38
+ :amount=>"",
39
+ :currency=>"USD",
40
+ :signed_date_time=>"",
41
+ :unsigned_field_names=>[],
42
+ # IMPORTANT: if you want to add
43
+ # any :unsigned_field_names, make sure
44
+ # you add them to both within the
45
+ # :unsigned_field_names array AND
46
+ # as a key value pair within this hash,
47
+ # used signed_field_names as an example
48
+
49
+ :signed_field_names =>
50
+ [
51
+ :profile_id,
52
+ :access_key,
53
+ :transaction_uuid,
54
+ :locale,
55
+ :transaction_type,
56
+ :reference_number,
57
+ :amount,
58
+ :currency,
59
+ :signed_date_time,
60
+ :unsigned_field_names,
61
+ :signed_field_names
62
+ ],
63
+
64
+ # config options
65
+ # if mode
66
+ :config_options=>{
67
+ :test_user_email=>"payment_tester@gmail.com",
68
+ :test_mode=>false
69
+ }
70
+ end
@@ -0,0 +1,11 @@
1
+ MyApp::Application.routes.draw do
2
+
3
+ get "/redirect_from_hop" => :redirect_from_hop, :controller=>:payments
4
+
5
+ resources :payments do
6
+ member do
7
+ get :confirm
8
+ end
9
+ end
10
+
11
+ end
data/lib/.DS_Store ADDED
Binary file
@@ -0,0 +1,23 @@
1
+ module SoPaid
2
+ module Configuration
3
+
4
+ mattr_accessor :vendors
5
+ self.vendors = {}
6
+
7
+ def configure
8
+ yield self
9
+ end
10
+
11
+ def add_payment_vendor(name="cybersource", options={})
12
+ new_vendor = ("SoPaid::" + name.classify).safe_constantize
13
+ raise "Payment Vendor '#{name}' gem/plugin not supported." if new_vendor.blank?
14
+ vo = options.delete(:vendor_options) || {}
15
+ co = options.delete(:config_options) || {}
16
+ vo ||= options
17
+
18
+ self.vendors[name] = new_vendor.payment_options(vo, co)
19
+ end
20
+
21
+
22
+ end
23
+ end
@@ -0,0 +1,143 @@
1
+ #require 'HOP'
2
+
3
+ module SoPaid
4
+ class Cybersource < SoPaid::Hop
5
+
6
+
7
+ @@pv_defaults = {
8
+ :live=>{
9
+ },
10
+ :test=>{
11
+ },
12
+ :secret_key=>"",
13
+ :profile_id=>"",
14
+ :access_key=>"",
15
+ :transaction_uuid=>"",
16
+ :locale=>"en-US",
17
+ :transaction_type=>"sale",
18
+ :reference_number=>"",
19
+ :amount=>"",
20
+ :currency=>"USD",
21
+ :signed_date_time=>"",
22
+ :unsigned_field_names=>[],
23
+
24
+ :signed_field_names =>
25
+ [
26
+ :profile_id,
27
+ :access_key,
28
+ :transaction_uuid,
29
+ :locale,
30
+ :transaction_type,
31
+ :reference_number,
32
+ :amount,
33
+ :currency,
34
+ :signed_date_time,
35
+ :unsigned_field_names,
36
+ :signed_field_names
37
+ ]
38
+ }
39
+
40
+ @@config_defaults = {
41
+ # optional for gem
42
+ :test_mode=>false,
43
+ :test_user_email=>"payment_tester@gmail.com"
44
+ }
45
+
46
+
47
+
48
+
49
+ # refer to http://apps.cybersource.com/library/documentation/dev_guides/Secure_Acceptance_WM/html/wwhelp/wwhimpl/js/html/wwhelp.htm#href=SC_api.12.1.html#1113432
50
+ # for more info on required keys
51
+ # needed signed fields:
52
+ # "access_key,profile_id,transaction_uuid,signed_field_names,unsigned_field_names,signed_date_time,locale,transaction_type,reference_number,amount,currency"
53
+ def generate_params
54
+ return @pv_order_params if @pv_order_params.present?
55
+
56
+ set_pv_fields
57
+ set_order_specific_params
58
+ set_signature
59
+
60
+ return @pv_order_params
61
+ end
62
+
63
+
64
+ def hop_url(user_email)
65
+ # test mode true or specific test email gets access to test page
66
+ if test? or @config_options[:test_user_email] == @current_user_email
67
+ test_hop_url
68
+ else
69
+ live_hop_url
70
+ end
71
+ end
72
+
73
+
74
+ private
75
+
76
+
77
+
78
+
79
+
80
+ def set_pv_fields
81
+ if live?
82
+ @pv_order_params = @pv_options[:live].presence || @pv_options
83
+ else
84
+ @pv_order_params = @pv_options[:test].presence || @pv_options
85
+ end
86
+
87
+ # we just set them above and are done with them
88
+ @pv_options.delete(:live)
89
+ @pv_options.delete(:test)
90
+ # merge pv_order_params on top of pv_options which is
91
+ # the combination of the class defaults and the configuration file defaults
92
+ @pv_order_params = merge_defaults(nil, @pv_order_params, @pv_options)
93
+ end
94
+
95
+
96
+ def set_order_specific_params
97
+ @pv_order_params[:amount] = @order.amount_cents if @pv_order_params[:amount].blank?
98
+ @pv_order_params[:reference_number] = @order.id.to_s if @pv_order_params[:reference_number].blank?
99
+ @pv_order_params[:transaction_uuid] = uniq_app_order_id if @pv_order_params[:transaction_uuid].blank?
100
+ @pv_order_params[:signed_date_time] = get_isotime if @pv_order_params[:signed_date_time].blank?
101
+ end
102
+
103
+
104
+ def set_signature
105
+ @pv_order_params[:signature] = sign_params
106
+ end
107
+
108
+
109
+ def sign_params
110
+ data = []
111
+ @pv_options[:signed_field_names].each do |key|
112
+ data << key.to_s + "=" + @pv_order_params[key].to_s
113
+ end
114
+ @pv_options[:signed_field_names] = @pv_options[:signed_field_names].join(",")
115
+ data = data.join(",")
116
+
117
+ encode_hop(data, @pv_order_params[:secret_key])
118
+ end
119
+
120
+
121
+ def uniq_app_order_id
122
+ @pv_order_params[:profile_id] + "_" + @order.id.to_s
123
+ end
124
+
125
+
126
+
127
+ def test?
128
+ @config_options[:test_mode]
129
+ end
130
+
131
+ def live?
132
+ !test?
133
+ end
134
+
135
+ def test_hop_url
136
+ "https://testsecureacceptance.cybersource.com/pay"
137
+ end
138
+
139
+ def live_hop_url
140
+ "https://secureacceptance.cybersource.com/pay"
141
+ end
142
+ end
143
+ end
@@ -0,0 +1,203 @@
1
+ # CyberSource Hosted Order Page Library
2
+ #
3
+ # Inserts fields into the checkout form for posting data to the CyberSource Hosted Order page
4
+ #
5
+
6
+ # require 'openssl'
7
+ # include OpenSSL
8
+ require 'hmac-sha2'
9
+ require 'base64'
10
+
11
+
12
+ module SoPaid
13
+ class Hop
14
+ @@pv_defaults = {
15
+
16
+ }
17
+
18
+ @@config_defaults = {
19
+ # optional for gem
20
+ :test_mode=>false,
21
+ :test_user_email=>"payment_tester@gmail.com"
22
+ }
23
+
24
+
25
+
26
+ def self.payment_options(pv_options={}, config_options={})
27
+ @@pv_defaults = self.merge_defaults([:live, :test], pv_options, @@pv_defaults)
28
+ @@config_defaults = self.merge_defaults(nil, config_options, @@config_defaults)
29
+
30
+ return self
31
+ end
32
+
33
+
34
+ def initialize(order, pv_options={}, config_options={})
35
+ @pv_order_params = {}.with_indifferent_access
36
+ @pv_options = self.merge_defaults([:live, :test], pv_options, @@pv_defaults)
37
+ @config_options = self.merge_defaults(nil, config_options, @@config_defaults)
38
+
39
+ @order = order
40
+ @current_user_email = @config_options[:current_user_email] || @config_options[:current_user].try(:email) || (@order.user.try(:email) if @order.respond_to?(:user))
41
+ end
42
+
43
+
44
+
45
+ def get_isotime
46
+ Time.now.utc.iso8601
47
+ end
48
+
49
+ def encode_hop(data, key)
50
+ mac = HMAC::SHA256.new(key)
51
+ mac.update data
52
+ Base64.encode64(mac.digest).gsub "\n", ''
53
+ end
54
+
55
+ def verify_signature(data,signature)
56
+ pub_digest = encode_hop(data, secret_key)
57
+ pub_digest.eql?(signature)
58
+ end
59
+
60
+ def verify_transaction_signature(message)
61
+ verify_signature(message[:signed_field_names], message[:signature])
62
+ end
63
+
64
+ def merge_defaults(modes=[], opts={}, default_opts={})
65
+ SoPaid::Hop.merge_defaults(modes, opts, default_opts)
66
+ end
67
+
68
+
69
+ def self.merge_defaults(modes=[], opts={}, default_opts={})
70
+ modes ||= []
71
+ new_opts = opts.clone.with_indifferent_access
72
+ new_default_opts = default_opts.clone.with_indifferent_access
73
+ modes.each do |mode|
74
+ new_default_opts[mode] ||= {}
75
+ new_opts_mode = new_opts[mode].is_a?(Hash) ? new_opts[mode] : {}
76
+ new_opts_mode.each_pair do |key, value|
77
+ if value.is_a?(Array)
78
+ new_default_opts[mode][key] = ((new_default_opts[mode][key] || []) + value).uniq
79
+ else
80
+ new_default_opts[mode][key] = value
81
+ end
82
+ end
83
+ new_opts.delete(mode)
84
+ end
85
+
86
+ # if mode was not provided via configuration file,
87
+ # this defaults to the opposite/non-provided mode,
88
+ # or uses the defaults set up in this file
89
+ new_opts.each_pair do |key, value|
90
+ if value.is_a?(Array)
91
+ new_default_opts[key] = ((new_default_opts[key] || []) + value).uniq
92
+ else
93
+ new_default_opts[key] = value
94
+ end
95
+ end
96
+
97
+ return new_default_opts
98
+ end
99
+
100
+
101
+ # def get_microtime
102
+ # t = Time.now
103
+ # sprintf("%d%03d", t.to_i, t.usec / 1000)
104
+ # end
105
+
106
+ # def encode_hop(data, key)
107
+ # Base64.encode64(OpenSSL::HMAC.digest(OpenSSL::Digest::SHA1.new, key, data)).chomp.gsub(/\n/,'')
108
+ # end
109
+
110
+
111
+ # def insert_signature3(amount="0.00",currency="usd",orderPage_transactionType='sale')
112
+ # profile_id = get_profile_id
113
+ # timestamp = get_microtime
114
+ # data = profile_id + amount + currency + timestamp + orderPage_transactionType
115
+ # pub = get_secret_key
116
+ # serial_number = get_serial_number
117
+ # pub_digest = encode_hop(data,pub)
118
+
119
+ # sig = "<input type='hidden' name='orderPage_transactionType' value='#{orderPage_transactionType}'>\n"
120
+ # sig << "<input type='hidden' name='amount' value='#{amount}'>\n"
121
+ # sig << "<input type='hidden' name='currency' value='#{currency}'>\n"
122
+ # sig << "<input type='hidden' name='orderPage_timestamp' value='#{timestamp}'>\n"
123
+ # sig << "<input type='hidden' name='merchantID' value='#{profile_id}'>\n"
124
+ # sig << "<input type='hidden' name='orderPage_signaturePublic' value='#{pub_digest}'>\n"
125
+ # sig << "<input type='hidden' name='orderPage_version' value='4'>\n"
126
+ # sig << "<input type='hidden' name='orderPage_serialNumber' value='#{serial_number}'>\n"
127
+ # sig
128
+ # end
129
+
130
+
131
+
132
+ # def insert_map_signature(assoc_array)
133
+ # assoc_array['mechantID'] = get_profile_id
134
+ # assoc_array['orderPage_timestamp'] = get_microtime
135
+ # assoc_array['orderPage_version'] = "4"
136
+ # assoc_array['orderPage_serialNumber'] = getSerialNumber
137
+
138
+ # fields = []
139
+ # values = ''
140
+ # inputs = ''
141
+ # assoc_array.each do |key,value|
142
+ # fields << key
143
+ # values << value
144
+ # inputs << '<input type="hidden" name="'+key+'" value="'+value+'">'+"\n"
145
+ # end
146
+
147
+ # pub = get_secret_key
148
+ # pub_digest = hop_hash(values,pub)
149
+ # inputs << '<input type="hidden" name="orderPage_signaturePublic" value="'+pub_digest+'">'+"\n"
150
+ # inputs << '<input type="hidden" name="orderPage_signedFields" value="'+fields+'">'+"\n"
151
+ # inputs
152
+ # end
153
+
154
+ # def insert_signature(amount="0.00",currency="usd")
155
+ # merchant_id = get_merchant_id
156
+ # timestamp = get_microtime
157
+ # data = merchant_id + amt + curr + timestamp
158
+ # serial_number = get_serial_number
159
+ # pub_digest = hop_hash(data, get_shared_secret)
160
+
161
+ # sig = "<input type='hidden' name='amount' value='#{amount}'>\n"
162
+ # sig << "<input type='hidden' name='currency' value='#{currency}'>\n"
163
+ # sig << "<input type='hidden' name='orderPage_timestamp' value='#{timestamp}'>\n"
164
+ # sig << "<input type='hidden' name='merchantID' value='#{merchant_id}'>\n"
165
+ # sig << "<input type='hidden' name='orderPage_signaturePublic' value='#{sig_hash}'>\n"
166
+ # sig << "<input type='hidden' name='orderPage_version' value='4'>\n"
167
+ # sig << "<input type='hidden' name='orderPage_serialNumber' value='#{serial_number}'>\n"
168
+ # sig
169
+ # end
170
+
171
+
172
+ # def insert_subscription_signature(subscription_amount="0.00",
173
+ # subscription_start_date="00000000",
174
+ # subscription_frequency=nil,
175
+ # subscription_number_of_payments="0",
176
+ # subscription_automatic_renew="true"
177
+ # )
178
+ # if subscription_frequency.nil? then return end
179
+
180
+ # data = subscription_amount + subscription_start_date + subscription_frequency + subscription_number_of_payments + subscription_automatic_renew
181
+ # pub = get_shared_secret
182
+ # pub_digest = hop_hash(data, pub)
183
+ # sign = '<input type="hidden" name="recurringSubscriptionInfo_amount" value="' + subscriptionAmount + '">' + "\n"
184
+ # sig << '<input type="hidden" name="recurringSubscriptionInfo_numberOfPayments" value="' + subscriptionNumberOfPayments + '">' + "\n"
185
+ # sig << '<input type="hidden" name="recurringSubscriptionInfo_frequency" value="' + subscriptionFrequency + '">' + "\n"
186
+ # sig << '<input type="hidden" name="recurringSubscriptionInfo_automaticRenew" value="' + subscriptionAutomaticRenew + '">' + "\n"
187
+ # sig << '<input type="hidden" name="recurringSubscriptionInfo_startDate" value="' + subscriptionStartDate + '">' + "\n"
188
+ # sig << '<input type="hidden" name="recurringSubscriptionInfo_signaturePublic" value="' + pub_digest + '">' + "\n"
189
+ # sig
190
+ # end
191
+
192
+ # def insert_subscription_id_signature(subscription_id)
193
+ # if subscription_id.nil? then return end
194
+
195
+ # pub_digest = hop_hash(subscription_id, get_shared_secret)
196
+ # str = '<input type="hidden" name="paySubscriptionCreateReply_subscriptionID" value="' + subscription_id + '">' + "\n"
197
+ # str << '<input type="hidden" name="paySubscriptionCreateReply_subscriptionIDPublicSignature" value="' + pub_digest + '">' + "\n"
198
+ # str
199
+ # end
200
+
201
+
202
+ end
203
+ end
@@ -0,0 +1,18 @@
1
+ module SoPaid
2
+ module PaymentVendor
3
+
4
+ def vendor(name=nil)
5
+ if name.present?
6
+ self.vendors[name.to_s]
7
+ elsif self.vendors.size == 1
8
+ # {"cybersource"=>SoPaid::Cybersource}
9
+ self.vendors.first.last
10
+ elsif self.vendors.size > 1
11
+ raise "No vendor name specified when calling SoPaid.vendor(:vendor_name). vendor_name must be specified when multiple payment vendors are loaded."
12
+ else
13
+ raise "No vendors have been loaded. Please run: rails generate payme:install. This will generate your payme.rb initilizer where you can load payment vendors."
14
+ end
15
+ end
16
+
17
+ end
18
+ end
@@ -0,0 +1,3 @@
1
+ module SoPaid
2
+ VERSION = "0.0.1"
3
+ end
data/lib/so_paid.rb ADDED
@@ -0,0 +1,13 @@
1
+ require "so_paid/version"
2
+
3
+ require 'so_paid/configuration'
4
+ require 'so_paid/payment_vendor'
5
+ require 'so_paid/hop'
6
+
7
+ require 'so_paid/cybersource'
8
+
9
+ module SoPaid
10
+ extend Configuration
11
+ extend PaymentVendor
12
+
13
+ end
data/so_paid.gemspec ADDED
@@ -0,0 +1,25 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'so_paid/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "so_paid"
8
+ spec.version = SoPaid::VERSION
9
+ spec.authors = ["mkralla11"]
10
+ spec.email = ["mike.mkrallaproductions@gmail.com"]
11
+ spec.description = %q{A no-nonsense, fully configurable Rails credit card/payment vendor gem.}
12
+ spec.summary = %q{There was a need to consolidate all credit card processing vendors for our web apps, but configuration needed to be at the forefront of the consolidated gem. So I built SoPaid which allows for easy extension, and a generous amount of options...and should work out of the box, if you're the plug-and-play type. Examine how the code is written to see how easy it is to extend and make your own payment_vendor class that inherits from Hop.}
13
+ spec.homepage = ""
14
+ spec.license = "MIT"
15
+
16
+ spec.files = `git ls-files`.split($/)
17
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
+ spec.require_paths = ["lib"]
20
+
21
+ spec.add_development_dependency "bundler", "~> 1.3"
22
+ spec.add_development_dependency "rake"
23
+ spec.add_development_dependency "ruby-hmac"
24
+ spec.add_development_dependency "rspec"
25
+ end
metadata ADDED
@@ -0,0 +1,124 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: so_paid
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - mkralla11
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2014-06-05 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ~>
18
+ - !ruby/object:Gem::Version
19
+ version: '1.3'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ~>
25
+ - !ruby/object:Gem::Version
26
+ version: '1.3'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ! '>='
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ! '>='
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: ruby-hmac
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ! '>='
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ! '>='
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: rspec
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ! '>='
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ! '>='
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ description: A no-nonsense, fully configurable Rails credit card/payment vendor gem.
70
+ email:
71
+ - mike.mkrallaproductions@gmail.com
72
+ executables: []
73
+ extensions: []
74
+ extra_rdoc_files: []
75
+ files:
76
+ - .gitignore
77
+ - Gemfile
78
+ - LICENSE
79
+ - LICENSE.txt
80
+ - README.md
81
+ - Rakefile
82
+ - examples/.DS_Store
83
+ - examples/app/controllers/payments_controller.rb
84
+ - examples/app/views/confirm.html.erb
85
+ - examples/config/initializers/pay_me.rb
86
+ - examples/config/routes.rb
87
+ - lib/.DS_Store
88
+ - lib/so_paid.rb
89
+ - lib/so_paid/configuration.rb
90
+ - lib/so_paid/cybersource.rb
91
+ - lib/so_paid/hop.rb
92
+ - lib/so_paid/payment_vendor.rb
93
+ - lib/so_paid/version.rb
94
+ - so_paid.gemspec
95
+ homepage: ''
96
+ licenses:
97
+ - MIT
98
+ metadata: {}
99
+ post_install_message:
100
+ rdoc_options: []
101
+ require_paths:
102
+ - lib
103
+ required_ruby_version: !ruby/object:Gem::Requirement
104
+ requirements:
105
+ - - ! '>='
106
+ - !ruby/object:Gem::Version
107
+ version: '0'
108
+ required_rubygems_version: !ruby/object:Gem::Requirement
109
+ requirements:
110
+ - - ! '>='
111
+ - !ruby/object:Gem::Version
112
+ version: '0'
113
+ requirements: []
114
+ rubyforge_project:
115
+ rubygems_version: 2.2.2
116
+ signing_key:
117
+ specification_version: 4
118
+ summary: There was a need to consolidate all credit card processing vendors for our
119
+ web apps, but configuration needed to be at the forefront of the consolidated gem.
120
+ So I built SoPaid which allows for easy extension, and a generous amount of options...and
121
+ should work out of the box, if you're the plug-and-play type. Examine how the code
122
+ is written to see how easy it is to extend and make your own payment_vendor class
123
+ that inherits from Hop.
124
+ test_files: []