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,47 @@
1
+ module ActiveMerchant #:nodoc:
2
+ module Billing #:nodoc:
3
+ class OrbitalSoftDescriptors < Model
4
+ PHONE_FORMAT_1 = /\A\d{3}-\d{3}-\d{4}\z/
5
+ PHONE_FORMAT_2 = /\A\d{3}-\w{7}\z/
6
+
7
+ # ==== Tampa PNS Soft Descriptors
8
+ # The support for Soft Descriptors via the PNS Host is only for customers processing through Chase
9
+ # Paymentech Canada.
10
+
11
+ # Unlike Salem, the only value that gets passed on the cardholder statement is the Merchant Name field.
12
+ # And for these customers, it is a maximum of 25 bytes of data.
13
+ #
14
+ # All other Soft Descriptor fields can optionally be sent, but will not be submitted to the settlement host
15
+ # and will not display on the cardholder statement.
16
+
17
+ attr_accessor :merchant_name, :product_description, :merchant_city, :merchant_phone, :merchant_url, :merchant_email
18
+
19
+ def initialize(options = {})
20
+ self.merchant_name = options[:merchant_name]
21
+ self.merchant_city = options[:merchant_city]
22
+ self.merchant_phone = options[:merchant_phone]
23
+ self.merchant_url = options[:merchant_url]
24
+ self.merchant_email = options[:merchant_email]
25
+ end
26
+
27
+ def validate
28
+ errors = []
29
+
30
+ errors << [:merchant_name, "is required"] if self.merchant_name.blank?
31
+ errors << [:merchant_name, "is required to be 25 bytes or less"] if self.merchant_name.bytesize > 25
32
+
33
+ if(!empty?(self.merchant_phone) && !self.merchant_phone.match(PHONE_FORMAT_1) && !self.merchant_phone.match(PHONE_FORMAT_2))
34
+ errors << [:merchant_phone, "is required to follow \"NNN-NNN-NNNN\" or \"NNN-AAAAAAA\" format"]
35
+ end
36
+
37
+ [:merchant_email, :merchant_url].each do |attr|
38
+ unless self.send(attr).blank?
39
+ errors << [attr, "is required to be 13 bytes or less"] if(self.send(attr).bytesize > 13)
40
+ end
41
+ end
42
+
43
+ errors_hash(errors)
44
+ end
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,207 @@
1
+ module ActiveMerchant #:nodoc:
2
+ module Billing #:nodoc:
3
+ class PacNetRavenGateway < Gateway
4
+
5
+ AVS_ADDRESS_CODES = {
6
+ 'avs_address_unavailable' => 'X',
7
+ 'avs_address_not_checked' => 'X',
8
+ 'avs_address_matched' => 'Y',
9
+ 'avs_address_not_matched' => 'N',
10
+ 'avs_address_partial_match' => 'N'
11
+ }
12
+
13
+ AVS_POSTAL_CODES = {
14
+ 'avs_postal_unavailable' => 'X',
15
+ 'avs_postal_not_checked' => 'X',
16
+ 'avs_postal_matched' => 'Y',
17
+ 'avs_postal_not_matched' => 'N',
18
+ 'avs_postal_partial_match' => 'N'
19
+ }
20
+
21
+ CVV2_CODES = {
22
+ 'cvv2_matched' => 'Y',
23
+ 'cvv2_not_matched' => 'N',
24
+ 'cvv2_unavailable' => 'X',
25
+ 'cvv2_not_checked' => 'X'
26
+ }
27
+
28
+ self.test_url = 'https://demo.deepcovelabs.com/realtime/'
29
+ self.live_url = 'https://raven.pacnetservices.com/realtime/'
30
+
31
+ self.supported_countries = ['US']
32
+ self.supported_cardtypes = [:visa, :master]
33
+ self.money_format = :cents
34
+ self.default_currency = 'USD'
35
+ self.homepage_url = 'http://www.pacnetservices.com/'
36
+ self.display_name = 'Raven PacNet'
37
+
38
+ def initialize(options = {})
39
+ requires!(options, :user, :secret, :prn)
40
+ super
41
+ end
42
+
43
+ def authorize(money, creditcard, options = {})
44
+ post = {}
45
+ add_creditcard(post, creditcard)
46
+ add_currency_code(post, money, options)
47
+ add_address(post, options)
48
+ post['PRN'] = @options[:prn]
49
+
50
+ commit('cc_preauth', money, post)
51
+ end
52
+
53
+ def purchase(money, creditcard, options = {})
54
+ post = {}
55
+ add_currency_code(post, money, options)
56
+ add_creditcard(post, creditcard)
57
+ add_address(post, options)
58
+ post['PRN'] = @options[:prn]
59
+
60
+ commit('cc_debit', money, post)
61
+ end
62
+
63
+ def void(authorization, options = {})
64
+ post = {}
65
+ post['TrackingNumber'] = authorization
66
+ post['PymtType'] = options[:pymt_type] || 'cc_debit'
67
+
68
+ commit('void', nil, post)
69
+ end
70
+
71
+ def capture(money, authorization, options = {})
72
+ post = {}
73
+ post['PreauthNumber'] = authorization
74
+ post['PRN'] = @options[:prn]
75
+ add_currency_code(post, money, options)
76
+
77
+ commit('cc_settle', money, post)
78
+ end
79
+
80
+ def refund(money, template_number, options = {})
81
+ post = {}
82
+ post['PRN'] = @options[:prn]
83
+ post['TemplateNumber'] = template_number
84
+ add_currency_code(post, money, options)
85
+
86
+ commit('cc_refund', money, post)
87
+ end
88
+
89
+ private
90
+
91
+ def add_creditcard(post, creditcard)
92
+ post['CardNumber'] = creditcard.number
93
+ post['Expiry'] = expdate(creditcard)
94
+ post['CVV2'] = creditcard.verification_value if creditcard.verification_value
95
+ end
96
+
97
+ def add_currency_code(post, money, options)
98
+ post['Currency'] = options[:currency] || currency(money)
99
+ end
100
+
101
+ def add_address(post, options)
102
+ if address = options[:billing_address] || options[:address]
103
+ post['BillingStreetAddressLineOne'] = address[:address1].to_s
104
+ post['BillingStreetAddressLineFour'] = address[:address2].to_s
105
+ post['BillingPostalCode'] = address[:zip].to_s
106
+ end
107
+ end
108
+
109
+ def parse(body)
110
+ Hash[body.split('&').map{|x| x.split('=').map{|y| CGI.unescape(y)}}]
111
+ end
112
+
113
+ def commit(action, money, parameters)
114
+ parameters['Amount'] = amount(money) unless action == 'void'
115
+
116
+ data = ssl_post url(action), post_data(action, parameters)
117
+
118
+ response = parse(data)
119
+ response[:action] = action
120
+
121
+ message = message_from(response)
122
+
123
+ test_mode = test? || message =~ /TESTMODE/
124
+
125
+ Response.new(success?(response), message, response,
126
+ :test => test_mode,
127
+ :authorization => response['TrackingNumber'],
128
+ :fraud_review => fraud_review?(response),
129
+ :avs_result => {
130
+ :postal_match => AVS_POSTAL_CODES[response['AVSPostalResponseCode']],
131
+ :street_match => AVS_ADDRESS_CODES[response['AVSAddressResponseCode']]
132
+ },
133
+ :cvv_result => CVV2_CODES[response['CVV2ResponseCode']]
134
+ )
135
+ end
136
+
137
+ def url(action)
138
+ (test? ? self.test_url : self.live_url) + endpoint(action)
139
+ end
140
+
141
+ def endpoint(action)
142
+ return 'void' if action == 'void'
143
+ 'submit'
144
+ end
145
+
146
+ def fraud_review?(response)
147
+ false
148
+ end
149
+
150
+ def success?(response)
151
+ if %w(cc_settle cc_debit cc_preauth cc_refund).include?(response[:action])
152
+ !response['ApprovalCode'].nil? and response['ErrorCode'].nil? and response['Status'] == 'Approved'
153
+ elsif response[:action] = 'void'
154
+ !response['ApprovalCode'].nil? and response['ErrorCode'].nil? and response['Status'] == 'Voided'
155
+ end
156
+ end
157
+
158
+ def message_from(response)
159
+ return response['Message'] if response['Message']
160
+
161
+ if response['Status'] == 'Approved'
162
+ "This transaction has been approved"
163
+ elsif response['Status'] == 'Declined'
164
+ "This transaction has been declined"
165
+ elsif response['Status'] == 'Voided'
166
+ "This transaction has been voided"
167
+ else
168
+ response['Status']
169
+ end
170
+ end
171
+
172
+ def post_data(action, parameters = {})
173
+ post = {}
174
+
175
+ post['PymtType'] = action
176
+ post['RAPIVersion'] = '2'
177
+ post['UserName'] = @options[:user]
178
+ post['Timestamp'] = timestamp
179
+ post['RequestID'] = request_id
180
+ post['Signature'] = signature(action, post, parameters)
181
+
182
+ request = post.merge(parameters).collect { |key, value| "#{key}=#{CGI.escape(value.to_s)}" }.join("&")
183
+ request
184
+ end
185
+
186
+ def timestamp
187
+ Time.now.strftime("%Y-%m-%dT%H:%M:%S.Z")
188
+ end
189
+
190
+ def request_id
191
+ SecureRandom.uuid
192
+ end
193
+
194
+ def signature(action, post, parameters = {})
195
+ string = if %w(cc_settle cc_debit cc_preauth cc_refund).include?(action)
196
+ post['UserName'] + post['Timestamp'] + post['RequestID'] + post['PymtType'] + parameters['Amount'].to_s + parameters['Currency']
197
+ elsif action == 'void'
198
+ post['UserName'] + post['Timestamp'] + post['RequestID'] + parameters['TrackingNumber']
199
+ else
200
+ post['UserName']
201
+ end
202
+ OpenSSL::HMAC.hexdigest(OpenSSL::Digest::SHA1.new(@options[:secret]), @options[:secret], string)
203
+ end
204
+ end
205
+ end
206
+ end
207
+
@@ -0,0 +1,122 @@
1
+ module ActiveMerchant #:nodoc:
2
+ module Billing #:nodoc:
3
+ class PagoFacilGateway < Gateway
4
+ self.test_url = 'https://www.pagofacil.net/st/public/Wsrtransaccion/index/format/json?'
5
+ self.live_url = 'https://www.pagofacil.net/ws/public/Wsrtransaccion/index/format/json?'
6
+
7
+ self.supported_countries = ['MX']
8
+ self.default_currency = 'MXN'
9
+ self.supported_cardtypes = [:visa, :master, :american_express, :jcb]
10
+
11
+ self.homepage_url = 'http://www.pagofacil.net/'
12
+ self.display_name = 'PagoFacil'
13
+
14
+ def initialize(options={})
15
+ requires!(options, :branch_id, :merchant_id, :service_id)
16
+ super
17
+ end
18
+
19
+ def purchase(money, credit_card, options={})
20
+ post = {}
21
+ add_invoice(post, money, options)
22
+ add_payment(post, credit_card)
23
+ add_address(post, options)
24
+ add_customer_data(post, options)
25
+ add_merchant_data(post)
26
+
27
+ commit(post)
28
+ end
29
+
30
+ private
31
+
32
+ def add_customer_data(post, options)
33
+ post[:email] = options[:email]
34
+ post[:celular] = options[:cellphone]
35
+ end
36
+
37
+ def add_address(post, options)
38
+ address = options.fetch(:billing_address, {})
39
+ post[:calleyNumero] = address[:address1]
40
+ post[:colonia] = address[:address2]
41
+ post[:municipio] = address[:city]
42
+ post[:estado] = address[:state]
43
+ post[:pais] = address[:country]
44
+ post[:telefono] = address[:phone]
45
+ post[:cp] = address[:zip]
46
+ end
47
+
48
+ def add_invoice(post, money, options)
49
+ post[:monto] = amount(money)
50
+ post[:idPedido] = options[:order_id]
51
+ add_currency(post, money, options)
52
+ end
53
+
54
+ def add_currency(post, money, options)
55
+ currency = options.fetch(:currency, currency(money))
56
+ unless currency == self.class.default_currency
57
+ post[:divisa] = currency
58
+ end
59
+ end
60
+
61
+ def add_payment(post, credit_card)
62
+ post[:nombre] = credit_card.first_name
63
+ post[:apellidos] = credit_card.last_name
64
+ post[:numeroTarjeta] = credit_card.number
65
+ post[:cvt] = credit_card.verification_value
66
+ post[:mesExpiracion] = sprintf("%02d", credit_card.month)
67
+ post[:anyoExpiracion] = credit_card.year.to_s.slice(-2, 2)
68
+ end
69
+
70
+ def add_merchant_data(post)
71
+ post[:idSucursal] = options.fetch(:branch_id)
72
+ post[:idUsuario] = options.fetch(:merchant_id)
73
+ post[:idServicio] = options.fetch(:service_id)
74
+ end
75
+
76
+ def parse(body)
77
+ JSON.parse(body)["WebServices_Transacciones"]["transaccion"]
78
+ rescue JSON::ParserError
79
+ json_error(body)
80
+ end
81
+
82
+ def commit(parameters)
83
+ url = (test? ? test_url : live_url)
84
+ response = parse(ssl_post(url, post_data(parameters)))
85
+ Response.new(
86
+ success_from(response),
87
+ message_from(response),
88
+ response,
89
+ authorization: authorization_from(response),
90
+ test: test?
91
+ )
92
+ end
93
+
94
+ def success_from(response)
95
+ response["autorizado"] == "1" ||
96
+ response["autorizado"] == true
97
+ end
98
+
99
+ def message_from(response)
100
+ response["texto"]
101
+ end
102
+
103
+ def authorization_from(response)
104
+ response["autorizacion"]
105
+ end
106
+
107
+ def post_data(parameters = {})
108
+ {
109
+ method: 'transaccion',
110
+ data: parameters
111
+ }.to_query
112
+ end
113
+
114
+ def json_error(response)
115
+ {
116
+ "texto" => 'Invalid response received from the PagoFacil API.',
117
+ "raw_response" => response
118
+ }
119
+ end
120
+ end
121
+ end
122
+ end
@@ -0,0 +1,261 @@
1
+ require 'digest/md5'
2
+
3
+ module ActiveMerchant #:nodoc:
4
+ module Billing #:nodoc:
5
+ # This gateway accepts the following arguments:
6
+ # :login => your PayJunction username
7
+ # :password => your PayJunction pass
8
+ # Example use:
9
+ #
10
+ # gateway = ActiveMerchant::Billing::Base.gateway(:pay_gate_xml).new(
11
+ # :login => "my_account",
12
+ # :password => "my_pass"
13
+ # )
14
+ #
15
+ # # set up credit card obj as in main ActiveMerchant example
16
+ # creditcard = ActiveMerchant::Billing::CreditCard.new(
17
+ # :type => 'visa',
18
+ # :number => '4242424242424242',
19
+ # :month => 8,
20
+ # :year => 2009,
21
+ # :first_name => 'Bob',
22
+ # :last_name => 'Bobsen'
23
+ # )
24
+ #
25
+ # # run request
26
+ # response = gateway.purchase(1000, creditcard) # charge 10 dollars
27
+ #
28
+ # 1) Check whether the transaction was successful
29
+ #
30
+ # response.success?
31
+ #
32
+ # 2) Retrieve the message returned by PayJunction
33
+ #
34
+ # response.message
35
+ #
36
+ # 3) Retrieve the unique transaction ID returned by PayGateXML
37
+ #
38
+ # response.authorization
39
+ #
40
+ # This gateway has many other features which are not implemented here yet
41
+ # The basic setup here only supports auth/capture transactions.
42
+ #
43
+ # Test Transactions
44
+ #
45
+ # PayGateXML has a global test user/pass, but you can also sign up for your own.
46
+ # The class and the test come equipped with the global test creds
47
+ #
48
+ # Usage Details
49
+ #
50
+ # Below is a map of only SOME of the values accepted by PayGateXML and how you should submit
51
+ # each to ActiveMerchant
52
+ #
53
+ # PayGateXML Field ActiveMerchant Use
54
+ #
55
+ # pgid use :login value to gateway instantation
56
+ # pwd use :password value to gateway instantiation
57
+ #
58
+ # cname credit_card.name
59
+ # cc credit_card.number
60
+ # exp credit_card values formatted to YYYYMMDD
61
+ # budp South Africa only - set to 0 if purchase is not on budget
62
+ # amt include as argument to method for your transaction type
63
+ # ver do nothing, always set to current API version
64
+ #
65
+ # cref provide as :invoice in options, varchar(80)
66
+ # cur 3 char field, currently only ZAR
67
+ # cvv credit_card.verification
68
+ # bno batch processing number, i.e. you supply this
69
+ #
70
+ # others -- not used in this implementation
71
+ # nurl, rurl - must remain blank or absent or they will use an alternative authentication mechanism
72
+ # email, ip - must remain blank or absent or they will use a PayGate extra service call PayProtector
73
+ # threed - must remain blank unless you are using your own 3D Secure server
74
+ #
75
+ class PayGateXmlGateway < Gateway
76
+ self.live_url = 'https://www.paygate.co.za/payxml/process.trans'
77
+
78
+ # The countries the gateway supports merchants from as 2 digit ISO country codes
79
+ self.supported_countries = ['US', 'ZA']
80
+
81
+ # The card types supported by the payment gateway
82
+ self.supported_cardtypes = [:visa, :master, :american_express, :diners_club]
83
+
84
+ # The homepage URL of the gateway
85
+ self.homepage_url = 'http://paygate.co.za/'
86
+
87
+ # The name of the gateway
88
+ self.display_name = 'PayGate PayXML'
89
+
90
+ # PayGate only supports Rands
91
+ self.default_currency = 'ZAR'
92
+
93
+ # PayGate accepts only lowest denomination
94
+ self.money_format = :cents
95
+
96
+ # PayGateXML public test account - you can get a private one too
97
+ TEST_ID_3DSECURE = '10011013800'
98
+ TEST_ID = '10011021600'
99
+ TEST_PWD = 'test'
100
+
101
+ API_VERSION = '4.0'
102
+
103
+ DECLINE_CODES = {
104
+ # Credit Card Errors - These RESULT_CODEs are returned if the transaction cannot be authorized due to a problem with the card. The TRANSACTION_STATUS will be 2
105
+ 900001 => "Call for Approval",
106
+ 900002 => "Card Expired",
107
+ 900003 => "Insufficient Funds",
108
+ 900004 => "Invalid Card Number",
109
+ 900005 => "Bank Interface Timeout", # indicates a communications failure between the banks systems
110
+ 900006 => "Invalid Card",
111
+ 900007 => "Declined",
112
+ 900009 => "Lost Card",
113
+ 900010 => "Invalid Card Length",
114
+ 900011 => "Suspected Fraud",
115
+ 900012 => "Card Reported As Stolen",
116
+ 900013 => "Restricted Card",
117
+ 900014 => "Excessive Card Usage",
118
+ 900015 => "Card Blacklisted",
119
+
120
+ 900207 => "Declined; authentication failed", # indicates the cardholder did not enter their MasterCard SecureCode / Verified by Visa password correctly
121
+
122
+ 990020 => "Auth Declined",
123
+
124
+ 991001 => "Invalid expiry date",
125
+ 991002 => "Invalid amount",
126
+
127
+ # Communication Errors - These RESULT_CODEs are returned if the transaction cannot be completed due to an unexpected error. TRANSACTION_STATUS will be 0.
128
+ 900205 => "Unexpected authentication result (phase 1)",
129
+ 900206 => "Unexpected authentication result (phase 1)",
130
+
131
+ 990001 => "Could not insert into Database",
132
+
133
+ 990022 => "Bank not available",
134
+
135
+ 990053 => "Error processing transaction",
136
+
137
+ # Miscellaneous - Unless otherwise noted, the TRANSACTION_STATUS will be 0.
138
+ 900209 => "Transaction verification failed (phase 2)", # Indicates the verification data returned from MasterCard SecureCode / Verified by Visa has been altered
139
+ 900210 => "Authentication complete; transaction must be restarted", # Indicates that the MasterCard SecuerCode / Verified by Visa transaction has already been completed. Most likely caused by the customer clicking the refresh button
140
+
141
+ 990024 => "Duplicate Transaction Detected. Please check before submitting",
142
+
143
+ 990028 => "Transaction cancelled" # Customer clicks the 'Cancel' button on the payment page
144
+ }
145
+
146
+ SUCCESS_CODES = %w( 990004 990005 990017 990012 990018 990031 )
147
+
148
+ TRANSACTION_CODES = {
149
+ 0 => 'Not Done',
150
+ 1 => 'Approved',
151
+ 2 => 'Declined',
152
+ 3 => 'Paid',
153
+ 4 => 'Refunded',
154
+ 5 => 'Received by PayGate',
155
+ 6 => 'Replied to Client'
156
+ }
157
+
158
+ def initialize(options = {})
159
+ requires!(options, :login, :password)
160
+ super
161
+ end
162
+
163
+ def purchase(money, creditcard, options = {})
164
+ MultiResponse.run do |r|
165
+ r.process{authorize(money, creditcard, options)}
166
+ r.process{capture(money, r.authorization, options)}
167
+ end
168
+ end
169
+
170
+ def authorize(money, creditcard, options = {})
171
+ action = 'authtx'
172
+
173
+ options.merge!(:money => money, :creditcard => creditcard)
174
+ commit(action, build_request(action, options))
175
+ end
176
+
177
+ def capture(money, authorization, options = {})
178
+ action = 'settletx'
179
+
180
+ options.merge!(:money => money, :authorization => authorization)
181
+ commit(action, build_request(action, options))
182
+ end
183
+
184
+ private
185
+
186
+ def successful?(response)
187
+ SUCCESS_CODES.include?(response[:res])
188
+ end
189
+
190
+ def build_request(action, options={})
191
+ xml = Builder::XmlMarkup.new
192
+ xml.instruct!
193
+
194
+ xml.tag! 'protocol', :ver => API_VERSION, :pgid => (test? ? TEST_ID : @options[:login]), :pwd => @options[:password] do |protocol|
195
+ case action
196
+ when 'authtx'
197
+ money = options.delete(:money)
198
+ creditcard = options.delete(:creditcard)
199
+ build_authorization(protocol, money, creditcard, options)
200
+ when 'settletx'
201
+ money = options.delete(:money)
202
+ authorization = options.delete(:authorization)
203
+ build_capture(protocol, money, authorization, options)
204
+ else
205
+ raise "no action specified for build_request"
206
+ end
207
+ end
208
+
209
+ xml.target!
210
+ end
211
+
212
+ def build_authorization(xml, money, creditcard, options={})
213
+ xml.tag! 'authtx', {
214
+ :cref => options[:order_id],
215
+ :cname => creditcard.name,
216
+ :cc => creditcard.number,
217
+ :exp => "#{format(creditcard.month, :two_digits)}#{format(creditcard.year, :four_digits)}",
218
+ :budp => 0,
219
+ :amt => amount(money),
220
+ :cur => (options[:currency] || currency(money)),
221
+ :cvv => creditcard.verification_value
222
+ }
223
+ end
224
+
225
+ def build_capture(xml, money, authorization, options={})
226
+ xml.tag! 'settletx', {
227
+ :tid => authorization
228
+ }
229
+ end
230
+
231
+ def parse(action, body)
232
+ hash = {}
233
+ xml = REXML::Document.new(body)
234
+
235
+ response_action = action.gsub(/tx/, 'rx')
236
+ root = REXML::XPath.first(xml.root, response_action)
237
+ # we might have gotten an error
238
+ if root.nil?
239
+ root = REXML::XPath.first(xml.root, 'errorrx')
240
+ end
241
+ root.attributes.each do |name, value|
242
+ hash[name.to_sym] = value
243
+ end
244
+ hash
245
+ end
246
+
247
+ def commit(action, request)
248
+ response = parse(action, ssl_post(self.live_url, request))
249
+ Response.new(successful?(response), message_from(response), response,
250
+ :test => test?,
251
+ :authorization => response[:tid]
252
+ )
253
+ end
254
+
255
+ def message_from(response)
256
+ (response[:rdesc] || response[:edesc])
257
+ end
258
+ end
259
+ end
260
+ end
261
+