payu-latam 1.0.5 → 1.0.6
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/.rubocop.yml +1 -1
- data/README.md +162 -1
- data/lib/pay_u.rb +11 -0
- data/lib/pay_u/client.rb +87 -0
- data/lib/pay_u/configuration.rb +4 -0
- data/lib/pay_u/constants.rb +4 -2
- data/lib/pay_u/credit_card.rb +35 -0
- data/lib/pay_u/customer.rb +34 -0
- data/lib/pay_u/errors.rb +7 -0
- data/lib/pay_u/form.rb +1 -1
- data/lib/pay_u/plan.rb +67 -0
- data/lib/pay_u/resource.rb +81 -0
- data/lib/pay_u/subscription.rb +57 -0
- data/lib/pay_u/util/string.rb +12 -0
- data/lib/pay_u/version.rb +2 -1
- data/payu-latam.gemspec +1 -0
- data/spec/fixtures/credit_card.rb +12 -0
- data/spec/fixtures/plan.rb +15 -0
- data/spec/fixtures/responses/customer.json +5 -0
- data/spec/fixtures/responses/plan.json +18 -0
- data/spec/fixtures/responses/plan_not_found.json +4 -0
- data/spec/fixtures/responses/subscription.json +29 -0
- data/spec/helpers/stub.rb +35 -0
- data/spec/pay_u/configuration_spec.rb +4 -0
- data/spec/pay_u/confirmation_spec.rb +0 -1
- data/spec/pay_u/credit_card_spec.rb +21 -0
- data/spec/pay_u/form_spec.rb +0 -4
- data/spec/pay_u/plan_spec.rb +64 -0
- data/spec/pay_u/response_spec.rb +0 -1
- data/spec/pay_u/subscription_spec.rb +58 -0
- data/spec/spec_helper.rb +6 -0
- metadata +44 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: bc5ce65d0810e098497cd40608afac89a03abb5dbc95d56bd14cedda3ff6684f
|
|
4
|
+
data.tar.gz: e0ddbaa78f080c1fb1a7401ae66dfec04aa96b625c008332e129757dbe6885cc
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: f7c73c6e9c7dc40ae5301c9444fe8a72cd03c219ffc8304e3f23aa239c0d44acfac7df705dfbceae2678c3c2f70de5880a5421ad72ebd740a51c47712ec0e9ac
|
|
7
|
+
data.tar.gz: 9decca14c41d0d8250986b4500ebae9ef09ee8aba4f077d79f2099362813d96f1848128f18bbf6b2d461458b28e32e30b0429e0d8ae63c3a20a320bbe0012869
|
data/.rubocop.yml
CHANGED
data/README.md
CHANGED
|
@@ -20,17 +20,178 @@ PayU.configure do |config|
|
|
|
20
20
|
config.api_key = "4Vj8eK4rloUd272L48hsrarnUA" # Replace with your own API key
|
|
21
21
|
config.merchant_id = 508_029 # Replace with your own merchant ID
|
|
22
22
|
config.test = true # Test mode
|
|
23
|
+
config.account_ids = {
|
|
24
|
+
AR: 512_322,
|
|
25
|
+
BR: 512_327,
|
|
26
|
+
CL: 512_325,
|
|
27
|
+
CO: 512_321,
|
|
28
|
+
MX: 512_324,
|
|
29
|
+
PA: 512_326,
|
|
30
|
+
PE: 512_323,
|
|
31
|
+
}
|
|
23
32
|
end
|
|
24
33
|
|
|
25
34
|
order = PayU::Order.new(
|
|
26
35
|
amount: 20_000,
|
|
27
36
|
currency: :COP,
|
|
28
|
-
description: "Test PAYU"
|
|
37
|
+
description: "Test PAYU",
|
|
29
38
|
)
|
|
30
39
|
|
|
40
|
+
# Form params for WebCheckout
|
|
31
41
|
order.form.params
|
|
32
42
|
```
|
|
33
43
|
|
|
44
|
+
## Resources
|
|
45
|
+
|
|
46
|
+
### Order
|
|
47
|
+
|
|
48
|
+
The base object to build a transaction.
|
|
49
|
+
|
|
50
|
+
```ruby
|
|
51
|
+
#<PayU::Order:0x007f95818e5c10
|
|
52
|
+
@account_id=nil,
|
|
53
|
+
@amount=0.3e1,
|
|
54
|
+
@cc_number="************0086",
|
|
55
|
+
@currency=:USD,
|
|
56
|
+
@description=nil,
|
|
57
|
+
@email="test@test.com",
|
|
58
|
+
@extra_1="extra 1",
|
|
59
|
+
@extra_2="extra 2",
|
|
60
|
+
@extra_3="extra 3",
|
|
61
|
+
@payment_method="VISA",
|
|
62
|
+
@payment_method_code=2,
|
|
63
|
+
@reference_code="2205229",
|
|
64
|
+
@response_code=1,
|
|
65
|
+
@response_message="APPROVED",
|
|
66
|
+
@status_code=4,
|
|
67
|
+
@tax=nil,
|
|
68
|
+
@tax_return_base=nil,
|
|
69
|
+
@transaction_id="957aa79c-135d-413e-b7fc-aaaa0000cccc">
|
|
70
|
+
|
|
71
|
+
order.form # Form object
|
|
72
|
+
order.approved? # Transaction was approved
|
|
73
|
+
order.declined? # Transaction was declined
|
|
74
|
+
order.error? # Transaction failed
|
|
75
|
+
order.pending? # Transaction is pending
|
|
76
|
+
order.expired? # Transaction expired
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
### Confirmation
|
|
80
|
+
|
|
81
|
+
A confirmation object from the confirmation Webhook (POST when transaction is finalized)
|
|
82
|
+
|
|
83
|
+
```ruby
|
|
84
|
+
#<PayU::Confirmation:0x007f95818e5cb0
|
|
85
|
+
@order=#<PayU::Order:0x007f95818e5c10…> # Order object
|
|
86
|
+
@signature="cc3c8101113b056bc4b5b3d289dbb106", # Signature to verify
|
|
87
|
+
@signer=#<PayU::Signer::Confirmation:0x007f95822e3b40…>> # Signer to verify signature
|
|
88
|
+
|
|
89
|
+
confirmation.valid? # Signature is valid
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
### Response
|
|
93
|
+
|
|
94
|
+
A response object from the response Webhook (GET when the user leaves the payment page and is sent back to the commerce)
|
|
95
|
+
|
|
96
|
+
```ruby
|
|
97
|
+
#<PayU::Order:0x007f8a33bf7e48
|
|
98
|
+
@order=#<PayU::Order:0x007f8a33bf7e48…> # Order object
|
|
99
|
+
@signature="cc3c8101113b056bc4b5b3d289dbb106", # Signature to verify
|
|
100
|
+
@signer=#<PayU::Signer::Response:0x007f8a33bdf9d8…>> # Signer to verify signature
|
|
101
|
+
|
|
102
|
+
order.valid? # Signature is valid
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
### Customer
|
|
106
|
+
|
|
107
|
+
```ruby
|
|
108
|
+
PayU::Customer.create(
|
|
109
|
+
name: "Sample User Name",
|
|
110
|
+
email: "sample@sample.com",
|
|
111
|
+
)
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
### Credit card
|
|
115
|
+
|
|
116
|
+
```ruby
|
|
117
|
+
PayU::CreditCard.create(
|
|
118
|
+
name: "Sample User Name",
|
|
119
|
+
document: "1020304050",
|
|
120
|
+
number: "4242424242424242",
|
|
121
|
+
exp_month: 12,
|
|
122
|
+
exp_year: 20,
|
|
123
|
+
type: "VISA",
|
|
124
|
+
customer_id: 4ef04ef0aaaa,
|
|
125
|
+
)
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
### Plan
|
|
129
|
+
|
|
130
|
+
```ruby
|
|
131
|
+
PayU::Plan.create(
|
|
132
|
+
account_id: 512_321,
|
|
133
|
+
code: SecureRandom.hex(8),
|
|
134
|
+
description: "Plan",
|
|
135
|
+
interval: "MONTH",
|
|
136
|
+
interval_count: 1,
|
|
137
|
+
max_payments_allowed: 12,
|
|
138
|
+
payment_attempts_delay: 1,
|
|
139
|
+
data: {PLAN_VALUE: 20_000, PLAN_TAX: 0, PLAN_TAX_RETURN_BASE: 0},
|
|
140
|
+
currency: :COP,
|
|
141
|
+
)
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
### Subscription
|
|
145
|
+
|
|
146
|
+
Subscription object that ties a customer, a plan, and a credit card.
|
|
147
|
+
|
|
148
|
+
```ruby
|
|
149
|
+
#<PayU::Subscription:0x007fe0de8e4790
|
|
150
|
+
@current_period_end=2019-03-26 23:59:59 -0500,
|
|
151
|
+
@current_period_start=2019-02-27 00:00:00 -0500,
|
|
152
|
+
@customer=
|
|
153
|
+
#<PayU::Customer:0x007fe0de8d43e0
|
|
154
|
+
@credit_cards=
|
|
155
|
+
[#<PayU::CreditCard:0x007fe0de8ce288
|
|
156
|
+
@address={},
|
|
157
|
+
@customer_id=nil,
|
|
158
|
+
@document=nil,
|
|
159
|
+
@exp_month=nil,
|
|
160
|
+
@exp_year=nil,
|
|
161
|
+
@name=nil,
|
|
162
|
+
@number=nil,
|
|
163
|
+
@token="db092e5e-65aa-48c6-92b1-aaaa0000cccc",
|
|
164
|
+
@type=nil>],
|
|
165
|
+
@email="sample@sample.com",
|
|
166
|
+
@id="4ef04ef0aaaa",
|
|
167
|
+
@name="Sample User Name">,
|
|
168
|
+
@delivery_address={},
|
|
169
|
+
@extra_1=nil,
|
|
170
|
+
@extra_2=nil,
|
|
171
|
+
@id="44f09r1p5561",
|
|
172
|
+
@immediate_payment=true,
|
|
173
|
+
@installments=1,
|
|
174
|
+
@notify_url="https://example.com",
|
|
175
|
+
@plan=
|
|
176
|
+
#<PayU::Plan:0x007fe0de8d7a68
|
|
177
|
+
@account_id=512321,
|
|
178
|
+
@code="4689fe81dd927aae",
|
|
179
|
+
@currency=:COP,
|
|
180
|
+
@data={"PLAN_TAX_RETURN_BASE"=>0, "PLAN_TAX"=>0, "PLAN_VALUE"=>20000},
|
|
181
|
+
@description="Plan",
|
|
182
|
+
@id="6da3e0b5-cfb6-430d-93ef-aaaa0000cccc",
|
|
183
|
+
@interval=:MONTH,
|
|
184
|
+
@interval_count=1,
|
|
185
|
+
@max_payment_attempts=nil,
|
|
186
|
+
@max_payments_allowed=nil,
|
|
187
|
+
@max_pending_payments=nil,
|
|
188
|
+
@payment_attempts_delay=nil,
|
|
189
|
+
@trial_days=nil>,
|
|
190
|
+
@quantity=1,
|
|
191
|
+
@trial_days=nil>
|
|
192
|
+
```
|
|
193
|
+
|
|
194
|
+
|
|
34
195
|
## Sandbox
|
|
35
196
|
|
|
36
197
|
- Sandbox endpoint
|
data/lib/pay_u.rb
CHANGED
|
@@ -1,10 +1,14 @@
|
|
|
1
1
|
require "bigdecimal"
|
|
2
|
+
require "faraday"
|
|
2
3
|
require "virtus"
|
|
3
4
|
|
|
4
5
|
require "pay_u/version"
|
|
5
6
|
|
|
6
7
|
require "pay_u/constants"
|
|
7
8
|
require "pay_u/configuration"
|
|
9
|
+
require "pay_u/errors"
|
|
10
|
+
require "pay_u/util/string"
|
|
11
|
+
|
|
8
12
|
require "pay_u/signer/base"
|
|
9
13
|
require "pay_u/signer/form"
|
|
10
14
|
require "pay_u/signer/response"
|
|
@@ -13,3 +17,10 @@ require "pay_u/order"
|
|
|
13
17
|
require "pay_u/form"
|
|
14
18
|
require "pay_u/response"
|
|
15
19
|
require "pay_u/confirmation"
|
|
20
|
+
|
|
21
|
+
require "pay_u/client"
|
|
22
|
+
require "pay_u/resource"
|
|
23
|
+
require "pay_u/plan"
|
|
24
|
+
require "pay_u/credit_card"
|
|
25
|
+
require "pay_u/customer"
|
|
26
|
+
require "pay_u/subscription"
|
data/lib/pay_u/client.rb
ADDED
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
require "base64"
|
|
2
|
+
|
|
3
|
+
class PayU::Client
|
|
4
|
+
include Singleton
|
|
5
|
+
|
|
6
|
+
def initialize
|
|
7
|
+
@client ||= Faraday.new(url: PayU.configuration.api_url) do |connection|
|
|
8
|
+
connection.request :url_encoded
|
|
9
|
+
connection.response :logger if PayU.configuration.test?
|
|
10
|
+
connection.adapter Faraday.default_adapter
|
|
11
|
+
connection.basic_auth "pRRXKOl8ikMmt9u", "4Vj8eK4rloUd272L48hsrarnUA"
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
def get(url)
|
|
17
|
+
response = @client.get(&perform_request(url))
|
|
18
|
+
|
|
19
|
+
process_response(response)
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
def post(url, params: {})
|
|
24
|
+
response = @client.post(&perform_request_with_params(url, params))
|
|
25
|
+
|
|
26
|
+
process_response(response)
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
def put(url, params: {})
|
|
31
|
+
response = @client.put(&perform_request_with_params(url, params))
|
|
32
|
+
|
|
33
|
+
process_response(response)
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
def delete(url)
|
|
38
|
+
response = @client.delete(&perform_request(url))
|
|
39
|
+
|
|
40
|
+
response.success?
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
private def perform_request(url)
|
|
45
|
+
proc do |request|
|
|
46
|
+
request.url "payments-api/#{url}"
|
|
47
|
+
request.headers = request.headers.merge(default_headers)
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
private def perform_request_with_params(url, params)
|
|
53
|
+
proc do |request|
|
|
54
|
+
request.url "payments-api/#{url}"
|
|
55
|
+
request.headers = request.headers.merge(default_headers)
|
|
56
|
+
request.body = params.delete_if { |_, value| value.nil? }.to_json
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
private def process_response(response)
|
|
62
|
+
raise PayU::UnauthorizedError, "Unauthorized" if !response.success? && response.status == 401
|
|
63
|
+
|
|
64
|
+
body = JSON.parse(response.body)
|
|
65
|
+
|
|
66
|
+
return raise_error(response) unless response.success?
|
|
67
|
+
|
|
68
|
+
body
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
private def raise_error(response)
|
|
72
|
+
body = JSON.parse(response.body)
|
|
73
|
+
|
|
74
|
+
error_message = body["errorList"] ? body["errorList"].join : body["description"]
|
|
75
|
+
|
|
76
|
+
raise PayU::NotFoundError, error_message if response.status == 404
|
|
77
|
+
raise PayU::Error, error_message
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
|
|
81
|
+
private def default_headers
|
|
82
|
+
{
|
|
83
|
+
"Content-Type" => "application/json; charset=utf-8",
|
|
84
|
+
"Accept" => "application/json",
|
|
85
|
+
}
|
|
86
|
+
end
|
|
87
|
+
end
|
data/lib/pay_u/configuration.rb
CHANGED
|
@@ -8,6 +8,8 @@ module PayU
|
|
|
8
8
|
attribute :test, Boolean
|
|
9
9
|
attribute :response_url, String
|
|
10
10
|
attribute :confirmation_url, String
|
|
11
|
+
attribute :api_url, String
|
|
12
|
+
attribute :webcheckout_url, String
|
|
11
13
|
|
|
12
14
|
SANDBOX_API_KEY = "4Vj8eK4rloUd272L48hsrarnUA".freeze
|
|
13
15
|
SANDBOX_MERCHANT_ID = 508_029
|
|
@@ -28,6 +30,8 @@ module PayU
|
|
|
28
30
|
self.merchant_id = ENV.fetch("PAYU_MERCHANT_ID", SANDBOX_MERCHANT_ID) if merchant_id.nil?
|
|
29
31
|
self.test = ENV.fetch("PAYU_TEST", true) if test.nil?
|
|
30
32
|
self.account_ids = SANDBOX_ACCOUNT_IDS if account_ids.nil?
|
|
33
|
+
self.api_url = test ? PayU::TEST_API_URL : PayU::LIVE_API_URL
|
|
34
|
+
self.webcheckout_url = test ? PayU::TEST_WEBCHECKOUT_URL : PayU::LIVE_WEBCHECKOUT_URL
|
|
31
35
|
end
|
|
32
36
|
|
|
33
37
|
|
data/lib/pay_u/constants.rb
CHANGED
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
module PayU
|
|
2
|
-
|
|
3
|
-
|
|
2
|
+
TEST_API_URL = "https://sandbox.api.payulatam.com/".freeze
|
|
3
|
+
LIVE_API_URL = "https://api.payulatam.com/".freeze
|
|
4
|
+
TEST_WEBCHECKOUT_URL = "https://sandbox.checkout.payulatam.com/ppp-web-gateway-payu/".freeze
|
|
5
|
+
LIVE_WEBCHECKOUT_URL = "https://checkout.payulatam.com/ppp-web-gateway-payu/".freeze
|
|
4
6
|
end
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
class PayU::CreditCard
|
|
2
|
+
include Virtus.model
|
|
3
|
+
include PayU::Resource
|
|
4
|
+
|
|
5
|
+
ENDPOINT = "rest/v#{PayU::API_VERSION}/creditCards".freeze
|
|
6
|
+
|
|
7
|
+
attribute :token, String
|
|
8
|
+
attribute :name, String
|
|
9
|
+
attribute :document, String
|
|
10
|
+
attribute :number, String
|
|
11
|
+
attribute :exp_month, Integer
|
|
12
|
+
attribute :exp_year, Integer
|
|
13
|
+
attribute :type, String
|
|
14
|
+
attribute :address, Hash
|
|
15
|
+
attribute :customer_id, String
|
|
16
|
+
|
|
17
|
+
def to_params
|
|
18
|
+
{
|
|
19
|
+
name: name,
|
|
20
|
+
document: document,
|
|
21
|
+
number: number,
|
|
22
|
+
expMonth: exp_month,
|
|
23
|
+
expYear: exp_year,
|
|
24
|
+
type: type,
|
|
25
|
+
address: address,
|
|
26
|
+
}
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
def create_url
|
|
31
|
+
raise StandardError, "Missing customer id" unless customer_id
|
|
32
|
+
|
|
33
|
+
"#{PayU::Customer::ENDPOINT}/#{customer_id}/creditCards"
|
|
34
|
+
end
|
|
35
|
+
end
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
class PayU::Customer
|
|
2
|
+
include Virtus.model
|
|
3
|
+
include PayU::Resource
|
|
4
|
+
|
|
5
|
+
ENDPOINT = "rest/v#{PayU::API_VERSION}/customers".freeze
|
|
6
|
+
|
|
7
|
+
attribute :id, String
|
|
8
|
+
attribute :name, String
|
|
9
|
+
attribute :email, String
|
|
10
|
+
attribute :credit_cards, Array[PayU::CreditCard]
|
|
11
|
+
|
|
12
|
+
def self.new_from_api(params)
|
|
13
|
+
customer = super(params)
|
|
14
|
+
|
|
15
|
+
customer.name = params["fullName"]
|
|
16
|
+
|
|
17
|
+
if params["creditCards"]
|
|
18
|
+
customer.credit_cards = params["creditCards"].map do |credit_card|
|
|
19
|
+
PayU::CreditCard.new_from_api(credit_card)
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
customer
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
def to_params
|
|
28
|
+
{
|
|
29
|
+
fullName: name,
|
|
30
|
+
email: email,
|
|
31
|
+
creditCards: credit_cards.map(&:to_params),
|
|
32
|
+
}
|
|
33
|
+
end
|
|
34
|
+
end
|
data/lib/pay_u/errors.rb
ADDED
data/lib/pay_u/form.rb
CHANGED
data/lib/pay_u/plan.rb
ADDED
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
class PayU::Plan
|
|
2
|
+
include Virtus.model
|
|
3
|
+
include PayU::Resource
|
|
4
|
+
|
|
5
|
+
ENDPOINT = "rest/v#{PayU::API_VERSION}/plans".freeze
|
|
6
|
+
|
|
7
|
+
attribute :account_id, Integer
|
|
8
|
+
attribute :id, String
|
|
9
|
+
attribute :code, String
|
|
10
|
+
attribute :description, String
|
|
11
|
+
attribute :interval, Symbol
|
|
12
|
+
attribute :interval_count, Integer
|
|
13
|
+
attribute :max_payments_allowed, Integer
|
|
14
|
+
attribute :max_payment_attempts, Integer
|
|
15
|
+
attribute :payment_attempts_delay, Integer
|
|
16
|
+
attribute :max_pending_payments, Integer
|
|
17
|
+
attribute :trial_days, Integer
|
|
18
|
+
attribute :data, Hash
|
|
19
|
+
attribute :currency, Symbol
|
|
20
|
+
|
|
21
|
+
def self.new_from_api(params)
|
|
22
|
+
plan = super(params)
|
|
23
|
+
|
|
24
|
+
plan.code = params["planCode"]
|
|
25
|
+
plan.currency = params["additionalValues"].first["currency"].to_s
|
|
26
|
+
plan.data = params["additionalValues"].inject({}) do |memo, hash|
|
|
27
|
+
memo.merge(hash["name"].to_s => hash["value"])
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
plan
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
def to_params
|
|
35
|
+
{
|
|
36
|
+
accountId: account_id,
|
|
37
|
+
planCode: code,
|
|
38
|
+
description: description,
|
|
39
|
+
interval: interval,
|
|
40
|
+
intervalCount: interval_count,
|
|
41
|
+
maxPaymentsAllowed: max_payments_allowed,
|
|
42
|
+
paymentAttemptsDelay: payment_attempts_delay,
|
|
43
|
+
additionalValues: data.map do |name, value|
|
|
44
|
+
{name: name, value: value, currency: currency.to_s}
|
|
45
|
+
end,
|
|
46
|
+
}
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
def to_update_params
|
|
51
|
+
{
|
|
52
|
+
planCode: code,
|
|
53
|
+
description: description,
|
|
54
|
+
paymentAttemptsDelay: payment_attempts_delay,
|
|
55
|
+
maxPendingPayments: max_pending_payments,
|
|
56
|
+
maxPaymentAttempts: max_payment_attempts,
|
|
57
|
+
additionalValues: data.map do |name, value|
|
|
58
|
+
{name: name, value: value, currency: currency.to_s}
|
|
59
|
+
end,
|
|
60
|
+
}
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
private def identifier
|
|
65
|
+
code
|
|
66
|
+
end
|
|
67
|
+
end
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
module PayU::Resource
|
|
2
|
+
def self.included(base)
|
|
3
|
+
base.extend(ClassMethods)
|
|
4
|
+
end
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
def save
|
|
8
|
+
return update if id
|
|
9
|
+
|
|
10
|
+
self.attributes = self.class.create(attributes).attributes
|
|
11
|
+
|
|
12
|
+
true
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
def delete
|
|
17
|
+
self.class.client.delete url
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
def create_url
|
|
22
|
+
self.class::ENDPOINT
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
def to_update_params
|
|
27
|
+
to_params
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
private def update
|
|
32
|
+
response = self.class.client.put url, params: to_update_params
|
|
33
|
+
self.attributes = attributes.merge(self.class.new_from_api(response).attributes)
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
private def identifier
|
|
38
|
+
id
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
private def url
|
|
43
|
+
"#{self.class::ENDPOINT}/#{identifier}"
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
module ClassMethods
|
|
48
|
+
def client
|
|
49
|
+
@client ||= PayU::Client.instance
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
def new_from_api(params)
|
|
54
|
+
resource = new
|
|
55
|
+
|
|
56
|
+
resource.attributes = params.inject({}) do |memo, (key, value)|
|
|
57
|
+
local_key = key.to_underscore.to_sym
|
|
58
|
+
|
|
59
|
+
resource.respond_to?(local_key) ? memo.merge(local_key => value) : memo
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
resource
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
def retrieve(identifier)
|
|
67
|
+
response = client.get "#{self::ENDPOINT}/#{identifier}"
|
|
68
|
+
|
|
69
|
+
new_from_api(response)
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
def create(params)
|
|
74
|
+
resource = new(params)
|
|
75
|
+
|
|
76
|
+
response = client.post resource.create_url, params: resource.to_params
|
|
77
|
+
|
|
78
|
+
new_from_api(response)
|
|
79
|
+
end
|
|
80
|
+
end
|
|
81
|
+
end
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
class PayU::Subscription
|
|
2
|
+
include Virtus.model
|
|
3
|
+
include PayU::Resource
|
|
4
|
+
|
|
5
|
+
ENDPOINT = "rest/v#{PayU::API_VERSION}/subscriptions".freeze
|
|
6
|
+
|
|
7
|
+
attribute :id, String
|
|
8
|
+
attribute :quantity, Integer
|
|
9
|
+
attribute :installments, Integer
|
|
10
|
+
attribute :trial_days, Integer
|
|
11
|
+
attribute :current_period_start, Time
|
|
12
|
+
attribute :current_period_end, Time
|
|
13
|
+
attribute :immediate_payment, Boolean
|
|
14
|
+
attribute :extra_1, String
|
|
15
|
+
attribute :extra_2, String
|
|
16
|
+
attribute :delivery_address, Hash
|
|
17
|
+
attribute :notify_url, String
|
|
18
|
+
attribute :plan, PayU::Plan
|
|
19
|
+
attribute :customer, PayU::Customer
|
|
20
|
+
|
|
21
|
+
def self.new_from_api(params)
|
|
22
|
+
subscription = super(params)
|
|
23
|
+
|
|
24
|
+
subscription.extra_1 = params["extra1"]
|
|
25
|
+
subscription.extra_2 = params["extra2"]
|
|
26
|
+
subscription.current_period_start = Time.at(params["currentPeriodStart"] / 1000)
|
|
27
|
+
subscription.current_period_end = Time.at(params["currentPeriodEnd"] / 1000)
|
|
28
|
+
|
|
29
|
+
subscription.plan = PayU::Plan.new_from_api(params["plan"])
|
|
30
|
+
subscription.customer = PayU::Customer.new_from_api(params["customer"])
|
|
31
|
+
|
|
32
|
+
subscription
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
def to_params
|
|
37
|
+
{
|
|
38
|
+
quantity: quantity,
|
|
39
|
+
installments: installments,
|
|
40
|
+
trialDays: trial_days,
|
|
41
|
+
immediatePayment: immediate_payment,
|
|
42
|
+
extra1: extra_1,
|
|
43
|
+
extra2: extra_2,
|
|
44
|
+
customer: customer.to_params,
|
|
45
|
+
plan: plan.to_params,
|
|
46
|
+
deliveryAddress: delivery_address,
|
|
47
|
+
notifyUrl: notify_url,
|
|
48
|
+
}
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
def to_update_params
|
|
53
|
+
{
|
|
54
|
+
creditCardToken: customer.credit_cards.first.token,
|
|
55
|
+
}
|
|
56
|
+
end
|
|
57
|
+
end
|
data/lib/pay_u/version.rb
CHANGED
data/payu-latam.gemspec
CHANGED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
module Fixtures
|
|
2
|
+
def self.plan
|
|
3
|
+
{
|
|
4
|
+
account_id: 512_321,
|
|
5
|
+
code: SecureRandom.hex(8),
|
|
6
|
+
description: "Plan",
|
|
7
|
+
interval: "MONTH",
|
|
8
|
+
interval_count: 1,
|
|
9
|
+
max_payments_allowed: 12,
|
|
10
|
+
payment_attempts_delay: 1,
|
|
11
|
+
data: {PLAN_VALUE: 20_000, PLAN_TAX: 0, PLAN_TAX_RETURN_BASE: 0},
|
|
12
|
+
currency: :COP,
|
|
13
|
+
}
|
|
14
|
+
end
|
|
15
|
+
end
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
{
|
|
2
|
+
"id": "0bbc2f6c-c12e-41a3-b261-60fc83014fe1",
|
|
3
|
+
"planCode": "{{code}}",
|
|
4
|
+
"description": "Plan",
|
|
5
|
+
"accountId": "512321",
|
|
6
|
+
"intervalCount": 1,
|
|
7
|
+
"interval": "MONTH",
|
|
8
|
+
"maxPaymentsAllowed": 12,
|
|
9
|
+
"maxPaymentAttempts": 0,
|
|
10
|
+
"paymentAttemptsDelay": 1,
|
|
11
|
+
"maxPendingPayments": 0,
|
|
12
|
+
"trialDays": 0,
|
|
13
|
+
"additionalValues": [
|
|
14
|
+
{ "name": "PLAN_TAX", "value": 0, "currency": "COP" },
|
|
15
|
+
{ "name": "PLAN_VALUE", "value": 20000, "currency": "COP" },
|
|
16
|
+
{ "name": "PLAN_TAX_RETURN_BASE", "value": 0, "currency": "COP" }
|
|
17
|
+
]
|
|
18
|
+
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
{
|
|
2
|
+
"id": "44f09r1p5561",
|
|
3
|
+
"plan": {
|
|
4
|
+
"id": "6da3e0b5-cfb6-430d-93ef-f654eda54e16",
|
|
5
|
+
"planCode": "{{code}}",
|
|
6
|
+
"description": "Plan",
|
|
7
|
+
"accountId": "512321",
|
|
8
|
+
"intervalCount": 1,
|
|
9
|
+
"interval": "MONTH",
|
|
10
|
+
"additionalValues": [
|
|
11
|
+
{ "name": "PLAN_TAX_RETURN_BASE", "value": 0, "currency": "COP" },
|
|
12
|
+
{ "name": "PLAN_TAX", "value": 0, "currency": "COP" },
|
|
13
|
+
{ "name": "PLAN_VALUE", "value": 20000, "currency": "COP" }
|
|
14
|
+
]
|
|
15
|
+
},
|
|
16
|
+
"customer": {
|
|
17
|
+
"id": "4ef0aqk8kipn",
|
|
18
|
+
"fullName": "Sample User Name",
|
|
19
|
+
"email": "sample@sample.com",
|
|
20
|
+
"creditCards": [{ "token": "db092e5e-65aa-48c6-92b1-1b2581e93015" }]
|
|
21
|
+
},
|
|
22
|
+
"quantity": "1",
|
|
23
|
+
"installments": "1",
|
|
24
|
+
"currentPeriodStart": 1551243600000,
|
|
25
|
+
"currentPeriodEnd": 1553662799000,
|
|
26
|
+
"immediatePayment": true,
|
|
27
|
+
"deliveryAddress": {},
|
|
28
|
+
"notifyUrl": "https://example.com"
|
|
29
|
+
}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
module Helpers
|
|
2
|
+
def stub_subscription_request
|
|
3
|
+
stub_request(:post, /#{PayU::Subscription::ENDPOINT}/)
|
|
4
|
+
.to_return do |request|
|
|
5
|
+
{body: File.new("./spec/fixtures/responses/subscription.json").read
|
|
6
|
+
.gsub("{{code}}", JSON.parse(request.body)["plan"]["planCode"])}
|
|
7
|
+
end
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
def stub_plan_request
|
|
12
|
+
stub_request(:any, /#{PayU::Plan::ENDPOINT}/)
|
|
13
|
+
.to_return do |request|
|
|
14
|
+
code = if request.method == :post
|
|
15
|
+
JSON.parse(request.body)["planCode"]
|
|
16
|
+
else
|
|
17
|
+
request.uri.path.split("/").last
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
{body: File.new("./spec/fixtures/responses/plan.json").read.gsub("{{code}}", code)}
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
def stub_customer_request
|
|
26
|
+
stub_request(:post, /#{PayU::Customer::ENDPOINT}$/)
|
|
27
|
+
.to_return(body: File.new("./spec/fixtures/responses/customer.json"))
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
def stub_credit_card_request
|
|
32
|
+
stub_request(:post, %r{#{PayU::Customer::ENDPOINT}/.+/creditCards})
|
|
33
|
+
.to_return(body: {token: SecureRandom.uuid}.to_json)
|
|
34
|
+
end
|
|
35
|
+
end
|
|
@@ -3,6 +3,10 @@ require "spec_helper"
|
|
|
3
3
|
RSpec.describe PayU::Configuration do
|
|
4
4
|
let(:default_api_key) { "4Vj8eK4rloUd272L48hsrarnUA" }
|
|
5
5
|
|
|
6
|
+
after do
|
|
7
|
+
PayU.reset
|
|
8
|
+
end
|
|
9
|
+
|
|
6
10
|
it "assigns defaults" do
|
|
7
11
|
expect(PayU.configuration.api_key).to eq(default_api_key)
|
|
8
12
|
expect(PayU.configuration.test).to be_truthy
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
require "spec_helper"
|
|
2
|
+
|
|
3
|
+
RSpec.describe PayU::CreditCard do
|
|
4
|
+
before do
|
|
5
|
+
stub_customer_request
|
|
6
|
+
|
|
7
|
+
stub_credit_card_request
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
it "creates credit card token" do
|
|
11
|
+
customer = PayU::Customer.create(
|
|
12
|
+
name: "Sample User Name",
|
|
13
|
+
email: "sample@sample.com",
|
|
14
|
+
)
|
|
15
|
+
credit_card = PayU::CreditCard.create(Fixtures.credit_card.merge(customer_id: customer.id))
|
|
16
|
+
|
|
17
|
+
expect(credit_card.token).to(
|
|
18
|
+
match(/\b[0-9a-f]{8}\b-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-\b[0-9a-f]{12}\b/),
|
|
19
|
+
)
|
|
20
|
+
end
|
|
21
|
+
end
|
data/spec/pay_u/form_spec.rb
CHANGED
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
require "spec_helper"
|
|
2
|
+
|
|
3
|
+
RSpec.describe PayU::Plan do
|
|
4
|
+
before do
|
|
5
|
+
stub_request(:any, /#{PayU::Plan::ENDPOINT}/)
|
|
6
|
+
.to_return do |request|
|
|
7
|
+
code = if request.method == :post
|
|
8
|
+
JSON.parse(request.body)["planCode"]
|
|
9
|
+
else
|
|
10
|
+
request.uri.path.split("/").last
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
{body: File.new("./spec/fixtures/responses/plan.json").read.gsub("{{code}}", code)}
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
stub_request(:get, %r{#{PayU::Plan::ENDPOINT}/non-existent}).to_return(
|
|
17
|
+
status: 404,
|
|
18
|
+
body: File.new("./spec/fixtures/responses/plan_not_found.json"),
|
|
19
|
+
)
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
it "creates plan" do
|
|
23
|
+
plan = PayU::Plan.create(Fixtures.plan)
|
|
24
|
+
|
|
25
|
+
expect(plan.id).to match(/\b[0-9a-f]{8}\b-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-\b[0-9a-f]{12}\b/)
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
it "retrieves plan" do
|
|
29
|
+
code = "pro-#{SecureRandom.hex(4)}"
|
|
30
|
+
plan = PayU::Plan.create(Fixtures.plan.merge(code: code))
|
|
31
|
+
|
|
32
|
+
found_plan = PayU::Plan.retrieve(plan.code)
|
|
33
|
+
|
|
34
|
+
expect(found_plan.id).to match(plan.id)
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
it "updates plan" do
|
|
38
|
+
WebMock.disable!
|
|
39
|
+
plan = PayU::Plan.create(Fixtures.plan)
|
|
40
|
+
id = plan.id
|
|
41
|
+
description = "Description"
|
|
42
|
+
|
|
43
|
+
plan.description = description
|
|
44
|
+
plan.save
|
|
45
|
+
|
|
46
|
+
expect(plan.id).to eq(id)
|
|
47
|
+
expect(plan.description).to eq(description)
|
|
48
|
+
|
|
49
|
+
WebMock.enable!
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
it "deletes plan" do
|
|
53
|
+
WebMock.disable!
|
|
54
|
+
plan = PayU::Plan.create(Fixtures.plan)
|
|
55
|
+
|
|
56
|
+
plan.delete
|
|
57
|
+
|
|
58
|
+
expect do
|
|
59
|
+
PayU::Plan.retrieve(plan.code)
|
|
60
|
+
end.to raise_exception(PayU::NotFoundError, /Subscription plan not found/)
|
|
61
|
+
|
|
62
|
+
WebMock.enable!
|
|
63
|
+
end
|
|
64
|
+
end
|
data/spec/pay_u/response_spec.rb
CHANGED
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
require "spec_helper"
|
|
2
|
+
|
|
3
|
+
RSpec.describe PayU::CreditCard do
|
|
4
|
+
before do
|
|
5
|
+
stub_subscription_request
|
|
6
|
+
|
|
7
|
+
stub_plan_request
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
context "new plan" do
|
|
11
|
+
it "creates subscripition" do
|
|
12
|
+
plan_params = Fixtures.plan
|
|
13
|
+
subscription = PayU::Subscription.create(
|
|
14
|
+
subscription_params.merge(plan: plan_params),
|
|
15
|
+
)
|
|
16
|
+
|
|
17
|
+
expect(subscription.id).not_to be_nil
|
|
18
|
+
expect(subscription.customer.name).to eq(customer_params[:name])
|
|
19
|
+
expect(subscription.customer.email).to eq(customer_params[:email])
|
|
20
|
+
expect(subscription.plan.code).to eq(plan_params[:code])
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
context "existing plan" do
|
|
25
|
+
it "creates subscripition" do
|
|
26
|
+
plan = PayU::Plan.create(Fixtures.plan)
|
|
27
|
+
subscription = PayU::Subscription.create(subscription_params.merge(plan: {code: plan.code}))
|
|
28
|
+
|
|
29
|
+
expect(subscription.id).not_to be_nil
|
|
30
|
+
expect(subscription.customer.name).to eq(customer_params[:name])
|
|
31
|
+
expect(subscription.customer.email).to eq(customer_params[:email])
|
|
32
|
+
expect(subscription.plan.code).to eq(plan.code)
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
private def subscription_params
|
|
37
|
+
{
|
|
38
|
+
quantity: 1,
|
|
39
|
+
installments: 1,
|
|
40
|
+
trial_days: 0,
|
|
41
|
+
immediate_payment: true,
|
|
42
|
+
notify_url: "https://example.com",
|
|
43
|
+
customer: customer_params,
|
|
44
|
+
}
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
private def customer_params
|
|
48
|
+
{
|
|
49
|
+
name: "Sample User Name",
|
|
50
|
+
email: "sample@sample.com",
|
|
51
|
+
credit_cards: credit_cards_params,
|
|
52
|
+
}
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
private def credit_cards_params
|
|
56
|
+
[Fixtures.credit_card]
|
|
57
|
+
end
|
|
58
|
+
end
|
data/spec/spec_helper.rb
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
require "simplecov"
|
|
2
2
|
require "coveralls"
|
|
3
|
+
require "webmock/rspec"
|
|
3
4
|
|
|
4
5
|
SimpleCov.formatters = [
|
|
5
6
|
SimpleCov::Formatter::HTMLFormatter,
|
|
@@ -13,6 +14,9 @@ require "pry"
|
|
|
13
14
|
require "bundler/setup"
|
|
14
15
|
require "pay_u"
|
|
15
16
|
|
|
17
|
+
Dir["./spec/fixtures/*.rb"].each { |fixture| require fixture }
|
|
18
|
+
Dir["./spec/helpers/*.rb"].each { |fixture| require fixture }
|
|
19
|
+
|
|
16
20
|
if ENV["CIRCLE_ARTIFACTS"]
|
|
17
21
|
dir = File.join(ENV["CIRCLE_ARTIFACTS"], "coverage")
|
|
18
22
|
SimpleCov.coverage_dir(dir)
|
|
@@ -28,4 +32,6 @@ RSpec.configure do |config|
|
|
|
28
32
|
config.expect_with :rspec do |c|
|
|
29
33
|
c.syntax = :expect
|
|
30
34
|
end
|
|
35
|
+
|
|
36
|
+
config.include Helpers
|
|
31
37
|
end
|
metadata
CHANGED
|
@@ -1,15 +1,29 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: payu-latam
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 1.0.
|
|
4
|
+
version: 1.0.6
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Slang
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2019-
|
|
11
|
+
date: 2019-04-30 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
|
+
- !ruby/object:Gem::Dependency
|
|
14
|
+
name: faraday
|
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
|
16
|
+
requirements:
|
|
17
|
+
- - "~>"
|
|
18
|
+
- !ruby/object:Gem::Version
|
|
19
|
+
version: '0.15'
|
|
20
|
+
type: :runtime
|
|
21
|
+
prerelease: false
|
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
23
|
+
requirements:
|
|
24
|
+
- - "~>"
|
|
25
|
+
- !ruby/object:Gem::Version
|
|
26
|
+
version: '0.15'
|
|
13
27
|
- !ruby/object:Gem::Dependency
|
|
14
28
|
name: virtus
|
|
15
29
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -181,24 +195,42 @@ files:
|
|
|
181
195
|
- bin/console
|
|
182
196
|
- bin/setup
|
|
183
197
|
- lib/pay_u.rb
|
|
198
|
+
- lib/pay_u/client.rb
|
|
184
199
|
- lib/pay_u/configuration.rb
|
|
185
200
|
- lib/pay_u/confirmation.rb
|
|
186
201
|
- lib/pay_u/constants.rb
|
|
202
|
+
- lib/pay_u/credit_card.rb
|
|
203
|
+
- lib/pay_u/customer.rb
|
|
204
|
+
- lib/pay_u/errors.rb
|
|
187
205
|
- lib/pay_u/form.rb
|
|
188
206
|
- lib/pay_u/order.rb
|
|
207
|
+
- lib/pay_u/plan.rb
|
|
208
|
+
- lib/pay_u/resource.rb
|
|
189
209
|
- lib/pay_u/response.rb
|
|
190
210
|
- lib/pay_u/signer/base.rb
|
|
191
211
|
- lib/pay_u/signer/confirmation.rb
|
|
192
212
|
- lib/pay_u/signer/form.rb
|
|
193
213
|
- lib/pay_u/signer/response.rb
|
|
214
|
+
- lib/pay_u/subscription.rb
|
|
215
|
+
- lib/pay_u/util/string.rb
|
|
194
216
|
- lib/pay_u/version.rb
|
|
195
217
|
- payu-latam.gemspec
|
|
196
218
|
- spec/fixtures/confirmation.rb
|
|
219
|
+
- spec/fixtures/credit_card.rb
|
|
220
|
+
- spec/fixtures/plan.rb
|
|
197
221
|
- spec/fixtures/response.rb
|
|
222
|
+
- spec/fixtures/responses/customer.json
|
|
223
|
+
- spec/fixtures/responses/plan.json
|
|
224
|
+
- spec/fixtures/responses/plan_not_found.json
|
|
225
|
+
- spec/fixtures/responses/subscription.json
|
|
226
|
+
- spec/helpers/stub.rb
|
|
198
227
|
- spec/pay_u/configuration_spec.rb
|
|
199
228
|
- spec/pay_u/confirmation_spec.rb
|
|
229
|
+
- spec/pay_u/credit_card_spec.rb
|
|
200
230
|
- spec/pay_u/form_spec.rb
|
|
231
|
+
- spec/pay_u/plan_spec.rb
|
|
201
232
|
- spec/pay_u/response_spec.rb
|
|
233
|
+
- spec/pay_u/subscription_spec.rb
|
|
202
234
|
- spec/pay_u_spec.rb
|
|
203
235
|
- spec/spec_helper.rb
|
|
204
236
|
homepage: https://slangapp.com
|
|
@@ -227,10 +259,20 @@ specification_version: 4
|
|
|
227
259
|
summary: Ruby bindings for the PayU Latam API
|
|
228
260
|
test_files:
|
|
229
261
|
- spec/fixtures/confirmation.rb
|
|
262
|
+
- spec/fixtures/credit_card.rb
|
|
263
|
+
- spec/fixtures/plan.rb
|
|
230
264
|
- spec/fixtures/response.rb
|
|
265
|
+
- spec/fixtures/responses/customer.json
|
|
266
|
+
- spec/fixtures/responses/plan.json
|
|
267
|
+
- spec/fixtures/responses/plan_not_found.json
|
|
268
|
+
- spec/fixtures/responses/subscription.json
|
|
269
|
+
- spec/helpers/stub.rb
|
|
231
270
|
- spec/pay_u/configuration_spec.rb
|
|
232
271
|
- spec/pay_u/confirmation_spec.rb
|
|
272
|
+
- spec/pay_u/credit_card_spec.rb
|
|
233
273
|
- spec/pay_u/form_spec.rb
|
|
274
|
+
- spec/pay_u/plan_spec.rb
|
|
234
275
|
- spec/pay_u/response_spec.rb
|
|
276
|
+
- spec/pay_u/subscription_spec.rb
|
|
235
277
|
- spec/pay_u_spec.rb
|
|
236
278
|
- spec/spec_helper.rb
|