pci_proxy 1.1.0 → 1.2.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: e3809fc9d53de874082c4b1c7ffb7ad715adcfeb2fea22fef66266d4072d41bd
4
- data.tar.gz: 176d0778aa1f90c0e6f95fc141da290fd951ace11c3a5232a617bc9db21ba474
3
+ metadata.gz: 6a88f474d4153735ec851a18cbdfc91aded2a3b9ab310b29887e9a05e3943fc9
4
+ data.tar.gz: 46fb731fb0604451d084d29bf8cf0c1d7ab7e54475447fe22a594379fbd6d8ff
5
5
  SHA512:
6
- metadata.gz: 154eb6fd451665825ba0eb146fa12c51448c815cfc13dd1dbea93a65f49c35053c2ae1ae9691622ba198770cfc8ddbed7e01030e13504445cdf255d8010ac9b0
7
- data.tar.gz: 44975973ccded51daa015e25000291f7a992ec1ecd642119491a5c589bf16bf6e10f9a145c2164e344242425edf40de0b7f26fc6a64016bac3c67b94d104af97
6
+ metadata.gz: 43fb21c87681f6c3953259561beb31196231ff75e5b0d7df470c204f301c2a3d0e9230598d0c02dcc1295a7635b8a1bfa6044745e8c523256355f96a5ffdc295
7
+ data.tar.gz: 99d59b3029c316d64325a003b3f835bb9e0aeccda201450119f72bfccf7dc0e280a33bdd091283028a3f5ea2290d6442caee3d531196e063bd4476769c405f6b
data/CHANGELOG.md CHANGED
@@ -2,6 +2,8 @@
2
2
 
3
3
  A simple client library for [PCI Proxy](https://pci-proxy.com)'s API
4
4
 
5
+ v1.2.0 - 30th January 2020 - Add support for the [Check API](https://docs.pci-proxy.com/use-stored-cards/check)
6
+
5
7
  v1.1.0 - 17th January 2020 - Return an instance of PciProxy::Model::TokenisedCard instead of plain Hash
6
8
 
7
9
  v1.0.1 - 14th January 2020 - Relax dependency version requirements
data/lib/pci_proxy.rb CHANGED
@@ -2,7 +2,9 @@ require 'bundler'
2
2
  require "pci_proxy/version"
3
3
 
4
4
  require 'pci_proxy/base'
5
+ require 'pci_proxy/check'
5
6
  require 'pci_proxy/token'
7
+ require 'pci_proxy/model/check_result'
6
8
  require 'pci_proxy/model/tokenised_card'
7
9
 
8
10
  module PciProxy
@@ -20,4 +22,5 @@ module PciProxy
20
22
  HTTP_FORBIDDEN_CODE = 403
21
23
  HTTP_NOT_FOUND_CODE = 404
22
24
  HTTP_UNPROCESSABLE_ENTITY_CODE = 429
25
+
23
26
  end
@@ -4,6 +4,8 @@ require 'multi_json'
4
4
  module PciProxy
5
5
  class Base
6
6
 
7
+ JSON_UTF8_CONTENT_TYPE = 'application/json; charset=UTF-8'.freeze
8
+
7
9
  attr_reader :api_endpoint, :api_username, :api_password
8
10
 
9
11
  ##
@@ -17,19 +19,35 @@ module PciProxy
17
19
  end
18
20
 
19
21
  ##
20
- # Perform the API request
22
+ # Perform an API request via HTTP GET
21
23
  #
22
24
  # @param +endpoint+ [String] (Optional) - the API endpoint to hit - defaults to the value of the api_endpoint reader
23
- # @param +http_method+ [Symbol] (Optional) - the HTTP method to use - defaults to GET
24
- # @param +params+ [Hash] (Optional) - any parameters to supply to the API call
25
+ # @param +params+ [Hash] (Optional) - any URL parameters to supply to the API call
25
26
  #
26
27
  # @raise [PciProxyAPIError] in cases where the API responds with a non-200 response code
27
28
  # @return [Hash] parsed JSON response
29
+ def api_get(endpoint: @api_endpoint, params: {}, raise_on_error: true)
30
+ response = client.get(endpoint, params)
31
+
32
+ if raise_on_error == false || response.status == HTTP_OK_CODE
33
+ return MultiJson.load(response.body)
34
+ end
35
+
36
+ raise error_class(response), "HTTP status: #{response.status}, Response: #{response.body}"
37
+ end
38
+
39
+ ##
40
+ # Perform an API request via HTTP POST
41
+ #
42
+ # @param +endpoint+ [String] (Optional) - the API endpoint to hit - defaults to the value of the api_endpoint reader
43
+ # @param +body+ [Hash] (Optional) - the API request payload (will be converted to JSON)
28
44
  #
29
- def request(endpoint: @api_endpoint, http_method: :get, params: {})
30
- response = client.public_send(http_method, endpoint, params)
45
+ # @raise [PciProxyAPIError] in cases where the API responds with a non-200 response code
46
+ # @return [Hash] parsed JSON response
47
+ def api_post(endpoint: @api_endpoint, body: {}, raise_on_error: true)
48
+ response = client.post(endpoint, MultiJson.dump(body), "Content-Type" => JSON_UTF8_CONTENT_TYPE)
31
49
 
32
- if response.status == HTTP_OK_CODE
50
+ if raise_on_error == false || response.status == HTTP_OK_CODE
33
51
  return MultiJson.load(response.body)
34
52
  end
35
53
 
@@ -0,0 +1,62 @@
1
+ module PciProxy
2
+ class Check < Base
3
+
4
+ SANDBOX_ENDPOINT = 'https://api.sandbox.datatrans.com/v1/transactions/validate'.freeze
5
+ LIVE_ENDPOINT = 'https://api.datatrans.com/v1/transactions/validate'.freeze
6
+
7
+ CHF = 'CHF'.freeze
8
+ EUR = 'EUR'.freeze
9
+
10
+ # error codes
11
+ # "UNKNOWN_ERROR", "UNRECOGNIZED_PROPERTY", "INVALID_PROPERTY", "INVALID_TRANSACTION_STATUS", "TRANSACTION_NOT_FOUND", "INVALID_JSON_PAYLOAD", "UNAUTHORIZED", "EXPIRED_CARD", "INVALID_CARD", "UNSUPPORTED_CARD", "DUPLICATED_REFNO", "DECLINED", "BLOCKED_BY_VELOCITY_CHECKER", "CLIENT_ERROR" , "SERVER_ERROR"
12
+
13
+ ##
14
+ # Initialise with the specified +api_username+ and +api_password+ from PCI Proxy.
15
+ #
16
+ # Defaults to the sandbox API endpoint - to use the live environment,
17
+ # supply the LIVE_ENDPOINT constant as the value of the +endpoint+ kwarg
18
+ def initialize(api_username:, api_password:, endpoint: SANDBOX_ENDPOINT)
19
+ @api_endpoint = endpoint
20
+ @api_username = api_username
21
+ @api_password = api_password
22
+ end
23
+
24
+ ##
25
+ # Perform a check API request to verify the card token
26
+ #
27
+ # @param +reference+ [String] - caller's unique reference (any non-empty string value)
28
+ # @param +card_token+ [String] - card token obtained from the Token API - see PciProxy::Token
29
+ # @param +card_type+ [Symbol / String] - one of 'visa', 'mastercard' or 'amex'
30
+ # @param +expiry_month+ [Integer / String] - integer 1-12, or string '01' - '12'
31
+ # @param +expiry_year+ [Integer / String] - two or four digit year as a string or integer
32
+ # @param +currency+ [Integer / String] (Optional) - one of 'CHF' or 'EUR' - will default by card type where not specified
33
+ #
34
+ # @raise [PciProxyAPIError] in cases where the API responds with a non-200 response code
35
+ # @return [Hash] result from PCI Proxy, decoded from JSON
36
+ def execute(reference:, card_token:, card_type:, expiry_month:, expiry_year:, currency: nil)
37
+ raise "reference is required" if reference.empty?
38
+ raise "card_token is required" unless card_token && !card_token.empty?
39
+ raise "card_type must be one of 'visa', 'mastercard' or 'amex'" unless [:visa, :mastercard, :amex].include?(card_type.to_sym)
40
+ raise "invalid expiry_month" unless (1..12).include?(expiry_month.to_i)
41
+ raise "invalid expiry_year" unless expiry_year.to_i > 0
42
+
43
+ # default the currency where not specified - according to the documentation Amex should use EUR, Visa and MC should use CHF
44
+ currency ||= :amex == card_type ? EUR : CHF
45
+
46
+ card = {
47
+ alias: card_token,
48
+ expiryMonth: expiry_month.to_s,
49
+ expiryYear: expiry_year.to_s.chars.last(2).join
50
+ }
51
+
52
+ body = {
53
+ refno: reference,
54
+ currency: currency,
55
+ card: card
56
+ }
57
+
58
+ PciProxy::Model::CheckResult.new(api_post(endpoint: @api_endpoint, body: body, raise_on_error: false))
59
+ end
60
+
61
+ end
62
+ end
@@ -0,0 +1,18 @@
1
+ module PciProxy
2
+ module Model
3
+ class CheckResult
4
+
5
+ attr_reader :response, :status, :error, :auth_code, :transaction_id
6
+
7
+ def initialize(response)
8
+ @response = response
9
+ @auth_code = response["acquirerAuthorizationCode"]
10
+ @transaction_id = response["transactionId"]
11
+ @error = response["error"]
12
+
13
+ @status = @auth_code && @transaction_id && !@error ? 'success' : 'error'
14
+ end
15
+
16
+ end
17
+ end
18
+ end
@@ -2,7 +2,7 @@ module PciProxy
2
2
  module Model
3
3
  class TokenisedCard
4
4
 
5
- attr_reader :pan_token, :cvv_token, :type_slug, :response
5
+ attr_reader :response, :pan_token, :cvv_token, :type_slug
6
6
 
7
7
  def initialize(response)
8
8
  @response = response
@@ -1,25 +1,35 @@
1
1
  module PciProxy
2
2
  class Token < Base
3
3
 
4
+ SANDBOX_ENDPOINT = 'https://api.sandbox.datatrans.com/upp/services/v1/inline/token'.freeze
5
+ LIVE_ENDPOINT = 'https://api.datatrans.com/upp/services/v1/inline/token'.freeze
6
+
4
7
  ##
5
8
  # Initialise with the specified +api_username+ and +api_password+ from PCI Proxy.
6
- def initialize(api_username:, api_password:)
7
- @api_endpoint = 'https://api.sandbox.datatrans.com/upp/services/v1/inline/token'.freeze
9
+ #
10
+ # Defaults to the sandbox API endpoint - to use the live environment,
11
+ # supply the LIVE_ENDPOINT constant as the value of the +endpoint+ kwarg
12
+ def initialize(api_username:, api_password:, endpoint: SANDBOX_ENDPOINT)
13
+ @api_endpoint = endpoint
8
14
  @api_username = api_username
9
15
  @api_password = api_password
10
16
  end
11
17
 
12
18
  ##
13
- # Perform a token request to turn the specified +transaction_id+ into card and CVV tokens
19
+ # Perform a token API request to turn the specified +transaction_id+ into card and CVV tokens
14
20
  #
15
21
  # @param +return_payment_method+ (true/false) - whether or not to return the identified payment method (default: true)
16
22
  # @param +cvv_mandatory+ (true/false) - whether or not to consider the CVV alias should be mandatory (default: false)
17
23
  #
18
24
  # @raise [PciProxyAPIError] in cases where the API responds with a non-200 response code
19
- # @return [Hash] result from PCI Proxy, decoded from JSON
25
+ # @return [PciProxy::Model::TokenisedCard] wrapper object around the JSON response
20
26
  def execute(transaction_id:, return_payment_method: true, cvv_mandatory: false)
21
- response = request(params: { transactionId: transaction_id, returnPaymentMethod: return_payment_method, mandatoryAliasCVV: cvv_mandatory })
22
- PciProxy::Model::TokenisedCard.new(response)
27
+ raise "transaction_id is required" unless transaction_id && !transaction_id.empty?
28
+
29
+ PciProxy::Model::TokenisedCard.new(api_get(params: {
30
+ transactionId: transaction_id,
31
+ returnPaymentMethod: return_payment_method,
32
+ mandatoryAliasCVV: cvv_mandatory }))
23
33
  end
24
34
 
25
35
  end
@@ -1,3 +1,3 @@
1
1
  module PciProxy
2
- VERSION = "1.1.0"
2
+ VERSION = "1.2.0"
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: pci_proxy
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.1.0
4
+ version: 1.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Rory Sinclair
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2020-01-17 00:00:00.000000000 Z
11
+ date: 2020-01-30 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -100,6 +100,8 @@ files:
100
100
  - bin/setup
101
101
  - lib/pci_proxy.rb
102
102
  - lib/pci_proxy/base.rb
103
+ - lib/pci_proxy/check.rb
104
+ - lib/pci_proxy/model/check_result.rb
103
105
  - lib/pci_proxy/model/tokenised_card.rb
104
106
  - lib/pci_proxy/token.rb
105
107
  - lib/pci_proxy/version.rb