scanpay 1.0.0 → 1.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (3) hide show
  1. checksums.yaml +4 -4
  2. data/lib/scanpay.rb +47 -9
  3. metadata +4 -4
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 5ffa65f23cd1a8b6c6266024ba9d4b1f23c87c23
4
- data.tar.gz: 15c61f463bbe53410e9ef42e055b854dbd9db854
3
+ metadata.gz: 8a8d86c66c6c1685122ed840ad04f0e4c9b26307
4
+ data.tar.gz: 714ed63eda0cb5761025e7e05bb63bd7a78918bc
5
5
  SHA512:
6
- metadata.gz: 236a61508993ebfea15fda6c90b0b8b51b0236920d0e3e07ac048b4e26023a935b2196c89f8cf9834208a3e06c1b37104cf144a97690c2522ff66917d32bc203
7
- data.tar.gz: f3218fdf758c3dfd77f10f653af61bffc310c1dae7eb82818d411f1f8a08ad7f99e3fab8ef2030d49a76cbc99d70bb99cf7c1d6277523e6651ba86151319f4d7
6
+ metadata.gz: 66cfce49c09386d12eb486ae2c27fa70c2926d2b1b9aaf8feb63b9663039e92fe73fead6f6d9ead988bfbf81acadc2a72ed93247da0178fcfabfe5d88773eda7
7
+ data.tar.gz: 513ca5eddf661647ca8e4da56e3efd0f7b2792fe552756053437378e185d6ac55f30fb092df818c6df201360fac9b929ea6382a260969d29f6fac2a367f0faa0
@@ -2,10 +2,12 @@
2
2
  require 'base64'
3
3
  require 'json'
4
4
  require 'openssl'
5
+ require 'securerandom'
5
6
  require 'httpclient' # Thread-Safe. Consider https://github.com/httprb/http
6
7
 
7
8
  module Scanpay
8
- class Error < StandardError; end
9
+ class IdempotentResponseException < StandardError
10
+ end
9
11
 
10
12
  class Client
11
13
  @https
@@ -19,7 +21,7 @@ module Scanpay
19
21
  @apikey = apikey
20
22
  @headers = {
21
23
  'authorization' => 'basic ' + Base64.strict_encode64(apikey),
22
- 'x-sdk' => 'Ruby-1.0.0/' + RUBY_VERSION,
24
+ 'x-sdk' => 'Ruby-1.1.0/' + RUBY_VERSION,
23
25
  'content-type' => 'application/json',
24
26
  }
25
27
  end
@@ -33,6 +35,10 @@ module Scanpay
33
35
  return neq === 0
34
36
  end
35
37
 
38
+ def generateIdempotencyKey()
39
+ return SecureRandom.base64(32).delete('=')
40
+ end
41
+
36
42
  def request(path, data, opts={})
37
43
  hostname = opts['hostname'] || 'api.scanpay.dk'
38
44
  headers = @headers.clone
@@ -45,16 +51,32 @@ module Scanpay
45
51
  end
46
52
  res = (data === nil) ? @https.get('https://' + hostname + path, nil, headers) :
47
53
  @https.post('https://' + hostname + path, data.to_json, headers)
48
-
49
- return JSON.parse(res.body) if res.code == 200
50
- raise Error, res.reason
54
+ if headers['idempotency-key']
55
+ idem = res.header['idempotency-status'][0]
56
+ case idem
57
+ when 'OK'
58
+ # Do nothing
59
+ when 'ERROR'
60
+ raise "server failed to provide idempotency: #{res.reason}"
61
+ when ''
62
+ raise "missing response idempotency status: #{res.reason}"
63
+ else
64
+ raise "unknown idempotency status '#{idem}': #{res.reason}"
65
+ end
66
+ end
67
+ raise IdempotentResponseException, res.reason if res.code != 200
68
+ begin
69
+ return JSON.parse(res.body)
70
+ rescue JSON::ParserError => e
71
+ raise IdempotentResponseException, "invalid json response: #{e.message}"
72
+ end
51
73
  end
52
74
 
53
75
  # newURL: Create a new payment link
54
76
  def newURL(data, opts={})
55
77
  o = request('/v1/new', data, opts)
56
78
  return o['url'] if o['url'].is_a? String
57
- raise Error, 'invalid response from server'
79
+ raise 'invalid response from server'
58
80
  end
59
81
 
60
82
  # seq: Get array of changes since the reqested sequence number
@@ -64,18 +86,34 @@ module Scanpay
64
86
  end
65
87
  o = request('/v1/seq/' + num.to_s, nil, opts)
66
88
  return o if (o['changes'].kind_of? Array) && (o['seq'].is_a? Integer)
67
- raise Error, 'invalid response from server'
89
+ raise 'invalid response from server'
68
90
  end
69
91
 
70
92
  # handlePing: Convert body to JSON and validate signature
71
93
  def handlePing(body='', signature='')
72
94
  digest = OpenSSL::HMAC.digest(OpenSSL::Digest.new('sha256'), @apikey, body)
73
95
  is_valid = timesafe_equals(Base64.strict_encode64(digest), signature)
74
- raise Error, 'invalid signature' unless is_valid
96
+ raise 'invalid signature' unless is_valid
75
97
 
76
98
  o = JSON.parse(body)
77
99
  return o if (o['shopid'].is_a? Integer) && (o['seq'].is_a? Integer)
78
- raise Error, 'invalid ping'
100
+ raise 'invalid ping'
101
+ end
102
+
103
+ def charge(subid, data, opts={})
104
+ if !subid.is_a? Integer
105
+ raise ArgumentError, 'first argument is not an integer'
106
+ end
107
+ return request("/v1/subscribers/#{subid}/charge", data, opts);
108
+ end
109
+
110
+ def renew(subid, data, opts={})
111
+ if !subid.is_a? Integer
112
+ raise ArgumentError, 'first argument is not an integer'
113
+ end
114
+ o = request("/v1/subscribers/#{subid}/renew", data, opts);
115
+ return o['url'] if o['url'].is_a? String
116
+ raise 'invalid response from server'
79
117
  end
80
118
 
81
119
  private :request
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: scanpay
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0
4
+ version: 1.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Scanpay
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2017-12-05 00:00:00.000000000 Z
11
+ date: 2019-09-18 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: httpclient
@@ -16,14 +16,14 @@ dependencies:
16
16
  requirements:
17
17
  - - "~>"
18
18
  - !ruby/object:Gem::Version
19
- version: '2.6'
19
+ version: '2.8'
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - "~>"
25
25
  - !ruby/object:Gem::Version
26
- version: '2.6'
26
+ version: '2.8'
27
27
  description: Accept payments with the Scanpay payment gateway. See https://scanpay.dk
28
28
  for more details.
29
29
  email: contact@scanpay.dk