aktivemerchant 2.0.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.
Files changed (193) hide show
  1. checksums.yaml +7 -0
  2. data/CHANGELOG +1596 -0
  3. data/CONTRIBUTORS +511 -0
  4. data/MIT-LICENSE +20 -0
  5. data/README.md +18 -0
  6. data/lib/active_merchant.rb +108 -0
  7. data/lib/active_merchant/billing.rb +13 -0
  8. data/lib/active_merchant/billing/apple_pay_payment_token.rb +22 -0
  9. data/lib/active_merchant/billing/avs_result.rb +98 -0
  10. data/lib/active_merchant/billing/base.rb +72 -0
  11. data/lib/active_merchant/billing/check.rb +76 -0
  12. data/lib/active_merchant/billing/compatibility.rb +120 -0
  13. data/lib/active_merchant/billing/credit_card.rb +352 -0
  14. data/lib/active_merchant/billing/credit_card_formatting.rb +24 -0
  15. data/lib/active_merchant/billing/credit_card_methods.rb +160 -0
  16. data/lib/active_merchant/billing/cvv_result.rb +38 -0
  17. data/lib/active_merchant/billing/gateway.rb +268 -0
  18. data/lib/active_merchant/billing/gateways.rb +17 -0
  19. data/lib/active_merchant/billing/gateways/adyen.rb +209 -0
  20. data/lib/active_merchant/billing/gateways/alfabank.rb +117 -0
  21. data/lib/active_merchant/billing/gateways/app55.rb +176 -0
  22. data/lib/active_merchant/billing/gateways/authorize_net.rb +419 -0
  23. data/lib/active_merchant/billing/gateways/authorize_net_arb.rb +417 -0
  24. data/lib/active_merchant/billing/gateways/authorize_net_cim.rb +976 -0
  25. data/lib/active_merchant/billing/gateways/balanced.rb +256 -0
  26. data/lib/active_merchant/billing/gateways/bank_frick.rb +225 -0
  27. data/lib/active_merchant/billing/gateways/banwire.rb +105 -0
  28. data/lib/active_merchant/billing/gateways/barclays_epdq.rb +314 -0
  29. data/lib/active_merchant/billing/gateways/barclays_epdq_extra_plus.rb +15 -0
  30. data/lib/active_merchant/billing/gateways/be2bill.rb +131 -0
  31. data/lib/active_merchant/billing/gateways/beanstream.rb +188 -0
  32. data/lib/active_merchant/billing/gateways/beanstream/beanstream_core.rb +393 -0
  33. data/lib/active_merchant/billing/gateways/beanstream_interac.rb +54 -0
  34. data/lib/active_merchant/billing/gateways/blue_pay.rb +506 -0
  35. data/lib/active_merchant/billing/gateways/bogus.rb +140 -0
  36. data/lib/active_merchant/billing/gateways/borgun.rb +210 -0
  37. data/lib/active_merchant/billing/gateways/braintree.rb +19 -0
  38. data/lib/active_merchant/billing/gateways/braintree/braintree_common.rb +9 -0
  39. data/lib/active_merchant/billing/gateways/braintree_blue.rb +515 -0
  40. data/lib/active_merchant/billing/gateways/braintree_orange.rb +20 -0
  41. data/lib/active_merchant/billing/gateways/bridge_pay.rb +189 -0
  42. data/lib/active_merchant/billing/gateways/card_save.rb +23 -0
  43. data/lib/active_merchant/billing/gateways/card_stream.rb +220 -0
  44. data/lib/active_merchant/billing/gateways/cashnet.rb +191 -0
  45. data/lib/active_merchant/billing/gateways/cc5.rb +201 -0
  46. data/lib/active_merchant/billing/gateways/cecabank.rb +229 -0
  47. data/lib/active_merchant/billing/gateways/certo_direct.rb +278 -0
  48. data/lib/active_merchant/billing/gateways/checkout.rb +213 -0
  49. data/lib/active_merchant/billing/gateways/commercegate.rb +143 -0
  50. data/lib/active_merchant/billing/gateways/conekta.rb +209 -0
  51. data/lib/active_merchant/billing/gateways/cyber_source.rb +709 -0
  52. data/lib/active_merchant/billing/gateways/data_cash.rb +600 -0
  53. data/lib/active_merchant/billing/gateways/efsnet.rb +219 -0
  54. data/lib/active_merchant/billing/gateways/elavon.rb +348 -0
  55. data/lib/active_merchant/billing/gateways/epay.rb +275 -0
  56. data/lib/active_merchant/billing/gateways/evo_ca.rb +308 -0
  57. data/lib/active_merchant/billing/gateways/eway.rb +214 -0
  58. data/lib/active_merchant/billing/gateways/eway_managed.rb +291 -0
  59. data/lib/active_merchant/billing/gateways/eway_rapid.rb +524 -0
  60. data/lib/active_merchant/billing/gateways/exact.rb +218 -0
  61. data/lib/active_merchant/billing/gateways/fat_zebra.rb +173 -0
  62. data/lib/active_merchant/billing/gateways/federated_canada.rb +160 -0
  63. data/lib/active_merchant/billing/gateways/finansbank.rb +23 -0
  64. data/lib/active_merchant/billing/gateways/first_giving.rb +143 -0
  65. data/lib/active_merchant/billing/gateways/first_pay.rb +160 -0
  66. data/lib/active_merchant/billing/gateways/firstdata_e4.rb +355 -0
  67. data/lib/active_merchant/billing/gateways/garanti.rb +257 -0
  68. data/lib/active_merchant/billing/gateways/global_transport.rb +183 -0
  69. data/lib/active_merchant/billing/gateways/hdfc.rb +207 -0
  70. data/lib/active_merchant/billing/gateways/hps.rb +288 -0
  71. data/lib/active_merchant/billing/gateways/iats_payments.rb +251 -0
  72. data/lib/active_merchant/billing/gateways/ideal/ideal_base.rb +246 -0
  73. data/lib/active_merchant/billing/gateways/ideal/ideal_rabobank.pem +13 -0
  74. data/lib/active_merchant/billing/gateways/ideal/ideal_response.rb +29 -0
  75. data/lib/active_merchant/billing/gateways/ideal_rabobank.rb +66 -0
  76. data/lib/active_merchant/billing/gateways/inspire.rb +213 -0
  77. data/lib/active_merchant/billing/gateways/instapay.rb +163 -0
  78. data/lib/active_merchant/billing/gateways/iridium.rb +457 -0
  79. data/lib/active_merchant/billing/gateways/itransact.rb +448 -0
  80. data/lib/active_merchant/billing/gateways/jetpay.rb +275 -0
  81. data/lib/active_merchant/billing/gateways/linkpoint.rb +438 -0
  82. data/lib/active_merchant/billing/gateways/litle.rb +346 -0
  83. data/lib/active_merchant/billing/gateways/maxipago.rb +197 -0
  84. data/lib/active_merchant/billing/gateways/merchant_e_solutions.rb +170 -0
  85. data/lib/active_merchant/billing/gateways/merchant_one.rb +114 -0
  86. data/lib/active_merchant/billing/gateways/merchant_ware.rb +319 -0
  87. data/lib/active_merchant/billing/gateways/merchant_ware_version_four.rb +268 -0
  88. data/lib/active_merchant/billing/gateways/merchant_warrior.rb +195 -0
  89. data/lib/active_merchant/billing/gateways/mercury.rb +333 -0
  90. data/lib/active_merchant/billing/gateways/metrics_global.rb +303 -0
  91. data/lib/active_merchant/billing/gateways/migs.rb +265 -0
  92. data/lib/active_merchant/billing/gateways/migs/migs_codes.rb +100 -0
  93. data/lib/active_merchant/billing/gateways/modern_payments.rb +37 -0
  94. data/lib/active_merchant/billing/gateways/modern_payments_cim.rb +219 -0
  95. data/lib/active_merchant/billing/gateways/moneris.rb +309 -0
  96. data/lib/active_merchant/billing/gateways/moneris_us.rb +291 -0
  97. data/lib/active_merchant/billing/gateways/money_movers.rb +152 -0
  98. data/lib/active_merchant/billing/gateways/nab_transact.rb +280 -0
  99. data/lib/active_merchant/billing/gateways/net_registry.rb +198 -0
  100. data/lib/active_merchant/billing/gateways/netaxept.rb +181 -0
  101. data/lib/active_merchant/billing/gateways/netbilling.rb +190 -0
  102. data/lib/active_merchant/billing/gateways/netpay.rb +223 -0
  103. data/lib/active_merchant/billing/gateways/network_merchants.rb +242 -0
  104. data/lib/active_merchant/billing/gateways/nmi.rb +256 -0
  105. data/lib/active_merchant/billing/gateways/ogone.rb +435 -0
  106. data/lib/active_merchant/billing/gateways/openpay.rb +194 -0
  107. data/lib/active_merchant/billing/gateways/optimal_payment.rb +313 -0
  108. data/lib/active_merchant/billing/gateways/orbital.rb +803 -0
  109. data/lib/active_merchant/billing/gateways/orbital/orbital_soft_descriptors.rb +47 -0
  110. data/lib/active_merchant/billing/gateways/pac_net_raven.rb +207 -0
  111. data/lib/active_merchant/billing/gateways/pago_facil.rb +122 -0
  112. data/lib/active_merchant/billing/gateways/pay_gate_xml.rb +261 -0
  113. data/lib/active_merchant/billing/gateways/pay_junction.rb +390 -0
  114. data/lib/active_merchant/billing/gateways/pay_secure.rb +112 -0
  115. data/lib/active_merchant/billing/gateways/pay_u_latam.rb +462 -0
  116. data/lib/active_merchant/billing/gateways/paybox_direct.rb +188 -0
  117. data/lib/active_merchant/billing/gateways/payex.rb +412 -0
  118. data/lib/active_merchant/billing/gateways/payflow.rb +304 -0
  119. data/lib/active_merchant/billing/gateways/payflow/payflow_common_api.rb +209 -0
  120. data/lib/active_merchant/billing/gateways/payflow/payflow_express_response.rb +39 -0
  121. data/lib/active_merchant/billing/gateways/payflow/payflow_response.rb +13 -0
  122. data/lib/active_merchant/billing/gateways/payflow_express.rb +224 -0
  123. data/lib/active_merchant/billing/gateways/payflow_express_uk.rb +15 -0
  124. data/lib/active_merchant/billing/gateways/payflow_uk.rb +21 -0
  125. data/lib/active_merchant/billing/gateways/payment_express.rb +353 -0
  126. data/lib/active_merchant/billing/gateways/paymill.rb +281 -0
  127. data/lib/active_merchant/billing/gateways/paypal.rb +117 -0
  128. data/lib/active_merchant/billing/gateways/paypal/paypal_common_api.rb +670 -0
  129. data/lib/active_merchant/billing/gateways/paypal/paypal_express_response.rb +65 -0
  130. data/lib/active_merchant/billing/gateways/paypal/paypal_recurring_api.rb +262 -0
  131. data/lib/active_merchant/billing/gateways/paypal_ca.rb +13 -0
  132. data/lib/active_merchant/billing/gateways/paypal_digital_goods.rb +44 -0
  133. data/lib/active_merchant/billing/gateways/paypal_express.rb +264 -0
  134. data/lib/active_merchant/billing/gateways/paypal_express_common.rb +30 -0
  135. data/lib/active_merchant/billing/gateways/payscout.rb +162 -0
  136. data/lib/active_merchant/billing/gateways/paystation.rb +199 -0
  137. data/lib/active_merchant/billing/gateways/payway.rb +207 -0
  138. data/lib/active_merchant/billing/gateways/pin.rb +197 -0
  139. data/lib/active_merchant/billing/gateways/plugnpay.rb +283 -0
  140. data/lib/active_merchant/billing/gateways/psigate.rb +216 -0
  141. data/lib/active_merchant/billing/gateways/psl_card.rb +303 -0
  142. data/lib/active_merchant/billing/gateways/qbms.rb +292 -0
  143. data/lib/active_merchant/billing/gateways/quantum.rb +276 -0
  144. data/lib/active_merchant/billing/gateways/quickpay.rb +367 -0
  145. data/lib/active_merchant/billing/gateways/realex.rb +298 -0
  146. data/lib/active_merchant/billing/gateways/redsys.rb +391 -0
  147. data/lib/active_merchant/billing/gateways/sage.rb +175 -0
  148. data/lib/active_merchant/billing/gateways/sage/sage_bankcard.rb +87 -0
  149. data/lib/active_merchant/billing/gateways/sage/sage_core.rb +114 -0
  150. data/lib/active_merchant/billing/gateways/sage/sage_vault.rb +149 -0
  151. data/lib/active_merchant/billing/gateways/sage/sage_virtual_check.rb +102 -0
  152. data/lib/active_merchant/billing/gateways/sage_pay.rb +398 -0
  153. data/lib/active_merchant/billing/gateways/sallie_mae.rb +143 -0
  154. data/lib/active_merchant/billing/gateways/secure_net.rb +252 -0
  155. data/lib/active_merchant/billing/gateways/secure_pay.rb +201 -0
  156. data/lib/active_merchant/billing/gateways/secure_pay_au.rb +281 -0
  157. data/lib/active_merchant/billing/gateways/secure_pay_tech.rb +105 -0
  158. data/lib/active_merchant/billing/gateways/skip_jack.rb +452 -0
  159. data/lib/active_merchant/billing/gateways/smart_ps.rb +283 -0
  160. data/lib/active_merchant/billing/gateways/so_easy_pay.rb +194 -0
  161. data/lib/active_merchant/billing/gateways/spreedly_core.rb +247 -0
  162. data/lib/active_merchant/billing/gateways/stripe.rb +411 -0
  163. data/lib/active_merchant/billing/gateways/swipe_checkout.rb +157 -0
  164. data/lib/active_merchant/billing/gateways/tns.rb +227 -0
  165. data/lib/active_merchant/billing/gateways/trans_first.rb +126 -0
  166. data/lib/active_merchant/billing/gateways/transax.rb +23 -0
  167. data/lib/active_merchant/billing/gateways/transnational.rb +10 -0
  168. data/lib/active_merchant/billing/gateways/trust_commerce.rb +416 -0
  169. data/lib/active_merchant/billing/gateways/usa_epay.rb +25 -0
  170. data/lib/active_merchant/billing/gateways/usa_epay_advanced.rb +1516 -0
  171. data/lib/active_merchant/billing/gateways/usa_epay_transaction.rb +254 -0
  172. data/lib/active_merchant/billing/gateways/verifi.rb +225 -0
  173. data/lib/active_merchant/billing/gateways/viaklix.rb +183 -0
  174. data/lib/active_merchant/billing/gateways/vindicia.rb +385 -0
  175. data/lib/active_merchant/billing/gateways/webpay.rb +97 -0
  176. data/lib/active_merchant/billing/gateways/wepay.rb +189 -0
  177. data/lib/active_merchant/billing/gateways/wirecard.rb +421 -0
  178. data/lib/active_merchant/billing/gateways/worldpay.rb +331 -0
  179. data/lib/active_merchant/billing/gateways/worldpay_us.rb +181 -0
  180. data/lib/active_merchant/billing/model.rb +30 -0
  181. data/lib/active_merchant/billing/payment_token.rb +21 -0
  182. data/lib/active_merchant/billing/rails.rb +3 -0
  183. data/lib/active_merchant/billing/response.rb +91 -0
  184. data/lib/active_merchant/country.rb +332 -0
  185. data/lib/active_merchant/empty.rb +20 -0
  186. data/lib/active_merchant/errors.rb +29 -0
  187. data/lib/active_merchant/offsite_payments_shim.rb +19 -0
  188. data/lib/active_merchant/version.rb +3 -0
  189. data/lib/activemerchant.rb +1 -0
  190. data/lib/support/gateway_support.rb +71 -0
  191. data/lib/support/outbound_hosts.rb +25 -0
  192. data/lib/support/ssl_verify.rb +93 -0
  193. metadata +400 -0
@@ -0,0 +1,462 @@
1
+ require 'digest/md5'
2
+
3
+ module ActiveMerchant #:nodoc:
4
+ module Billing #:nodoc:
5
+ class PayULatamGateway < Gateway
6
+ self.test_url = 'https://stg.api.payulatam.com/payments-api/4.0/service.cgi'
7
+ self.live_url = 'https://api.payulatam.com/payments-api/4.0/service.cgi'
8
+
9
+ QUERIES_API_TEST_URL = 'https://stg.api.payulatam.com/reports-api/4.0/service.cgi'
10
+ QUERIES_API_LIVE_URL = 'https://api.payulatam.com/reports-api/4.0/service.cgi'
11
+
12
+ self.supported_countries = %w(BR AR CO MX PA PE)
13
+ self.default_currency = 'USD'
14
+ # Depends on the country, see http://docs.payulatam.com/integracion-con-api/api-de-pagos-2/medios-de-pago-por-pais/
15
+ self.supported_cardtypes = [:visa, :master, :american_express]
16
+
17
+ self.homepage_url = 'http://www.payulatam.net/'
18
+ self.display_name = 'PayU'
19
+
20
+ ORDER_STATUS = {
21
+ :NEW => 'The order has been created',
22
+ :IN_PROGRESS => 'The order is being processed',
23
+ :AUTHORIZED => 'The last transaction of the order has been approved',
24
+ :CAPTURED => 'The last transaction of the capture process has been approved',
25
+ :CANCELLED => 'The last transaction of the order has been canceled',
26
+ :DECLINED => 'The last transaction of the order has been declined',
27
+ :REFUNDED => 'The last transaction of the order has been refunded'
28
+ }
29
+
30
+ TRANSACTION_STATUS = {
31
+ :APPROVED => 'Transaction approved',
32
+ :DECLINED => 'Transaction declined',
33
+ :ERROR => 'Error in the processing of the transaction',
34
+ :EXPIRED => 'Transaction expired',
35
+ :PENDING => 'Transaction is pending or in validation',
36
+ :SUBMITTED => 'Transaction sent to the bank and for some reason has not finish processing. Only applies to API reports'
37
+ }
38
+
39
+ QUOTAS = {
40
+ :'1' => 'Payment on site',
41
+ :'2' => 'Business funding',
42
+ :'3' => 'Payment network funding'
43
+ }
44
+
45
+ RESPONSE_CODE = {
46
+ :ERROR => 'There was an error in the process/transaction',
47
+ :APPROVED => 'The transaction was approved',
48
+ :ANTIFRAUD_REJECTED => 'The transaction was rejected by the anti-fraud module',
49
+ :PAYMENT_NETWORK_REJECTED => 'The payment network has rejected the transaction',
50
+ :ENTITY_DECLINED => 'The transaction has been declined by the bank or there has been an error with the payment network',
51
+ :INTERNAL_PAYMENT_PROVIDER_ERROR => 'An error has occurred within the system of the payment network',
52
+ :INACTIVE_PAYMENT_PROVIDER => 'The payment provide is not currently activated for your account',
53
+ :DIGITAL_CERTIFICATE_NOT_FOUND => 'The payment network has reported an error in the authentication of the transaction',
54
+ :INVALID_EXPIRATION_DATE_OR_SECURITY_CODE => 'The security code or expiration date is invalid',
55
+ :INSUFFICIENT_FUNDS => 'The account does not have sufficient funds for this transaction',
56
+ :CREDIT_CARD_NOT_AUTHORIZE_FOR_INTERNET_TRANSACTIONS => 'The credit card is not authorized for internet transactions',
57
+ :INVALID_TRANSACTION => 'The payment network has reported that this transaction is not valid',
58
+ :INVALID_CARD => 'Invalid card',
59
+ :EXPIRED_CARD => 'Expired card',
60
+ :RESTRICTED_CARD => 'This card has been restricted for purchases',
61
+ :CONTACT_THE_ENTITY => 'Please contact your bank',
62
+ :REPEAT_TRANSACTION => 'Please attempt the transaction again',
63
+ :ENTITY_MESSAGING_ERROR => 'The financial network has reported an error in their communication with the bank',
64
+ :BANK_UNREACHABLE => 'The bank is unable to be reached at this time',
65
+ :EXCEEDED_AMOUNT => 'This transaction has exceeded the limit set by the bank',
66
+ :NOT_ACCEPTED_TRANSACTION => 'This transaction was not accepted by the bank',
67
+ :ERROR_CONVERTING_TRANSACTION_AMOUNTS => 'An error has occurred in the currency conversion process',
68
+ :EXPIRED_TRANSACTION => 'The transaction has expired',
69
+ :PENDING_TRANSACTION_REVIEW => 'The transaction was been stopped and must be revised, this may occur because of security filters',
70
+ :PENDING_TRANSACTION_CONFIRMATION => 'The transaction is pending confirmation',
71
+ :PENDING_TRANSACTION_TRANSMISSION => 'The transaction is pending communication with the payment network. Normally this only occurs in cases of cash payment',
72
+ :PAYMENT_NETWORK_BAD_RESPONSE => 'This message is communicated when connection with the payment network is inconsistent',
73
+ :PAYMENT_NETWORK_NO_CONNECTION => 'A connection with the payment network is unavailable',
74
+ :PAYMENT_NETWORK_NO_RESPONSE => 'The payment network has not responded',
75
+ :FIX_NOT_REQUIRED => 'Clinical transactions: Internal code only',
76
+ :AUTOMATICALLY_FIXED_AND_SUCCESS_REVERSAL => 'Clinical transactions: Internal code only',
77
+ :AUTOMATICALLY_FIXED_AND_UNSUCCESS_REVERSAL => 'Clinical transactions: Internal code only',
78
+ :AUTOMATIC_FIXED_NOT_SUPPORTED => 'Clinical transactions: Internal code only',
79
+ :NOT_FIXED_FOR_ERROR_STATE => 'Clinical transactions: Internal code only',
80
+ :ERROR_FIXING_AND_REVERSING => 'Clinical transactions: Internal code only',
81
+ :ERROR_FIXING_INCOMPLETE_DATA => 'Clinical transactions: Internal code only'
82
+ }
83
+
84
+ SECURITY_CODE = {
85
+ :'0' => 'Not provided',
86
+ :'1' => 'Provided',
87
+ :'2' => 'Unreadable',
88
+ :'9' => 'Non-existent'
89
+ }
90
+
91
+ SUPPORTED_CURRENCIES = %w(ARS BRL COP MXN PEN USD)
92
+
93
+ SUPPORTED_LANGUAGES = %w(en es pt)
94
+
95
+ TRANSACTION_SOURCE = {
96
+ :WEB => 'Online Transaction (E-commerce)',
97
+ :MOTO => 'Mail Order Telephone Order',
98
+ :RETAIL => 'Retail',
99
+ :MOBILE => 'Mobile transaction'
100
+ }
101
+
102
+ def initialize(options={})
103
+ requires!(options, :merchant_id, :api_login, :api_key, :country_account_id)
104
+ super
105
+ end
106
+
107
+ def store(payment, options = {})
108
+ requires!(options, :language)
109
+ commit(:store, nil, payment, nil, options)
110
+ end
111
+
112
+ def purchase(money, payment, options={})
113
+ requires!(options, :order_id, :language, :description)
114
+ commit(:purchase, money, payment, nil, options)
115
+ end
116
+
117
+ def authorize(money, payment, options={})
118
+ requires!(options, :order_id, :language, :description)
119
+ commit(:authorize, money, payment, nil, options)
120
+ end
121
+
122
+ def capture(money, authorization, options={})
123
+ requires!(options, :order_id)
124
+ commit(:capture, money, nil, authorization, options)
125
+ end
126
+
127
+ def refund(money, authorization, options={})
128
+ requires!(options, :order_id)
129
+ commit(:refund, money, nil, authorization, options)
130
+ end
131
+
132
+ def void(authorization, options={})
133
+ requires!(options, :order_id)
134
+ commit(:void, nil, nil, authorization, options)
135
+ end
136
+
137
+ private
138
+
139
+ def commit(action, money, payment_method_or_reference, authorization, options = {})
140
+ amount = amount(money)
141
+ currency = options[:currency] || currency(money)
142
+ options = options.clone
143
+ post = {}
144
+
145
+ if [:authorize, :purchase].include?(action)
146
+ options[:command] = 'SUBMIT_TRANSACTION'
147
+ options[:transaction_type] = (action == :authorize ? 'AUTHORIZATION' : 'AUTHORIZATION_AND_CAPTURE')
148
+ build_auth_or_purchase_request(post, amount, currency, payment_method_or_reference, options)
149
+ elsif [:capture, :refund, :void].include?(action)
150
+ options[:command] = 'SUBMIT_TRANSACTION'
151
+ options[:transaction_type] = action.to_s.upcase
152
+ build_capture_void_or_refund_request(post, amount, currency, payment_method_or_reference, authorization, options)
153
+ elsif action == :store
154
+ options[:command] = 'CREATE_TOKEN'
155
+ build_store_request(post, amount, currency, payment_method_or_reference, authorization, options)
156
+ end
157
+
158
+ url = (test? ? test_url : live_url)
159
+ response = parse(ssl_post(url, post_data(post), headers(options)))
160
+
161
+ Response.new(success_from(response),
162
+ message_from(response),
163
+ response,
164
+ authorization: authorization_from(response),
165
+ test: test?)
166
+ end
167
+
168
+ def parse(body)
169
+ JSON.parse(body)
170
+ rescue JSON::ParserError
171
+ {
172
+ 'error' => "Invalid response received from the PayU Latam API: #{body.inspect}"
173
+ }
174
+ end
175
+
176
+ def success_from(response)
177
+ response['code'] == 'SUCCESS' && (!response['creditCardToken'].nil? || (!response['transactionResponse'].nil? && response['transactionResponse']['state'] == 'APPROVED'))
178
+ end
179
+
180
+ def message_from(response)
181
+ msg = nil
182
+ unless response['transactionResponse'].nil?
183
+ if response['transactionResponse']['responseCode']
184
+ msg = RESPONSE_CODE[response['transactionResponse']['responseCode'].to_sym]
185
+ else
186
+ msg = response['transactionResponse']['state']
187
+ end
188
+ end
189
+ msg = (response['error'] ? response['error'] : 'Successful transaction') if msg.blank?
190
+ msg
191
+ end
192
+
193
+ def authorization_from(response)
194
+ return nil unless success_from(response)
195
+ # Store call
196
+ return response['creditCardToken']['creditCardTokenId'] if response['creditCardToken']
197
+ [response['transactionResponse']['orderId'], response['transactionResponse']['transactionId'], response['transactionResponse']['authorizationCode']].compact.join(';')
198
+ end
199
+
200
+ def build_auth_or_purchase_request(post, amount, currency, payment_method_or_reference, options = {})
201
+ add_common_params(post, options)
202
+ add_transaction_for_auth_or_purchase_request(post, amount, currency, payment_method_or_reference, options)
203
+ end
204
+
205
+ def build_capture_void_or_refund_request(post, amount, currency, payment_method_or_reference, authorization, options = {})
206
+ add_common_params(post, options)
207
+ add_transaction_for_capture_void_or_refund_request(post, amount, currency, payment_method_or_reference, authorization, options)
208
+ end
209
+
210
+ def build_store_request(post, amount, currency, payment_method_or_reference, authorization, options = {})
211
+ add_common_params(post, options)
212
+ add_credit_card_token_for_store_request(post, amount, currency, payment_method_or_reference, authorization, options)
213
+ end
214
+
215
+ def add_common_params(post, options = {})
216
+ post[:language] ||= options[:language] || 'en'
217
+ post[:command] ||= options[:command] || 'SUBMIT_TRANSACTION'
218
+ post[:test] = test? ? 'true' : 'false'
219
+ post[:merchant] = {
220
+ :apiLogin => options[:api_login] || @options[:api_login],
221
+ :apiKey => options[:api_key] || @options[:api_key]
222
+ }
223
+ end
224
+
225
+ def add_transaction_for_auth_or_purchase_request(post, amount, currency, payment_method_or_reference, options = {})
226
+ post[:transaction] ||= {}
227
+
228
+ add_transaction_order(post, amount, currency, payment_method_or_reference, options)
229
+ add_transaction_order_shipping_address(post, amount, currency, payment_method_or_reference, options)
230
+ add_transaction_order_buyer(post, amount, currency, payment_method_or_reference, options)
231
+ add_transaction_order_additional_values(post, amount, currency, payment_method_or_reference, options)
232
+ add_transaction_credit_card(post, amount, currency, payment_method_or_reference, options)
233
+ add_transaction_payer(post, amount, currency, payment_method_or_reference, options)
234
+ add_transaction_extra_parameters(post, amount, currency, payment_method_or_reference, options)
235
+
236
+ # For authorization and capture: AUTHORIZATION_AND_CAPTURE. For authorization: AUTHORIZATION. Required
237
+ post[:transaction][:type] ||= options[:transaction_type]
238
+ # The payment method. Required
239
+ post[:transaction][:paymentMethod] ||= (options[:payment_method] || (card_brand(payment_method_or_reference).upcase unless payment_method_or_reference.is_a? String))
240
+ # The transaction source
241
+ post[:transaction][:source] ||= options[:source] if options[:source]
242
+ # Expiration date of the transaction. For example: 2014-01-10’T’13:00:00. Applies only for cash payment methods
243
+ post[:transaction][:expirationDate] ||= options[:expiration_date] if options[:expiration_date]
244
+ # The session ID of the device on which the transaction takes place
245
+ post[:transaction][:deviceSessionId] ||= options[:session_id] if options[:session_id]
246
+ # The IP address of the connection where the transaction took place
247
+ post[:transaction][:ipAddress] ||= options[:ip] if options[:ip]
248
+ # The cookie stored on the device where the transaction takes place
249
+ post[:transaction][:cookie] ||= options[:cookie] if options[:cookie]
250
+ # The user agent of the browser where the transaction takes place
251
+ post[:transaction][:userAgent] ||= options[:user_agent] if options[:user_agent]
252
+ # It is mandatory only if your PayU account from Brazil is associated with a bank account in another country
253
+ post[:transaction][:termsAndConditionsAcepted] ||= options[:terms_and_conditions_accepted] if options[:terms_and_conditions_accepted]
254
+ # Undocumented
255
+ post[:transaction][:paymentCountry] ||= options[:payment_country]
256
+ # The stored token
257
+ post[:transaction][:creditCardTokenId] ||= payment_method_or_reference if payment_method_or_reference.is_a? String
258
+ end
259
+
260
+ def add_transaction_order(post, amount, currency, payment_method_or_reference, options = {})
261
+ # The order data. Required
262
+ post[:transaction][:order] ||= {}
263
+
264
+ # The identifier of the account. Required
265
+ post[:transaction][:order][:accountId] ||= (options[:country_account_id] || @options[:country_account_id])
266
+ # The reference code of the order. Represents the identifier of the transaction in the commercial system.
267
+ # It must be unique for each transaction. Required
268
+ post[:transaction][:order][:referenceCode] ||= options[:order_id]
269
+ # The order description. Required
270
+ post[:transaction][:order][:description] ||= options[:description]
271
+ # The language used in the system emails sent to the merchant and the customer. Required
272
+ post[:transaction][:order][:language] ||= options[:language]
273
+ # The notification or confirmation URL of the order
274
+ post[:transaction][:order][:notifyUrl] ||= options[:notify_url] if options[:notify_url]
275
+ # Partner ID used within PayU
276
+ post[:transaction][:order][:partnerId] ||= options[:partner_id] if options[:partner_id]
277
+ # The signature associated with order
278
+ post[:transaction][:order][:signature] ||= (options[:signature] || signature(amount, currency, options))
279
+ end
280
+
281
+ def signature(amount, currency, options = {})
282
+ raw = "#{options[:api_key] || @options[:api_key]}~#{options[:merchant_id] || @options[:merchant_id]}~#{options[:order_id]}~#{amount}~#{currency}"
283
+ Digest::MD5.hexdigest(raw)
284
+ end
285
+
286
+ def add_transaction_order_shipping_address(post, amount, currency, payment_method_or_reference, options = {})
287
+ address = (options[:shipping_address] || {})
288
+
289
+ # The shipping address of the order
290
+ post[:transaction][:order][:shippingAddress] ||= {}
291
+
292
+ # First line of the shipping address
293
+ post[:transaction][:order][:shippingAddress][:street1] ||= address[:address1] if address[:address1]
294
+ # Second line of the shipping address
295
+ post[:transaction][:order][:shippingAddress][:street2] ||= address[:address2] if address[:address2]
296
+ # City of the shipping address
297
+ post[:transaction][:order][:shippingAddress][:city] ||= address[:city] if address[:city]
298
+ # State or department of the shipping address. For brazil send only two characters. Example: If it's Sao Paulo send SP.
299
+ post[:transaction][:order][:shippingAddress][:state] ||= address[:state] if address[:state]
300
+ # Country of the shipping address
301
+ post[:transaction][:order][:shippingAddress][:country] ||= address[:country] if address[:country]
302
+ # Postal code of the shipping address
303
+ post[:transaction][:order][:shippingAddress][:postalCode] ||= address[:zip] if address[:zip]
304
+ # Telephone number associated with the shipping address
305
+ post[:transaction][:order][:shippingAddress][:phone] ||= address[:phone] if address[:phone]
306
+ end
307
+
308
+ def add_transaction_order_buyer(post, amount, currency, payment_method_or_reference, options = {})
309
+ address = (options[:shipping_address] || options[:billing_address] || {})
310
+
311
+ # Buyer information
312
+ post[:transaction][:order][:buyer] ||= {}
313
+
314
+ # Identifier of the buyer in the merchant’s system
315
+ post[:transaction][:order][:buyer][:merchantBuyerId] ||= options[:user_id] if options[:user_id]
316
+ # Buyer’s full name. Required in Brazil
317
+ post[:transaction][:order][:buyer][:fullName] ||= (address[:name] || (payment_method_or_reference.last_name if payment_method_or_reference.respond_to? :last_name))
318
+ # Buyer’s email address
319
+ post[:transaction][:order][:buyer][:emailAddress] ||= options[:email] if options[:email]
320
+ # Buyer’s contact telephone number
321
+ post[:transaction][:order][:buyer][:contactPhone] ||= address[:phone]
322
+ # Identification number of the buyer. For Brazil, you must use the CPF. Required in Brazil
323
+ post[:transaction][:order][:buyer][:dniNumber] ||= options[:buyer_dni_number] if options[:buyer_dni_number]
324
+ # CNPJ identification number if buyer is a company in Brazil. Required in Brazil
325
+ post[:transaction][:order][:buyer][:cnpj] ||= options[:buyer_cnpj] if options[:buyer_cnpj]
326
+
327
+ # Buyer’s shipping address. Required in Brazil
328
+ post[:transaction][:order][:buyer][:shippingAddress] ||= {}
329
+ # Additional line for shipping address of the buyer. Required in Brazil
330
+ post[:transaction][:order][:buyer][:shippingAddress][:street1] ||= address[:address1] if address[:address1]
331
+ # City of the shipping address of the buyer. Required in Brazil
332
+ post[:transaction][:order][:buyer][:shippingAddress][:city] ||= address[:city] if address[:city]
333
+ # State of the shipping address of the buyer. Required in Brazil
334
+ post[:transaction][:order][:buyer][:shippingAddress][:state] ||= address[:state] if address[:state]
335
+ # Country of the shipping address of the buyer. Required in Brazil
336
+ post[:transaction][:order][:buyer][:shippingAddress][:country] ||= address[:country] if address[:country]
337
+ # Postal code of the shipping address of the buyer. For Brazil you must use the CEP. Required in Brazil
338
+ post[:transaction][:order][:buyer][:shippingAddress][:postalCode] ||= address[:zip] if address[:zip]
339
+ # Telephone of the buyer’s shipping address. Required in Brazil
340
+ post[:transaction][:order][:buyer][:shippingAddress][:phone] ||= address[:phone] if address[:phone]
341
+ end
342
+
343
+ def add_transaction_order_additional_values(post, amount, currency, payment_method_or_reference, options = {})
344
+ # Values or amounts associated with the order. In this field you can set an amount per ticket.
345
+ post[:transaction][:order][:additionalValues] ||= {}
346
+
347
+ # The type of amount: TX_VALUE, TX_TAX, TX_TAX_RETURN_BASE, TX_ADDITIONAL_VALUE
348
+ post[:transaction][:order][:additionalValues][:TX_VALUE] ||= {}
349
+ # The value. For example: 1000.00
350
+ post[:transaction][:order][:additionalValues][:TX_VALUE][:value] ||= amount if amount
351
+ # The ISO currency code associated with the amount
352
+ post[:transaction][:order][:additionalValues][:TX_VALUE][:currency] ||= currency if currency
353
+ end
354
+
355
+ def add_transaction_credit_card(post, amount, currency, payment_method_or_reference, options = {})
356
+ # The data of the credit card used
357
+ post[:transaction][:creditCard] ||= {}
358
+
359
+ # The number of the credit card used. Required
360
+ post[:transaction][:creditCard][:number] ||= payment_method_or_reference.number if payment_method_or_reference.respond_to? :number
361
+ # The security code found on the back of the credit card (CVC2, CVV2, CID)
362
+ post[:transaction][:creditCard][:securityCode] ||= (options[:security_code] || (payment_method_or_reference.verification_value if payment_method_or_reference.respond_to? :verification_value))
363
+ # The date of expiration of the card. Format YYYY/MM. Required
364
+ post[:transaction][:creditCard][:expirationDate] ||= "#{format(payment_method_or_reference.year, :four_digits)}/#{format(payment_method_or_reference.month, :two_digits)}" if payment_method_or_reference.respond_to? :year
365
+ # The name of the credit card holder. Required
366
+ post[:transaction][:creditCard][:name] ||= payment_method_or_reference.last_name if payment_method_or_reference.respond_to? :last_name
367
+ # The name of the bank that issued the credit card
368
+ post[:transaction][:creditCard][:issuerBank] ||= options[:issuer] if options[:issuer]
369
+ # Allows processing of credit card transactions without the security code cvv2. Available only for accounts active in Brazil. Requires prior PayU authorization before use.
370
+ post[:transaction][:creditCard][:processWithoutCvv2] ||= (options[:ignore_cvv] || (@options[:ignore_cvv] ? 'true' : 'false'))
371
+ end
372
+
373
+ def add_transaction_payer(post, amount, currency, payment_method_or_reference, options = {})
374
+ address = (options[:payer_billing_address] || {})
375
+
376
+ # The information of the payer
377
+ post[:transaction][:payer] ||= {}
378
+ # The identifier of the payer in the commercial system
379
+ post[:transaction][:payer][:merchantPayerId] ||= options[:payer_user_id] if options[:payer_user_id]
380
+ # The complete name of the payer. Required
381
+ post[:transaction][:payer][:fullName] ||= (address[:name] || (payment_method_or_reference.last_name if payment_method_or_reference.respond_to? :last_name))
382
+
383
+ # The billing address
384
+ post[:transaction][:payer][:billingAddress] ||= {}
385
+ # The first line of the billing address
386
+ post[:transaction][:payer][:billingAddress][:street1] ||= address[:address1] if address[:address1]
387
+ # The second line of the billing address
388
+ post[:transaction][:payer][:billingAddress][:street2] ||= address[:address2] if address[:address2]
389
+ # The city of the billing address
390
+ post[:transaction][:payer][:billingAddress][:city] ||= address[:city] if address[:city]
391
+ # The state or department of the billing address
392
+ post[:transaction][:payer][:billingAddress][:state] ||= address[:state] if address[:state]
393
+ # The country of the billing address
394
+ post[:transaction][:payer][:billingAddress][:country] ||= address[:country] if address[:country]
395
+ # The postal code of the billing address
396
+ post[:transaction][:payer][:billingAddress][:postalCode] ||= address[:zip] if address[:zip]
397
+ # The telephone number associated with the billing address
398
+ post[:transaction][:payer][:billingAddress][:phone] ||= address[:phone] if address[:phone]
399
+
400
+ # The email of the payer
401
+ post[:transaction][:payer][:emailAddress] ||= options[:payer_email] if options[:payer_email]
402
+ # The telephone number of the payer
403
+ post[:transaction][:payer][:contactPhone] ||= address[:phone] if address[:phone]
404
+ # The identification number of the payer. Required in Brazil
405
+ post[:transaction][:payer][:dniNumber] ||= options[:payer_dni_number] if options[:payer_dni_number]
406
+ end
407
+
408
+ def add_transaction_extra_parameters(post, amount, currency, payment_method_or_reference, options = {})
409
+ # Additional parameters or data associated with a transaction. These parameters may vary according to the means of payment or transaction preferences
410
+ post[:transaction][:extraParameters] ||= {}
411
+ post[:transaction][:extraParameters][:INSTALLMENTS_NUMBER] ||= (options[:installments_number] || 1)
412
+ end
413
+
414
+ def add_transaction_for_capture_void_or_refund_request(post, amount, currency, payment_method_or_reference, authorization, options = {})
415
+ order_id, transaction_id, authorization_code = authorization.split(';')
416
+
417
+ # The transaction data. Required
418
+ post[:transaction] ||= {}
419
+
420
+ # The order data. Required
421
+ post[:transaction][:order] ||= {}
422
+ # The ID of the transaction associated with the order
423
+ post[:transaction][:order][:id] ||= order_id
424
+
425
+ # Use CAPTURE, VOID for cancellation, and REFUND
426
+ post[:transaction][:type] ||= options[:transaction_type]
427
+ # The identifier of the related transaction. Required
428
+ # If the current transaction is CAPTURE or VOID, the identifier of the transaction is sent as AUTHORIZATION.
429
+ # If the current transaction is REFUND, the identifier of the transaction is sent as AUTHORIZATION_AND_CAPTURE or CAPTURE.
430
+ post[:transaction][:parentTransactionId] = transaction_id
431
+ end
432
+
433
+ def add_credit_card_token_for_store_request(post, amount, currency, payment_method_or_reference, authorization, options = {})
434
+ post[:creditCardToken] ||= {}
435
+
436
+ # Unique identifier of the payer in the shop
437
+ post[:creditCardToken][:payerId] ||= options[:payer_user_id] if options[:payer_user_id]
438
+ # Cardholder data must be filled out as they appear on the credit card
439
+ post[:creditCardToken][:name] ||= payment_method_or_reference.last_name if payment_method_or_reference.respond_to? :last_name
440
+ # Client identification number
441
+ post[:creditCardToken][:identificationNumber] ||= options[:identification_number] if options[:identification_number]
442
+ # Ex. Visa, MasterCard, American Express, etc.
443
+ post[:creditCardToken][:paymentMethod] ||= (options[:payment_method] || card_brand(payment_method_or_reference).upcase)
444
+ # Number of credit card
445
+ post[:creditCardToken][:number] ||= payment_method_or_reference.number if payment_method_or_reference.respond_to? :number
446
+ # Expiration date of the credit card
447
+ post[:creditCardToken][:expirationDate] ||= "#{format(payment_method_or_reference.year, :four_digits)}/#{format(payment_method_or_reference.month, :two_digits)}" if payment_method_or_reference.respond_to? :year
448
+ end
449
+
450
+ def post_data(params)
451
+ params.nil? ? '{}' : params.to_json
452
+ end
453
+
454
+ def headers(options)
455
+ {
456
+ 'Accept' => 'application/json',
457
+ 'Content-Type' => 'application/json; charset=utf-8',
458
+ }
459
+ end
460
+ end
461
+ end
462
+ end