killbill-payu-latam 0.0.1 → 0.0.2
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/NEWS +3 -0
- data/README.md +155 -1
- data/VERSION +1 -1
- data/killbill-payu-latam.gemspec +1 -1
- data/lib/payu_latam.rb +1 -0
- data/lib/payu_latam/api.rb +148 -24
- data/pom.xml +1 -1
- data/spec/payu_latam/base_plugin_spec.rb +0 -30
- data/spec/payu_latam/remote/integration_spec.rb +72 -1
- metadata +5 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 258296e92114a0ad40e4fba3d9863203a278285f
|
4
|
+
data.tar.gz: 915019234f3b2624b2bb889d4c472519fdc809b1
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 82c1a136c316d91ba1cf41b19ce73cc78d2b75cc930cb9ca784e5b57c705249d36f44bb8b120a89c369e74879b9dfbbc778c6bc71d4975af22b01702e0714da7
|
7
|
+
data.tar.gz: 455102e745e66506fba62ac7cce0eaacfe831462251cfeb20d17ea6164e2f223a820ff77c77f903dacb9ea442e7e4d57c7cf407e3af307a163c0837d7c8f67d0
|
data/README.md
CHANGED
@@ -1,4 +1,158 @@
|
|
1
1
|
killbill-payu-latam-plugin
|
2
2
|
==========================
|
3
3
|
|
4
|
-
Plugin to use PayU Latam as a gateway
|
4
|
+
Plugin to use [PayU Latam](http://www.payulatam.com/) as a gateway.
|
5
|
+
|
6
|
+
Release builds are available on [Maven Central](http://search.maven.org/#search%7Cga%7C1%7Cg%3A%22org.kill-bill.billing.plugin.ruby%22%20AND%20a%3A%22payu-latam-plugin%22) with coordinates `org.kill-bill.billing.plugin.ruby:payu-latam-plugin`.
|
7
|
+
|
8
|
+
Requirements
|
9
|
+
------------
|
10
|
+
|
11
|
+
The plugin needs a database. The latest version of the schema can be found here: https://raw.github.com/killbill/killbill-payu-latam-plugin/master/db/ddl.sql.
|
12
|
+
|
13
|
+
Usage
|
14
|
+
-----
|
15
|
+
|
16
|
+
### Credit cards
|
17
|
+
|
18
|
+
Add a payment method:
|
19
|
+
|
20
|
+
```
|
21
|
+
curl -v \
|
22
|
+
-u admin:password \
|
23
|
+
-H "X-Killbill-ApiKey: bob" \
|
24
|
+
-H "X-Killbill-ApiSecret: lazar" \
|
25
|
+
-H "Content-Type: application/json" \
|
26
|
+
-H "X-Killbill-CreatedBy: demo" \
|
27
|
+
-X POST \
|
28
|
+
--data-binary '{
|
29
|
+
"pluginName": "killbill-payu-latam",
|
30
|
+
"pluginInfo": {
|
31
|
+
"properties": [
|
32
|
+
{
|
33
|
+
"key": "ccLastName",
|
34
|
+
"value": "APPROVED"
|
35
|
+
},
|
36
|
+
{
|
37
|
+
"key": "ccExpirationMonth",
|
38
|
+
"value": 12
|
39
|
+
},
|
40
|
+
{
|
41
|
+
"key": "ccExpirationYear",
|
42
|
+
"value": 2017
|
43
|
+
},
|
44
|
+
{
|
45
|
+
"key": "ccNumber",
|
46
|
+
"value": 4111111111111111
|
47
|
+
}
|
48
|
+
]
|
49
|
+
}
|
50
|
+
}' \
|
51
|
+
"http://127.0.0.1:8080/1.0/kb/accounts/<ACCOUNT_ID>/paymentMethods?isDefault=true&pluginProperty=skip_gw=true"
|
52
|
+
```
|
53
|
+
|
54
|
+
Notes:
|
55
|
+
* Make sure to replace *ACCOUNT_ID* with the id of the Kill Bill account
|
56
|
+
* Remove `skip_gw=true` to store the credit card in the [PayU vault](http://docs.payulatam.com/en/api-integration/what-you-should-know-about-api-tokenization/)
|
57
|
+
|
58
|
+
To trigger a payment:
|
59
|
+
|
60
|
+
```
|
61
|
+
curl -v \
|
62
|
+
-u admin:password \
|
63
|
+
-H "X-Killbill-ApiKey: bob" \
|
64
|
+
-H "X-Killbill-ApiSecret: lazar" \
|
65
|
+
-H "Content-Type: application/json" \
|
66
|
+
-H "X-Killbill-CreatedBy: demo" \
|
67
|
+
-X POST \
|
68
|
+
--data-binary '{"transactionType":"PURCHASE","amount":"500","currency":"BRL","transactionExternalKey":"INV-'$(uuidgen)'-PURCHASE"}' \
|
69
|
+
"http://127.0.0.1:8080/1.0/kb/accounts/<ACCOUNT_ID>/payments?pluginProperty=security_code=123"
|
70
|
+
```
|
71
|
+
|
72
|
+
Notes:
|
73
|
+
* Make sure to replace *ACCOUNT_ID* with the id of the Kill Bill account
|
74
|
+
* Required plugin properties (such as `security_code`) will depend on the [country](http://docs.payulatam.com/en/api-integration/api-payments/4132-2/)
|
75
|
+
* To trigger payments in different countries, set `payment_processor_account_id=XXX` where XXX is one of colombia, panama, peru, mexico, argentina or brazil
|
76
|
+
|
77
|
+
### HPP
|
78
|
+
|
79
|
+
Add a payment method:
|
80
|
+
|
81
|
+
```
|
82
|
+
curl -v \
|
83
|
+
-u admin:password \
|
84
|
+
-H "X-Killbill-ApiKey: bob" \
|
85
|
+
-H "X-Killbill-ApiSecret: lazar" \
|
86
|
+
-H "Content-Type: application/json" \
|
87
|
+
-H "X-Killbill-CreatedBy: demo" \
|
88
|
+
-X POST \
|
89
|
+
--data-binary '{
|
90
|
+
"pluginName": "killbill-payu-latam",
|
91
|
+
"pluginInfo": {}
|
92
|
+
}' \
|
93
|
+
"http://127.0.0.1:8080/1.0/kb/accounts/<ACCOUNT_ID>/paymentMethods?isDefault=true&pluginProperty=skip_gw=true"
|
94
|
+
```
|
95
|
+
|
96
|
+
Notes:
|
97
|
+
* Make sure to replace *ACCOUNT_ID* with the id of the Kill Bill account
|
98
|
+
|
99
|
+
|
100
|
+
To create a voucher:
|
101
|
+
|
102
|
+
```
|
103
|
+
curl -v \
|
104
|
+
-u admin:password \
|
105
|
+
-H "X-Killbill-ApiKey: bob" \
|
106
|
+
-H "X-Killbill-ApiSecret: lazar" \
|
107
|
+
-H "Content-Type: application/json" \
|
108
|
+
-H "X-Killbill-CreatedBy: demo" \
|
109
|
+
-X POST \
|
110
|
+
--data-binary '{
|
111
|
+
"formFields": [
|
112
|
+
{
|
113
|
+
"key": "paymentMethod",
|
114
|
+
"value": "BALOTO"
|
115
|
+
},
|
116
|
+
{
|
117
|
+
"key": "name",
|
118
|
+
"value": "José Pérez"
|
119
|
+
},
|
120
|
+
{
|
121
|
+
"key": "email",
|
122
|
+
"value": "payu@killbill.io"
|
123
|
+
},
|
124
|
+
{
|
125
|
+
"key": "city",
|
126
|
+
"value": "Bogotá"
|
127
|
+
},
|
128
|
+
{
|
129
|
+
"key": "state",
|
130
|
+
"value": "Cundinamarca"
|
131
|
+
},
|
132
|
+
{
|
133
|
+
"key": "country",
|
134
|
+
"value": "CO"
|
135
|
+
},
|
136
|
+
{
|
137
|
+
"key": "amount",
|
138
|
+
"value": 400000
|
139
|
+
},
|
140
|
+
{
|
141
|
+
"key": "currency",
|
142
|
+
"value": "COP"
|
143
|
+
}
|
144
|
+
]
|
145
|
+
}' \
|
146
|
+
"http://127.0.0.1:8080/1.0/kb/paymentGateways/hosted/form/<ACCOUNT_ID>"
|
147
|
+
```
|
148
|
+
|
149
|
+
Notes:
|
150
|
+
* Make sure to replace *ACCOUNT_ID* with the id of the Kill Bill account
|
151
|
+
|
152
|
+
|
153
|
+
Here is what happens behind the scenes:
|
154
|
+
|
155
|
+
* The plugin creates the voucher in PayU.
|
156
|
+
* The plugin creates the payment in Kill Bill. During the payment call, Kill Bill will call back the plugin, which will in turn create a row in the `responses` table (to keep track of the created vouchers in PayU). A Kill Bill transaction id will always match a unique voucher in PayU.
|
157
|
+
* Kill Bill will start polling the plugin for the payment status, which it will get from PayU using the queries API.
|
158
|
+
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.0.
|
1
|
+
0.0.2
|
data/killbill-payu-latam.gemspec
CHANGED
@@ -24,7 +24,7 @@ Gem::Specification.new do |s|
|
|
24
24
|
|
25
25
|
s.add_dependency 'killbill', '~> 3.2.0'
|
26
26
|
s.add_dependency 'aktivemerchant', '~> 2.0.0'
|
27
|
-
s.add_dependency '
|
27
|
+
s.add_dependency 'koffsite_payments', '~> 3.0.0'
|
28
28
|
s.add_dependency 'activerecord', '~> 4.1.0'
|
29
29
|
s.add_dependency 'actionpack', '~> 4.1.0'
|
30
30
|
s.add_dependency 'actionview', '~> 4.1.0'
|
data/lib/payu_latam.rb
CHANGED
data/lib/payu_latam/api.rb
CHANGED
@@ -4,6 +4,7 @@ module Killbill #:nodoc:
|
|
4
4
|
|
5
5
|
def initialize
|
6
6
|
gateway_builder = Proc.new do |config|
|
7
|
+
::OffsitePayments.mode = config[:test] ? :test : :production
|
7
8
|
::ActiveMerchant::Billing::PayULatamGateway.new :api_login => config[:api_login],
|
8
9
|
:api_key => config[:api_key],
|
9
10
|
:country_account_id => config[:country_account_id],
|
@@ -38,13 +39,32 @@ module Killbill #:nodoc:
|
|
38
39
|
end
|
39
40
|
|
40
41
|
def purchase_payment(kb_account_id, kb_payment_id, kb_payment_transaction_id, kb_payment_method_id, amount, currency, properties, context)
|
41
|
-
#
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
42
|
+
# Direct payment?
|
43
|
+
if find_value_from_properties(properties, 'from_hpp') != 'true'
|
44
|
+
options = {}
|
45
|
+
add_required_options(properties, options)
|
46
|
+
properties = merge_properties(properties, options)
|
47
|
+
super(kb_account_id, kb_payment_id, kb_payment_transaction_id, kb_payment_method_id, amount, currency, properties, context)
|
48
|
+
else
|
49
|
+
# Nope, HPP
|
50
|
+
payu_order_id = find_value_from_properties(properties, 'payu_order_id')
|
51
|
+
payu_transaction_id = find_value_from_properties(properties, 'payu_transaction_id')
|
52
|
+
payment_processor_account_id = find_value_from_properties(properties, 'payment_processor_account_id')
|
53
|
+
|
54
|
+
# Record a response row, to keep track of the created vouchers in PayU
|
55
|
+
response = @response_model.create(:api_call => :build_form_descriptor,
|
56
|
+
:kb_account_id => kb_account_id,
|
57
|
+
:kb_payment_id => kb_payment_id,
|
58
|
+
:kb_payment_transaction_id => kb_payment_transaction_id,
|
59
|
+
:transaction_type => :PURCHASE,
|
60
|
+
:authorization => [payu_order_id, payu_transaction_id].join(';'),
|
61
|
+
:payment_processor_account_id => payment_processor_account_id,
|
62
|
+
:kb_tenant_id => context.tenant_id,
|
63
|
+
:success => true)
|
64
|
+
|
65
|
+
# Get the payment status from PayU (we are required to fetch the status from PayU within 7 minutes of the URL creation)
|
66
|
+
get_payment_transaction_info_from_payu(kb_payment_id, kb_payment_transaction_id, amount, currency, properties_to_hash(properties), context.tenant_id, response)
|
67
|
+
end
|
48
68
|
end
|
49
69
|
|
50
70
|
def void_payment(kb_account_id, kb_payment_id, kb_payment_transaction_id, kb_payment_method_id, properties, context)
|
@@ -78,11 +98,11 @@ module Killbill #:nodoc:
|
|
78
98
|
end
|
79
99
|
|
80
100
|
def get_payment_info(kb_account_id, kb_payment_id, properties, context)
|
81
|
-
|
82
|
-
options = {}
|
101
|
+
t_info_plugins = super(kb_account_id, kb_payment_id, properties, context)
|
83
102
|
|
84
|
-
|
85
|
-
|
103
|
+
t_info_plugins = get_payment_info_from_payu(kb_payment_id, properties_to_hash(properties), context) if t_info_plugins.empty?
|
104
|
+
|
105
|
+
t_info_plugins
|
86
106
|
end
|
87
107
|
|
88
108
|
def search_payments(search_key, offset, limit, properties, context)
|
@@ -146,22 +166,53 @@ module Killbill #:nodoc:
|
|
146
166
|
end
|
147
167
|
|
148
168
|
def build_form_descriptor(kb_account_id, descriptor_fields, properties, context)
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
#
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
169
|
+
payu_hpp_credentials = payu_hpp_credentials(properties_to_hash(properties))
|
170
|
+
|
171
|
+
# Prepare the PayU request
|
172
|
+
# Available fields:
|
173
|
+
# * :expiration_date
|
174
|
+
# * :customer (:name, :email, :phone, :dni_number)
|
175
|
+
# * :billing_address (:address1, :city, :state, :country)
|
176
|
+
form_fields = properties_to_hash(descriptor_fields)
|
177
|
+
payu_reference_code = form_fields[:externalKey] || SecureRandom.uuid
|
178
|
+
options = {
|
179
|
+
# Required fields
|
180
|
+
:order_id => payu_reference_code,
|
181
|
+
:description => form_fields['description'] || 'Kill Bill payment',
|
182
|
+
:payment_method => form_fields['paymentMethod'] || 'BALOTO',
|
183
|
+
}.merge(payu_hpp_credentials)
|
184
|
+
descriptor_fields = merge_properties(descriptor_fields, options)
|
185
|
+
|
186
|
+
# Create the voucher
|
187
|
+
descriptor = super(kb_account_id, descriptor_fields, properties, context)
|
188
|
+
payu_response = properties_to_hash(descriptor.form_fields)
|
189
|
+
descriptor.form_url = payu_response[:url]
|
190
|
+
|
191
|
+
# Create the payment in Kill Bill to start the polling
|
192
|
+
kb_account = @kb_apis.account_user_api.get_account_by_id(kb_account_id, context)
|
193
|
+
kb_payment_method_id = (@kb_apis.payment_api.get_account_payment_methods(kb_account_id, false, [], context).find { |pm| pm.plugin_name == 'killbill-payu-latam' }).id
|
194
|
+
kb_payment_id = nil
|
195
|
+
payment_external_key = payu_response[:order_id]
|
196
|
+
payment_transaction_external_key = payu_reference_code
|
197
|
+
# See purchase call above
|
198
|
+
properties = hash_to_properties(:from_hpp => true, :payu_order_id => payu_response[:order_id], :payu_transaction_id => payu_response[:transaction_id])
|
199
|
+
|
200
|
+
@kb_apis.payment_api.create_purchase(kb_account,
|
201
|
+
kb_payment_method_id,
|
202
|
+
kb_payment_id,
|
203
|
+
form_fields[:amount],
|
204
|
+
form_fields[:currency] || kb_account.currency,
|
205
|
+
payment_external_key,
|
206
|
+
payment_transaction_external_key,
|
207
|
+
properties,
|
208
|
+
context)
|
209
|
+
|
210
|
+
descriptor
|
160
211
|
end
|
161
212
|
|
162
213
|
def process_notification(notification, properties, context)
|
163
214
|
# Pass extra parameters for the gateway here
|
164
|
-
options
|
215
|
+
options = {}
|
165
216
|
properties = merge_properties(properties, options)
|
166
217
|
|
167
218
|
super(notification, properties, context) do |gw_notification, service|
|
@@ -175,8 +226,81 @@ module Killbill #:nodoc:
|
|
175
226
|
|
176
227
|
private
|
177
228
|
|
229
|
+
def get_payment_info_from_payu(kb_payment_id, options, context)
|
230
|
+
kb_payment = @kb_apis.payment_api.get_payment(kb_payment_id, false, [], context)
|
231
|
+
|
232
|
+
t_info_plugins = []
|
233
|
+
kb_payment.transactions.each do |transaction|
|
234
|
+
t_info_plugins << get_payment_transaction_info_from_payu(kb_payment_id, transaction.id, transaction.amount, transaction.currency, options, context.tenant_id)
|
235
|
+
end
|
236
|
+
t_info_plugins
|
237
|
+
end
|
238
|
+
|
239
|
+
def get_payment_transaction_info_from_payu(kb_payment_id, kb_payment_transaction_id, amount, currency, options, kb_tenant_id, response=nil)
|
240
|
+
# Guaranteed to have a unique mapping KB transaction <=> PayU HPP creation
|
241
|
+
response = @response_model.where("transaction_type = 'PURCHASE' AND kb_payment_id = '#{kb_payment_id}' AND kb_payment_transaction_id = '#{kb_payment_transaction_id}' AND kb_tenant_id = '#{kb_tenant_id}'").order(:created_at)[0] if response.nil?
|
242
|
+
raise "Unable to retrieve response for kb_payment_id=#{kb_payment_id}, kb_payment_transaction_id=#{kb_payment_transaction_id}, kb_tenant_id=#{kb_tenant_id}" if response.nil?
|
243
|
+
|
244
|
+
# Retrieve the transaction from PayU
|
245
|
+
order_id, transaction_id = response.authorization.split(';')
|
246
|
+
payu_status = (get_payu_status(transaction_id, options) || {})[:status]
|
247
|
+
|
248
|
+
transaction = nil
|
249
|
+
if payu_status == 'APPROVED'
|
250
|
+
transaction = response.create_payu_latam_transaction(:kb_account_id => response.kb_account_id,
|
251
|
+
:kb_tenant_id => response.kb_tenant_id,
|
252
|
+
:amount_in_cents => amount,
|
253
|
+
:currency => currency,
|
254
|
+
:api_call => :purchase,
|
255
|
+
:kb_payment_id => kb_payment_id,
|
256
|
+
:kb_payment_transaction_id => kb_payment_transaction_id,
|
257
|
+
:transaction_type => response.transaction_type,
|
258
|
+
:payment_processor_account_id => response.payment_processor_account_id,
|
259
|
+
:txn_id => response.txn_id,
|
260
|
+
:payu_latam_response_id => response.id)
|
261
|
+
end
|
262
|
+
|
263
|
+
t_info_plugin = response.to_transaction_info_plugin(transaction)
|
264
|
+
t_info_plugin.status = payu_status_to_plugin_status(payu_status)
|
265
|
+
t_info_plugin
|
266
|
+
end
|
267
|
+
|
268
|
+
def payu_status_to_plugin_status(payu_status)
|
269
|
+
if payu_status == 'APPROVED'
|
270
|
+
:PROCESSED
|
271
|
+
elsif payu_status == 'DECLINED' || payu_status == 'ERROR' || payu_status == 'EXPIRED'
|
272
|
+
:ERROR
|
273
|
+
elsif payu_status == 'PENDING'
|
274
|
+
:PENDING
|
275
|
+
else
|
276
|
+
:UNDEFINED
|
277
|
+
end
|
278
|
+
end
|
279
|
+
|
280
|
+
def get_payu_status(transaction_id, options)
|
281
|
+
options = payu_hpp_credentials(options)
|
282
|
+
helper = get_active_merchant_module.const_get('Helper').new(nil, options.delete(:account_id), options)
|
283
|
+
helper.transaction_status(transaction_id)
|
284
|
+
end
|
285
|
+
|
286
|
+
def payu_hpp_credentials(options)
|
287
|
+
payment_processor_account_id = options[:payment_processor_account_id] || :default
|
288
|
+
gateway = lookup_gateway(payment_processor_account_id)
|
289
|
+
|
290
|
+
{
|
291
|
+
:credential2 => gateway.options[:api_login],
|
292
|
+
:credential3 => gateway.options[:api_key],
|
293
|
+
:credential4 => gateway.options[:country_account_id],
|
294
|
+
:account_id => gateway.options[:merchant_id]
|
295
|
+
}
|
296
|
+
end
|
297
|
+
|
298
|
+
def get_active_merchant_module
|
299
|
+
::OffsitePayments::Integrations::PayULatam
|
300
|
+
end
|
301
|
+
|
178
302
|
def add_required_options(properties, options)
|
179
|
-
language
|
303
|
+
language = find_value_from_properties(properties, 'language') || 'en'
|
180
304
|
options[:language] ||= language
|
181
305
|
end
|
182
306
|
end
|
data/pom.xml
CHANGED
@@ -25,7 +25,7 @@
|
|
25
25
|
<groupId>org.kill-bill.billing.plugin.ruby</groupId>
|
26
26
|
<artifactId>payu-latam-plugin</artifactId>
|
27
27
|
<packaging>pom</packaging>
|
28
|
-
<version>0.0.
|
28
|
+
<version>0.0.2</version>
|
29
29
|
<name>payu-latam-plugin</name>
|
30
30
|
<url>http://github.com/killbill/killbill-payu-latam-plugin</url>
|
31
31
|
<description>Plugin for accessing PayuLatam as a payment gateway</description>
|
@@ -28,34 +28,4 @@ describe Killbill::PayuLatam::PaymentPlugin do
|
|
28
28
|
it 'should start and stop correctly' do
|
29
29
|
@plugin.stop_plugin
|
30
30
|
end
|
31
|
-
|
32
|
-
# No support for HPP
|
33
|
-
|
34
|
-
#xit 'should generate forms correctly' do
|
35
|
-
# kb_account_id = SecureRandom.uuid
|
36
|
-
# kb_tenant_id = SecureRandom.uuid
|
37
|
-
# context = @plugin.kb_apis.create_context(kb_tenant_id)
|
38
|
-
# fields = @plugin.hash_to_properties({
|
39
|
-
# :order_id => '1234',
|
40
|
-
# :amount => 10
|
41
|
-
# })
|
42
|
-
# form = @plugin.build_form_descriptor kb_account_id, fields, [], context
|
43
|
-
|
44
|
-
# form.kb_account_id.should == kb_account_id
|
45
|
-
# form.form_method.should == 'POST'
|
46
|
-
# form.form_url.should == 'https://payulatam.com'
|
47
|
-
|
48
|
-
# form_fields = @plugin.properties_to_hash(form.form_fields)
|
49
|
-
#end
|
50
|
-
|
51
|
-
#xit 'should receive notifications correctly' do
|
52
|
-
# description = 'description'
|
53
|
-
|
54
|
-
# kb_tenant_id = SecureRandom.uuid
|
55
|
-
# context = @plugin.kb_apis.create_context(kb_tenant_id)
|
56
|
-
# properties = @plugin.hash_to_properties({ :description => description })
|
57
|
-
|
58
|
-
# notification = ""
|
59
|
-
# gw_notification = @plugin.process_notification notification, properties, context
|
60
|
-
#end
|
61
31
|
end
|
@@ -12,6 +12,17 @@ module ActiveMerchant #:nodoc:
|
|
12
12
|
end
|
13
13
|
end
|
14
14
|
|
15
|
+
class PayUJavaPaymentApi < ::Killbill::Plugin::ActiveMerchant::RSpec::FakeJavaPaymentApi
|
16
|
+
|
17
|
+
def get_account_payment_methods(kb_account_id, plugin_info, properties, context)
|
18
|
+
[OpenStruct.new(:plugin_name => 'killbill-payu-latam', :id => SecureRandom.uuid)]
|
19
|
+
end
|
20
|
+
|
21
|
+
def create_purchase(kb_account, kb_payment_method_id, kb_payment_id, amount, currency, payment_external_key, payment_transaction_external_key, properties, context)
|
22
|
+
add_payment(SecureRandom.uuid, SecureRandom.uuid, payment_transaction_external_key, :PURCHASE)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
15
26
|
describe Killbill::PayuLatam::PaymentPlugin do
|
16
27
|
|
17
28
|
include ::Killbill::Plugin::ActiveMerchant::RSpec
|
@@ -23,7 +34,7 @@ describe Killbill::PayuLatam::PaymentPlugin do
|
|
23
34
|
@plugin = Killbill::PayuLatam::PaymentPlugin.new
|
24
35
|
|
25
36
|
@account_api = ::Killbill::Plugin::ActiveMerchant::RSpec::FakeJavaUserAccountApi.new
|
26
|
-
@payment_api =
|
37
|
+
@payment_api = PayUJavaPaymentApi.new
|
27
38
|
svcs = {:account_user_api => @account_api, :payment_api => @payment_api}
|
28
39
|
@plugin.kb_apis = Killbill::Plugin::KillbillApi.new('payu', svcs)
|
29
40
|
|
@@ -152,6 +163,66 @@ describe Killbill::PayuLatam::PaymentPlugin do
|
|
152
163
|
# payment_response.transaction_type.should == :VOID
|
153
164
|
#end
|
154
165
|
|
166
|
+
# HPP
|
167
|
+
it 'should generate vouchers correctly' do
|
168
|
+
properties = [create_pm_kv_info('payment_processor_account_id', 'colombia')]
|
169
|
+
nb_payments = @payment_api.payments.size
|
170
|
+
|
171
|
+
# Generate the voucher
|
172
|
+
payment_properties = {
|
173
|
+
:externalKey => SecureRandom.uuid,
|
174
|
+
:amount => 6000,
|
175
|
+
:currency => 'COP'
|
176
|
+
}
|
177
|
+
descriptor_fields = @plugin.hash_to_properties(payment_properties)
|
178
|
+
descriptor = @plugin.build_form_descriptor(@pm.kb_account_id, descriptor_fields, properties, @plugin.kb_apis.create_context(@call_context.tenant_id))
|
179
|
+
|
180
|
+
# Verify the descriptor
|
181
|
+
descriptor.kb_account_id.should == @pm.kb_account_id
|
182
|
+
descriptor.form_method.should == 'GET'
|
183
|
+
descriptor.form_url.should_not be_nil
|
184
|
+
# For manual debugging
|
185
|
+
puts "Redirect to: #{descriptor.form_url}"
|
186
|
+
payu_order_id = @plugin.find_value_from_properties(descriptor.form_fields, 'order_id')
|
187
|
+
payu_order_id.should_not be_nil
|
188
|
+
payu_transaction_id = @plugin.find_value_from_properties(descriptor.form_fields, 'transaction_id')
|
189
|
+
payu_transaction_id.should_not be_nil
|
190
|
+
|
191
|
+
# Verify the pending payment has been created in Kill Bill
|
192
|
+
@payment_api.payments.size.should == nb_payments + 1
|
193
|
+
payment = @payment_api.payments[-1]
|
194
|
+
payment.transactions.size.should == 1
|
195
|
+
payment.transactions[0].external_key.should == payment_properties[:externalKey]
|
196
|
+
|
197
|
+
# Trigger manually the purchase call (this is done automatically in a live system)
|
198
|
+
properties << create_pm_kv_info('from_hpp', 'true')
|
199
|
+
properties << create_pm_kv_info('payu_order_id', payu_order_id)
|
200
|
+
properties << create_pm_kv_info('payu_transaction_id', payu_transaction_id)
|
201
|
+
payment_response = @plugin.purchase_payment(@pm.kb_account_id, payment.id, payment.transactions[0].id, @pm.id, payment_properties[:amount], payment_properties[:currency], properties, @plugin.kb_apis.create_context(@call_context.tenant_id))
|
202
|
+
payment_response.status.should == :PENDING
|
203
|
+
|
204
|
+
# Verify the response row was created
|
205
|
+
response = Killbill::PayuLatam::PayuLatamResponse.all[-1]
|
206
|
+
response.kb_account_id.should == @pm.kb_account_id
|
207
|
+
response.kb_payment_id.should == payment.id
|
208
|
+
response.kb_payment_transaction_id.should == payment.transactions[0].id
|
209
|
+
response.transaction_type.should == 'PURCHASE'
|
210
|
+
response.authorization.should == "#{payu_order_id};#{payu_transaction_id}"
|
211
|
+
response.payment_processor_account_id.should == 'colombia'
|
212
|
+
response.kb_tenant_id.should == @call_context.tenant_id
|
213
|
+
|
214
|
+
# Verify the payment in PayU
|
215
|
+
t_info_plugins = @plugin.get_payment_info(@pm.kb_account_id, payment.id, properties, @plugin.kb_apis.create_context(@call_context.tenant_id))
|
216
|
+
t_info_plugins.size.should == 1
|
217
|
+
t_info_plugin = t_info_plugins[0]
|
218
|
+
t_info_plugin.status.should == :PENDING
|
219
|
+
t_info_plugin.kb_payment_id.should == payment.id
|
220
|
+
t_info_plugin.kb_transaction_payment_id.should == payment.transactions[0].id
|
221
|
+
t_info_plugin.transaction_type.should == :PURCHASE
|
222
|
+
#t_info_plugin.amount.should == payment_properties[:amount]
|
223
|
+
#t_info_plugin.currency.should == payment_properties[:currency]
|
224
|
+
end
|
225
|
+
|
155
226
|
private
|
156
227
|
|
157
228
|
def valid_cc_info
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: killbill-payu-latam
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Kill Bill core team
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2015-01-09 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: killbill
|
@@ -39,17 +39,17 @@ dependencies:
|
|
39
39
|
prerelease: false
|
40
40
|
type: :runtime
|
41
41
|
- !ruby/object:Gem::Dependency
|
42
|
-
name:
|
42
|
+
name: koffsite_payments
|
43
43
|
version_requirements: !ruby/object:Gem::Requirement
|
44
44
|
requirements:
|
45
45
|
- - ~>
|
46
46
|
- !ruby/object:Gem::Version
|
47
|
-
version:
|
47
|
+
version: 3.0.0
|
48
48
|
requirement: !ruby/object:Gem::Requirement
|
49
49
|
requirements:
|
50
50
|
- - ~>
|
51
51
|
- !ruby/object:Gem::Version
|
52
|
-
version:
|
52
|
+
version: 3.0.0
|
53
53
|
prerelease: false
|
54
54
|
type: :runtime
|
55
55
|
- !ruby/object:Gem::Dependency
|