gonow-activemerchant 1.15.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 (189) hide show
  1. data/CHANGELOG +690 -0
  2. data/CONTRIBUTORS +237 -0
  3. data/MIT-LICENSE +20 -0
  4. data/README.rdoc +165 -0
  5. data/gem-public_cert.pem +20 -0
  6. data/lib/active_merchant.rb +47 -0
  7. data/lib/active_merchant/billing.rb +9 -0
  8. data/lib/active_merchant/billing/avs_result.rb +98 -0
  9. data/lib/active_merchant/billing/base.rb +57 -0
  10. data/lib/active_merchant/billing/check.rb +68 -0
  11. data/lib/active_merchant/billing/credit_card.rb +178 -0
  12. data/lib/active_merchant/billing/credit_card_formatting.rb +21 -0
  13. data/lib/active_merchant/billing/credit_card_methods.rb +125 -0
  14. data/lib/active_merchant/billing/cvv_result.rb +38 -0
  15. data/lib/active_merchant/billing/expiry_date.rb +34 -0
  16. data/lib/active_merchant/billing/gateway.rb +170 -0
  17. data/lib/active_merchant/billing/gateways.rb +18 -0
  18. data/lib/active_merchant/billing/gateways/authorize_net.rb +664 -0
  19. data/lib/active_merchant/billing/gateways/authorize_net_cim.rb +858 -0
  20. data/lib/active_merchant/billing/gateways/barclays_epdq.rb +308 -0
  21. data/lib/active_merchant/billing/gateways/beanstream.rb +139 -0
  22. data/lib/active_merchant/billing/gateways/beanstream/beanstream_core.rb +282 -0
  23. data/lib/active_merchant/billing/gateways/beanstream_interac.rb +54 -0
  24. data/lib/active_merchant/billing/gateways/blue_pay.rb +11 -0
  25. data/lib/active_merchant/billing/gateways/bogus.rb +132 -0
  26. data/lib/active_merchant/billing/gateways/braintree.rb +17 -0
  27. data/lib/active_merchant/billing/gateways/braintree/braintree_common.rb +9 -0
  28. data/lib/active_merchant/billing/gateways/braintree_blue.rb +293 -0
  29. data/lib/active_merchant/billing/gateways/braintree_orange.rb +17 -0
  30. data/lib/active_merchant/billing/gateways/braspag.rb +188 -0
  31. data/lib/active_merchant/billing/gateways/card_stream.rb +230 -0
  32. data/lib/active_merchant/billing/gateways/cyber_source.rb +430 -0
  33. data/lib/active_merchant/billing/gateways/data_cash.rb +597 -0
  34. data/lib/active_merchant/billing/gateways/efsnet.rb +235 -0
  35. data/lib/active_merchant/billing/gateways/elavon.rb +134 -0
  36. data/lib/active_merchant/billing/gateways/epay.rb +268 -0
  37. data/lib/active_merchant/billing/gateways/eway.rb +277 -0
  38. data/lib/active_merchant/billing/gateways/eway_managed.rb +231 -0
  39. data/lib/active_merchant/billing/gateways/exact.rb +222 -0
  40. data/lib/active_merchant/billing/gateways/federated_canada.rb +168 -0
  41. data/lib/active_merchant/billing/gateways/first_pay.rb +177 -0
  42. data/lib/active_merchant/billing/gateways/garanti.rb +262 -0
  43. data/lib/active_merchant/billing/gateways/ideal/ideal_base.rb +250 -0
  44. data/lib/active_merchant/billing/gateways/ideal/ideal_rabobank.pem +13 -0
  45. data/lib/active_merchant/billing/gateways/ideal/ideal_response.rb +29 -0
  46. data/lib/active_merchant/billing/gateways/ideal_rabobank.rb +55 -0
  47. data/lib/active_merchant/billing/gateways/inspire.rb +221 -0
  48. data/lib/active_merchant/billing/gateways/instapay.rb +164 -0
  49. data/lib/active_merchant/billing/gateways/iridium.rb +258 -0
  50. data/lib/active_merchant/billing/gateways/jetpay.rb +276 -0
  51. data/lib/active_merchant/billing/gateways/linkpoint.rb +454 -0
  52. data/lib/active_merchant/billing/gateways/merchant_e_solutions.rb +156 -0
  53. data/lib/active_merchant/billing/gateways/merchant_ware.rb +289 -0
  54. data/lib/active_merchant/billing/gateways/modern_payments.rb +36 -0
  55. data/lib/active_merchant/billing/gateways/modern_payments_cim.rb +220 -0
  56. data/lib/active_merchant/billing/gateways/moneris.rb +209 -0
  57. data/lib/active_merchant/billing/gateways/net_registry.rb +189 -0
  58. data/lib/active_merchant/billing/gateways/netaxept.rb +239 -0
  59. data/lib/active_merchant/billing/gateways/netbilling.rb +168 -0
  60. data/lib/active_merchant/billing/gateways/nmi.rb +13 -0
  61. data/lib/active_merchant/billing/gateways/ogone.rb +292 -0
  62. data/lib/active_merchant/billing/gateways/orbital.rb +321 -0
  63. data/lib/active_merchant/billing/gateways/orbital/orbital_soft_descriptors.rb +46 -0
  64. data/lib/active_merchant/billing/gateways/pay_junction.rb +392 -0
  65. data/lib/active_merchant/billing/gateways/pay_secure.rb +120 -0
  66. data/lib/active_merchant/billing/gateways/paybox_direct.rb +207 -0
  67. data/lib/active_merchant/billing/gateways/payflow.rb +253 -0
  68. data/lib/active_merchant/billing/gateways/payflow/payflow_common_api.rb +207 -0
  69. data/lib/active_merchant/billing/gateways/payflow/payflow_express_response.rb +39 -0
  70. data/lib/active_merchant/billing/gateways/payflow/payflow_response.rb +13 -0
  71. data/lib/active_merchant/billing/gateways/payflow_express.rb +222 -0
  72. data/lib/active_merchant/billing/gateways/payflow_express_uk.rb +15 -0
  73. data/lib/active_merchant/billing/gateways/payflow_uk.rb +21 -0
  74. data/lib/active_merchant/billing/gateways/payment_express.rb +235 -0
  75. data/lib/active_merchant/billing/gateways/paypal.rb +121 -0
  76. data/lib/active_merchant/billing/gateways/paypal/paypal_common_api.rb +351 -0
  77. data/lib/active_merchant/billing/gateways/paypal/paypal_express_response.rb +49 -0
  78. data/lib/active_merchant/billing/gateways/paypal_ca.rb +13 -0
  79. data/lib/active_merchant/billing/gateways/paypal_express.rb +177 -0
  80. data/lib/active_merchant/billing/gateways/paypal_express_common.rb +25 -0
  81. data/lib/active_merchant/billing/gateways/plugnpay.rb +298 -0
  82. data/lib/active_merchant/billing/gateways/psigate.rb +219 -0
  83. data/lib/active_merchant/billing/gateways/psl_card.rb +304 -0
  84. data/lib/active_merchant/billing/gateways/qbms.rb +295 -0
  85. data/lib/active_merchant/billing/gateways/quantum.rb +282 -0
  86. data/lib/active_merchant/billing/gateways/quickpay.rb +218 -0
  87. data/lib/active_merchant/billing/gateways/realex.rb +311 -0
  88. data/lib/active_merchant/billing/gateways/sage.rb +146 -0
  89. data/lib/active_merchant/billing/gateways/sage/sage_bankcard.rb +88 -0
  90. data/lib/active_merchant/billing/gateways/sage/sage_core.rb +116 -0
  91. data/lib/active_merchant/billing/gateways/sage/sage_virtual_check.rb +97 -0
  92. data/lib/active_merchant/billing/gateways/sage_pay.rb +320 -0
  93. data/lib/active_merchant/billing/gateways/sallie_mae.rb +144 -0
  94. data/lib/active_merchant/billing/gateways/secure_net.rb +330 -0
  95. data/lib/active_merchant/billing/gateways/secure_pay.rb +31 -0
  96. data/lib/active_merchant/billing/gateways/secure_pay_au.rb +193 -0
  97. data/lib/active_merchant/billing/gateways/secure_pay_tech.rb +113 -0
  98. data/lib/active_merchant/billing/gateways/skip_jack.rb +453 -0
  99. data/lib/active_merchant/billing/gateways/smart_ps.rb +271 -0
  100. data/lib/active_merchant/billing/gateways/stripe.rb +212 -0
  101. data/lib/active_merchant/billing/gateways/trans_first.rb +127 -0
  102. data/lib/active_merchant/billing/gateways/transax.rb +25 -0
  103. data/lib/active_merchant/billing/gateways/trust_commerce.rb +423 -0
  104. data/lib/active_merchant/billing/gateways/usa_epay.rb +194 -0
  105. data/lib/active_merchant/billing/gateways/verifi.rb +233 -0
  106. data/lib/active_merchant/billing/gateways/viaklix.rb +189 -0
  107. data/lib/active_merchant/billing/gateways/wirecard.rb +318 -0
  108. data/lib/active_merchant/billing/gateways/worldpay.rb +280 -0
  109. data/lib/active_merchant/billing/integrations.rb +17 -0
  110. data/lib/active_merchant/billing/integrations/action_view_helper.rb +68 -0
  111. data/lib/active_merchant/billing/integrations/bogus.rb +23 -0
  112. data/lib/active_merchant/billing/integrations/bogus/helper.rb +17 -0
  113. data/lib/active_merchant/billing/integrations/bogus/notification.rb +11 -0
  114. data/lib/active_merchant/billing/integrations/bogus/return.rb +10 -0
  115. data/lib/active_merchant/billing/integrations/chronopay.rb +23 -0
  116. data/lib/active_merchant/billing/integrations/chronopay/helper.rb +120 -0
  117. data/lib/active_merchant/billing/integrations/chronopay/notification.rb +158 -0
  118. data/lib/active_merchant/billing/integrations/chronopay/return.rb +10 -0
  119. data/lib/active_merchant/billing/integrations/direc_pay.rb +41 -0
  120. data/lib/active_merchant/billing/integrations/direc_pay/helper.rb +200 -0
  121. data/lib/active_merchant/billing/integrations/direc_pay/notification.rb +76 -0
  122. data/lib/active_merchant/billing/integrations/direc_pay/return.rb +32 -0
  123. data/lib/active_merchant/billing/integrations/direc_pay/status.rb +37 -0
  124. data/lib/active_merchant/billing/integrations/directebanking.rb +47 -0
  125. data/lib/active_merchant/billing/integrations/directebanking/helper.rb +90 -0
  126. data/lib/active_merchant/billing/integrations/directebanking/notification.rb +120 -0
  127. data/lib/active_merchant/billing/integrations/directebanking/return.rb +11 -0
  128. data/lib/active_merchant/billing/integrations/e_payment_plans.rb +48 -0
  129. data/lib/active_merchant/billing/integrations/e_payment_plans/helper.rb +34 -0
  130. data/lib/active_merchant/billing/integrations/e_payment_plans/notification.rb +84 -0
  131. data/lib/active_merchant/billing/integrations/gestpay.rb +25 -0
  132. data/lib/active_merchant/billing/integrations/gestpay/common.rb +42 -0
  133. data/lib/active_merchant/billing/integrations/gestpay/helper.rb +70 -0
  134. data/lib/active_merchant/billing/integrations/gestpay/notification.rb +85 -0
  135. data/lib/active_merchant/billing/integrations/gestpay/return.rb +10 -0
  136. data/lib/active_merchant/billing/integrations/helper.rb +96 -0
  137. data/lib/active_merchant/billing/integrations/hi_trust.rb +27 -0
  138. data/lib/active_merchant/billing/integrations/hi_trust/helper.rb +58 -0
  139. data/lib/active_merchant/billing/integrations/hi_trust/notification.rb +59 -0
  140. data/lib/active_merchant/billing/integrations/hi_trust/return.rb +67 -0
  141. data/lib/active_merchant/billing/integrations/moneybookers.rb +26 -0
  142. data/lib/active_merchant/billing/integrations/moneybookers/helper.rb +59 -0
  143. data/lib/active_merchant/billing/integrations/moneybookers/notification.rb +129 -0
  144. data/lib/active_merchant/billing/integrations/nochex.rb +88 -0
  145. data/lib/active_merchant/billing/integrations/nochex/helper.rb +68 -0
  146. data/lib/active_merchant/billing/integrations/nochex/notification.rb +94 -0
  147. data/lib/active_merchant/billing/integrations/nochex/return.rb +10 -0
  148. data/lib/active_merchant/billing/integrations/notification.rb +62 -0
  149. data/lib/active_merchant/billing/integrations/paypal.rb +39 -0
  150. data/lib/active_merchant/billing/integrations/paypal/helper.rb +119 -0
  151. data/lib/active_merchant/billing/integrations/paypal/notification.rb +154 -0
  152. data/lib/active_merchant/billing/integrations/paypal/return.rb +10 -0
  153. data/lib/active_merchant/billing/integrations/quickpay.rb +21 -0
  154. data/lib/active_merchant/billing/integrations/quickpay/helper.rb +72 -0
  155. data/lib/active_merchant/billing/integrations/quickpay/notification.rb +74 -0
  156. data/lib/active_merchant/billing/integrations/return.rb +42 -0
  157. data/lib/active_merchant/billing/integrations/sage_pay_form.rb +37 -0
  158. data/lib/active_merchant/billing/integrations/sage_pay_form/encryption.rb +33 -0
  159. data/lib/active_merchant/billing/integrations/sage_pay_form/helper.rb +111 -0
  160. data/lib/active_merchant/billing/integrations/sage_pay_form/notification.rb +210 -0
  161. data/lib/active_merchant/billing/integrations/sage_pay_form/return.rb +31 -0
  162. data/lib/active_merchant/billing/integrations/two_checkout.rb +23 -0
  163. data/lib/active_merchant/billing/integrations/two_checkout/helper.rb +59 -0
  164. data/lib/active_merchant/billing/integrations/two_checkout/notification.rb +114 -0
  165. data/lib/active_merchant/billing/integrations/two_checkout/return.rb +17 -0
  166. data/lib/active_merchant/billing/integrations/valitor.rb +33 -0
  167. data/lib/active_merchant/billing/integrations/valitor/helper.rb +86 -0
  168. data/lib/active_merchant/billing/integrations/valitor/notification.rb +13 -0
  169. data/lib/active_merchant/billing/integrations/valitor/response_fields.rb +97 -0
  170. data/lib/active_merchant/billing/integrations/valitor/return.rb +13 -0
  171. data/lib/active_merchant/billing/integrations/world_pay.rb +27 -0
  172. data/lib/active_merchant/billing/integrations/world_pay/helper.rb +100 -0
  173. data/lib/active_merchant/billing/integrations/world_pay/notification.rb +160 -0
  174. data/lib/active_merchant/billing/response.rb +32 -0
  175. data/lib/active_merchant/common.rb +14 -0
  176. data/lib/active_merchant/common/connection.rb +177 -0
  177. data/lib/active_merchant/common/country.rb +328 -0
  178. data/lib/active_merchant/common/error.rb +26 -0
  179. data/lib/active_merchant/common/post_data.rb +24 -0
  180. data/lib/active_merchant/common/posts_data.rb +63 -0
  181. data/lib/active_merchant/common/requires_parameters.rb +16 -0
  182. data/lib/active_merchant/common/utils.rb +22 -0
  183. data/lib/active_merchant/common/validateable.rb +81 -0
  184. data/lib/active_merchant/version.rb +3 -0
  185. data/lib/activemerchant.rb +1 -0
  186. data/lib/certs/cacert.pem +7815 -0
  187. data/lib/support/gateway_support.rb +58 -0
  188. data/lib/support/outbound_hosts.rb +25 -0
  189. metadata +276 -0
@@ -0,0 +1,454 @@
1
+ require 'rexml/document'
2
+
3
+ module ActiveMerchant #:nodoc:
4
+ module Billing #:nodoc:
5
+
6
+ # Initialization Options
7
+ # :login Your store number
8
+ # :pem The text of your linkpoint PEM file. Note
9
+ # this is not the path to file, but its
10
+ # contents. If you are only using one PEM
11
+ # file on your site you can declare it
12
+ # globally and then you won't need to
13
+ # include this option
14
+ #
15
+ #
16
+ # A valid store number is required. Unfortunately, with LinkPoint
17
+ # YOU CAN'T JUST USE ANY OLD STORE NUMBER. Also, you can't just
18
+ # generate your own PEM file. You'll need to use a special PEM file
19
+ # provided by LinkPoint.
20
+ #
21
+ # Go to http://www.linkpoint.com/support/sup_teststore.asp to set up
22
+ # a test account and obtain your PEM file.
23
+ #
24
+ # Declaring PEM file Globally
25
+ # ActiveMerchant::Billing::LinkpointGateway.pem_file = File.read( File.dirname(__FILE__) + '/../mycert.pem' )
26
+ #
27
+ #
28
+ # Valid Order Options
29
+ # :result =>
30
+ # LIVE Production mode
31
+ # GOOD Approved response in test mode
32
+ # DECLINE Declined response in test mode
33
+ # DUPLICATE Duplicate response in test mode
34
+ #
35
+ # :ponumber Order number
36
+ #
37
+ # :transactionorigin => Source of the transaction
38
+ # ECI Email or Internet
39
+ # MAIL Mail order
40
+ # MOTO Mail order/Telephone
41
+ # TELEPHONE Telephone
42
+ # RETAIL Face-to-face
43
+ #
44
+ # :ordertype =>
45
+ # SALE Real live sale
46
+ # PREAUTH Authorize only
47
+ # POSTAUTH Forced Ticket or Ticket Only transaction
48
+ # VOID
49
+ # CREDIT
50
+ # CALCSHIPPING For shipping charges calculations
51
+ # CALCTAX For sales tax calculations
52
+ #
53
+ # Recurring Options
54
+ # :action =>
55
+ # SUBMIT
56
+ # MODIFY
57
+ # CANCEL
58
+ #
59
+ # :installments Identifies how many recurring payments to charge the customer
60
+ # :startdate Date to begin charging the recurring payments. Format: YYYYMMDD or "immediate"
61
+ # :periodicity =>
62
+ # MONTHLY
63
+ # BIMONTHLY
64
+ # WEEKLY
65
+ # BIWEEKLY
66
+ # YEARLY
67
+ # DAILY
68
+ # :threshold Tells how many times to retry the transaction (if it fails) before contacting the merchant.
69
+ # :comments Uh... comments
70
+ #
71
+ #
72
+ # For reference:
73
+ #
74
+ # https://www.linkpointcentral.com/lpc/docs/Help/APIHelp/lpintguide.htm
75
+ #
76
+ # Entities = {
77
+ # :payment => [:subtotal, :tax, :vattax, :shipping, :chargetotal],
78
+ # :billing => [:name, :address1, :address2, :city, :state, :zip, :country, :email, :phone, :fax, :addrnum],
79
+ # :shipping => [:name, :address1, :address2, :city, :state, :zip, :country, :weight, :items, :carrier, :total],
80
+ # :creditcard => [:cardnumber, :cardexpmonth, :cardexpyear, :cvmvalue, :track],
81
+ # :telecheck => [:routing, :account, :checknumber, :bankname, :bankstate, :dl, :dlstate, :void, :accounttype, :ssn],
82
+ # :transactiondetails => [:transactionorigin, :oid, :ponumber, :taxexempt, :terminaltype, :ip, :reference_number, :recurring, :tdate],
83
+ # :periodic => [:action, :installments, :threshold, :startdate, :periodicity, :comments],
84
+ # :notes => [:comments, :referred]
85
+ # :items => [:item => [:price, :quantity, :description, :id, :options => [:option => [:name, :value]]]]
86
+ # }
87
+ #
88
+ #
89
+ # LinkPoint's Items entity is an optional entity that can be attached to orders.
90
+ # It is entered as :line_items to be consistent with the CyberSource implementation
91
+ #
92
+ # The line_item hash goes in the options hash and should look like
93
+ #
94
+ # :line_items => [
95
+ # {
96
+ # :id => '123456',
97
+ # :description => 'Logo T-Shirt',
98
+ # :price => '12.00',
99
+ # :quantity => '1',
100
+ # :options => [
101
+ # {
102
+ # :name => 'Color',
103
+ # :value => 'Red'
104
+ # },
105
+ # {
106
+ # :name => 'Size',
107
+ # :value => 'XL'
108
+ # }
109
+ # ]
110
+ # },
111
+ # {
112
+ # :id => '111',
113
+ # :description => 'keychain',
114
+ # :price => '3.00',
115
+ # :quantity => '1'
116
+ # }
117
+ # ]
118
+ # This functionality is only supported by this particular gateway may
119
+ # be changed at any time
120
+ #
121
+ class LinkpointGateway < Gateway
122
+ # Your global PEM file. This will be assigned to you by linkpoint
123
+ #
124
+ # Example:
125
+ #
126
+ # ActiveMerchant::Billing::LinkpointGateway.pem_file = File.read( File.dirname(__FILE__) + '/../mycert.pem' )
127
+ #
128
+ cattr_accessor :pem_file
129
+
130
+ TEST_URL = 'https://staging.linkpt.net:1129/'
131
+ LIVE_URL = 'https://secure.linkpt.net:1129/'
132
+
133
+ # We don't have the certificate to verify LinkPoint
134
+ self.ssl_strict = false
135
+
136
+ self.supported_countries = ['US']
137
+ self.supported_cardtypes = [:visa, :master, :american_express, :discover, :jcb, :diners_club]
138
+ self.homepage_url = 'http://www.linkpoint.com/'
139
+ self.display_name = 'LinkPoint'
140
+
141
+ def initialize(options = {})
142
+ requires!(options, :login)
143
+
144
+ @options = {
145
+ :result => 'LIVE',
146
+ :pem => LinkpointGateway.pem_file
147
+ }.update(options)
148
+
149
+ raise ArgumentError, "You need to pass in your pem file using the :pem parameter or set it globally using ActiveMerchant::Billing::LinkpointGateway.pem_file = File.read( File.dirname(__FILE__) + '/../mycert.pem' ) or similar" if @options[:pem].blank?
150
+ end
151
+
152
+ # Send a purchase request with periodic options
153
+ # Recurring Options
154
+ # :action =>
155
+ # SUBMIT
156
+ # MODIFY
157
+ # CANCEL
158
+ #
159
+ # :installments Identifies how many recurring payments to charge the customer
160
+ # :startdate Date to begin charging the recurring payments. Format: YYYYMMDD or "immediate"
161
+ # :periodicity =>
162
+ # :monthly
163
+ # :bimonthly
164
+ # :weekly
165
+ # :biweekly
166
+ # :yearly
167
+ # :daily
168
+ # :threshold Tells how many times to retry the transaction (if it fails) before contacting the merchant.
169
+ # :comments Uh... comments
170
+ #
171
+ def recurring(money, creditcard, options={})
172
+ requires!(options, [:periodicity, :bimonthly, :monthly, :biweekly, :weekly, :yearly, :daily], :installments, :order_id )
173
+
174
+ options.update(
175
+ :ordertype => "SALE",
176
+ :action => options[:action] || "SUBMIT",
177
+ :installments => options[:installments] || 12,
178
+ :startdate => options[:startdate] || "immediate",
179
+ :periodicity => options[:periodicity].to_s || "monthly",
180
+ :comments => options[:comments] || nil,
181
+ :threshold => options[:threshold] || 3
182
+ )
183
+ commit(money, creditcard, options)
184
+ end
185
+
186
+ # Buy the thing
187
+ def purchase(money, creditcard, options={})
188
+ requires!(options, :order_id)
189
+ options.update(
190
+ :ordertype => "SALE"
191
+ )
192
+ commit(money, creditcard, options)
193
+ end
194
+
195
+ #
196
+ # Authorize the transaction
197
+ #
198
+ # Reserves the funds on the customer's credit card, but does not charge the card.
199
+ #
200
+ def authorize(money, creditcard, options = {})
201
+ requires!(options, :order_id)
202
+ options.update(
203
+ :ordertype => "PREAUTH"
204
+ )
205
+ commit(money, creditcard, options)
206
+ end
207
+
208
+ #
209
+ # Post an authorization.
210
+ #
211
+ # Captures the funds from an authorized transaction.
212
+ # Order_id must be a valid order id from a prior authorized transaction.
213
+ #
214
+ def capture(money, authorization, options = {})
215
+ options.update(
216
+ :order_id => authorization,
217
+ :ordertype => "POSTAUTH"
218
+ )
219
+ commit(money, nil, options)
220
+ end
221
+
222
+ # Void a previous transaction
223
+ def void(identification, options = {})
224
+ options.update(
225
+ :order_id => identification,
226
+ :ordertype => "VOID"
227
+ )
228
+ commit(nil, nil, options)
229
+ end
230
+
231
+ #
232
+ # Refund an order
233
+ #
234
+ # identification must be a valid order id previously submitted by SALE
235
+ #
236
+ def refund(money, identification, options = {})
237
+ options.update(
238
+ :ordertype => "CREDIT",
239
+ :order_id => identification
240
+ )
241
+ commit(money, nil, options)
242
+ end
243
+
244
+ def credit(money, identification, options = {})
245
+ deprecated CREDIT_DEPRECATION_MESSAGE
246
+ refund(money, identification, options)
247
+ end
248
+
249
+ def test?
250
+ @options[:test] || super
251
+ end
252
+
253
+ private
254
+ # Commit the transaction by posting the XML file to the LinkPoint server
255
+ def commit(money, creditcard, options = {})
256
+ response = parse(ssl_post(test? ? TEST_URL : LIVE_URL, post_data(money, creditcard, options)))
257
+
258
+ Response.new(successful?(response), response[:message], response,
259
+ :test => test?,
260
+ :authorization => response[:ordernum],
261
+ :avs_result => { :code => response[:avs].to_s[2,1] },
262
+ :cvv_result => response[:avs].to_s[3,1]
263
+ )
264
+ end
265
+
266
+ def successful?(response)
267
+ response[:approved] == "APPROVED"
268
+ end
269
+
270
+ # Build the XML file
271
+ def post_data(money, creditcard, options)
272
+ params = parameters(money, creditcard, options)
273
+
274
+ xml = REXML::Document.new
275
+ order = xml.add_element("order")
276
+
277
+ # Merchant Info
278
+ merchantinfo = order.add_element("merchantinfo")
279
+ merchantinfo.add_element("configfile").text = @options[:login]
280
+
281
+ # Loop over the params hash to construct the XML string
282
+ for key, value in params
283
+ elem = order.add_element(key.to_s)
284
+ if key == :items
285
+ build_items(elem, value)
286
+ else
287
+ for k, v in params[key]
288
+ elem.add_element(k.to_s).text = params[key][k].to_s if params[key][k]
289
+ end
290
+ end
291
+ # Linkpoint doesn't understand empty elements:
292
+ order.delete(elem) if elem.size == 0
293
+ end
294
+ return xml.to_s
295
+ end
296
+
297
+ # adds LinkPoint's Items entity to the XML. Called from post_data
298
+ def build_items(element, items)
299
+ for item in items
300
+ item_element = element.add_element("item")
301
+ for key, value in item
302
+ if key == :options
303
+ options_element = item_element.add_element("options")
304
+ for option in value
305
+ opt_element = options_element.add_element("option")
306
+ opt_element.add_element("name").text = option[:name] unless option[:name].blank?
307
+ opt_element.add_element("value").text = option[:value] unless option[:value].blank?
308
+ end
309
+ else
310
+ item_element.add_element(key.to_s).text = item[key].to_s unless item[key].blank?
311
+ end
312
+ end
313
+ end
314
+ end
315
+
316
+ # Set up the parameters hash just once so we don't have to do it
317
+ # for every action.
318
+ def parameters(money, creditcard, options = {})
319
+
320
+ params = {
321
+ :payment => {
322
+ :subtotal => amount(options[:subtotal]),
323
+ :tax => amount(options[:tax]),
324
+ :vattax => amount(options[:vattax]),
325
+ :shipping => amount(options[:shipping]),
326
+ :chargetotal => amount(money)
327
+ },
328
+ :transactiondetails => {
329
+ :transactionorigin => options[:transactionorigin] || "ECI",
330
+ :oid => options[:order_id],
331
+ :ponumber => options[:ponumber],
332
+ :taxexempt => options[:taxexempt],
333
+ :terminaltype => options[:terminaltype],
334
+ :ip => options[:ip],
335
+ :reference_number => options[:reference_number],
336
+ :recurring => options[:recurring] || "NO", #DO NOT USE if you are using the periodic billing option.
337
+ :tdate => options[:tdate]
338
+ },
339
+ :orderoptions => {
340
+ :ordertype => options[:ordertype],
341
+ :result => @options[:result]
342
+ },
343
+ :periodic => {
344
+ :action => options[:action],
345
+ :installments => options[:installments],
346
+ :threshold => options[:threshold],
347
+ :startdate => options[:startdate],
348
+ :periodicity => options[:periodicity],
349
+ :comments => options[:comments]
350
+ },
351
+ :telecheck => {
352
+ :routing => options[:telecheck_routing],
353
+ :account => options[:telecheck_account],
354
+ :checknumber => options[:telecheck_checknumber],
355
+ :bankname => options[:telecheck_bankname],
356
+ :dl => options[:telecheck_dl],
357
+ :dlstate => options[:telecheck_dlstate],
358
+ :void => options[:telecheck_void],
359
+ :accounttype => options[:telecheck_accounttype],
360
+ :ssn => options[:telecheck_ssn],
361
+ }
362
+ }
363
+
364
+ if creditcard
365
+ params[:creditcard] = {
366
+ :cardnumber => creditcard.number,
367
+ :cardexpmonth => creditcard.month,
368
+ :cardexpyear => format_creditcard_expiry_year(creditcard.year),
369
+ :track => nil
370
+ }
371
+
372
+ if creditcard.verification_value?
373
+ params[:creditcard][:cvmvalue] = creditcard.verification_value
374
+ params[:creditcard][:cvmindicator] = 'provided'
375
+ else
376
+ params[:creditcard][:cvmindicator] = 'not_provided'
377
+ end
378
+ end
379
+
380
+ if billing_address = options[:billing_address] || options[:address]
381
+
382
+ params[:billing] = {}
383
+ params[:billing][:name] = billing_address[:name] || (creditcard ? creditcard.name : nil)
384
+ params[:billing][:address1] = billing_address[:address1] unless billing_address[:address1].blank?
385
+ params[:billing][:address2] = billing_address[:address2] unless billing_address[:address2].blank?
386
+ params[:billing][:city] = billing_address[:city] unless billing_address[:city].blank?
387
+ params[:billing][:state] = billing_address[:state] unless billing_address[:state].blank?
388
+ params[:billing][:zip] = billing_address[:zip] unless billing_address[:zip].blank?
389
+ params[:billing][:country] = billing_address[:country] unless billing_address[:country].blank?
390
+ params[:billing][:company] = billing_address[:company] unless billing_address[:company].blank?
391
+ params[:billing][:phone] = billing_address[:phone] unless billing_address[:phone].blank?
392
+ params[:billing][:email] = options[:email] unless options[:email].blank?
393
+ end
394
+
395
+ if shipping_address = options[:shipping_address]
396
+
397
+ params[:shipping] = {}
398
+ params[:shipping][:name] = shipping_address[:name] || creditcard ? creditcard.name : nil
399
+ params[:shipping][:address1] = shipping_address[:address1] unless shipping_address[:address1].blank?
400
+ params[:shipping][:address2] = shipping_address[:address2] unless shipping_address[:address2].blank?
401
+ params[:shipping][:city] = shipping_address[:city] unless shipping_address[:city].blank?
402
+ params[:shipping][:state] = shipping_address[:state] unless shipping_address[:state].blank?
403
+ params[:shipping][:zip] = shipping_address[:zip] unless shipping_address[:zip].blank?
404
+ params[:shipping][:country] = shipping_address[:country] unless shipping_address[:country].blank?
405
+ end
406
+
407
+ params[:items] = options[:line_items] if options[:line_items]
408
+
409
+ return params
410
+ end
411
+
412
+ def parse(xml)
413
+
414
+ # For reference, a typical response...
415
+ # <r_csp></r_csp>
416
+ # <r_time></r_time>
417
+ # <r_ref></r_ref>
418
+ # <r_error></r_error>
419
+ # <r_ordernum></r_ordernum>
420
+ # <r_message>This is a test transaction and will not show up in the Reports</r_message>
421
+ # <r_code></r_code>
422
+ # <r_tdate>Thu Feb 2 15:40:21 2006</r_tdate>
423
+ # <r_score></r_score>
424
+ # <r_authresponse></r_authresponse>
425
+ # <r_approved>APPROVED</r_approved>
426
+ # <r_avs></r_avs>
427
+
428
+ response = {:message => "Global Error Receipt", :complete => false}
429
+
430
+ xml = REXML::Document.new("<response>#{xml}</response>")
431
+ xml.root.elements.each do |node|
432
+ response[node.name.downcase.sub(/^r_/, '').to_sym] = normalize(node.text)
433
+ end unless xml.root.nil?
434
+
435
+ response
436
+ end
437
+
438
+ # Make a ruby type out of the response string
439
+ def normalize(field)
440
+ case field
441
+ when "true" then true
442
+ when "false" then false
443
+ when "" then nil
444
+ when "null" then nil
445
+ else field
446
+ end
447
+ end
448
+
449
+ def format_creditcard_expiry_year(year)
450
+ sprintf("%.4i", year)[-2..-1]
451
+ end
452
+ end
453
+ end
454
+ end