apruve 0.11.0 → 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.gitignore +1 -0
- data/Gemfile +2 -0
- data/Gemfile.lock +33 -1
- data/README.md +26 -29
- data/lib/apruve.rb +6 -2
- data/lib/apruve/client.rb +2 -2
- data/lib/apruve/error.rb +4 -3
- data/lib/apruve/resources.rb +7 -5
- data/lib/apruve/resources/invoice.rb +69 -0
- data/lib/apruve/resources/invoice_item.rb +7 -0
- data/lib/apruve/resources/merchant.rb +11 -0
- data/lib/apruve/resources/order.rb +81 -0
- data/lib/apruve/resources/{line_item.rb → order_item.rb} +1 -1
- data/lib/apruve/resources/subscription.rb +1 -1
- data/lib/apruve/resources/webhook_endpoint.rb +33 -0
- data/lib/apruve/version.rb +1 -1
- data/spec/apruve/apruve_spec.rb +5 -5
- data/spec/apruve/resources/{payment_item_spec.rb → invoice_item_spec.rb} +5 -4
- data/spec/apruve/resources/invoice_spec.rb +291 -0
- data/spec/apruve/resources/merchant_spec.rb +56 -0
- data/spec/apruve/resources/{line_item_spec.rb → order_item_spec.rb} +2 -2
- data/spec/apruve/resources/order_spec.rb +220 -0
- data/spec/apruve/resources/payment_request_spec.rb +19 -0
- data/spec/apruve/resources/subscription_adjustment_spec.rb +10 -10
- data/spec/apruve/resources/subscription_spec.rb +6 -6
- data/spec/apruve/resources/webhook_endpoint_spec.rb +137 -0
- data/spec/spec_helper.rb +3 -0
- metadata +21 -14
- data/lib/apruve/resources/payment.rb +0 -43
- data/lib/apruve/resources/payment_item.rb +0 -7
- data/lib/apruve/resources/payment_request.rb +0 -59
- data/spec/apruve/resources/payment_spec.rb +0 -129
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 735a689ea67cfd8585c45094ec9a2072a7ba3304
|
4
|
+
data.tar.gz: 646194c5ea1924ed63b51945cc5549611c8df5aa
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a0a108dff171f307f6e9f81040d190ed6ad96ac9d58472fc788f46903dbe1d887f7f51640c512d3929faa1a72e811cb38bb0ef9b51fef248baeb8ca9737b18a1
|
7
|
+
data.tar.gz: 6ed0eff7cd5cb2d7eca970ddcf9b7fc10e347b088165c345b32048cd84ed9f9f328a8531a6f09081d096ce3a3949b6c6c90c2506f6efdb4c97c2d6664b0d067a
|
data/.gitignore
CHANGED
data/Gemfile
CHANGED
data/Gemfile.lock
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
apruve (0.
|
4
|
+
apruve (1.0.0)
|
5
5
|
addressable (~> 2.3)
|
6
6
|
faraday (>= 0.8.6, <= 0.9.0)
|
7
7
|
faraday_middleware (~> 0.9)
|
@@ -10,10 +10,12 @@ GEM
|
|
10
10
|
remote: https://rubygems.org/
|
11
11
|
specs:
|
12
12
|
addressable (2.3.6)
|
13
|
+
ast (2.3.0)
|
13
14
|
coderay (1.1.0)
|
14
15
|
crack (0.4.2)
|
15
16
|
safe_yaml (~> 1.0.0)
|
16
17
|
diff-lcs (1.2.5)
|
18
|
+
docile (1.1.5)
|
17
19
|
faker (1.3.0)
|
18
20
|
i18n (~> 0.5)
|
19
21
|
faraday (0.9.0)
|
@@ -21,6 +23,7 @@ GEM
|
|
21
23
|
faraday_middleware (0.9.1)
|
22
24
|
faraday (>= 0.7.4, < 0.10)
|
23
25
|
ffi (1.9.3)
|
26
|
+
ffi (1.9.3-x86-mingw32)
|
24
27
|
guard (1.6.2)
|
25
28
|
listen (>= 0.6.0)
|
26
29
|
lumberjack (>= 1.0.2)
|
@@ -40,10 +43,19 @@ GEM
|
|
40
43
|
method_source (0.8.2)
|
41
44
|
multipart-post (2.0.0)
|
42
45
|
net-http-persistent (2.9.4)
|
46
|
+
parser (2.3.1.2)
|
47
|
+
ast (~> 2.2)
|
48
|
+
powerpack (0.1.1)
|
43
49
|
pry (0.10.0)
|
44
50
|
coderay (~> 1.1.0)
|
45
51
|
method_source (~> 0.8.1)
|
46
52
|
slop (~> 3.4)
|
53
|
+
pry (0.10.0-x86-mingw32)
|
54
|
+
coderay (~> 1.1.0)
|
55
|
+
method_source (~> 0.8.1)
|
56
|
+
slop (~> 3.4)
|
57
|
+
win32console (~> 1.3)
|
58
|
+
rainbow (2.1.0)
|
47
59
|
rake (10.3.2)
|
48
60
|
rb-fsevent (0.9.4)
|
49
61
|
rb-inotify (0.9.5)
|
@@ -61,18 +73,33 @@ GEM
|
|
61
73
|
rspec-core (>= 2.99.0.beta1)
|
62
74
|
rspec-expectations (>= 2.99.0.beta1)
|
63
75
|
rspec-mocks (2.99.1)
|
76
|
+
rubocop (0.40.0)
|
77
|
+
parser (>= 2.3.1.0, < 3.0)
|
78
|
+
powerpack (~> 0.1)
|
79
|
+
rainbow (>= 1.99.1, < 3.0)
|
80
|
+
ruby-progressbar (~> 1.7)
|
81
|
+
unicode-display_width (~> 1.0, >= 1.0.1)
|
82
|
+
ruby-progressbar (1.8.1)
|
64
83
|
safe_yaml (1.0.3)
|
84
|
+
simplecov (0.11.2)
|
85
|
+
docile (~> 1.1.0)
|
86
|
+
json (~> 1.8)
|
87
|
+
simplecov-html (~> 0.10.0)
|
88
|
+
simplecov-html (0.10.0)
|
65
89
|
slop (3.5.0)
|
66
90
|
terminal-table (1.4.5)
|
67
91
|
thor (0.19.1)
|
92
|
+
unicode-display_width (1.0.5)
|
68
93
|
vcr (2.9.2)
|
69
94
|
webmock (1.18.0)
|
70
95
|
addressable (>= 2.3.6)
|
71
96
|
crack (>= 0.3.2)
|
97
|
+
win32console (1.3.2-x86-mingw32)
|
72
98
|
yard (0.8.7.4)
|
73
99
|
|
74
100
|
PLATFORMS
|
75
101
|
ruby
|
102
|
+
x86-mingw32
|
76
103
|
|
77
104
|
DEPENDENCIES
|
78
105
|
addressable
|
@@ -89,6 +116,11 @@ DEPENDENCIES
|
|
89
116
|
rake
|
90
117
|
rspec
|
91
118
|
rspec-its
|
119
|
+
rubocop
|
120
|
+
simplecov
|
92
121
|
vcr
|
93
122
|
webmock
|
94
123
|
yard
|
124
|
+
|
125
|
+
BUNDLED WITH
|
126
|
+
1.12.5
|
data/README.md
CHANGED
@@ -1,8 +1,7 @@
|
|
1
1
|
# Apruve
|
2
2
|
|
3
|
-
Apruve helps B2B merchants by
|
4
|
-
|
5
|
-
integrate Apruve!
|
3
|
+
Apruve helps B2B merchants by helping manage complex business sales. The apruve gem makes it easier for merchants on
|
4
|
+
Ruby-based platforms to integrate Apruve!
|
6
5
|
|
7
6
|
## Installation
|
8
7
|
|
@@ -38,16 +37,16 @@ For [test.apruve.com](test.apruve.com)
|
|
38
37
|
For [www.apruve.com](www.apruve.com)
|
39
38
|
Apruve.configure('YOUR_APRUVE_API_KEY', 'prod')
|
40
39
|
|
41
|
-
### Create
|
40
|
+
### Create an Order
|
42
41
|
|
43
|
-
@
|
42
|
+
@order = Apruve::Order.new(
|
44
43
|
merchant_id: your_merchant_id,
|
45
44
|
currency: 'USD',
|
46
45
|
amount_cents: 6000,
|
47
46
|
shipping_cents: 500
|
48
47
|
)
|
49
48
|
|
50
|
-
@
|
49
|
+
@order.order_items << Apruve::OrderItem.new(
|
51
50
|
title: 'Letter Paper',
|
52
51
|
description: '20 lb ream (500 Sheets). Paper dimensions are 8.5 x 11.00 inches.',
|
53
52
|
sku: 'LTR-20R',
|
@@ -67,15 +66,13 @@ At the top of the file, import the apruve.js script.
|
|
67
66
|
|
68
67
|
Write a little Javascript to configure apruve.js
|
69
68
|
|
70
|
-
1. set the
|
71
|
-
|
72
|
-
3. register a callback to capture apruve.paymentRequestId
|
69
|
+
1. use setOrder to set the order JSON and secureHash string
|
70
|
+
1. register a callback to capture orderId
|
73
71
|
|
74
72
|
``` javascript
|
75
|
-
apruve.
|
76
|
-
apruve.
|
77
|
-
|
78
|
-
$('#paymentRequestId').val(apruve.paymentRequestId)
|
73
|
+
apruve.setOrder(<%= @order.to_json %>, '<%= @order.secure_hash %>');
|
74
|
+
apruve.registerApruveCallback(apruve.APRUVE_COMPLETE_EVENT, function (orderId) {
|
75
|
+
$('#orderId').val(orderId)
|
79
76
|
$('#finishOrder').submit();
|
80
77
|
});
|
81
78
|
```
|
@@ -86,22 +83,22 @@ Decide where to put the Apruve button
|
|
86
83
|
|
87
84
|
### Back on your server...
|
88
85
|
|
89
|
-
Use the
|
86
|
+
Use the orderId to issue an Invoice
|
90
87
|
|
91
|
-
|
92
|
-
|
88
|
+
apruve_invoice = Apruve::Invoice.new(order_id: params[:order_id], amount_cents: params[:charge], issue_on_create: true)
|
89
|
+
apruve_invoice.save!
|
93
90
|
|
94
|
-
Save the status and the
|
91
|
+
Save the status and the invoice ID with the payment in your database
|
95
92
|
|
96
93
|
# dependent on your system, but something like this...
|
97
|
-
|
98
|
-
|
99
|
-
|
94
|
+
my_invoice.apruve_invoice_id = apruve_invoice.id
|
95
|
+
my_invoice.apruve_invoice_status = apruve_payment.status
|
96
|
+
my_invoice.save!
|
100
97
|
|
101
|
-
(optional) If you track orders separately from payments, save the
|
98
|
+
(optional) If you track orders separately from payments, save the orderId with your order in your database
|
102
99
|
|
103
100
|
# dependent on your system, but something like this...
|
104
|
-
my_order.
|
101
|
+
my_order.apruve_order_id = params[:order_id]
|
105
102
|
my_order.save
|
106
103
|
|
107
104
|
### Create a web hook listener
|
@@ -109,13 +106,13 @@ Save the status and the payment ID with the payment in your database
|
|
109
106
|
# dependent on your system, but if you use Sinatra, it might look something like this...
|
110
107
|
post '/webhook_notify' do
|
111
108
|
# We got a webhook. You should look up the order in your database and complete or cancel it as appropriate.
|
112
|
-
puts "GOT WEBHOOK DATA FOR
|
113
|
-
|
114
|
-
|
115
|
-
if
|
116
|
-
|
117
|
-
elsif
|
118
|
-
|
109
|
+
puts "GOT WEBHOOK DATA FOR INVOICE #{@webhook_data}"
|
110
|
+
my_invoice.find_by(apruve_invoice_id: @webhook_data[:invoice_id])
|
111
|
+
my_invoice.apruve_payment_status = @webhook_data[:status]
|
112
|
+
if my_invoice.apruve_invoice_status == 'closed'
|
113
|
+
my_invoice.complete_order
|
114
|
+
elsif my_invoice.apruve_invoice_status == 'canceled'
|
115
|
+
my_invoice.cancel_order
|
119
116
|
end
|
120
117
|
end
|
121
118
|
|
data/lib/apruve.rb
CHANGED
@@ -14,7 +14,7 @@ module Apruve
|
|
14
14
|
:scheme => 'http',
|
15
15
|
:host => 'localhost',
|
16
16
|
:port => 3000,
|
17
|
-
:version => '
|
17
|
+
:version => 'v4',
|
18
18
|
}
|
19
19
|
|
20
20
|
class << self
|
@@ -57,6 +57,10 @@ module Apruve
|
|
57
57
|
self.client.put *args
|
58
58
|
end
|
59
59
|
|
60
|
+
def patch(*args, &block)
|
61
|
+
self.client.patch *args
|
62
|
+
end
|
63
|
+
|
60
64
|
def unstore(*args, &block)
|
61
65
|
self.client.delete *args
|
62
66
|
end
|
@@ -88,7 +92,7 @@ module Apruve
|
|
88
92
|
|
89
93
|
def js_url
|
90
94
|
port_param = [443, 80].include?(@config[:port]) ? '' : ":#{@config[:port]}"
|
91
|
-
"#{@config[:scheme]}://#{@config[:host]}#{port_param}/js/apruve.js"
|
95
|
+
"#{@config[:scheme]}://#{@config[:host]}#{port_param}/js/v4/apruve.js"
|
92
96
|
end
|
93
97
|
end
|
94
98
|
|
data/lib/apruve/client.rb
CHANGED
@@ -11,7 +11,7 @@ module Apruve
|
|
11
11
|
:scheme => 'http',
|
12
12
|
:host => 'localhost',
|
13
13
|
:port => 3000,
|
14
|
-
:version => '
|
14
|
+
:version => 'v4',
|
15
15
|
:logging_level => 'WARN',
|
16
16
|
:connection_timeout => 60,
|
17
17
|
:read_timeout => 60,
|
@@ -88,7 +88,7 @@ module Apruve
|
|
88
88
|
private
|
89
89
|
|
90
90
|
def is_http_method? method
|
91
|
-
[:get, :post, :put, :delete].include? method
|
91
|
+
[:get, :post, :put, :delete, :patch].include? method
|
92
92
|
end
|
93
93
|
|
94
94
|
def respond_to?(method, include_private = false)
|
data/lib/apruve/error.rb
CHANGED
@@ -25,11 +25,12 @@ module Apruve
|
|
25
25
|
# set_attrs
|
26
26
|
errors = body.fetch('errors', nil)
|
27
27
|
unless errors.nil?
|
28
|
-
error = errors[0]
|
29
|
-
extra = error[:
|
28
|
+
error = errors[0]
|
29
|
+
extra = error[:source] ? " -- #{error[:source][:parameter]}" : ""
|
30
|
+
extra += error[:detail] ? " -- #{error[:detail]}" : ""
|
30
31
|
"#{self.class.name}(#{response[:status]}):: "\
|
31
32
|
"#{response[:method].to_s.upcase} #{response[:url].to_s}: "\
|
32
|
-
"#{error[:
|
33
|
+
"#{error[:title]} #{extra}"
|
33
34
|
end
|
34
35
|
end
|
35
36
|
end
|
data/lib/apruve/resources.rb
CHANGED
@@ -2,9 +2,11 @@
|
|
2
2
|
|
3
3
|
require_relative 'resources/validation_error'
|
4
4
|
require_relative 'resources/apruve_object'
|
5
|
-
require_relative 'resources/
|
6
|
-
require_relative 'resources/
|
7
|
-
require_relative 'resources/
|
8
|
-
require_relative 'resources/
|
5
|
+
require_relative 'resources/order'
|
6
|
+
require_relative 'resources/order_item'
|
7
|
+
require_relative 'resources/invoice'
|
8
|
+
require_relative 'resources/invoice_item'
|
9
|
+
require_relative 'resources/merchant'
|
9
10
|
require_relative 'resources/subscription'
|
10
|
-
require_relative 'resources/subscription_adjustment'
|
11
|
+
require_relative 'resources/subscription_adjustment'
|
12
|
+
require_relative 'resources/webhook_endpoint'
|
@@ -0,0 +1,69 @@
|
|
1
|
+
module Apruve
|
2
|
+
class Invoice < Apruve::ApruveObject
|
3
|
+
attr_accessor :id, :order_id, :status, :amount_cents, :currency, :merchant_notes, :merchant_invoice_id, :shipping_cents,
|
4
|
+
:tax_cents, :invoice_items, :payments, :created_at, :opened_at, :due_at, :final_state_at, :issue_on_create, :links
|
5
|
+
|
6
|
+
def self.find(id)
|
7
|
+
response = Apruve.get("invoices/#{id}")
|
8
|
+
Invoice.new(response.body)
|
9
|
+
end
|
10
|
+
|
11
|
+
def initialize(params)
|
12
|
+
super
|
13
|
+
# hydrate payment items if appropriate
|
14
|
+
if @invoice_items.nil?
|
15
|
+
@invoice_items = []
|
16
|
+
elsif @invoice_items.is_a?(Array) && @invoice_items.first.is_a?(Hash)
|
17
|
+
hydrated_items = []
|
18
|
+
@invoice_items.each do |item|
|
19
|
+
hydrated_items << Apruve::OrderItem.new(item)
|
20
|
+
end
|
21
|
+
@invoice_items = hydrated_items
|
22
|
+
end
|
23
|
+
@currency = Apruve.default_currency if currency.nil?
|
24
|
+
end
|
25
|
+
|
26
|
+
def validate
|
27
|
+
errors = []
|
28
|
+
errors << 'order_id must be set' if order_id.nil?
|
29
|
+
errors << 'amount_cents must be set' if amount_cents.nil?
|
30
|
+
raise Apruve::ValidationError.new(errors) if errors.length > 0
|
31
|
+
end
|
32
|
+
|
33
|
+
def save!
|
34
|
+
validate
|
35
|
+
response = Apruve.post('invoices', self.to_json)
|
36
|
+
self.id = response.body['id']
|
37
|
+
self.status = response.body['status']
|
38
|
+
self.status
|
39
|
+
end
|
40
|
+
|
41
|
+
def update!
|
42
|
+
validate
|
43
|
+
response = Apruve.patch("invoices/#{id}", self.to_json)
|
44
|
+
self.status = response.body['status']
|
45
|
+
self.status
|
46
|
+
end
|
47
|
+
|
48
|
+
def issue!
|
49
|
+
validate
|
50
|
+
response = Apruve.post("invoices/#{id}/issue")
|
51
|
+
self.status = response.body['status']
|
52
|
+
self.status
|
53
|
+
end
|
54
|
+
|
55
|
+
def close!
|
56
|
+
validate
|
57
|
+
response = Apruve.post("invoices/#{id}/close")
|
58
|
+
self.status = response.body['status']
|
59
|
+
self.status
|
60
|
+
end
|
61
|
+
|
62
|
+
def cancel!
|
63
|
+
validate
|
64
|
+
response = Apruve.post("invoices/#{id}/cancel")
|
65
|
+
self.status = response.body['status']
|
66
|
+
self.status
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
@@ -0,0 +1,81 @@
|
|
1
|
+
module Apruve
|
2
|
+
class Order < Apruve::ApruveObject
|
3
|
+
attr_accessor :id, :merchant_id, :customer_id, :merchant_order_id, :status, :amount_cents, :currency, :tax_cents,
|
4
|
+
:shipping_cents, :expire_at, :order_items, :accepts_payments_via, :accepts_payment_terms, :payment_terms,
|
5
|
+
:created_at, :updated_at, :final_state_at, :default_payment_method, :links, :finalize_on_create, :invoice_on_create
|
6
|
+
|
7
|
+
def self.find(id)
|
8
|
+
response = Apruve.get("orders/#{id}")
|
9
|
+
logger.debug response.body
|
10
|
+
Order.new(response.body)
|
11
|
+
end
|
12
|
+
|
13
|
+
def self.finalize!(id)
|
14
|
+
response = Apruve.post("orders/#{id}/finalize")
|
15
|
+
logger.debug response.body
|
16
|
+
Order.new(response.body)
|
17
|
+
end
|
18
|
+
|
19
|
+
def self.invoices_for(order_id)
|
20
|
+
response = Apruve.get("orders/#{order_id}/invoices")
|
21
|
+
ret = []
|
22
|
+
response.body.each do |i|
|
23
|
+
ret << Invoice.new(i)
|
24
|
+
end
|
25
|
+
ret
|
26
|
+
end
|
27
|
+
|
28
|
+
def self.cancel!(id)
|
29
|
+
response = Apruve.post("orders/#{id}/cancel")
|
30
|
+
logger.debug response.body
|
31
|
+
Order.new(response.body)
|
32
|
+
end
|
33
|
+
|
34
|
+
def update!
|
35
|
+
response = Apruve.patch("orders/#{id}", {order: self}.to_json )
|
36
|
+
logger.debug response.body
|
37
|
+
initialize response.body
|
38
|
+
end
|
39
|
+
|
40
|
+
def initialize(params)
|
41
|
+
super
|
42
|
+
# hydrate line items if appropriate
|
43
|
+
if @order_items.nil?
|
44
|
+
@order_items = []
|
45
|
+
elsif @order_items.is_a?(Array) && @order_items.first.is_a?(Hash)
|
46
|
+
hydrated_items = []
|
47
|
+
@order_items.each do |item|
|
48
|
+
hydrated_items << Apruve::OrderItem.new(item)
|
49
|
+
end
|
50
|
+
@order_items = hydrated_items
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
def validate
|
55
|
+
errors = []
|
56
|
+
errors << 'merchant_id must be set' if merchant_id.nil?
|
57
|
+
raise Apruve::ValidationError.new(errors) if errors.length > 0
|
58
|
+
end
|
59
|
+
|
60
|
+
def value_string
|
61
|
+
# add each field in the PR
|
62
|
+
str = "#{merchant_id}#{merchant_order_id}#{amount_cents}#{currency}#{tax_cents}#{shipping_cents}#{expire_at}#{accepts_payment_terms}#{finalize_on_create}#{invoice_on_create}"
|
63
|
+
|
64
|
+
# add the line items
|
65
|
+
self.order_items.each do |item|
|
66
|
+
str += "#{item.title}#{item.plan_code}#{item.amount_cents}#{item.price_ea_cents}"\
|
67
|
+
"#{item.quantity}#{item.merchant_notes}#{item.description}#{item.variant_info}#{item.sku}"\
|
68
|
+
"#{item.vendor}#{item.view_product_url}"
|
69
|
+
end
|
70
|
+
|
71
|
+
str
|
72
|
+
end
|
73
|
+
|
74
|
+
def secure_hash
|
75
|
+
if Apruve.client.api_key.nil?
|
76
|
+
raise 'api_key has not been set. Set it with Apruve.configure(api_key, environment, options)'
|
77
|
+
end
|
78
|
+
Digest::SHA256.hexdigest(Apruve.client.api_key+value_string)
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|