judopay 2.0.1 → 2.1.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/LICENSE +21 -0
- data/judopay.gemspec +2 -2
- data/lib/judopay/error.rb +6 -2
- data/lib/judopay/model.rb +16 -0
- data/lib/judopay/models/android_payment.rb +26 -0
- data/lib/judopay/models/android_preauth.rb +8 -0
- data/lib/judopay/models/apple_payment.rb +26 -0
- data/lib/judopay/models/apple_preauth.rb +9 -0
- data/lib/judopay/models/card_payment.rb +1 -2
- data/lib/judopay/models/card_preauth.rb +0 -1
- data/lib/judopay/models/inner/pk_payment.rb +17 -0
- data/lib/judopay/models/inner/pk_payment_token.rb +13 -0
- data/lib/judopay/models/inner/transmitted_field.rb +39 -0
- data/lib/judopay/models/inner/wallet.rb +30 -0
- data/lib/judopay/models/register_card.rb +0 -1
- data/lib/judopay/models/save_card.rb +0 -1
- data/lib/judopay/models/token_payment.rb +1 -2
- data/lib/judopay/models/web_payments/payment.rb +1 -0
- data/lib/judopay/version.rb +1 -1
- data/spec/factories.rb +62 -2
- data/spec/fixtures/transactions/android_payment.json +26 -0
- data/spec/fixtures/transactions/apple_payment.json +26 -0
- data/spec/judopay/android_payment_spec.rb +74 -0
- data/spec/judopay/apple_payment_spec.rb +80 -0
- data/test/base/payments_tests.rb +7 -0
- data/test/base/token_payment_tests.rb +7 -0
- data/test/register_card_test.rb +9 -4
- data/test/void_test.rb +1 -0
- metadata +21 -8
- data/LICENSE.txt +0 -22
- data/lib/judopay/models/consumer_location.rb +0 -8
- data/tutorials/judo_getting_started.md +0 -74
- data/tutorials/judo_making_a_payment.md +0 -84
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: ee2fddf46aa4fa23cc6e41a1bf37766134704c47
|
4
|
+
data.tar.gz: 41e0f0af43a8c59434748d81a4a7a2f3b3736da1
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 3b73e9514861890092abbfc44c3538298a2231ca8f296efb9cd602658c0f37061e1f1acce80b0194f0c9e55c7b8436de87130af057402038e40a025ddd703569
|
7
|
+
data.tar.gz: 505a41b6bfe31584202759a318fdc24369851b3d3cf12d511cbc293f4e757871384ec8fb99b1b007cb16536296851a93bab80694b6561b55d512d63f0a355a0d
|
data/LICENSE
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
MIT License
|
2
|
+
|
3
|
+
Copyright (c) 2016 Alternative Payments Ltd
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
7
|
+
in the Software without restriction, including without limitation the rights
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
10
|
+
furnished to do so, subject to the following conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
13
|
+
copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
21
|
+
SOFTWARE.
|
data/judopay.gemspec
CHANGED
@@ -6,9 +6,9 @@ require 'judopay/version'
|
|
6
6
|
Gem::Specification.new do |spec|
|
7
7
|
spec.name = 'judopay'
|
8
8
|
spec.version = Judopay::SDK_VERSION
|
9
|
-
spec.authors = ['
|
9
|
+
spec.authors = ['Judopay']
|
10
10
|
spec.email = ['developersupport@judopay.com']
|
11
|
-
spec.summary = 'Ruby
|
11
|
+
spec.summary = 'Ruby gem for using the Judopay API'
|
12
12
|
spec.description = ''
|
13
13
|
spec.homepage = 'http://www.judopay.com'
|
14
14
|
spec.license = 'MIT'
|
data/lib/judopay/error.rb
CHANGED
@@ -46,8 +46,12 @@ module Judopay
|
|
46
46
|
def extract_field_errors(field_errors)
|
47
47
|
result = []
|
48
48
|
|
49
|
-
field_errors.
|
50
|
-
result <<
|
49
|
+
if field_errors.is_a?(Hash) && field_errors.key?('receiptId')
|
50
|
+
result << 'Duplicate transaction. Receipt id: ' + field_errors['receiptId'].to_s
|
51
|
+
else
|
52
|
+
field_errors.to_a.each do |field_error|
|
53
|
+
result << FieldError.new(field_error['message'], field_error['code'], field_error['fieldName'], field_error['detail'])
|
54
|
+
end
|
51
55
|
end
|
52
56
|
|
53
57
|
result
|
data/lib/judopay/model.rb
CHANGED
@@ -116,3 +116,19 @@ module Judopay
|
|
116
116
|
end
|
117
117
|
end
|
118
118
|
end
|
119
|
+
|
120
|
+
module ActiveModel
|
121
|
+
module Validations
|
122
|
+
module ClassMethods
|
123
|
+
def validate_nested_model(*attr_names)
|
124
|
+
validates_with BlockValidator, _merge_attributes(attr_names) do |model, attr, value|
|
125
|
+
if value.is_a?(Judopay::Model) && !value.valid?
|
126
|
+
value.errors.each { |field, message| model.errors["#{attr}.#{field}"] = message }
|
127
|
+
elsif !value.is_a?(Judopay::Model)
|
128
|
+
model.errors[attr] = 'should be valid Model object'
|
129
|
+
end
|
130
|
+
end
|
131
|
+
end
|
132
|
+
end
|
133
|
+
end
|
134
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
require_relative '../model'
|
2
|
+
require_relative 'inner/wallet'
|
3
|
+
|
4
|
+
module Judopay
|
5
|
+
class AndroidPayment < Model
|
6
|
+
@resource_path = 'transactions/payments'
|
7
|
+
@valid_api_methods = [:create]
|
8
|
+
|
9
|
+
attribute :your_consumer_reference, String # required
|
10
|
+
attribute :your_payment_reference, String # required
|
11
|
+
attribute :your_payment_meta_data, Hash
|
12
|
+
attribute :judo_id, String # required
|
13
|
+
attribute :amount, Float # required
|
14
|
+
attribute :currency, String
|
15
|
+
attribute :client_details, Hash
|
16
|
+
attribute :wallet, Judopay::Wallet
|
17
|
+
|
18
|
+
validates_presence_of :your_consumer_reference,
|
19
|
+
:your_payment_reference,
|
20
|
+
:judo_id,
|
21
|
+
:amount,
|
22
|
+
:currency
|
23
|
+
|
24
|
+
validate_nested_model :wallet
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
require_relative '../model'
|
2
|
+
require_relative 'inner/pk_payment'
|
3
|
+
|
4
|
+
module Judopay
|
5
|
+
class ApplePayment < Model
|
6
|
+
@resource_path = 'transactions/payments'
|
7
|
+
@valid_api_methods = [:create]
|
8
|
+
|
9
|
+
attribute :your_consumer_reference, String # required
|
10
|
+
attribute :your_payment_reference, String # required
|
11
|
+
attribute :your_payment_meta_data, Hash
|
12
|
+
attribute :judo_id, String # required
|
13
|
+
attribute :amount, Float # required
|
14
|
+
attribute :currency, String
|
15
|
+
attribute :client_details, Hash
|
16
|
+
attribute :pk_payment, Judopay::PkPayment
|
17
|
+
|
18
|
+
validates_presence_of :your_consumer_reference,
|
19
|
+
:your_payment_reference,
|
20
|
+
:judo_id,
|
21
|
+
:amount,
|
22
|
+
:currency
|
23
|
+
|
24
|
+
validate_nested_model :pk_payment
|
25
|
+
end
|
26
|
+
end
|
@@ -1,7 +1,6 @@
|
|
1
1
|
require_relative '../model'
|
2
2
|
require_relative 'payment'
|
3
3
|
require_relative 'card_address'
|
4
|
-
require_relative 'consumer_location'
|
5
4
|
|
6
5
|
module Judopay
|
7
6
|
class CardPayment < Model
|
@@ -17,10 +16,10 @@ module Judopay
|
|
17
16
|
attribute :expiry_date, String # required for card transactions
|
18
17
|
attribute :cv2, String # required for card transactions
|
19
18
|
attribute :card_address, Judopay::CardAddress
|
20
|
-
attribute :consumer_location, Judopay::ConsumerLocation
|
21
19
|
attribute :mobile_number, String
|
22
20
|
attribute :email_address, String
|
23
21
|
attribute :currency, String
|
22
|
+
attribute :client_details, Hash
|
24
23
|
|
25
24
|
validates_presence_of :your_consumer_reference,
|
26
25
|
:your_payment_reference,
|
@@ -0,0 +1,17 @@
|
|
1
|
+
require_relative 'transmitted_field'
|
2
|
+
require_relative 'pk_payment_token'
|
3
|
+
|
4
|
+
module Judopay
|
5
|
+
class PkPayment < TransmittedField
|
6
|
+
attribute :token, Judopay::PkPaymentToken
|
7
|
+
attribute :billing_address, String
|
8
|
+
attribute :shipping_address, String
|
9
|
+
|
10
|
+
validate_nested_model :token
|
11
|
+
|
12
|
+
def self.new(*args)
|
13
|
+
self.field_name = 'pk_payment'
|
14
|
+
super(*args)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
require_relative '../../model'
|
2
|
+
|
3
|
+
module Judopay
|
4
|
+
class PkPaymentToken < Model
|
5
|
+
attribute :payment_instrument_name, String
|
6
|
+
attribute :payment_network, String
|
7
|
+
attribute :payment_data, Hash
|
8
|
+
|
9
|
+
validates_presence_of :payment_instrument_name,
|
10
|
+
:payment_network,
|
11
|
+
:payment_data
|
12
|
+
end
|
13
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
require_relative '../../model'
|
2
|
+
require 'judopay/mash'
|
3
|
+
require 'json'
|
4
|
+
|
5
|
+
module Judopay
|
6
|
+
class TransmittedField < Model
|
7
|
+
WRONG_OBJECT_ERROR_MESSAGE = 'You passed wrong value to the %s. Please pass Hash or json-encoded string'.freeze
|
8
|
+
WRONG_JSON_ERROR_MESSAGE = 'Can\'t decode %s object from JSON'.freeze
|
9
|
+
|
10
|
+
class << self
|
11
|
+
attr_accessor :field_name
|
12
|
+
|
13
|
+
def new(*args)
|
14
|
+
super(validate_data(*args))
|
15
|
+
end
|
16
|
+
|
17
|
+
protected
|
18
|
+
|
19
|
+
def validate_data(data)
|
20
|
+
data = parse_string(data) if data.is_a?(String)
|
21
|
+
raise Judopay::ValidationError, format(WRONG_OBJECT_ERROR_MESSAGE, name) unless data.is_a?(Hash) || data.is_a?(Judopay::Mash)
|
22
|
+
data = Judopay::Mash.new(data)
|
23
|
+
data = data[field_name] if data.key?(field_name)
|
24
|
+
|
25
|
+
data
|
26
|
+
end
|
27
|
+
|
28
|
+
def parse_string(string)
|
29
|
+
JSON.parse(string)
|
30
|
+
rescue
|
31
|
+
raise Judopay::ValidationError, format(WRONG_JSON_ERROR_MESSAGE, name)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
def ==(other)
|
36
|
+
to_yaml == other.to_yaml
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
require_relative 'transmitted_field'
|
2
|
+
|
3
|
+
module Judopay
|
4
|
+
class Wallet < TransmittedField
|
5
|
+
attribute :encrypted_message, String
|
6
|
+
attribute :environment, Integer
|
7
|
+
attribute :ephemeral_public_key, String
|
8
|
+
attribute :google_transaction_id, String
|
9
|
+
attribute :instrument_details, String
|
10
|
+
attribute :instrument_type, String
|
11
|
+
attribute :public_key, String
|
12
|
+
attribute :tag, String
|
13
|
+
attribute :version, Integer
|
14
|
+
|
15
|
+
validates_presence_of :encrypted_message,
|
16
|
+
:environment,
|
17
|
+
:ephemeral_public_key,
|
18
|
+
:google_transaction_id,
|
19
|
+
:instrument_details,
|
20
|
+
:instrument_type,
|
21
|
+
:public_key,
|
22
|
+
:tag,
|
23
|
+
:version
|
24
|
+
|
25
|
+
def self.new(*args)
|
26
|
+
self.field_name = 'wallet'
|
27
|
+
super(*args)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -1,7 +1,6 @@
|
|
1
1
|
require_relative '../model'
|
2
2
|
require_relative 'payment'
|
3
3
|
require_relative 'card_address'
|
4
|
-
require_relative 'consumer_location'
|
5
4
|
|
6
5
|
module Judopay
|
7
6
|
class TokenPayment < Model
|
@@ -16,10 +15,10 @@ module Judopay
|
|
16
15
|
attribute :consumer_token, String
|
17
16
|
attribute :card_token, String
|
18
17
|
attribute :cv2, String
|
19
|
-
attribute :consumer_location, Judopay::ConsumerLocation
|
20
18
|
attribute :mobile_number, String
|
21
19
|
attribute :email_address, String
|
22
20
|
attribute :currency, String
|
21
|
+
attribute :client_details, Hash
|
23
22
|
|
24
23
|
validates_presence_of :your_consumer_reference,
|
25
24
|
:your_payment_reference,
|
@@ -16,6 +16,7 @@ module Judopay
|
|
16
16
|
attribute :client_ip_address, String
|
17
17
|
attribute :client_user_agent, String
|
18
18
|
attribute :currency, String
|
19
|
+
attribute :client_details, Hash
|
19
20
|
attribute :web_payment_operation, Judopay::WebPayments::WebPaymentOperation
|
20
21
|
|
21
22
|
validates_presence_of :judo_id,
|
data/lib/judopay/version.rb
CHANGED
data/spec/factories.rb
CHANGED
@@ -11,13 +11,18 @@ models = %w(
|
|
11
11
|
save_card
|
12
12
|
register_card
|
13
13
|
void
|
14
|
+
apple_payment
|
15
|
+
android_payment
|
14
16
|
)
|
15
17
|
models.each { |model| require_relative '../lib/judopay/models/' + model }
|
18
|
+
require 'securerandom'
|
16
19
|
|
17
20
|
FactoryGirl.define do
|
18
21
|
trait :payment_details do
|
19
22
|
your_consumer_reference 123
|
20
|
-
your_payment_reference
|
23
|
+
sequence :your_payment_reference do |n|
|
24
|
+
SecureRandom.hex(21) + n.to_s
|
25
|
+
end
|
21
26
|
amount 1.01
|
22
27
|
end
|
23
28
|
|
@@ -46,7 +51,9 @@ FactoryGirl.define do
|
|
46
51
|
trait :valid_collection_or_refund_details do
|
47
52
|
receipt_id '1234'
|
48
53
|
amount 1.01
|
49
|
-
your_payment_reference
|
54
|
+
sequence :your_payment_reference do |n|
|
55
|
+
SecureRandom.hex(21) + n.to_s
|
56
|
+
end
|
50
57
|
end
|
51
58
|
|
52
59
|
trait :client_ip_address_and_user_agent do
|
@@ -145,4 +152,57 @@ FactoryGirl.define do
|
|
145
152
|
factory :void, :class => Judopay::Void do
|
146
153
|
valid_collection_or_refund_details
|
147
154
|
end
|
155
|
+
|
156
|
+
factory :apple_payment, :class => Judopay::ApplePayment do
|
157
|
+
payment_details
|
158
|
+
valid_judo_id
|
159
|
+
currency 'GBP'
|
160
|
+
|
161
|
+
client_details do
|
162
|
+
{
|
163
|
+
:key => 'someValidKey',
|
164
|
+
:value => 'someValidValue'
|
165
|
+
}
|
166
|
+
end
|
167
|
+
|
168
|
+
pk_payment do
|
169
|
+
{
|
170
|
+
:token => {
|
171
|
+
:payment_instrument_name => 'Visa 9911',
|
172
|
+
:payment_network => 'Visa',
|
173
|
+
:payment_data => {
|
174
|
+
:version => 'EC_v1',
|
175
|
+
:data => 'someData',
|
176
|
+
:signature => 'someData',
|
177
|
+
:header => {
|
178
|
+
:ephemeralPublicKey => 'someData',
|
179
|
+
:publicKeyHash => 'someData',
|
180
|
+
:transactionId => 'someData'
|
181
|
+
}
|
182
|
+
}
|
183
|
+
},
|
184
|
+
:billing_address => nil,
|
185
|
+
:shipping_address => nil
|
186
|
+
}
|
187
|
+
end
|
188
|
+
end
|
189
|
+
factory :android_payment, :class => Judopay::AndroidPayment do
|
190
|
+
payment_details
|
191
|
+
valid_judo_id
|
192
|
+
currency 'GBP'
|
193
|
+
|
194
|
+
wallet do
|
195
|
+
{
|
196
|
+
:encrypted_message => 'ZW5jcnlwdGVkTWVzc2FnZQ==',
|
197
|
+
:environment => 3,
|
198
|
+
:ephemeral_public_key => 'ZXBoZW1lcmFsUHVibGljS2V5',
|
199
|
+
:google_transaction_id => '123456789',
|
200
|
+
:instrument_details => '1234',
|
201
|
+
:instrument_type => 'VISA',
|
202
|
+
:public_key => 'someKey',
|
203
|
+
:tag => 'c2lnbmF0dXJl',
|
204
|
+
:version => 1
|
205
|
+
}
|
206
|
+
end
|
207
|
+
end
|
148
208
|
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
{
|
2
|
+
"receiptId": "xxxxxxx",
|
3
|
+
"yourPaymentReference": "xxxxxxxxxxxxxxxxxxxxxx",
|
4
|
+
"type": "Payment",
|
5
|
+
"createdAt": "2016-11-03T15:02:26.8290+00:00",
|
6
|
+
"result": "Success",
|
7
|
+
"message": "AuthCode: xxxxxx",
|
8
|
+
"judoId": "xxxxxxxxx",
|
9
|
+
"merchantName": "xxxxxxxxxxxx",
|
10
|
+
"appearsOnStatementAs": "xxxxxxxxxxxxx",
|
11
|
+
"originalAmount": "0.02",
|
12
|
+
"netAmount": "0.02",
|
13
|
+
"amount": "0.02",
|
14
|
+
"currency": "GBP",
|
15
|
+
"cardDetails": {
|
16
|
+
"cardLastfour": "xxxx",
|
17
|
+
"endDate": "xxxx",
|
18
|
+
"cardToken": "xxxx",
|
19
|
+
"cardType": 1
|
20
|
+
},
|
21
|
+
"consumer": {
|
22
|
+
"consumerToken": "xxxxxxxxxxxxxx",
|
23
|
+
"yourConsumerReference": "xxxxxxxxxxxxxxxx"
|
24
|
+
},
|
25
|
+
"walletType": 2
|
26
|
+
}
|
@@ -0,0 +1,26 @@
|
|
1
|
+
{
|
2
|
+
"receiptId": "someReceipt",
|
3
|
+
"yourPaymentReference": "NEW_PR_123123123",
|
4
|
+
"type": "Payment",
|
5
|
+
"createdAt": "2016-10-31T10:09:10.4378+00:00",
|
6
|
+
"result": "Success",
|
7
|
+
"message": "AuthCode: xxxxxx",
|
8
|
+
"judoId": "someId",
|
9
|
+
"merchantName": "PiePay Project",
|
10
|
+
"appearsOnStatementAs": "APL*\/PiePayProject ",
|
11
|
+
"originalAmount": "0.02",
|
12
|
+
"netAmount": "0.02",
|
13
|
+
"amount": "0.02",
|
14
|
+
"currency": "GBP",
|
15
|
+
"cardDetails": {
|
16
|
+
"cardLastfour": "xxxx",
|
17
|
+
"endDate": "xxxx",
|
18
|
+
"cardToken": "xxxxxxxxxxxxxx",
|
19
|
+
"cardType": 1
|
20
|
+
},
|
21
|
+
"consumer": {
|
22
|
+
"consumerToken": "xxxxxxxxx",
|
23
|
+
"yourConsumerReference": "Myconsumerref"
|
24
|
+
},
|
25
|
+
"walletType": 1
|
26
|
+
}
|
@@ -0,0 +1,74 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require_relative '../../lib/judopay/models/android_payment'
|
3
|
+
|
4
|
+
describe Judopay::AndroidPayment do
|
5
|
+
it 'should create a new payment given wallet object' do
|
6
|
+
stub_post('/transactions/payments').
|
7
|
+
to_return(:status => 200,
|
8
|
+
:body => lambda { |_request| fixture('transactions/android_payment.json') })
|
9
|
+
|
10
|
+
payment = build(:android_payment)
|
11
|
+
response = payment.create
|
12
|
+
|
13
|
+
expect(response).to be_a(Hash)
|
14
|
+
expect(response.result).to eq('Success')
|
15
|
+
end
|
16
|
+
|
17
|
+
it 'should return a bad request exception if basic validation fails' do
|
18
|
+
expect(lambda do
|
19
|
+
Judopay::AndroidPayment.new.create
|
20
|
+
end).to raise_error(Judopay::ValidationError)
|
21
|
+
end
|
22
|
+
|
23
|
+
it 'should use the configured Judo ID if one isn\'t provided in the payment request' do
|
24
|
+
stub_post('/transactions/payments').
|
25
|
+
to_return(:status => 200,
|
26
|
+
:body => lambda { |_request| fixture('transactions/android_payment.json') })
|
27
|
+
|
28
|
+
Judopay.configure do |config|
|
29
|
+
config.judo_id = '123-456'
|
30
|
+
end
|
31
|
+
|
32
|
+
payment = build(:android_payment, :judo_id => nil)
|
33
|
+
payment.create
|
34
|
+
|
35
|
+
expect(payment.valid?).to eq(true)
|
36
|
+
expect(payment.judo_id).to eq('123-456')
|
37
|
+
end
|
38
|
+
|
39
|
+
it 'properly coerces wallet field from_json' do
|
40
|
+
json_string = '{"wallet":{"encryptedMessage":"SomeBase64encodedData","environment":1,'\
|
41
|
+
'"ephemeralPublicKey":"SomeBase64encodedData","googleTransactionId":"someId",'\
|
42
|
+
'"instrumentDetails":"1234","instrumentType":"VISA","publicKey":"SomeBase64encodedData",'\
|
43
|
+
'"tag":"SomeBase64encodedData","version":1}}'
|
44
|
+
|
45
|
+
wallet = Judopay::Wallet.new(
|
46
|
+
:encrypted_message => 'SomeBase64encodedData',
|
47
|
+
:environment => 1,
|
48
|
+
:ephemeral_public_key => 'SomeBase64encodedData',
|
49
|
+
:google_transaction_id => 'someId',
|
50
|
+
:instrument_details => '1234',
|
51
|
+
:instrument_type => 'VISA',
|
52
|
+
:publicKey => 'SomeBase64encodedData',
|
53
|
+
:tag => 'SomeBase64encodedData',
|
54
|
+
:version => 1
|
55
|
+
)
|
56
|
+
|
57
|
+
payment = build(:android_payment, :wallet => json_string)
|
58
|
+
expect(payment.wallet).to be == wallet
|
59
|
+
end
|
60
|
+
|
61
|
+
it 'should raise an error when bad wallet passed' do
|
62
|
+
expect(lambda do
|
63
|
+
Judopay::AndroidPayment.new(:wallet => '{"someInvalidJson}}')
|
64
|
+
end).to raise_error(Judopay::ValidationError, format(Judopay::Wallet::WRONG_JSON_ERROR_MESSAGE, 'Judopay::Wallet'))
|
65
|
+
|
66
|
+
expect(lambda do
|
67
|
+
Judopay::AndroidPayment.new(:wallet => 1)
|
68
|
+
end).to raise_error(Judopay::ValidationError, format(Judopay::Wallet::WRONG_OBJECT_ERROR_MESSAGE, 'Judopay::Wallet'))
|
69
|
+
|
70
|
+
expect(lambda do
|
71
|
+
build(:android_payment, :wallet => '{"valid_json":"Without token field"}').create
|
72
|
+
end).to raise_error(Judopay::ValidationError)
|
73
|
+
end
|
74
|
+
end
|
@@ -0,0 +1,80 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'json'
|
3
|
+
require_relative '../../lib/judopay/models/apple_payment'
|
4
|
+
|
5
|
+
describe Judopay::ApplePayment do
|
6
|
+
it 'should create a new payment given pk_payment object' do
|
7
|
+
stub_post('/transactions/payments').
|
8
|
+
to_return(:status => 200,
|
9
|
+
:body => lambda { |_request| fixture('transactions/apple_payment.json') })
|
10
|
+
|
11
|
+
payment = build(:apple_payment)
|
12
|
+
response = payment.create
|
13
|
+
|
14
|
+
expect(response).to be_a(Hash)
|
15
|
+
expect(response.result).to eq('Success')
|
16
|
+
end
|
17
|
+
|
18
|
+
it 'should return a bad request exception if basic validation fails' do
|
19
|
+
expect(lambda do
|
20
|
+
Judopay::ApplePayment.new.create
|
21
|
+
end).to raise_error(Judopay::ValidationError)
|
22
|
+
end
|
23
|
+
|
24
|
+
it 'should use the configured Judo ID if one isn\'t provided in the payment request' do
|
25
|
+
stub_post('/transactions/payments').
|
26
|
+
to_return(:status => 200,
|
27
|
+
:body => lambda { |_request| fixture('transactions/apple_payment.json') })
|
28
|
+
|
29
|
+
Judopay.configure do |config|
|
30
|
+
config.judo_id = '123-456'
|
31
|
+
end
|
32
|
+
|
33
|
+
payment = build(:apple_payment, :judo_id => nil)
|
34
|
+
payment.create
|
35
|
+
|
36
|
+
expect(payment.valid?).to eq(true)
|
37
|
+
expect(payment.judo_id).to eq('123-456')
|
38
|
+
end
|
39
|
+
|
40
|
+
it 'properly coerces pk_payment field from_json' do
|
41
|
+
json_string = '{"pkPayment":{"token":{"paymentInstrumentName":"Visa XXXX","paymentNetwork":"Visa","paymentData"'\
|
42
|
+
':{"version":"EC_v1","data":"SomeBase64encodedData","signature":"SomeBase64encodedData","header":{"ephemeralPublicKey"'\
|
43
|
+
':"someKey","publicKeyHash":"someKey","transactionId":"someId"}}},"billingAddress":1,"shippingAddress":2}}'
|
44
|
+
pk_payment = Judopay::PkPayment.new(
|
45
|
+
:token => Judopay::PkPaymentToken.new(
|
46
|
+
:payment_instrument_name => 'Visa XXXX',
|
47
|
+
:payment_network => 'Visa',
|
48
|
+
:payment_data => {
|
49
|
+
'version' => 'EC_v1',
|
50
|
+
'data' => 'SomeBase64encodedData',
|
51
|
+
'signature' => 'SomeBase64encodedData',
|
52
|
+
'header' => {
|
53
|
+
'ephemeral_public_key' => 'someKey',
|
54
|
+
'public_key_hash' => 'someKey',
|
55
|
+
'transaction_id' => 'someId'
|
56
|
+
}
|
57
|
+
}
|
58
|
+
),
|
59
|
+
:billing_address => '1',
|
60
|
+
:shipping_address => '2'
|
61
|
+
)
|
62
|
+
|
63
|
+
payment = build(:apple_payment, :pk_payment => json_string)
|
64
|
+
expect(payment.pk_payment).to be == pk_payment
|
65
|
+
end
|
66
|
+
|
67
|
+
it 'should raise an error when bad pk_payment passed' do
|
68
|
+
expect(lambda do
|
69
|
+
Judopay::ApplePayment.new(:pk_payment => '{"someInvalidJson}}')
|
70
|
+
end).to raise_error(Judopay::ValidationError, format(Judopay::PkPayment::WRONG_JSON_ERROR_MESSAGE, 'Judopay::PkPayment'))
|
71
|
+
|
72
|
+
expect(lambda do
|
73
|
+
Judopay::ApplePayment.new(:pk_payment => 1)
|
74
|
+
end).to raise_error(Judopay::ValidationError, format(Judopay::PkPayment::WRONG_OBJECT_ERROR_MESSAGE, 'Judopay::PkPayment'))
|
75
|
+
|
76
|
+
expect(lambda do
|
77
|
+
build(:apple_payment, :pk_payment => '{"valid_json":"Without token field"}').create
|
78
|
+
end).to raise_error(Judopay::ValidationError)
|
79
|
+
end
|
80
|
+
end
|
data/test/base/payments_tests.rb
CHANGED
@@ -37,4 +37,11 @@ module PaymentTests
|
|
37
37
|
get_model(:your_consumer_reference => nil).create
|
38
38
|
end
|
39
39
|
end
|
40
|
+
|
41
|
+
def test_duplicate_payment
|
42
|
+
model = get_model
|
43
|
+
TestHelpers::AssertionHelper.assert_successful_payment(model.create)
|
44
|
+
|
45
|
+
TestHelpers::AssertionHelper.api_exception_with_errors(1, 86, 409, 4) { model.create }
|
46
|
+
end
|
40
47
|
end
|
@@ -88,4 +88,11 @@ module TokenPaymentTests
|
|
88
88
|
get_model(:your_consumer_reference => nil, :cv2 => nil).create
|
89
89
|
end
|
90
90
|
end
|
91
|
+
|
92
|
+
def test_duplicate_payment
|
93
|
+
model = get_model
|
94
|
+
TestHelpers::AssertionHelper.assert_successful_payment(model.create)
|
95
|
+
|
96
|
+
TestHelpers::AssertionHelper.api_exception_with_errors(1, 86, 409, 4) { model.create }
|
97
|
+
end
|
91
98
|
end
|
data/test/register_card_test.rb
CHANGED
@@ -19,6 +19,12 @@ class RegisterCardTest < IntegrationBase
|
|
19
19
|
assert_equal('1.01', result['amount'])
|
20
20
|
end
|
21
21
|
|
22
|
+
def test_payment_without_currency
|
23
|
+
result = get_model(:currency => nil).create
|
24
|
+
|
25
|
+
TestHelpers::AssertionHelper.assert_successful_payment(result)
|
26
|
+
end
|
27
|
+
|
22
28
|
def test_payment_with_negative_amount
|
23
29
|
# Unneeded test
|
24
30
|
assert_true(true)
|
@@ -29,9 +35,8 @@ class RegisterCardTest < IntegrationBase
|
|
29
35
|
assert_true(true)
|
30
36
|
end
|
31
37
|
|
32
|
-
def
|
33
|
-
|
34
|
-
|
35
|
-
TestHelpers::AssertionHelper.assert_successful_payment(result)
|
38
|
+
def test_duplicate_payment
|
39
|
+
# Unneeded test
|
40
|
+
assert_true(true)
|
36
41
|
end
|
37
42
|
end
|
data/test/void_test.rb
CHANGED
@@ -24,6 +24,7 @@ class VoidTest < IntegrationBase
|
|
24
24
|
response = void.create
|
25
25
|
|
26
26
|
TestHelpers::AssertionHelper.assert_successful_payment(response)
|
27
|
+
void.your_payment_reference = SecureRandom.hex(18) + Time.now.to_i.to_s
|
27
28
|
TestHelpers::AssertionHelper.api_exception_with_errors(0, 51) { void.create }
|
28
29
|
end
|
29
30
|
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: judopay
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.0
|
4
|
+
version: 2.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
|
-
-
|
7
|
+
- Judopay
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2016-
|
11
|
+
date: 2016-11-11 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rspec
|
@@ -254,7 +254,7 @@ files:
|
|
254
254
|
- ".yardopts"
|
255
255
|
- CHANGELOG.md
|
256
256
|
- Gemfile
|
257
|
-
- LICENSE
|
257
|
+
- LICENSE
|
258
258
|
- README.md
|
259
259
|
- Rakefile
|
260
260
|
- judopay.gemspec
|
@@ -270,11 +270,18 @@ files:
|
|
270
270
|
- lib/judopay/error.rb
|
271
271
|
- lib/judopay/mash.rb
|
272
272
|
- lib/judopay/model.rb
|
273
|
+
- lib/judopay/models/android_payment.rb
|
274
|
+
- lib/judopay/models/android_preauth.rb
|
275
|
+
- lib/judopay/models/apple_payment.rb
|
276
|
+
- lib/judopay/models/apple_preauth.rb
|
273
277
|
- lib/judopay/models/card_address.rb
|
274
278
|
- lib/judopay/models/card_payment.rb
|
275
279
|
- lib/judopay/models/card_preauth.rb
|
276
280
|
- lib/judopay/models/collection.rb
|
277
|
-
- lib/judopay/models/
|
281
|
+
- lib/judopay/models/inner/pk_payment.rb
|
282
|
+
- lib/judopay/models/inner/pk_payment_token.rb
|
283
|
+
- lib/judopay/models/inner/transmitted_field.rb
|
284
|
+
- lib/judopay/models/inner/wallet.rb
|
278
285
|
- lib/judopay/models/market/collection.rb
|
279
286
|
- lib/judopay/models/market/payment.rb
|
280
287
|
- lib/judopay/models/market/preauth.rb
|
@@ -307,6 +314,8 @@ files:
|
|
307
314
|
- spec/fixtures/card_payments/validate.json
|
308
315
|
- spec/fixtures/token_payments/create.json
|
309
316
|
- spec/fixtures/transactions/all.json
|
317
|
+
- spec/fixtures/transactions/android_payment.json
|
318
|
+
- spec/fixtures/transactions/apple_payment.json
|
310
319
|
- spec/fixtures/transactions/find.json
|
311
320
|
- spec/fixtures/transactions/find_not_found.json
|
312
321
|
- spec/fixtures/transactions/register_card.json
|
@@ -314,6 +323,8 @@ files:
|
|
314
323
|
- spec/fixtures/transactions/void.json
|
315
324
|
- spec/fixtures/web_payments/payments/create.json
|
316
325
|
- spec/fixtures/web_payments/payments/find.json
|
326
|
+
- spec/judopay/android_payment_spec.rb
|
327
|
+
- spec/judopay/apple_payment_spec.rb
|
317
328
|
- spec/judopay/card_address_spec.rb
|
318
329
|
- spec/judopay/card_payment_spec.rb
|
319
330
|
- spec/judopay/card_preauth_spec.rb
|
@@ -353,8 +364,6 @@ files:
|
|
353
364
|
- test/token_payment_test.rb
|
354
365
|
- test/token_preauth_test.rb
|
355
366
|
- test/void_test.rb
|
356
|
-
- tutorials/judo_getting_started.md
|
357
|
-
- tutorials/judo_making_a_payment.md
|
358
367
|
homepage: http://www.judopay.com
|
359
368
|
licenses:
|
360
369
|
- MIT
|
@@ -378,7 +387,7 @@ rubyforge_project:
|
|
378
387
|
rubygems_version: 2.5.1
|
379
388
|
signing_key:
|
380
389
|
specification_version: 4
|
381
|
-
summary: Ruby
|
390
|
+
summary: Ruby gem for using the Judopay API
|
382
391
|
test_files:
|
383
392
|
- spec/factories.rb
|
384
393
|
- spec/faraday/response_spec.rb
|
@@ -389,6 +398,8 @@ test_files:
|
|
389
398
|
- spec/fixtures/card_payments/validate.json
|
390
399
|
- spec/fixtures/token_payments/create.json
|
391
400
|
- spec/fixtures/transactions/all.json
|
401
|
+
- spec/fixtures/transactions/android_payment.json
|
402
|
+
- spec/fixtures/transactions/apple_payment.json
|
392
403
|
- spec/fixtures/transactions/find.json
|
393
404
|
- spec/fixtures/transactions/find_not_found.json
|
394
405
|
- spec/fixtures/transactions/register_card.json
|
@@ -396,6 +407,8 @@ test_files:
|
|
396
407
|
- spec/fixtures/transactions/void.json
|
397
408
|
- spec/fixtures/web_payments/payments/create.json
|
398
409
|
- spec/fixtures/web_payments/payments/find.json
|
410
|
+
- spec/judopay/android_payment_spec.rb
|
411
|
+
- spec/judopay/apple_payment_spec.rb
|
399
412
|
- spec/judopay/card_address_spec.rb
|
400
413
|
- spec/judopay/card_payment_spec.rb
|
401
414
|
- spec/judopay/card_preauth_spec.rb
|
data/LICENSE.txt
DELETED
@@ -1,22 +0,0 @@
|
|
1
|
-
Copyright (c) 2016 Alternative Payments Ltd
|
2
|
-
|
3
|
-
MIT License
|
4
|
-
|
5
|
-
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
-
a copy of this software and associated documentation files (the
|
7
|
-
"Software"), to deal in the Software without restriction, including
|
8
|
-
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
-
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
-
permit persons to whom the Software is furnished to do so, subject to
|
11
|
-
the following conditions:
|
12
|
-
|
13
|
-
The above copyright notice and this permission notice shall be
|
14
|
-
included in all copies or substantial portions of the Software.
|
15
|
-
|
16
|
-
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
-
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
-
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
-
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
-
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
-
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
-
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
@@ -1,74 +0,0 @@
|
|
1
|
-
# Getting started - Ruby
|
2
|
-
|
3
|
-
[Include standard create account/getting started sections]
|
4
|
-
|
5
|
-
## Installation
|
6
|
-
|
7
|
-
The Judopay gem supports Ruby 1.9.3 and above (including 2.0.x and 2.1.x).
|
8
|
-
|
9
|
-
Add this line to your application's Gemfile:
|
10
|
-
|
11
|
-
gem 'judopay'
|
12
|
-
|
13
|
-
And then execute:
|
14
|
-
|
15
|
-
$ bundle
|
16
|
-
|
17
|
-
Or install it yourself as:
|
18
|
-
|
19
|
-
$ gem install judopay
|
20
|
-
|
21
|
-
## Dependencies
|
22
|
-
|
23
|
-
These will all be automatically installed for you when you install the Judopay gem.
|
24
|
-
|
25
|
-
### virtus
|
26
|
-
https://github.com/solnic/virtus
|
27
|
-
Provides a common API for defining attributes on a model
|
28
|
-
|
29
|
-
### httpclient
|
30
|
-
https://github.com/nahi/httpclient
|
31
|
-
HTTP client adaptor used by Faraday
|
32
|
-
|
33
|
-
### activemodel
|
34
|
-
https://github.com/rails/rails/tree/master/activemodel
|
35
|
-
Provides pre-request validation of user input
|
36
|
-
|
37
|
-
### faraday
|
38
|
-
https://github.com/lostisland/faraday
|
39
|
-
Simple, but flexible HTTP client library
|
40
|
-
|
41
|
-
### rash
|
42
|
-
https://github.com/tcocca/rash
|
43
|
-
Extension to Hashie::Mash to convert all keys in the hash to underscore
|
44
|
-
|
45
|
-
### addressable
|
46
|
-
https://github.com/sporkmonger/addressable
|
47
|
-
Used for generation of URIs
|
48
|
-
|
49
|
-
# Configuration
|
50
|
-
|
51
|
-
You configure the Judopay gem by passing a block. For example:
|
52
|
-
|
53
|
-
Judopay.configure do |config|
|
54
|
-
config.judo_id = 12345
|
55
|
-
end
|
56
|
-
|
57
|
-
# Authentication
|
58
|
-
You can authenticate either with basic authentication by passing your login and password credentials or using an existing OAuth2 access token.
|
59
|
-
|
60
|
-
### Basic authentication
|
61
|
-
|
62
|
-
Judopay.configure do |config|
|
63
|
-
config.judo_id = 12345
|
64
|
-
config.api_token = 'your-token'
|
65
|
-
config.api_secret = 'your-secret'
|
66
|
-
end
|
67
|
-
|
68
|
-
### OAuth2 access token authentication
|
69
|
-
|
70
|
-
Judopay.configure do |config|
|
71
|
-
config.judo_id = 12345
|
72
|
-
config.oauth_access_token = 'your-oauth-token'
|
73
|
-
end
|
74
|
-
|
@@ -1,84 +0,0 @@
|
|
1
|
-
# Making a payment - Ruby
|
2
|
-
|
3
|
-
First, configure Judopay with your authentication credentials (as described in the Getting Started guide).
|
4
|
-
|
5
|
-
Judopay.configure do |config|
|
6
|
-
config.api_token = 'your-token'
|
7
|
-
config.api_secret = 'your-secret'
|
8
|
-
end
|
9
|
-
|
10
|
-
To make a new payment with full card details, create a new Judopay::Payment. You can check on the required fields and the format of each field in the _Judopay REST API reference_.
|
11
|
-
|
12
|
-
transaction = Judopay::Payment.new(
|
13
|
-
:your_consumer_reference => '123',
|
14
|
-
:your_payment_reference => '456',
|
15
|
-
:judo_id => '123-456-789',
|
16
|
-
:amount => 5.01,
|
17
|
-
:card_number => '4976000000003436',
|
18
|
-
:expiry_date => '12/15',
|
19
|
-
:cv2 => '452',
|
20
|
-
:card_address => {
|
21
|
-
:line1 => '32 Edward Street',
|
22
|
-
:town => 'Camborne',
|
23
|
-
:postcode => 'TR14 8PA'
|
24
|
-
},
|
25
|
-
:consumer_location => {
|
26
|
-
:latitude => 51.5033630,
|
27
|
-
:longitude => -0.1276250
|
28
|
-
}
|
29
|
-
)
|
30
|
-
|
31
|
-
To send the request to the API, call:
|
32
|
-
|
33
|
-
response = payment.create
|
34
|
-
|
35
|
-
If the payment is successful, you'll receive a response like this:
|
36
|
-
|
37
|
-
#<Judopay::Mash amount=5.01 appears_on_statement_as="JudoPay/XXX" card_details=#<Judopay::Mash card_lastfour="3436" card_token="WidQ0QXs4VMloCCerfGFHQkLVFwbwjVc" card_type=1 end_date="1215"> consumer=#<Judopay::Mash consumer_token="rFl6UUihdSfpJt3x" your_consumer_reference="123"> created_at="2014-07-08T15:49:10.8587+01:00" currency="GBP" judo_id=100978394 merchant_name="XXXX" message="AuthCode: 570320" net_amount=5.01 original_amount=5.01 receipt_id="465377" result="Success" type="Payment">
|
38
|
-
|
39
|
-
The Judopay::Mash object behaves like a traditional Hash, but with extra special powers. See:
|
40
|
-
|
41
|
-
http://www.intridea.com/blog/2008/4/12/mash-mocking-hash-for-total-poser-objects
|
42
|
-
|
43
|
-
## Error handling
|
44
|
-
|
45
|
-
When making a payment, there are a number of different scenarios that can arise. It is important to handle all of the different exceptions in your code.
|
46
|
-
|
47
|
-
begin
|
48
|
-
response = payment.create
|
49
|
-
rescue Judopay::ValidationError => e
|
50
|
-
puts e.message
|
51
|
-
puts e.model_errors.inspect # Hash of validation errors
|
52
|
-
rescue Judopay::BadRequest => e
|
53
|
-
# Invalid parameters were supplied to Judopay's API
|
54
|
-
puts e.message
|
55
|
-
puts e.model_errors.inspect # Hash of validation errors
|
56
|
-
rescue Judopay::NotAuthorized => e
|
57
|
-
# You're not authorized to make the request - check credentials and permissions in the Judopay portal
|
58
|
-
rescue Judopay::NotFound => e
|
59
|
-
# The resource was not found
|
60
|
-
rescue Judopay::Conflict => e
|
61
|
-
# Rate limiting - you have made too many requests to the Judopay API
|
62
|
-
rescue Judopay::Error => e
|
63
|
-
# There was a problem connecting to the API
|
64
|
-
rescue => e
|
65
|
-
# A problem occurred outside the Judopay gem
|
66
|
-
end
|
67
|
-
|
68
|
-
## Logging
|
69
|
-
|
70
|
-
To help you debug your Judopay integration, you can attach a logger to the gem.
|
71
|
-
|
72
|
-
For example, to log debug messages to the file 'log.txt':
|
73
|
-
|
74
|
-
logger = Logger.new('log.txt')
|
75
|
-
logger.level = Logger::DEBUG
|
76
|
-
Judopay.configure do |config|
|
77
|
-
config.logger = logger
|
78
|
-
end
|
79
|
-
|
80
|
-
If you're using Rails, you use the built-in logger to write to your existing application log file:
|
81
|
-
|
82
|
-
Judopay.configure do |config|
|
83
|
-
config.logger = Rails.logger
|
84
|
-
end
|