bluepay-rb 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: e599250e3dd8cfc8e2d6f4085eebc8ed1816012e9a44796166ec7bbc0ecfc54b
4
+ data.tar.gz: 66073df0519b149be5b964e98851ae911fcfe265206e6e44fa9b18668e9434d9
5
+ SHA512:
6
+ metadata.gz: 0b7c7734a534546e6440d6fe3202a33bb71ca97fe6c45ba1efca2246fdccad327392c0b56e12521f232509e2c8b2714bcfa16eea48aaec2a5ab4a712e9a72811
7
+ data.tar.gz: 9cda89b64bc786b6f2bb7fda7a6d012e1164ab5f754da52cc3966d0e70708b09ae78ee983a205046b20f77f4019ca580fcf76c4845410f140378ad28f21f7351
@@ -0,0 +1,9 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /_yardoc/
4
+ /coverage/
5
+ /doc/
6
+ /pkg/
7
+ /spec/reports/
8
+ /tmp/
9
+ /.env
@@ -0,0 +1,6 @@
1
+ ---
2
+ language: ruby
3
+ cache: bundler
4
+ rvm:
5
+ - 2.6.5
6
+ before_install: gem install bundler -v 2.1.4
@@ -0,0 +1,6 @@
1
+ # Changelog
2
+
3
+ ## 0.1.0 - 2020-04-23
4
+
5
+ - Initial release with Auth, Sale, Card, BankAccount.
6
+ - Update rake.
data/Gemfile ADDED
@@ -0,0 +1,7 @@
1
+ source "https://rubygems.org"
2
+
3
+ # Specify your gem's dependencies in bluepay-rb.gemspec
4
+ gemspec
5
+
6
+ gem "rake", "~> 12.0"
7
+ gem "minitest", "~> 5.0"
@@ -0,0 +1,33 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ bluepay-rb (0.1.0)
5
+
6
+ GEM
7
+ remote: https://rubygems.org/
8
+ specs:
9
+ binding_of_caller (0.8.0)
10
+ debug_inspector (>= 0.0.1)
11
+ coderay (1.1.2)
12
+ debug_inspector (0.0.3)
13
+ dotenv (2.7.5)
14
+ method_source (1.0.0)
15
+ minitest (5.14.0)
16
+ pry (0.13.1)
17
+ coderay (~> 1.1)
18
+ method_source (~> 1.0)
19
+ rake (12.3.3)
20
+
21
+ PLATFORMS
22
+ ruby
23
+
24
+ DEPENDENCIES
25
+ binding_of_caller (~> 0.8.0)
26
+ bluepay-rb!
27
+ dotenv (~> 2.7.5)
28
+ minitest (~> 5.0)
29
+ pry (~> 0.13.1)
30
+ rake (~> 12.0)
31
+
32
+ BUNDLED WITH
33
+ 2.1.4
@@ -0,0 +1,7 @@
1
+ Copyright 2020 Near Apogee Consulting
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
4
+
5
+ The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
6
+
7
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,197 @@
1
+ # Bluepay::Rb
2
+
3
+ Simple Bluepay API Wrapper.
4
+
5
+ ## Installation
6
+
7
+ Add this line to your application's Gemfile:
8
+
9
+ ```ruby
10
+ gem 'bluepay-rb'
11
+ ```
12
+
13
+ And then execute:
14
+
15
+ $ bundle install
16
+
17
+ Or install it yourself as:
18
+
19
+ $ gem install bluepay-rb
20
+
21
+ ## Usage
22
+
23
+ ```ruby
24
+ Bluepay.account_id = "blah"
25
+ Bluepay.secret_key = "supersecret"
26
+ Bluepay.mode = :live
27
+
28
+ auth = Bluepay::Auth.new(
29
+ amount: '0.00',
30
+ source: Bluepay::Card.new(
31
+ cc_num: '4111111111111111',
32
+ cc_expires: '1227',
33
+ cvcvv2: "723",
34
+ name1: 'Bobby',
35
+ name2: 'Tester',
36
+ addr1: '123 Test St.',
37
+ addr2: 'Apt #500',
38
+ city: 'Testville',
39
+ state: 'IL',
40
+ zipcode: '94321',
41
+ country: 'USA',
42
+ phone: '123-123-1234',
43
+ email: 'test@bluepay.com',
44
+ company_name: ''
45
+ )
46
+ ).create!
47
+
48
+ auth.trans_id
49
+ #=> "10080152343"
50
+
51
+ report = Bluepay::Report.generate!(
52
+ query_by_settlement: true,
53
+ report_start_date: '2020-04-01',
54
+ report_end_date: '2020-04-30'
55
+ )
56
+ report.rows.first.id
57
+ #=> "10080152343"
58
+
59
+ report.rows.first
60
+ # => #<OpenStruct id="100867577224", payment_type="CREDIT", trans_type="AUTH", amount="0.00", card_type="VISA", payment_account="xxxxxxxxxxxx1111", order_id="100867577224", invoice_id="100867577224", custom_id="", custom_id2="", master_id="", status="1", f_void="", message="INFORMATION STORED", origin="bp10emu", issue_date="2020-04-06 11:17:25", settle_date="", rebilling_id="", settlement_id="", card_expire="1225", bank_name="", addr1="123 Test St.", addr2="Apt #500", city="Testville", state="IL", zip="54321", phone="123-123-1234", email="test@bluepay.com", auth_code="", name1="Bob", name2="Tester", company_name="", memo="", backend_id="", doc_type="", f_captured="", avs_result="_", cvv_result="_", card_present="0", merchdata="", level_3_data="", remote_ip="75.139.119.161", connected_ip="75.139.119.161", level_2_data="">
61
+
62
+ report = Bluepay::Report.generate!(
63
+ transaction_id: '100867577224',
64
+ report_start_date: '2020-04-01',
65
+ report_end_date: '2020-04-30'
66
+ )
67
+ report.rows.first.id
68
+ #=> "10080152343"
69
+
70
+ report.rows.first
71
+ # => #<OpenStruct id="100867577224", payment_type="CREDIT", trans_type="AUTH", amount="0.00", card_type="VISA", payment_account="xxxxxxxxxxxx1111", order_id="100867577224", invoice_id="100867577224", custom_id="", custom_id2="", master_id="", status="1", f_void="", message="INFORMATION STORED", origin="bp10emu", issue_date="2020-04-06 11:17:25", settle_date="", rebilling_id="", settlement_id="", card_expire="1225", bank_name="", addr1="123 Test St.", addr2="Apt #500", city="Testville", state="IL", zip="54321", phone="123-123-1234", email="test@bluepay.com", auth_code="", name1="Bob", name2="Tester", company_name="", memo="", backend_id="", doc_type="", f_captured="", avs_result="_", cvv_result="_", card_present="0", merchdata="", level_3_data="", remote_ip="75.139.119.161", connected_ip="75.139.119.161", level_2_data="">
72
+
73
+ report = Bluepay::Report.generate!(
74
+ transaction_id: '10008..',
75
+ starts_on: Date.new
76
+ ends_on: Date.new
77
+ )
78
+
79
+ report['100867577224']
80
+ # => #<OpenStruct id="100867577224", payment_type="CREDIT", trans_type="AUTH", amount="0.00", card_type="VISA", payment_account="xxxxxxxxxxxx1111", order_id="100867577224", invoice_id="100867577224", custom_id="", custom_id2="", master_id="", status="1", f_void="", message="INFORMATION STORED", origin="bp10emu", issue_date="2020-04-06 11:17:25", settle_date="", rebilling_id="", settlement_id="", card_expire="1225", bank_name="", addr1="123 Test St.", addr2="Apt #500", city="Testville", state="IL", zip="54321", phone="123-123-1234", email="test@bluepay.com", auth_code="", name1="Bob", name2="Tester", company_name="", memo="", backend_id="", doc_type="", f_captured="", avs_result="_", cvv_result="_", card_present="0", merchdata="", level_3_data="", remote_ip="75.139.119.161", connected_ip="75.139.119.161", level_2_data="">
81
+
82
+ card = Bluepay::Card.new(
83
+ cc_num: '4111111111111111',
84
+ cc_expires: '1227',
85
+ cvcvv2: "723",
86
+ name1: 'Bobby',
87
+ name2: 'Tester',
88
+ addr1: '123 Test St.',
89
+ addr2: 'Apt #500',
90
+ city: 'Testville',
91
+ state: 'IL',
92
+ zipcode: '94321',
93
+ country: 'USA',
94
+ phone: '123-123-1234',
95
+ email: 'test@bluepay.com',
96
+ company_name: ''
97
+ ).save!
98
+ #=> <BluePay::Card>
99
+ card.trans_id
100
+ #=> card.trans_id
101
+ card.auth
102
+ #=> <Bluepay::Auth>
103
+
104
+ Bluepay::BankAccount.new(
105
+ ach_routing: '123123123',
106
+ ach_account: '123456789',
107
+ ach_account_type: 'C',
108
+ name1: 'Bobby',
109
+ name2: 'Tester',
110
+ addr1: '123 Test St.',
111
+ addr2: 'Apt #500',
112
+ city: 'Testville',
113
+ state: 'IL',
114
+ zipcode: '94321',
115
+ country: 'USA',
116
+ phone: '123-123-1234',
117
+ email: 'test@bluepay.com',
118
+ company_name: ''
119
+ ).save!
120
+ #=> <BluePay::BankAccount>
121
+ bank_account.trans_id
122
+ #=> bank_account.trans_id
123
+ bank_account.auth
124
+ #=> <Bluepay::Auth>
125
+
126
+
127
+ transaction = Bluepay::Transaction.retrieve!('10080152343')
128
+ transaction.amount
129
+ #=> "10.00"
130
+
131
+ ```
132
+
133
+ ### Parameters
134
+
135
+ When you pass parameters to this gem's methods, we convert them to the API's
136
+ style of parameters for you. This means you can pass `symbols` as keys and that
137
+ there is a 1:1 mapping to the paramters in the Bluepay provided API
138
+ documentation.
139
+
140
+ ### Parameter Conversions
141
+
142
+ Some paramerters will be converted to the expected strings before passing to
143
+ the Bluepay API.
144
+
145
+ - `:amount` can take an `Integer` of the amount in cents, a `Float` in dollars,
146
+ or a formatted string.
147
+ - dates/times can take a `Date` or `Datetime` instance or a formatted string.
148
+
149
+ ### Timezones
150
+
151
+ Bluepay uses the Central Timezone (US). Some parameters will convert time/date
152
+ like objects to strings but will use the given objects hours. As such, you must
153
+ pass in approriate date or time objects in Central Timezone or offset.
154
+
155
+ ## TODOS
156
+
157
+ - Response Parameter Conversion (i.e. "10.00" to 1000)
158
+
159
+
160
+ ## Bluepay Documentation
161
+
162
+
163
+ - https://www.bluepay.com/sites/default/files/documentation/BluePay_bp10emu/BluePay%201-0%20Emulator.txt
164
+ - https://www.bluepay.com/sites/default/files/documentation/BluePay_stq/BluePay_Single_Transaction_Query.txt
165
+ - https://www.bluepay.com/sites/default/files/documentation/BluePay_bpdailyreport2/bpdailyreport2.pdf
166
+
167
+ ## Development
168
+
169
+ After checking out the repo, run `bin/setup` to install dependencies. Then, run
170
+ `rake test` to run the tests. You can also run `bin/console` for an interactive
171
+ prompt that will allow you to experiment.
172
+
173
+ The gem doesn't come with default credentials for BluePay. You will need to
174
+ provide those
175
+
176
+ ## Testing
177
+
178
+ Add a `.env` to run tests.
179
+
180
+ ```
181
+ BLUEPAY_ACCOUNT_ID=100....
182
+ BLUEPAY_SECRET_KEY=WCP0....
183
+ ```
184
+
185
+ Run tests with:
186
+ ```
187
+ rake test
188
+ ```
189
+
190
+ ## Releases
191
+ To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
192
+
193
+
194
+ ## Contributing
195
+
196
+ Bug reports and pull requests are welcome on GitHub at https://github.com/nearapogee/bluepay-rb.
197
+
@@ -0,0 +1,10 @@
1
+ require "bundler/gem_tasks"
2
+ require "rake/testtask"
3
+
4
+ Rake::TestTask.new(:test) do |t|
5
+ t.libs << "test"
6
+ t.libs << "lib"
7
+ t.test_files = FileList["test/**/*_test.rb"]
8
+ end
9
+
10
+ task :default => :test
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "bundler/setup"
4
+ require "bluepay/rb"
5
+
6
+ # You can add fixtures and/or initialization code here to make experimenting
7
+ # with your gem easier. You can also use a different console, if you like.
8
+
9
+ # (If you use this, don't forget to add pry to your Gemfile!)
10
+ # require "pry"
11
+ # Pry.start
12
+
13
+ require "irb"
14
+ IRB.start(__FILE__)
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+ set -vx
5
+
6
+ bundle install
7
+
8
+ # Do any other automated setup that you need to do here
@@ -0,0 +1,37 @@
1
+ require_relative 'lib/bluepay/version'
2
+
3
+ Gem::Specification.new do |spec|
4
+ spec.name = "bluepay-rb"
5
+ spec.version = Bluepay::VERSION
6
+ spec.authors = ["Matt Smith"]
7
+ spec.email = ["matt@nearapogee.com"]
8
+
9
+ #spec.cert_chain = ['certs/nearapogee.pem']
10
+ #spec.signing_key = File.expand_path("~/.ssh/gem-private_key.pem") if $0 =~ /gem\z/
11
+
12
+ spec.summary = %q{Simple Bluepay API Wrapper}
13
+ spec.description = %q{Bluepay Payment Gateway API wrapper written for Ruby.}
14
+ spec.homepage = "https://github.com/nearapogee/bluepay-rb"
15
+ spec.license = "MIT"
16
+
17
+ spec.required_ruby_version = Gem::Requirement.new(">= 2.3.0")
18
+
19
+ spec.metadata["allowed_push_host"] = "https://rubygems.org"
20
+
21
+ spec.metadata["homepage_uri"] = spec.homepage
22
+ spec.metadata["source_code_uri"] = spec.homepage
23
+ spec.metadata["changelog_uri"] = "#{spec.homepage}/CHANGELOG.md"
24
+
25
+ # Specify which files should be added to the gem when it is released.
26
+ # The `git ls-files -z` loads the files in the RubyGem that have been added into git.
27
+ spec.files = Dir.chdir(File.expand_path('..', __FILE__)) do
28
+ `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
29
+ end
30
+ spec.bindir = "exe"
31
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
32
+ spec.require_paths = ["lib"]
33
+
34
+ spec.add_development_dependency 'binding_of_caller', '~> 0.8.0'
35
+ spec.add_development_dependency 'pry', '~> 0.13.1'
36
+ spec.add_development_dependency 'dotenv', '~> 2.7.5'
37
+ end
@@ -0,0 +1,26 @@
1
+ -----BEGIN CERTIFICATE-----
2
+ MIIETTCCArWgAwIBAgIBATANBgkqhkiG9w0BAQsFADAoMSYwJAYDVQQDDB1ydWJ5
3
+ Z2Vtcy9EQz1uZWFyYXBvZ2VlL0RDPWNvbTAeFw0yMDA0MjMxMzU5MjFaFw0yMTA0
4
+ MjMxMzU5MjFaMCgxJjAkBgNVBAMMHXJ1YnlnZW1zL0RDPW5lYXJhcG9nZWUvREM9
5
+ Y29tMIIBojANBgkqhkiG9w0BAQEFAAOCAY8AMIIBigKCAYEAremv/+dmoA8sQG/z
6
+ ailh1FYtjQtO9zlRaQoGepfF2vypccKCiYpD5V1Ql2fvZ/XzmZUxNJ6wN4ywnfg0
7
+ nNWTfa9yOTKEpDhcBGNawxVwUEP3xFN41bqJB8TT2+eTEVJEMtnPQv71uNiQi8iw
8
+ euHEHso5MDBLw+eBE8i4qfuGKUpuu0JUDEngk5TBILoVoOqhoZw/Cor3460ioc61
9
+ mETF8cGHzzyRWocjpGoOND5vvr+vBRKcWAu7EsX4O1/YTW/fAW40bZ1zq56NIyls
10
+ E/0kpLJeTd8XDC+tdzlOOLVHyswd4TtdA9Pm87FmTQgOo/oo0BiUHR50eHAVdc2a
11
+ WeSm14X/S4Xwfx//EvUVNkmunWKWaRIC3A/FAfdwyrf5rLVe5AuijtqP1OWEYqGr
12
+ KnP6WuR71rg386iQnj/38rWNA1kRB2fswHinIbK5wMe2nvizBndxvw7AEfBauV5a
13
+ K2JvStq9OqHn11yljQcDVJs1kCoxCqhcd7nzzFrjz/EA8YEDAgMBAAGjgYEwfzAJ
14
+ BgNVHRMEAjAAMAsGA1UdDwQEAwIEsDAdBgNVHQ4EFgQUAsVDD7LB1HIrDBznXfs1
15
+ qjgRGQUwIgYDVR0RBBswGYEXcnVieWdlbXNAbmVhcmFwb2dlZS5jb20wIgYDVR0S
16
+ BBswGYEXcnVieWdlbXNAbmVhcmFwb2dlZS5jb20wDQYJKoZIhvcNAQELBQADggGB
17
+ ACQyVArEHOckVl8+BqcE+V8gJS4RyM3BBFXYus+HWT0w+Kc38RBh0mlBPvVFwULp
18
+ fzyQHhYl4zqn0ZP9WWIh+U/xTXCAizXOQYcjzhSKUUgJGplLaMGOUhMbL0oPYeYB
19
+ IkUGZ+rDXeyDNqJCHaDkPRCqJbCqzz2g8DlnJ6Ko5PIwkOePS1BTgF3baZnFbZRQ
20
+ PU49NUBDg5KX1CEnKFigBODwTIZkcAwBJa15gheWnRK8/X0+Qlv4Xdrgl642wDb/
21
+ WlC6rqxAjBSICB1PFUkNBWLFVoFuwkcHeQK6YxoRd9NPbcR9eYVI6Aj5MQC0BZ7e
22
+ +nVOks/610Wek8zoWarzLOSTqtZMwd7WzbwM9a1H5v88VVsEir/xJ2Ieo1ZjSzGr
23
+ JC7Od13bsLCMhf9qBO8876QE1w5EHqZMTGSKX3j1ZSri/9Qx+EU3abfNZSbeUAH4
24
+ SXApunUTnbZTm8kuiCGbwkZ9A3ldwlSWeFXI76mCvQxi3NezS3RPqPhjG7VPrJCL
25
+ AA==
26
+ -----END CERTIFICATE-----
@@ -0,0 +1,33 @@
1
+ require "bluepay/version"
2
+
3
+ require "bluepay/interface"
4
+ require "bluepay/base"
5
+
6
+ require "bluepay/card"
7
+ require "bluepay/bank_account"
8
+
9
+ module Bluepay
10
+
11
+ HMAC_SHA512 = 'HMAC_SHA512'.freeze
12
+ HMAC_SHA256 = 'HMAC_SHA256'.freeze
13
+ SHA512 = 'SHA512'.freeze
14
+ SHA256 = 'SHA256'.freeze
15
+ MD5 = 'MD5'.freeze
16
+
17
+ class << self
18
+ attr_accessor :account_id, :secret_key
19
+ attr_writer :mode, :hash_type, :response_version
20
+
21
+ def mode
22
+ @mode ||= :test
23
+ end
24
+
25
+ def hash_type
26
+ @hash_type ||= HMAC_SHA512
27
+ end
28
+
29
+ def response_version
30
+ @response_version ||= '11'
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,13 @@
1
+ module Bluepay
2
+ module BP10EMU
3
+ include Interface
4
+ PATH = "/interfaces/bp10emu".freeze
5
+
6
+ def data
7
+ {
8
+ 'MERCHANT' => Bluepay.account_id
9
+ }.merge(request_params)
10
+ end
11
+
12
+ end
13
+ end
@@ -0,0 +1,6 @@
1
+ module Bluepay
2
+ module BPDAILYREPORT2
3
+ include Interface
4
+ PATH = '/interfaces/bpdailyreport2'.freeze
5
+ end
6
+ end
@@ -0,0 +1,6 @@
1
+ module Bluepay
2
+ module STQ
3
+ include Interface
4
+ PATH = '/interfaces/stq'.freeze
5
+ end
6
+ end
@@ -0,0 +1,10 @@
1
+ module Bluepay
2
+ class Auth < TransactionBase
3
+
4
+ def initialize(*args)
5
+ super(*args)
6
+ self.params[:transaction_type] = 'AUTH'
7
+ end
8
+
9
+ end
10
+ end
@@ -0,0 +1,28 @@
1
+ module Bluepay
2
+ class BankAccount
3
+ include Parameters
4
+
5
+ attr_reader :auth
6
+
7
+ def initialize(params={})
8
+ self.params = params
9
+ self.params[:payment_type] = 'ACH'
10
+ end
11
+
12
+ def save!
13
+ return self if @auth && @auth.trans_id && @auth.trans_id.length > 0
14
+
15
+ @auth = Bluepay::Auth.new(
16
+ amount: "0.00",
17
+ source: self
18
+ ).create!
19
+
20
+ _params = @auth.to_h
21
+ (class << self; self; end).class_eval do
22
+ _params.each { |k, v| define_method(k) { v } }
23
+ end
24
+ self
25
+ end
26
+
27
+ end
28
+ end
@@ -0,0 +1,26 @@
1
+ require 'bluepay/parameters'
2
+ require 'bluepay/tamper_proof_seal'
3
+ require "bluepay/request"
4
+ require "bluepay/response"
5
+
6
+ module Bluepay
7
+ class Base
8
+ include Parameters
9
+ include TamperProofSeal
10
+
11
+ attr_reader :request, :response
12
+
13
+ def initialize(params={})
14
+ self.params = params
15
+
16
+ self.params[:mode] ||= Bluepay.mode.to_s.upcase
17
+ self.params[:tps_hash_type] ||= Bluepay.hash_type
18
+ self.params[:responseversion] ||= Bluepay.response_version
19
+ end
20
+
21
+ end
22
+ end
23
+
24
+ require 'bluepay/transaction_base'
25
+ require 'bluepay/transaction'
26
+ require 'bluepay/report'
@@ -0,0 +1,28 @@
1
+ module Bluepay
2
+ class Card
3
+ include Parameters
4
+
5
+ attr_reader :auth
6
+
7
+ def initialize(params={})
8
+ self.params = params
9
+ self.params[:payment_type] = 'CREDIT'
10
+ end
11
+
12
+ def save!
13
+ return self if @auth && @auth.trans_id && @auth.trans_id.length > 0
14
+
15
+ @auth = Bluepay::Auth.new(
16
+ amount: "0.00",
17
+ source: self
18
+ ).create!
19
+
20
+ _params = @auth.to_h
21
+ (class << self; self; end).class_eval do
22
+ _params.each { |k, v| define_method(k) { v } }
23
+ end
24
+ self
25
+ end
26
+
27
+ end
28
+ end
@@ -0,0 +1,22 @@
1
+ require 'bluepay/parameters'
2
+
3
+ module Bluepay
4
+ module Interface
5
+ include Parameters
6
+
7
+ def path
8
+ self.class::PATH
9
+ end
10
+
11
+ def data
12
+ {
13
+ 'ACCOUNT_ID' => Bluepay.account_id
14
+ }.merge(request_params)
15
+ end
16
+
17
+ end
18
+ end
19
+
20
+ require 'bluepay/BP10EMU'
21
+ require 'bluepay/BPDAILYREPORT2'
22
+ require 'bluepay/STQ'
@@ -0,0 +1,63 @@
1
+ module Bluepay
2
+ module Parameters
3
+
4
+ DEFAULT_CONVERTER = ->(value) { value.to_s }
5
+ BOOLEAN_CONVERTER = ->(value) {
6
+ case value
7
+ when TrueClass then '1'
8
+ when FalseClass then '0'
9
+ else
10
+ value
11
+ end
12
+ }
13
+
14
+ def self.included(receiver)
15
+ receiver.attr_writer :params
16
+ receiver.extend ClassMethods
17
+ end
18
+
19
+ module ClassMethods
20
+ def convert(*args)
21
+ converter = args.pop
22
+ args.each {|arg| self.converters[arg] = converter }
23
+ end
24
+
25
+ def converters
26
+ @_converters ||= Hash.new
27
+ end
28
+
29
+ def converter(param)
30
+ converter = self.converters[param]
31
+ converter ||= self.superclass.converter(param) rescue nil
32
+ converter
33
+ end
34
+
35
+ def convert!(param, value)
36
+ converter = converter(param)
37
+ converter ||= DEFAULT_CONVERTER
38
+ converter.call(value)
39
+ end
40
+ end
41
+
42
+ def params
43
+ @params ||= Hash.new
44
+ end
45
+
46
+ def converted_params
47
+ params.inject(Hash.new) {|memo, kv|
48
+ k, v = kv
49
+ memo[k] = self.class.convert!(k, v)
50
+ memo
51
+ }
52
+ end
53
+
54
+ def bluepay_params
55
+ converted_params.inject(Hash.new) {|memo, kv|
56
+ k, v = kv
57
+ memo[k.to_s.upcase] = v
58
+ memo
59
+ }
60
+ end
61
+
62
+ end
63
+ end
@@ -0,0 +1 @@
1
+ require "bluepay"
@@ -0,0 +1,58 @@
1
+ require 'date'
2
+
3
+ module Bluepay
4
+ class Report < Base
5
+ include BPDAILYREPORT2
6
+
7
+ def self.generate!(params={})
8
+ new(params).generate!
9
+ end
10
+
11
+ def initialize(params={})
12
+ super(params)
13
+ end
14
+
15
+ convert :report_start_date, :report_end_date, ->(date) {
16
+ case date
17
+ when Date, DateTime then date.strftime("%F %T")
18
+ else
19
+ date
20
+ end
21
+ }
22
+
23
+ convert :query_by_settlement,
24
+ :query_by_hierarchy,
25
+ :exclude_errors,
26
+ BOOLEAN_CONVERTER
27
+
28
+ def request_params
29
+ bluepay_params.
30
+ merge(tps(
31
+ :report_start_date,
32
+ :report_end_date
33
+ ))
34
+ end
35
+
36
+ def generate!
37
+ @request = Request.new(self)
38
+ @response = request.execute!
39
+
40
+ _data = response.data
41
+ (class << self; self; end).class_eval do
42
+ _data.each { |k, v| define_method(k) { v } }
43
+ end
44
+
45
+ self
46
+ end
47
+
48
+ def [](id)
49
+ return nil unless self.respond_to?(:rows)
50
+ @_lookup ||= self.rows.inject({}) { |memo, row|
51
+ memo[row.id] = row
52
+ memo
53
+ }
54
+ @_lookup[id]
55
+ end
56
+
57
+ end
58
+ end
@@ -0,0 +1,34 @@
1
+ require 'net/http'
2
+
3
+ module Bluepay
4
+ class Request
5
+ HOST = 'secure.bluepay.com'.freeze
6
+ PORT = 443.freeze
7
+
8
+ attr_reader :action
9
+
10
+ def initialize(action)
11
+ @action = action
12
+ end
13
+
14
+ def execute!
15
+ uri = URI::HTTPS.build(
16
+ host: HOST,
17
+ path: action.path
18
+ )
19
+
20
+ req = Net::HTTP::Post.new(uri)
21
+ req.set_form_data(action.data)
22
+ req['User-Agent'] = 'BluepayRB Ruby Client'
23
+ req['Content-Type'] = 'application/x-www-form-urlencoded'
24
+
25
+ res = Net::HTTP.start(
26
+ HOST, PORT,
27
+ use_ssl: true,
28
+ ) { |http| http.request(req) }
29
+
30
+ Response.new(res)
31
+ end
32
+
33
+ end
34
+ end
@@ -0,0 +1,65 @@
1
+ module Bluepay
2
+ # bpdailyreport2 returns csv in body
3
+ # bp10emu returns 302, html body, details are in Location header
4
+ # stq returns query string in body
5
+ #
6
+ # #data returns a unified merge of all the data sources, with tabular data
7
+ # under the key :rows as an array of OpenStruct instances
8
+ class Response
9
+
10
+ LOCATION = 'Location'.freeze
11
+
12
+ attr_reader :response, :action
13
+
14
+ def initialize(http)
15
+ @response = http
16
+ end
17
+
18
+ def location_query_params
19
+ URI.decode_www_form(URI(response['Location']).query).sort.to_h rescue {}
20
+ end
21
+
22
+ def body_params
23
+ URI.decode_www_form(response.body).sort.to_h rescue {}
24
+ end
25
+
26
+ def params
27
+ location_query_params.merge(body_params).inject({}) { |memo, kv|
28
+ k, v = kv
29
+ memo[k.to_s.downcase.to_sym] = v
30
+ memo
31
+ }
32
+ end
33
+
34
+ def body_csv
35
+ require 'csv'
36
+ CSV.parse(response.body, headers: true) rescue Array.new
37
+ end
38
+
39
+ def body_rows
40
+ body_csv.each.map {|r| OpenStruct.new(r.to_h)}
41
+ end
42
+
43
+ def data
44
+ params.to_h.merge(
45
+ rows: body_rows
46
+ )
47
+ end
48
+
49
+ def to_h
50
+ data
51
+ end
52
+
53
+ def code
54
+ response.code.to_i
55
+ end
56
+
57
+ def body
58
+ response.body
59
+ end
60
+
61
+ def headers
62
+ response.to_hash
63
+ end
64
+ end
65
+ end
@@ -0,0 +1,10 @@
1
+ module Bluepay
2
+ class Sale < TransactionBase
3
+
4
+ def initialize(*args)
5
+ super(*args)
6
+ self.params[:transaction_type] = 'SALE'
7
+ end
8
+
9
+ end
10
+ end
@@ -0,0 +1,43 @@
1
+ module Bluepay
2
+ module TamperProofSeal
3
+
4
+ def tps(*keys)
5
+ type = self.params[:tps_hash_type]
6
+ _params = self.converted_params
7
+ args = keys.map {|k| _params[k] }
8
+ { 'TAMPER_PROOF_SEAL' => hash(type, *args) }
9
+ end
10
+
11
+ def hash(type, *args)
12
+ _args = args.insert(0, Bluepay.account_id).map(&:to_s).join
13
+
14
+ case type
15
+ when HMAC_SHA512, nil
16
+ OpenSSL::HMAC.hexdigest('sha512', Bluepay.secret_key, _args)
17
+ when HMAC_SHA256
18
+ OpenSSL::HMAC.hexdigest('sha256', Bluepay.secret_key, _args)
19
+ when SHA512
20
+ Digest::SHA512.hexdigest([
21
+ Bluepay.secret_key,
22
+ _args,
23
+ type
24
+ ].join)
25
+ when SHA256
26
+ then Digest::SHA256.hexdigest([
27
+ Bluepay.secret_key,
28
+ _args,
29
+ type
30
+ ].join)
31
+ when MD5
32
+ Digest::MD5.hexdigest([
33
+ Bluepay.secret_key,
34
+ _args,
35
+ type
36
+ ].join)
37
+ else
38
+ raise "Please set Bluepay.hash=."
39
+ end
40
+ end
41
+
42
+ end
43
+ end
@@ -0,0 +1,46 @@
1
+ module Bluepay
2
+ class Transaction < Base
3
+ include STQ
4
+
5
+ def self.retrieve!(id, params = {})
6
+ new(params.merge(id: id)).retrieve!
7
+ end
8
+
9
+ def self.query!(params = {})
10
+ new(params).retrieve!
11
+ end
12
+
13
+ def initialize(params={})
14
+ super(params)
15
+ end
16
+
17
+ convert :limit_one, :exclude_errors,
18
+ :f_captured, :isnull_f_captured,
19
+ BOOLEAN_CONVERTER
20
+
21
+ def request_params
22
+ bluepay_params.
23
+ merge(tps(
24
+ :report_start_date,
25
+ :report_end_date
26
+ ))
27
+ end
28
+
29
+ def retrieve!
30
+ @request = Request.new(self)
31
+ @response = request.execute!
32
+
33
+ _data = response.data
34
+ (class << self; self; end).class_eval do
35
+ _data.each { |k, v| define_method(k) { v } }
36
+ end
37
+
38
+ self
39
+ end
40
+
41
+ def to_h
42
+ response.data
43
+ end
44
+
45
+ end
46
+ end
@@ -0,0 +1,61 @@
1
+ module Bluepay
2
+ class TransactionBase < Base
3
+ include BP10EMU
4
+
5
+ attr_accessor :source
6
+
7
+ def initialize(*args)
8
+ super(*args)
9
+ self.source = params.delete(:source)
10
+ end
11
+
12
+ def self.create!(params={})
13
+ new(params).create!
14
+ end
15
+
16
+ def create!
17
+ @request = Request.new(self)
18
+ @response = request.execute!
19
+
20
+ _params = response.params
21
+ (class << self; self; end).class_eval do
22
+ _params.each { |k, v| define_method(k) { v } }
23
+ end
24
+ self
25
+ end
26
+
27
+ def to_h
28
+ response.data
29
+ end
30
+
31
+ convert :amount, ->(amount) {
32
+ case amount
33
+ when Integer then amount.to_s.rjust(3, '0').insert(-3, '.')
34
+ when Float then "%.2f" % amount
35
+ else
36
+ amount
37
+ end
38
+ }
39
+
40
+ def request_params
41
+ _params = bluepay_params
42
+ _params.merge!(source.bluepay_params) if source
43
+ _params.merge!(tps(
44
+ :transaction_type,
45
+ :amount,
46
+ :rebilling,
47
+ :reb_first_date,
48
+ :reb_expr,
49
+ :reb_cycles,
50
+ :reb_amount,
51
+ :rrno,
52
+ :mode
53
+ ))
54
+ _params
55
+ end
56
+
57
+ end
58
+ end
59
+
60
+ require 'bluepay/auth'
61
+ require 'bluepay/sale'
@@ -0,0 +1,3 @@
1
+ module Bluepay
2
+ VERSION = "0.1.0"
3
+ end
metadata ADDED
@@ -0,0 +1,120 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: bluepay-rb
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Matt Smith
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2020-04-23 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: binding_of_caller
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: 0.8.0
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: 0.8.0
27
+ - !ruby/object:Gem::Dependency
28
+ name: pry
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: 0.13.1
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: 0.13.1
41
+ - !ruby/object:Gem::Dependency
42
+ name: dotenv
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: 2.7.5
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: 2.7.5
55
+ description: Bluepay Payment Gateway API wrapper written for Ruby.
56
+ email:
57
+ - matt@nearapogee.com
58
+ executables: []
59
+ extensions: []
60
+ extra_rdoc_files: []
61
+ files:
62
+ - ".gitignore"
63
+ - ".travis.yml"
64
+ - CHANGELOG.md
65
+ - Gemfile
66
+ - Gemfile.lock
67
+ - MIT-LICENSE
68
+ - README.md
69
+ - Rakefile
70
+ - bin/console
71
+ - bin/setup
72
+ - bluepay-rb.gemspec
73
+ - certs/nearapogee.pem
74
+ - lib/bluepay.rb
75
+ - lib/bluepay/BP10EMU.rb
76
+ - lib/bluepay/BPDAILYREPORT2.rb
77
+ - lib/bluepay/STQ.rb
78
+ - lib/bluepay/auth.rb
79
+ - lib/bluepay/bank_account.rb
80
+ - lib/bluepay/base.rb
81
+ - lib/bluepay/card.rb
82
+ - lib/bluepay/interface.rb
83
+ - lib/bluepay/parameters.rb
84
+ - lib/bluepay/rb.rb
85
+ - lib/bluepay/report.rb
86
+ - lib/bluepay/request.rb
87
+ - lib/bluepay/response.rb
88
+ - lib/bluepay/sale.rb
89
+ - lib/bluepay/tamper_proof_seal.rb
90
+ - lib/bluepay/transaction.rb
91
+ - lib/bluepay/transaction_base.rb
92
+ - lib/bluepay/version.rb
93
+ homepage: https://github.com/nearapogee/bluepay-rb
94
+ licenses:
95
+ - MIT
96
+ metadata:
97
+ allowed_push_host: https://rubygems.org
98
+ homepage_uri: https://github.com/nearapogee/bluepay-rb
99
+ source_code_uri: https://github.com/nearapogee/bluepay-rb
100
+ changelog_uri: https://github.com/nearapogee/bluepay-rb/CHANGELOG.md
101
+ post_install_message:
102
+ rdoc_options: []
103
+ require_paths:
104
+ - lib
105
+ required_ruby_version: !ruby/object:Gem::Requirement
106
+ requirements:
107
+ - - ">="
108
+ - !ruby/object:Gem::Version
109
+ version: 2.3.0
110
+ required_rubygems_version: !ruby/object:Gem::Requirement
111
+ requirements:
112
+ - - ">="
113
+ - !ruby/object:Gem::Version
114
+ version: '0'
115
+ requirements: []
116
+ rubygems_version: 3.0.3
117
+ signing_key:
118
+ specification_version: 4
119
+ summary: Simple Bluepay API Wrapper
120
+ test_files: []