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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: b8c745f83c512fc5cebfcc5e5b3d8c1813aa49dc
4
- data.tar.gz: a52d91b27aee9ddb4340c7dfaa511cd82bf00de6
3
+ metadata.gz: ced241ac3d66937fcd864c09c71975f8dde92ab4
4
+ data.tar.gz: 598d15da58553b95ae9ab6bc7260dcf1e3c09df2
5
5
  SHA512:
6
- metadata.gz: ea5699eb3b5e0df35e0b8f101e9fba318da601c7d9b20a480c2502a4cd5dac49458e0e8c516e927194e6017d3acc437b96cfda69678ba0c333499ec6b60db811
7
- data.tar.gz: ce79cd9c2bfebb86cc91456e41ed1f2a78ea9e7b2d1b2524a9142623977c75d09d1157b233698abb857e6724a6d4cb006cf9f6858ad5c53c58da489a05addfe8
6
+ metadata.gz: 92602bcd6623a3e57c10bd276eb5fd331c8490c2912228d6db8afbbdcfdc20bf3d0d5d914e53a8eed81d599a175e4cb6fd1866112968fbf80c854c9f7d3ea24a
7
+ data.tar.gz: ed81996b1a92893e00a3b4e92a88e9508e8abf57846e0511de88e397cec14fccdd294b884274e0273050a025a0c6bae35eb666fddcb750c02f4b1b28ea4d0ee4
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,6 @@
1
+ module Bitkassa
2
+ ##
3
+ # Generic Bitkassa Exception.
4
+ class Exception < StandardError
5
+ end
6
+ 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.2
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-11-21 00:00:00.000000000 Z
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