bitkassa 0.1.2 → 0.1.3
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
- checksums.yaml.gz.sig +0 -0
- data.tar.gz.sig +0 -0
- data/lib/bitkassa/authentication.rb +18 -0
- data/lib/bitkassa/config.rb +35 -0
- data/lib/bitkassa/exception.rb +6 -0
- data/lib/bitkassa/payment_request.rb +51 -0
- data/lib/bitkassa/payment_response.rb +45 -0
- data/lib/bitkassa/payment_result.rb +79 -0
- data/lib/bitkassa/request.rb +104 -0
- data/lib/bitkassa/status_request.rb +20 -0
- metadata +10 -2
- metadata.gz.sig +0 -0
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: ced241ac3d66937fcd864c09c71975f8dde92ab4
|
4
|
+
data.tar.gz: 598d15da58553b95ae9ab6bc7260dcf1e3c09df2
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 92602bcd6623a3e57c10bd276eb5fd331c8490c2912228d6db8afbbdcfdc20bf3d0d5d914e53a8eed81d599a175e4cb6fd1866112968fbf80c854c9f7d3ea24a
|
7
|
+
data.tar.gz: ed81996b1a92893e00a3b4e92a88e9508e8abf57846e0511de88e397cec14fccdd294b884274e0273050a025a0c6bae35eb666fddcb750c02f4b1b28ea4d0ee4
|
checksums.yaml.gz.sig
CHANGED
Binary file
|
data.tar.gz.sig
CHANGED
Binary file
|
@@ -0,0 +1,18 @@
|
|
1
|
+
module Bitkassa
|
2
|
+
##
|
3
|
+
# Authenticates a message.
|
4
|
+
# Ensures that incoming requests originated at Bitkassa.
|
5
|
+
# And signs our own requests so Bitkassa knows it was us who sent the request.
|
6
|
+
class Authentication
|
7
|
+
def self.sign(payload, sent_at)
|
8
|
+
message = "#{Bitkassa.config.secret_api_key}#{payload}#{sent_at}"
|
9
|
+
digest = Digest::SHA256.hexdigest(message)
|
10
|
+
"#{digest}#{sent_at}"
|
11
|
+
end
|
12
|
+
|
13
|
+
def self.valid?(signature, payload)
|
14
|
+
sent_at = signature[64..-1]
|
15
|
+
signature == sign(payload, sent_at)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
module Bitkassa
|
2
|
+
##
|
3
|
+
# Contains the global configuration for the library.
|
4
|
+
class Config
|
5
|
+
# The Secret API key you received with your Bitkassa Account.
|
6
|
+
attr_accessor :secret_api_key
|
7
|
+
# The Merchant ID you received with your Bitkassa Account.
|
8
|
+
attr_accessor :merchant_id
|
9
|
+
# Base URI where all calls are redirected to. Defaults to
|
10
|
+
# +https://www.bitkassa.nl/api/v1+.
|
11
|
+
# Use when e.g. a proxy or self-hosted variant is used.
|
12
|
+
attr_accessor :base_uri
|
13
|
+
|
14
|
+
# Gets the current debug mode.
|
15
|
+
attr_reader :debug
|
16
|
+
|
17
|
+
# Sets defaults for the configuration.
|
18
|
+
def initialize
|
19
|
+
@base_uri = "https://www.bitkassa.nl/api/v1"
|
20
|
+
self.debug = false
|
21
|
+
end
|
22
|
+
|
23
|
+
# Enable or disable debug mode. Boolean.
|
24
|
+
def debug=(mode)
|
25
|
+
@debug = mode
|
26
|
+
|
27
|
+
if mode
|
28
|
+
HTTPI.log = true
|
29
|
+
HTTPI.log_level = :debug
|
30
|
+
else
|
31
|
+
HTTPI.log = false
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,51 @@
|
|
1
|
+
module Bitkassa
|
2
|
+
##
|
3
|
+
# Make a PaymentRequest.
|
4
|
+
#
|
5
|
+
# This will return the payment-response whith all returned information.
|
6
|
+
# A payment-request consists of a payload containing the information for the
|
7
|
+
# payment and an authentication message, being a signed version of the
|
8
|
+
# payload.
|
9
|
+
class PaymentRequest < Request
|
10
|
+
attr_accessor :currency,
|
11
|
+
:amount,
|
12
|
+
:description,
|
13
|
+
:return_url,
|
14
|
+
:update_url,
|
15
|
+
:meta_info
|
16
|
+
##
|
17
|
+
# Attributes for the payload
|
18
|
+
#
|
19
|
+
# * +attributes+ +Hash+:
|
20
|
+
# ** +currency+ +String+ required. "EUR" or "BTC"
|
21
|
+
# ** +amount+ +Integer+ required, amount to be paid in cents or satoshis
|
22
|
+
# ** +description+,
|
23
|
+
# ** +return_url+,
|
24
|
+
# ** +update_url+,
|
25
|
+
# ** +meta_info+
|
26
|
+
def attributes
|
27
|
+
{
|
28
|
+
currency: @currency,
|
29
|
+
amount: @amount,
|
30
|
+
description: @description,
|
31
|
+
return_url: @return_url,
|
32
|
+
update_url: @update_url,
|
33
|
+
meta_info: @meta_info
|
34
|
+
}
|
35
|
+
end
|
36
|
+
|
37
|
+
##
|
38
|
+
# Override can_perform the require "currency" and "amount"
|
39
|
+
def can_perform?
|
40
|
+
return false if currency.nil?
|
41
|
+
return false if amount.nil?
|
42
|
+
super
|
43
|
+
end
|
44
|
+
|
45
|
+
##
|
46
|
+
# Payload action is "start_payment"
|
47
|
+
def payload_action
|
48
|
+
"start_payment"
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
module Bitkassa
|
2
|
+
# A +PaymentResponse+ represents the immediate response after requesting a
|
3
|
+
# payment. It can will parse the JSON and contain the information nessecary
|
4
|
+
# to determine the status of the payment request.
|
5
|
+
class PaymentResponse
|
6
|
+
##
|
7
|
+
# Refer to +Initialize+ for the description of all attributes.
|
8
|
+
attr_accessor :payment_id,
|
9
|
+
:payment_url,
|
10
|
+
:address,
|
11
|
+
:amount,
|
12
|
+
:bitcoin_url,
|
13
|
+
:expire,
|
14
|
+
:error,
|
15
|
+
:success
|
16
|
+
##
|
17
|
+
# Generate a PaymentResponse from a JSON payload.
|
18
|
+
def self.from_json(json)
|
19
|
+
new(JSON.parse(json))
|
20
|
+
end
|
21
|
+
|
22
|
+
##
|
23
|
+
# Initialize a new payment response. Usually done by a +PaymentRequest+.
|
24
|
+
#
|
25
|
+
# Attributes:
|
26
|
+
# * +payment_id+, Unique ID assigned to this payment by Bitkassa
|
27
|
+
# * +payment_url+, The Bitcoin payment URL which you can show (as link
|
28
|
+
# and/or QR) for the customer to pay from his wallet (if you're hosting
|
29
|
+
# your own payment page)
|
30
|
+
# * +address+ The Bitcoin address where the customer is supposed to send
|
31
|
+
# his payment.
|
32
|
+
# * +amount+, The amount in satoshis to be paid.
|
33
|
+
# * +expire+, Unix timestamp when the payment expires (typically 15
|
34
|
+
# minutes after start)
|
35
|
+
# * +error+, Reason why the payment could not be initiated. Only set when
|
36
|
+
# payment errord.
|
37
|
+
# * +success+, Confirmation that the API call was processed successfull
|
38
|
+
def initialize(attributes)
|
39
|
+
attributes.each do |key, value|
|
40
|
+
setter_method = "#{key}=".to_sym
|
41
|
+
send(setter_method, value)
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
@@ -0,0 +1,79 @@
|
|
1
|
+
module Bitkassa
|
2
|
+
# A +PaymentResult+ represents the result which is posted to return_url.
|
3
|
+
# This callback contains the status of the payment.
|
4
|
+
class PaymentResult
|
5
|
+
# Contains the payload exactly as posted by Bitkassa
|
6
|
+
attr_accessor :raw_payload
|
7
|
+
# Contains the authentication_message as posted by Bitkass
|
8
|
+
attr_accessor :raw_authentication
|
9
|
+
|
10
|
+
##
|
11
|
+
# Initialize a +PaymentResult+ from a www-url-encoded body.
|
12
|
+
def self.from_form_urlencoded(body)
|
13
|
+
params = Hash[URI.decode_www_form(body)]
|
14
|
+
new(raw_payload: params["p"], raw_authentication: params["a"])
|
15
|
+
end
|
16
|
+
|
17
|
+
##
|
18
|
+
# Attributes:
|
19
|
+
# +raw_payload+ the original, unencoded string containing the payload.
|
20
|
+
# +raw_authentication+ the original string containing the signed message.
|
21
|
+
def initialize(attributes)
|
22
|
+
attributes.each do |key, value|
|
23
|
+
setter_method = "#{key}=".to_sym
|
24
|
+
send(setter_method, value)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
##
|
29
|
+
# Gives the extracted payment_id.
|
30
|
+
def payment_id
|
31
|
+
payload["payment_id"]
|
32
|
+
end
|
33
|
+
|
34
|
+
##
|
35
|
+
# Gives the extracted payment_status.
|
36
|
+
def payment_status
|
37
|
+
payload["payment_status"]
|
38
|
+
end
|
39
|
+
|
40
|
+
##
|
41
|
+
# Gives the extracted meta_info.
|
42
|
+
def meta_info
|
43
|
+
payload["meta_info"]
|
44
|
+
end
|
45
|
+
|
46
|
+
##
|
47
|
+
# Wether or not this payment result can be considered valid.
|
48
|
+
# Authentication is checked, payload and authentication should be available
|
49
|
+
# and the decoded JSON should be valid JSON.
|
50
|
+
# When the result is valid, it is safe to assume no-one tampered with it
|
51
|
+
# and that it was sent by Bitkassa.
|
52
|
+
def valid?
|
53
|
+
return false if raw_payload.nil? || raw_payload.empty?
|
54
|
+
return false if raw_authentication.nil? || raw_authentication.empty?
|
55
|
+
return false unless json_valid?
|
56
|
+
|
57
|
+
Authentication.valid?(raw_authentication, json_payload)
|
58
|
+
end
|
59
|
+
|
60
|
+
private
|
61
|
+
|
62
|
+
def payload
|
63
|
+
@payload ||= JSON.parse(json_payload)
|
64
|
+
end
|
65
|
+
|
66
|
+
def json_payload
|
67
|
+
Base64.decode64(raw_payload)
|
68
|
+
end
|
69
|
+
|
70
|
+
def json_valid?
|
71
|
+
begin
|
72
|
+
payload
|
73
|
+
rescue JSON::ParserError
|
74
|
+
return false
|
75
|
+
end
|
76
|
+
true
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
@@ -0,0 +1,104 @@
|
|
1
|
+
module Bitkassa
|
2
|
+
##
|
3
|
+
# Generic HTTP Request
|
4
|
+
class Request
|
5
|
+
# Override the class that is initialized to capture the +perform+ response.
|
6
|
+
# Defaults to +Bitkassa::PaymentResponse+.
|
7
|
+
attr_writer :responder
|
8
|
+
|
9
|
+
# Overrides the default +Bitkassa::Authentication+ to sign the
|
10
|
+
# authentication
|
11
|
+
attr_writer :authenticator
|
12
|
+
|
13
|
+
## Initalize a request
|
14
|
+
# * +attributes+ +Hash+
|
15
|
+
def initialize(attributes = {})
|
16
|
+
@initialized_at = Time.now.to_i
|
17
|
+
assign_attributes(attributes)
|
18
|
+
end
|
19
|
+
|
20
|
+
##
|
21
|
+
# Make the request.
|
22
|
+
#
|
23
|
+
# returns +Bitkassa::PaymentResponse+ Regardless of the response, this
|
24
|
+
# this PaymentResponse is initialized.
|
25
|
+
#
|
26
|
+
# When a payment cannot be made because of incorrect or missing data,
|
27
|
+
# a +Bitkassa::Exception+ is raised.
|
28
|
+
def perform
|
29
|
+
if can_perform?
|
30
|
+
response = HTTPI.post(uri, params_string)
|
31
|
+
responder.from_json(response.body)
|
32
|
+
else
|
33
|
+
fail Bitkassa::Exception,
|
34
|
+
"Your merchant_id or merchant_key are not set"
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
##
|
39
|
+
# Defines the attributes to be serialised in the payload
|
40
|
+
# merchant_id and action will be merged by default.
|
41
|
+
def attributes
|
42
|
+
{}
|
43
|
+
end
|
44
|
+
|
45
|
+
##
|
46
|
+
# Defines the action to insert into the payload.
|
47
|
+
def payload_action
|
48
|
+
""
|
49
|
+
end
|
50
|
+
|
51
|
+
def can_perform?
|
52
|
+
return false if Bitkassa.config.merchant_id.nil?
|
53
|
+
return false if Bitkassa.config.merchant_id.empty?
|
54
|
+
return false if Bitkassa.config.secret_api_key.nil?
|
55
|
+
return false if Bitkassa.config.secret_api_key.empty?
|
56
|
+
true
|
57
|
+
end
|
58
|
+
|
59
|
+
protected
|
60
|
+
|
61
|
+
def json_payload
|
62
|
+
attributes.merge(
|
63
|
+
action: payload_action,
|
64
|
+
merchant_id: Bitkassa.config.merchant_id
|
65
|
+
).to_json
|
66
|
+
end
|
67
|
+
|
68
|
+
def assign_attributes(attributes)
|
69
|
+
attributes.each do |name, value|
|
70
|
+
send("#{name}=", value)
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
def responder
|
75
|
+
@responder ||= Bitkassa::PaymentResponse
|
76
|
+
end
|
77
|
+
|
78
|
+
def authenticator
|
79
|
+
@authenticator ||= Authentication
|
80
|
+
end
|
81
|
+
|
82
|
+
private
|
83
|
+
|
84
|
+
def uri
|
85
|
+
Bitkassa.config.base_uri
|
86
|
+
end
|
87
|
+
|
88
|
+
def params
|
89
|
+
{ p: payload, a: authentication }
|
90
|
+
end
|
91
|
+
|
92
|
+
def authentication
|
93
|
+
authenticator.sign(json_payload, @initialized_at)
|
94
|
+
end
|
95
|
+
|
96
|
+
def payload
|
97
|
+
Base64.urlsafe_encode64(json_payload)
|
98
|
+
end
|
99
|
+
|
100
|
+
def params_string
|
101
|
+
params.map { |k, v| [k, "=", v].join }.join("&")
|
102
|
+
end
|
103
|
+
end
|
104
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
module Bitkassa
|
2
|
+
# Checks the status of a payment
|
3
|
+
class StatusRequest < Request
|
4
|
+
attr_accessor :payment_id
|
5
|
+
|
6
|
+
def attributes
|
7
|
+
{ payment_id: @payment_id }
|
8
|
+
end
|
9
|
+
|
10
|
+
def payload_action
|
11
|
+
"get_payment_status"
|
12
|
+
end
|
13
|
+
|
14
|
+
def can_perform?
|
15
|
+
return false if payment_id.nil?
|
16
|
+
|
17
|
+
super
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: bitkassa
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Bèr Kessels
|
@@ -30,7 +30,7 @@ cert_chain:
|
|
30
30
|
Kh4io+CNPvyPs1ZT/YqWsWIoi0cW5LCWGSXMThk1AY80jVv3XrlzMRZewVMjUInv
|
31
31
|
KOmiB20daFpjM5ZM
|
32
32
|
-----END CERTIFICATE-----
|
33
|
-
date: 2015-
|
33
|
+
date: 2015-12-23 00:00:00.000000000 Z
|
34
34
|
dependencies:
|
35
35
|
- !ruby/object:Gem::Dependency
|
36
36
|
name: httpi
|
@@ -109,6 +109,14 @@ extensions: []
|
|
109
109
|
extra_rdoc_files: []
|
110
110
|
files:
|
111
111
|
- lib/bitkassa.rb
|
112
|
+
- lib/bitkassa/authentication.rb
|
113
|
+
- lib/bitkassa/config.rb
|
114
|
+
- lib/bitkassa/exception.rb
|
115
|
+
- lib/bitkassa/payment_request.rb
|
116
|
+
- lib/bitkassa/payment_response.rb
|
117
|
+
- lib/bitkassa/payment_result.rb
|
118
|
+
- lib/bitkassa/request.rb
|
119
|
+
- lib/bitkassa/status_request.rb
|
112
120
|
homepage: http://github.com/berkes/bitkassa
|
113
121
|
licenses:
|
114
122
|
- MIT
|
metadata.gz.sig
CHANGED
Binary file
|