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,600 @@
1
+ require "active_support/core_ext/string/access"
2
+
3
+ module ActiveMerchant
4
+ module Billing
5
+ class DataCashGateway < Gateway
6
+ self.default_currency = 'GBP'
7
+ self.supported_countries = ['GB']
8
+
9
+ # From the DataCash docs; Page 13, the following cards are
10
+ # usable:
11
+ # American Express, ATM, Carte Blanche, Diners Club, Discover,
12
+ # EnRoute, GE Capital, JCB, Laser, Maestro, Mastercard, Solo,
13
+ # Switch, Visa, Visa Delta, VISA Electron, Visa Purchasing
14
+ #
15
+ # Note continuous authority is only supported for :visa, :master and :american_express card types
16
+ self.supported_cardtypes = [ :visa, :master, :american_express, :discover, :diners_club, :jcb, :maestro, :switch, :solo, :laser ]
17
+
18
+ self.homepage_url = 'http://www.datacash.com/'
19
+ self.display_name = 'DataCash'
20
+
21
+ # Datacash server URLs
22
+ self.test_url = 'https://testserver.datacash.com/Transaction'
23
+ self.live_url = 'https://mars.transaction.datacash.com/Transaction'
24
+
25
+ # Different Card Transaction Types
26
+ AUTH_TYPE = 'auth'
27
+ CANCEL_TYPE = 'cancel'
28
+ FULFILL_TYPE = 'fulfill'
29
+ PRE_TYPE = 'pre'
30
+ REFUND_TYPE = 'refund'
31
+ TRANSACTION_REFUND_TYPE = 'txn_refund'
32
+
33
+ # Constant strings for use in the ExtendedPolicy complex element for
34
+ # CV2 checks
35
+ POLICY_ACCEPT = 'accept'
36
+ POLICY_REJECT = 'reject'
37
+
38
+ # Datacash success code
39
+ DATACASH_SUCCESS = '1'
40
+
41
+ # Creates a new DataCashGateway
42
+ #
43
+ # The gateway requires that a valid login and password be passed
44
+ # in the +options+ hash.
45
+ #
46
+ # ==== Options
47
+ #
48
+ # * <tt>:login</tt> -- The Datacash account login.
49
+ # * <tt>:password</tt> -- The Datacash account password.
50
+ # * <tt>:test => +true+ or +false+</tt> -- Use the test or live Datacash url.
51
+ #
52
+ def initialize(options = {})
53
+ requires!(options, :login, :password)
54
+ super
55
+ end
56
+
57
+ # Perform a purchase, which is essentially an authorization and capture in a single operation.
58
+ #
59
+ # ==== Parameters
60
+ # * <tt>money</tt> The amount to be authorized as an Integer value in cents.
61
+ # * <tt>authorization_or_credit_card</tt>:: The continuous authority reference or CreditCard details for the transaction.
62
+ # * <tt>options</tt> A hash of optional parameters.
63
+ # * <tt>:order_id</tt> A unique reference for this order (corresponds to merchantreference in datacash documentation)
64
+ # * <tt>:set_up_continuous_authority</tt>
65
+ # Set to true to set up a recurring historic transaction account be set up.
66
+ # Only supported for :visa, :master and :american_express card types
67
+ # See http://www.datacash.com/services/recurring/historic.php for more details of historic transactions.
68
+ # * <tt>:address</tt>:: billing address for card
69
+ #
70
+ # The continuous authority reference will be available in response#params['ca_reference'] if you have requested one
71
+ def purchase(money, authorization_or_credit_card, options = {})
72
+ requires!(options, :order_id)
73
+
74
+ if authorization_or_credit_card.is_a?(String)
75
+ request = build_purchase_or_authorization_request_with_continuous_authority_reference_request(AUTH_TYPE, money, authorization_or_credit_card, options)
76
+ else
77
+ request = build_purchase_or_authorization_request_with_credit_card_request(AUTH_TYPE, money, authorization_or_credit_card, options)
78
+ end
79
+
80
+ commit(request)
81
+ end
82
+
83
+ # Performs an authorization, which reserves the funds on the customer's credit card, but does not
84
+ # charge the card.
85
+ #
86
+ # ==== Parameters
87
+ #
88
+ # * <tt>money</tt> The amount to be authorized as an Integer value in cents.
89
+ # * <tt>authorization_or_credit_card</tt>:: The continuous authority reference or CreditCard details for the transaction.
90
+ # * <tt>options</tt> A hash of optional parameters.
91
+ # * <tt>:order_id</tt> A unique reference for this order (corresponds to merchantreference in datacash documentation)
92
+ # * <tt>:set_up_continuous_authority</tt>::
93
+ # Set to true to set up a recurring historic transaction account be set up.
94
+ # Only supported for :visa, :master and :american_express card types
95
+ # See http://www.datacash.com/services/recurring/historic.php for more details of historic transactions.
96
+ # * <tt>:address</tt>:: billing address for card
97
+ #
98
+ # The continuous authority reference will be available in response#params['ca_reference'] if you have requested one
99
+ def authorize(money, authorization_or_credit_card, options = {})
100
+ requires!(options, :order_id)
101
+
102
+ if authorization_or_credit_card.is_a?(String)
103
+ request = build_purchase_or_authorization_request_with_continuous_authority_reference_request(AUTH_TYPE, money, authorization_or_credit_card, options)
104
+ else
105
+ request = build_purchase_or_authorization_request_with_credit_card_request(PRE_TYPE, money, authorization_or_credit_card, options)
106
+ end
107
+
108
+ commit(request)
109
+ end
110
+
111
+ # Captures the funds from an authorized transaction.
112
+ #
113
+ # ==== Parameters
114
+ #
115
+ # * <tt>money</tt> -- The amount to be captured as anInteger value in cents.
116
+ # * <tt>authorization</tt> -- The authorization returned from the previous authorize request.
117
+ def capture(money, authorization, options = {})
118
+ commit(build_void_or_capture_request(FULFILL_TYPE, money, authorization, options))
119
+ end
120
+
121
+ # Void a previous transaction
122
+ #
123
+ # ==== Parameters
124
+ #
125
+ # * <tt>authorization</tt> - The authorization returned from the previous authorize request.
126
+ def void(authorization, options = {})
127
+ request = build_void_or_capture_request(CANCEL_TYPE, nil, authorization, options)
128
+
129
+ commit(request)
130
+ end
131
+
132
+ # Refund to a card
133
+ #
134
+ # ==== Parameters
135
+ #
136
+ # * <tt>money</tt> The amount to be refunded as an Integer value in cents. Set to nil for a full refund on existing transaction.
137
+ # * <tt>reference_or_credit_card</tt> The credit card you want to refund OR the datacash_reference for the existing transaction you are refunding
138
+ # * <tt>options</tt> Are ignored when refunding via reference to an existing transaction, otherwise
139
+ # * <tt>:order_id</tt> A unique reference for this order (corresponds to merchantreference in datacash documentation)
140
+ # * <tt>:address</tt>:: billing address for card
141
+ def credit(money, reference_or_credit_card, options = {})
142
+ if reference_or_credit_card.is_a?(String)
143
+ ActiveMerchant.deprecated CREDIT_DEPRECATION_MESSAGE
144
+ refund(money, reference_or_credit_card)
145
+ else
146
+ request = build_refund_request(money, reference_or_credit_card, options)
147
+ commit(request)
148
+ end
149
+ end
150
+
151
+ def refund(money, reference, options = {})
152
+ commit(build_transaction_refund_request(money, reference))
153
+ end
154
+
155
+ private
156
+ # Create the xml document for a 'cancel' or 'fulfill' transaction.
157
+ #
158
+ # Final XML should look like:
159
+ # <Request>
160
+ # <Authentication>
161
+ # <client>99000001</client>
162
+ # <password>******</password>
163
+ # </Authentication>
164
+ # <Transaction>
165
+ # <TxnDetails>
166
+ # <amount>25.00</amount>
167
+ # </TxnDetails>
168
+ # <HistoricTxn>
169
+ # <reference>4900200000000001</reference>
170
+ # <authcode>A6</authcode>
171
+ # <method>fulfill</method>
172
+ # </HistoricTxn>
173
+ # </Transaction>
174
+ # </Request>
175
+ #
176
+ # Parameters:
177
+ # * <tt>type</tt> must be FULFILL_TYPE or CANCEL_TYPE
178
+ # * <tt>money</tt> - optional - Integer value in cents
179
+ # * <tt>authorization</tt> - the Datacash authorization from a previous succesful authorize transaction
180
+ # * <tt>options</tt>
181
+ # * <tt>order_id</tt> - A unique reference for the transaction
182
+ #
183
+ # Returns:
184
+ # -Builder xml document
185
+ #
186
+ def build_void_or_capture_request(type, money, authorization, options)
187
+ parsed_authorization = parse_authorization_string(authorization)
188
+ xml = Builder::XmlMarkup.new :indent => 2
189
+ xml.instruct!
190
+ xml.tag! :Request do
191
+ add_authentication(xml)
192
+
193
+ xml.tag! :Transaction do
194
+ xml.tag! :HistoricTxn do
195
+ xml.tag! :reference, parsed_authorization[:reference]
196
+ xml.tag! :authcode, parsed_authorization[:auth_code]
197
+ xml.tag! :method, type
198
+ end
199
+
200
+ if money
201
+ xml.tag! :TxnDetails do
202
+ xml.tag! :merchantreference, format_reference_number(options[:order_id])
203
+ xml.tag! :amount, amount(money), :currency => options[:currency] || currency(money)
204
+ xml.tag! :capturemethod, 'ecomm'
205
+ end
206
+ end
207
+ end
208
+ end
209
+ xml.target!
210
+ end
211
+
212
+ # Create the xml document for an 'auth' or 'pre' transaction with a credit card
213
+ #
214
+ # Final XML should look like:
215
+ #
216
+ # <Request>
217
+ # <Authentication>
218
+ # <client>99000000</client>
219
+ # <password>*******</password>
220
+ # </Authentication>
221
+ # <Transaction>
222
+ # <TxnDetails>
223
+ # <merchantreference>123456</merchantreference>
224
+ # <amount currency="EUR">10.00</amount>
225
+ # </TxnDetails>
226
+ # <CardTxn>
227
+ # <Card>
228
+ # <pan>4444********1111</pan>
229
+ # <expirydate>03/04</expirydate>
230
+ # <Cv2Avs>
231
+ # <street_address1>Flat 7</street_address1>
232
+ # <street_address2>89 Jumble
233
+ # Street</street_address2>
234
+ # <street_address3>Mytown</street_address3>
235
+ # <postcode>AV12FR</postcode>
236
+ # <cv2>123</cv2>
237
+ # <ExtendedPolicy>
238
+ # <cv2_policy notprovided="reject"
239
+ # notchecked="accept"
240
+ # matched="accept"
241
+ # notmatched="reject"
242
+ # partialmatch="reject"/>
243
+ # <postcode_policy notprovided="reject"
244
+ # notchecked="accept"
245
+ # matched="accept"
246
+ # notmatched="reject"
247
+ # partialmatch="accept"/>
248
+ # <address_policy notprovided="reject"
249
+ # notchecked="accept"
250
+ # matched="accept"
251
+ # notmatched="reject"
252
+ # partialmatch="accept"/>
253
+ # </ExtendedPolicy>
254
+ # </Cv2Avs>
255
+ # </Card>
256
+ # <method>auth</method>
257
+ # </CardTxn>
258
+ # </Transaction>
259
+ # </Request>
260
+ #
261
+ # Parameters:
262
+ # -type must be 'auth' or 'pre'
263
+ # -money - A money object with the price and currency
264
+ # -credit_card - The credit_card details to use
265
+ # -options:
266
+ # :order_id is the merchant reference number
267
+ # :billing_address is the billing address for the cc
268
+ # :address is the delivery address
269
+ #
270
+ # Returns:
271
+ # -xml: Builder document containing the markup
272
+ #
273
+ def build_purchase_or_authorization_request_with_credit_card_request(type, money, credit_card, options)
274
+ xml = Builder::XmlMarkup.new :indent => 2
275
+ xml.instruct!
276
+ xml.tag! :Request do
277
+ add_authentication(xml)
278
+
279
+ xml.tag! :Transaction do
280
+ if options[:set_up_continuous_authority]
281
+ xml.tag! :ContAuthTxn, :type => 'setup'
282
+ end
283
+ xml.tag! :CardTxn do
284
+ xml.tag! :method, type
285
+ add_credit_card(xml, credit_card, options[:billing_address])
286
+ end
287
+ xml.tag! :TxnDetails do
288
+ xml.tag! :merchantreference, format_reference_number(options[:order_id])
289
+ xml.tag! :amount, amount(money), :currency => options[:currency] || currency(money)
290
+ xml.tag! :capturemethod, 'ecomm'
291
+ end
292
+ end
293
+ end
294
+ xml.target!
295
+ end
296
+
297
+ # Create the xml document for an 'auth' or 'pre' transaction with
298
+ # continuous authorization
299
+ #
300
+ # Final XML should look like:
301
+ #
302
+ # <Request>
303
+ # <Transaction>
304
+ # <ContAuthTxn type="historic" />
305
+ # <TxnDetails>
306
+ # <merchantreference>3851231</merchantreference>
307
+ # <capturemethod>cont_auth</capturemethod>
308
+ # <amount currency="GBP">18.50</amount>
309
+ # </TxnDetails>
310
+ # <HistoricTxn>
311
+ # <reference>4500200040925092</reference>
312
+ # <method>auth</method>
313
+ # </HistoricTxn>
314
+ # </Transaction>
315
+ # <Authentication>
316
+ # <client>99000001</client>
317
+ # <password>mypasswd</password>
318
+ # </Authentication>
319
+ # </Request>
320
+ #
321
+ # Parameters:
322
+ # -type must be 'auth' or 'pre'
323
+ # -money - A money object with the price and currency
324
+ # -authorization - The authorization containing a continuous authority reference previously set up on a credit card
325
+ # -options:
326
+ # :order_id is the merchant reference number
327
+ #
328
+ # Returns:
329
+ # -xml: Builder document containing the markup
330
+ #
331
+ def build_purchase_or_authorization_request_with_continuous_authority_reference_request(type, money, authorization, options)
332
+ parsed_authorization = parse_authorization_string(authorization)
333
+ raise ArgumentError, "The continuous authority reference is required for continuous authority transactions" if parsed_authorization[:ca_reference].blank?
334
+
335
+ xml = Builder::XmlMarkup.new :indent => 2
336
+ xml.instruct!
337
+ xml.tag! :Request do
338
+ add_authentication(xml)
339
+ xml.tag! :Transaction do
340
+ xml.tag! :ContAuthTxn, :type => 'historic'
341
+ xml.tag! :HistoricTxn do
342
+ xml.tag! :reference, parsed_authorization[:ca_reference]
343
+ xml.tag! :method, type
344
+ end
345
+ xml.tag! :TxnDetails do
346
+ xml.tag! :merchantreference, format_reference_number(options[:order_id])
347
+ xml.tag! :amount, amount(money), :currency => options[:currency] || currency(money)
348
+ xml.tag! :capturemethod, 'cont_auth'
349
+ end
350
+ end
351
+ end
352
+ xml.target!
353
+ end
354
+
355
+ # Create the xml document for a full or partial refund transaction with
356
+ #
357
+ # Final XML should look like:
358
+ #
359
+ # <Request>
360
+ # <Authentication>
361
+ # <client>99000001</client>
362
+ # <password>*******</password>
363
+ # </Authentication>
364
+ # <Transaction>
365
+ # <HistoricTxn>
366
+ # <method>txn_refund</method>
367
+ # <reference>12345678</reference>
368
+ # </HistoricTxn>
369
+ # <TxnDetails>
370
+ # <amount>10.00</amount>
371
+ # </TxnDetails>
372
+ # </Transaction>
373
+ # </Request>
374
+ #
375
+ def build_transaction_refund_request(money, authorization)
376
+ parsed_authorization = parse_authorization_string(authorization)
377
+ xml = Builder::XmlMarkup.new :indent => 2
378
+ xml.instruct!
379
+ xml.tag! :Request do
380
+ add_authentication(xml)
381
+ xml.tag! :Transaction do
382
+ xml.tag! :HistoricTxn do
383
+ xml.tag! :reference, parsed_authorization[:reference]
384
+ xml.tag! :method, TRANSACTION_REFUND_TYPE
385
+ end
386
+ unless money.nil?
387
+ xml.tag! :TxnDetails do
388
+ xml.tag! :amount, amount(money)
389
+ end
390
+ end
391
+ end
392
+ end
393
+ xml.target!
394
+ end
395
+
396
+ # Create the xml document for a full or partial refund with
397
+ #
398
+ # Final XML should look like:
399
+ #
400
+ # <Request>
401
+ # <Authentication>
402
+ # <client>99000001</client>
403
+ # <password>*****</password>
404
+ # </Authentication>
405
+ # <Transaction>
406
+ # <CardTxn>
407
+ # <Card>
408
+ # <pan>633300*********1</pan>
409
+ # <expirydate>04/06</expirydate>
410
+ # <startdate>01/04</startdate>
411
+ # </Card>
412
+ # <method>refund</method>
413
+ # </CardTxn>
414
+ # <TxnDetails>
415
+ # <merchantreference>1000001</merchantreference>
416
+ # <amount currency="GBP">95.99</amount>
417
+ # </TxnDetails>
418
+ # </Transaction>
419
+ # </Request>
420
+ def build_refund_request(money, credit_card, options)
421
+ xml = Builder::XmlMarkup.new :indent => 2
422
+ xml.instruct!
423
+ xml.tag! :Request do
424
+ add_authentication(xml)
425
+ xml.tag! :Transaction do
426
+ xml.tag! :CardTxn do
427
+ xml.tag! :method, REFUND_TYPE
428
+ add_credit_card(xml, credit_card, options[:billing_address])
429
+ end
430
+ xml.tag! :TxnDetails do
431
+ xml.tag! :merchantreference, format_reference_number(options[:order_id])
432
+ xml.tag! :amount, amount(money)
433
+ end
434
+ end
435
+ end
436
+ xml.target!
437
+ end
438
+
439
+
440
+ # Adds the authentication element to the passed builder xml doc
441
+ #
442
+ # Parameters:
443
+ # -xml: Builder document that is being built up
444
+ #
445
+ # Returns:
446
+ # -none: The results is stored in the passed xml document
447
+ #
448
+ def add_authentication(xml)
449
+ xml.tag! :Authentication do
450
+ xml.tag! :client, @options[:login]
451
+ xml.tag! :password, @options[:password]
452
+ end
453
+ end
454
+
455
+ # Add credit_card details to the passed XML Builder doc
456
+ #
457
+ # Parameters:
458
+ # -xml: Builder document that is being built up
459
+ # -credit_card: ActiveMerchant::Billing::CreditCard object
460
+ # -billing_address: Hash containing all of the billing address details
461
+ #
462
+ # Returns:
463
+ # -none: The results is stored in the passed xml document
464
+ #
465
+ def add_credit_card(xml, credit_card, address)
466
+
467
+ xml.tag! :Card do
468
+
469
+ # DataCash calls the CC number 'pan'
470
+ xml.tag! :pan, credit_card.number
471
+ xml.tag! :expirydate, format_date(credit_card.month, credit_card.year)
472
+
473
+ # optional values - for Solo etc
474
+ if [ 'switch', 'solo' ].include?(card_brand(credit_card).to_s)
475
+
476
+ xml.tag! :issuenumber, credit_card.issue_number unless credit_card.issue_number.blank?
477
+
478
+ if !credit_card.start_month.blank? && !credit_card.start_year.blank?
479
+ xml.tag! :startdate, format_date(credit_card.start_month, credit_card.start_year)
480
+ end
481
+ end
482
+
483
+ xml.tag! :Cv2Avs do
484
+ xml.tag! :cv2, credit_card.verification_value if credit_card.verification_value?
485
+ if address
486
+ xml.tag! :street_address1, address[:address1] unless address[:address1].blank?
487
+ xml.tag! :street_address2, address[:address2] unless address[:address2].blank?
488
+ xml.tag! :street_address3, address[:address3] unless address[:address3].blank?
489
+ xml.tag! :street_address4, address[:address4] unless address[:address4].blank?
490
+ xml.tag! :postcode, address[:zip] unless address[:zip].blank?
491
+ end
492
+
493
+ # The ExtendedPolicy defines what to do when the passed data
494
+ # matches, or not...
495
+ #
496
+ # All of the following elements MUST be present for the
497
+ # xml to be valid (or can drop the ExtendedPolicy and use
498
+ # a predefined one
499
+ xml.tag! :ExtendedPolicy do
500
+ xml.tag! :cv2_policy,
501
+ :notprovided => POLICY_REJECT,
502
+ :notchecked => POLICY_REJECT,
503
+ :matched => POLICY_ACCEPT,
504
+ :notmatched => POLICY_REJECT,
505
+ :partialmatch => POLICY_REJECT
506
+ xml.tag! :postcode_policy,
507
+ :notprovided => POLICY_ACCEPT,
508
+ :notchecked => POLICY_ACCEPT,
509
+ :matched => POLICY_ACCEPT,
510
+ :notmatched => POLICY_REJECT,
511
+ :partialmatch => POLICY_ACCEPT
512
+ xml.tag! :address_policy,
513
+ :notprovided => POLICY_ACCEPT,
514
+ :notchecked => POLICY_ACCEPT,
515
+ :matched => POLICY_ACCEPT,
516
+ :notmatched => POLICY_REJECT,
517
+ :partialmatch => POLICY_ACCEPT
518
+ end
519
+ end
520
+ end
521
+ end
522
+
523
+ # Send the passed data to DataCash for processing
524
+ #
525
+ # Parameters:
526
+ # -request: The XML data that is to be sent to Datacash
527
+ #
528
+ # Returns:
529
+ # - ActiveMerchant::Billing::Response object
530
+ #
531
+ def commit(request)
532
+ response = parse(ssl_post(test? ? self.test_url : self.live_url, request))
533
+
534
+ Response.new(response[:status] == DATACASH_SUCCESS, response[:reason], response,
535
+ :test => test?,
536
+ :authorization => "#{response[:datacash_reference]};#{response[:authcode]};#{response[:ca_reference]}"
537
+ )
538
+ end
539
+
540
+ # Returns a date string in the format Datacash expects
541
+ #
542
+ # Parameters:
543
+ # -month: integer, the month
544
+ # -year: integer, the year
545
+ #
546
+ # Returns:
547
+ # -String: date in MM/YY format
548
+ #
549
+ def format_date(month, year)
550
+ "#{format(month,:two_digits)}/#{format(year, :two_digits)}"
551
+ end
552
+
553
+ # Parse the datacash response and create a Response object
554
+ #
555
+ # Parameters:
556
+ # -body: The XML returned from Datacash
557
+ #
558
+ # Returns:
559
+ # -a hash with all of the values returned in the Datacash XML response
560
+ #
561
+ def parse(body)
562
+
563
+ response = {}
564
+ xml = REXML::Document.new(body)
565
+ root = REXML::XPath.first(xml, "//Response")
566
+
567
+ root.elements.to_a.each do |node|
568
+ parse_element(response, node)
569
+ end
570
+
571
+ response
572
+ end
573
+
574
+ # Parse an xml element
575
+ #
576
+ # Parameters:
577
+ # -response: The hash that the values are being returned in
578
+ # -node: The node that is currently being read
579
+ #
580
+ # Returns:
581
+ # - none (results are stored in the passed hash)
582
+ def parse_element(response, node)
583
+ if node.has_elements?
584
+ node.elements.each{|e| parse_element(response, e) }
585
+ else
586
+ response[node.name.underscore.to_sym] = node.text
587
+ end
588
+ end
589
+
590
+ def format_reference_number(number)
591
+ number.to_s.gsub(/[^A-Za-z0-9]/, '').rjust(6, "0").first(30)
592
+ end
593
+
594
+ def parse_authorization_string(authorization)
595
+ reference, auth_code, ca_reference = authorization.to_s.split(';')
596
+ {:reference => reference, :auth_code => auth_code, :ca_reference => ca_reference}
597
+ end
598
+ end
599
+ end
600
+ end