yetanothernguyen-activemerchant 1.16.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 (192) hide show
  1. data/CHANGELOG +711 -0
  2. data/CONTRIBUTORS +245 -0
  3. data/MIT-LICENSE +20 -0
  4. data/gem-public_cert.pem +20 -0
  5. data/lib/active_merchant.rb +52 -0
  6. data/lib/active_merchant/billing.rb +9 -0
  7. data/lib/active_merchant/billing/avs_result.rb +98 -0
  8. data/lib/active_merchant/billing/base.rb +57 -0
  9. data/lib/active_merchant/billing/check.rb +68 -0
  10. data/lib/active_merchant/billing/credit_card.rb +178 -0
  11. data/lib/active_merchant/billing/credit_card_formatting.rb +21 -0
  12. data/lib/active_merchant/billing/credit_card_methods.rb +125 -0
  13. data/lib/active_merchant/billing/cvv_result.rb +38 -0
  14. data/lib/active_merchant/billing/expiry_date.rb +34 -0
  15. data/lib/active_merchant/billing/gateway.rb +170 -0
  16. data/lib/active_merchant/billing/gateways.rb +18 -0
  17. data/lib/active_merchant/billing/gateways/authorize_net.rb +672 -0
  18. data/lib/active_merchant/billing/gateways/authorize_net_cim.rb +858 -0
  19. data/lib/active_merchant/billing/gateways/barclays_epdq.rb +308 -0
  20. data/lib/active_merchant/billing/gateways/beanstream.rb +139 -0
  21. data/lib/active_merchant/billing/gateways/beanstream/beanstream_core.rb +282 -0
  22. data/lib/active_merchant/billing/gateways/beanstream_interac.rb +54 -0
  23. data/lib/active_merchant/billing/gateways/blue_pay.rb +11 -0
  24. data/lib/active_merchant/billing/gateways/bogus.rb +142 -0
  25. data/lib/active_merchant/billing/gateways/braintree.rb +17 -0
  26. data/lib/active_merchant/billing/gateways/braintree/braintree_common.rb +9 -0
  27. data/lib/active_merchant/billing/gateways/braintree_blue.rb +303 -0
  28. data/lib/active_merchant/billing/gateways/braintree_orange.rb +17 -0
  29. data/lib/active_merchant/billing/gateways/card_stream.rb +230 -0
  30. data/lib/active_merchant/billing/gateways/cyber_source.rb +430 -0
  31. data/lib/active_merchant/billing/gateways/data_cash.rb +597 -0
  32. data/lib/active_merchant/billing/gateways/efsnet.rb +235 -0
  33. data/lib/active_merchant/billing/gateways/elavon.rb +134 -0
  34. data/lib/active_merchant/billing/gateways/epay.rb +268 -0
  35. data/lib/active_merchant/billing/gateways/eway.rb +277 -0
  36. data/lib/active_merchant/billing/gateways/eway_managed.rb +231 -0
  37. data/lib/active_merchant/billing/gateways/exact.rb +222 -0
  38. data/lib/active_merchant/billing/gateways/federated_canada.rb +168 -0
  39. data/lib/active_merchant/billing/gateways/first_pay.rb +177 -0
  40. data/lib/active_merchant/billing/gateways/garanti.rb +262 -0
  41. data/lib/active_merchant/billing/gateways/ideal/ideal_base.rb +250 -0
  42. data/lib/active_merchant/billing/gateways/ideal/ideal_rabobank.pem +13 -0
  43. data/lib/active_merchant/billing/gateways/ideal/ideal_response.rb +29 -0
  44. data/lib/active_merchant/billing/gateways/ideal_rabobank.rb +55 -0
  45. data/lib/active_merchant/billing/gateways/inspire.rb +221 -0
  46. data/lib/active_merchant/billing/gateways/instapay.rb +164 -0
  47. data/lib/active_merchant/billing/gateways/iridium.rb +258 -0
  48. data/lib/active_merchant/billing/gateways/jetpay.rb +276 -0
  49. data/lib/active_merchant/billing/gateways/linkpoint.rb +454 -0
  50. data/lib/active_merchant/billing/gateways/merchant_e_solutions.rb +156 -0
  51. data/lib/active_merchant/billing/gateways/merchant_ware.rb +289 -0
  52. data/lib/active_merchant/billing/gateways/modern_payments.rb +36 -0
  53. data/lib/active_merchant/billing/gateways/modern_payments_cim.rb +220 -0
  54. data/lib/active_merchant/billing/gateways/moneris.rb +209 -0
  55. data/lib/active_merchant/billing/gateways/net_registry.rb +189 -0
  56. data/lib/active_merchant/billing/gateways/netaxept.rb +239 -0
  57. data/lib/active_merchant/billing/gateways/netbilling.rb +168 -0
  58. data/lib/active_merchant/billing/gateways/nmi.rb +13 -0
  59. data/lib/active_merchant/billing/gateways/ogone.rb +292 -0
  60. data/lib/active_merchant/billing/gateways/orbital.rb +321 -0
  61. data/lib/active_merchant/billing/gateways/orbital/orbital_soft_descriptors.rb +46 -0
  62. data/lib/active_merchant/billing/gateways/pay_junction.rb +392 -0
  63. data/lib/active_merchant/billing/gateways/pay_secure.rb +120 -0
  64. data/lib/active_merchant/billing/gateways/paybox_direct.rb +207 -0
  65. data/lib/active_merchant/billing/gateways/payflow.rb +253 -0
  66. data/lib/active_merchant/billing/gateways/payflow/payflow_common_api.rb +207 -0
  67. data/lib/active_merchant/billing/gateways/payflow/payflow_express_response.rb +39 -0
  68. data/lib/active_merchant/billing/gateways/payflow/payflow_response.rb +13 -0
  69. data/lib/active_merchant/billing/gateways/payflow_express.rb +222 -0
  70. data/lib/active_merchant/billing/gateways/payflow_express_uk.rb +15 -0
  71. data/lib/active_merchant/billing/gateways/payflow_uk.rb +21 -0
  72. data/lib/active_merchant/billing/gateways/payment_express.rb +235 -0
  73. data/lib/active_merchant/billing/gateways/paypal.rb +121 -0
  74. data/lib/active_merchant/billing/gateways/paypal/paypal_common_api.rb +351 -0
  75. data/lib/active_merchant/billing/gateways/paypal/paypal_express_response.rb +49 -0
  76. data/lib/active_merchant/billing/gateways/paypal_ca.rb +13 -0
  77. data/lib/active_merchant/billing/gateways/paypal_express.rb +177 -0
  78. data/lib/active_merchant/billing/gateways/paypal_express_common.rb +25 -0
  79. data/lib/active_merchant/billing/gateways/paystation.rb +201 -0
  80. data/lib/active_merchant/billing/gateways/plugnpay.rb +298 -0
  81. data/lib/active_merchant/billing/gateways/psigate.rb +219 -0
  82. data/lib/active_merchant/billing/gateways/psl_card.rb +304 -0
  83. data/lib/active_merchant/billing/gateways/qbms.rb +293 -0
  84. data/lib/active_merchant/billing/gateways/quantum.rb +282 -0
  85. data/lib/active_merchant/billing/gateways/quickpay.rb +223 -0
  86. data/lib/active_merchant/billing/gateways/realex.rb +311 -0
  87. data/lib/active_merchant/billing/gateways/sage.rb +146 -0
  88. data/lib/active_merchant/billing/gateways/sage/sage_bankcard.rb +88 -0
  89. data/lib/active_merchant/billing/gateways/sage/sage_core.rb +116 -0
  90. data/lib/active_merchant/billing/gateways/sage/sage_virtual_check.rb +97 -0
  91. data/lib/active_merchant/billing/gateways/sage_pay.rb +320 -0
  92. data/lib/active_merchant/billing/gateways/sallie_mae.rb +144 -0
  93. data/lib/active_merchant/billing/gateways/secure_net.rb +330 -0
  94. data/lib/active_merchant/billing/gateways/secure_pay.rb +31 -0
  95. data/lib/active_merchant/billing/gateways/secure_pay_au.rb +193 -0
  96. data/lib/active_merchant/billing/gateways/secure_pay_tech.rb +113 -0
  97. data/lib/active_merchant/billing/gateways/skip_jack.rb +453 -0
  98. data/lib/active_merchant/billing/gateways/smart_ps.rb +271 -0
  99. data/lib/active_merchant/billing/gateways/stripe.rb +212 -0
  100. data/lib/active_merchant/billing/gateways/trans_first.rb +127 -0
  101. data/lib/active_merchant/billing/gateways/transax.rb +25 -0
  102. data/lib/active_merchant/billing/gateways/trust_commerce.rb +423 -0
  103. data/lib/active_merchant/billing/gateways/usa_epay.rb +194 -0
  104. data/lib/active_merchant/billing/gateways/verifi.rb +233 -0
  105. data/lib/active_merchant/billing/gateways/viaklix.rb +189 -0
  106. data/lib/active_merchant/billing/gateways/wirecard.rb +318 -0
  107. data/lib/active_merchant/billing/gateways/worldpay.rb +280 -0
  108. data/lib/active_merchant/billing/integrations.rb +17 -0
  109. data/lib/active_merchant/billing/integrations/action_view_helper.rb +70 -0
  110. data/lib/active_merchant/billing/integrations/bogus.rb +23 -0
  111. data/lib/active_merchant/billing/integrations/bogus/helper.rb +17 -0
  112. data/lib/active_merchant/billing/integrations/bogus/notification.rb +11 -0
  113. data/lib/active_merchant/billing/integrations/bogus/return.rb +10 -0
  114. data/lib/active_merchant/billing/integrations/chronopay.rb +23 -0
  115. data/lib/active_merchant/billing/integrations/chronopay/helper.rb +120 -0
  116. data/lib/active_merchant/billing/integrations/chronopay/notification.rb +158 -0
  117. data/lib/active_merchant/billing/integrations/chronopay/return.rb +10 -0
  118. data/lib/active_merchant/billing/integrations/direc_pay.rb +41 -0
  119. data/lib/active_merchant/billing/integrations/direc_pay/helper.rb +200 -0
  120. data/lib/active_merchant/billing/integrations/direc_pay/notification.rb +76 -0
  121. data/lib/active_merchant/billing/integrations/direc_pay/return.rb +32 -0
  122. data/lib/active_merchant/billing/integrations/direc_pay/status.rb +37 -0
  123. data/lib/active_merchant/billing/integrations/directebanking.rb +47 -0
  124. data/lib/active_merchant/billing/integrations/directebanking/helper.rb +90 -0
  125. data/lib/active_merchant/billing/integrations/directebanking/notification.rb +120 -0
  126. data/lib/active_merchant/billing/integrations/directebanking/return.rb +11 -0
  127. data/lib/active_merchant/billing/integrations/e_payment_plans.rb +48 -0
  128. data/lib/active_merchant/billing/integrations/e_payment_plans/helper.rb +34 -0
  129. data/lib/active_merchant/billing/integrations/e_payment_plans/notification.rb +84 -0
  130. data/lib/active_merchant/billing/integrations/gestpay.rb +25 -0
  131. data/lib/active_merchant/billing/integrations/gestpay/common.rb +42 -0
  132. data/lib/active_merchant/billing/integrations/gestpay/helper.rb +70 -0
  133. data/lib/active_merchant/billing/integrations/gestpay/notification.rb +85 -0
  134. data/lib/active_merchant/billing/integrations/gestpay/return.rb +10 -0
  135. data/lib/active_merchant/billing/integrations/helper.rb +96 -0
  136. data/lib/active_merchant/billing/integrations/hi_trust.rb +27 -0
  137. data/lib/active_merchant/billing/integrations/hi_trust/helper.rb +58 -0
  138. data/lib/active_merchant/billing/integrations/hi_trust/notification.rb +59 -0
  139. data/lib/active_merchant/billing/integrations/hi_trust/return.rb +67 -0
  140. data/lib/active_merchant/billing/integrations/migs.rb +22 -0
  141. data/lib/active_merchant/billing/integrations/migs/helper.rb +64 -0
  142. data/lib/active_merchant/billing/integrations/migs/return.rb +54 -0
  143. data/lib/active_merchant/billing/integrations/moneybookers.rb +26 -0
  144. data/lib/active_merchant/billing/integrations/moneybookers/helper.rb +59 -0
  145. data/lib/active_merchant/billing/integrations/moneybookers/notification.rb +129 -0
  146. data/lib/active_merchant/billing/integrations/nochex.rb +88 -0
  147. data/lib/active_merchant/billing/integrations/nochex/helper.rb +68 -0
  148. data/lib/active_merchant/billing/integrations/nochex/notification.rb +94 -0
  149. data/lib/active_merchant/billing/integrations/nochex/return.rb +10 -0
  150. data/lib/active_merchant/billing/integrations/notification.rb +62 -0
  151. data/lib/active_merchant/billing/integrations/paypal.rb +39 -0
  152. data/lib/active_merchant/billing/integrations/paypal/helper.rb +119 -0
  153. data/lib/active_merchant/billing/integrations/paypal/notification.rb +154 -0
  154. data/lib/active_merchant/billing/integrations/paypal/return.rb +10 -0
  155. data/lib/active_merchant/billing/integrations/quickpay.rb +21 -0
  156. data/lib/active_merchant/billing/integrations/quickpay/helper.rb +72 -0
  157. data/lib/active_merchant/billing/integrations/quickpay/notification.rb +74 -0
  158. data/lib/active_merchant/billing/integrations/return.rb +42 -0
  159. data/lib/active_merchant/billing/integrations/sage_pay_form.rb +37 -0
  160. data/lib/active_merchant/billing/integrations/sage_pay_form/encryption.rb +33 -0
  161. data/lib/active_merchant/billing/integrations/sage_pay_form/helper.rb +111 -0
  162. data/lib/active_merchant/billing/integrations/sage_pay_form/notification.rb +210 -0
  163. data/lib/active_merchant/billing/integrations/sage_pay_form/return.rb +31 -0
  164. data/lib/active_merchant/billing/integrations/two_checkout.rb +23 -0
  165. data/lib/active_merchant/billing/integrations/two_checkout/helper.rb +59 -0
  166. data/lib/active_merchant/billing/integrations/two_checkout/notification.rb +114 -0
  167. data/lib/active_merchant/billing/integrations/two_checkout/return.rb +17 -0
  168. data/lib/active_merchant/billing/integrations/valitor.rb +33 -0
  169. data/lib/active_merchant/billing/integrations/valitor/helper.rb +86 -0
  170. data/lib/active_merchant/billing/integrations/valitor/notification.rb +13 -0
  171. data/lib/active_merchant/billing/integrations/valitor/response_fields.rb +97 -0
  172. data/lib/active_merchant/billing/integrations/valitor/return.rb +13 -0
  173. data/lib/active_merchant/billing/integrations/world_pay.rb +27 -0
  174. data/lib/active_merchant/billing/integrations/world_pay/helper.rb +100 -0
  175. data/lib/active_merchant/billing/integrations/world_pay/notification.rb +160 -0
  176. data/lib/active_merchant/billing/response.rb +32 -0
  177. data/lib/active_merchant/common.rb +14 -0
  178. data/lib/active_merchant/common/connection.rb +177 -0
  179. data/lib/active_merchant/common/country.rb +328 -0
  180. data/lib/active_merchant/common/error.rb +26 -0
  181. data/lib/active_merchant/common/post_data.rb +24 -0
  182. data/lib/active_merchant/common/posts_data.rb +63 -0
  183. data/lib/active_merchant/common/requires_parameters.rb +16 -0
  184. data/lib/active_merchant/common/utils.rb +22 -0
  185. data/lib/active_merchant/common/validateable.rb +81 -0
  186. data/lib/active_merchant/railtie.rb +9 -0
  187. data/lib/active_merchant/version.rb +3 -0
  188. data/lib/activemerchant.rb +1 -0
  189. data/lib/certs/cacert.pem +7815 -0
  190. data/lib/support/gateway_support.rb +58 -0
  191. data/lib/support/outbound_hosts.rb +25 -0
  192. metadata +281 -0
@@ -0,0 +1,298 @@
1
+ module ActiveMerchant
2
+ module Billing
3
+
4
+ class PlugnpayGateway < Gateway
5
+ class PlugnpayPostData < PostData
6
+ # Fields that will be sent even if they are blank
7
+ self.required_fields = [ :publisher_name, :publisher_password,
8
+ :card_amount, :card_name, :card_number, :card_exp, :orderID ]
9
+ end
10
+
11
+ URL = 'https://pay1.plugnpay.com/payment/pnpremote.cgi'
12
+
13
+ CARD_CODE_MESSAGES = {
14
+ "M" => "Card verification number matched",
15
+ "N" => "Card verification number didn't match",
16
+ "P" => "Card verification number was not processed",
17
+ "S" => "Card verification number should be on card but was not indicated",
18
+ "U" => "Issuer was not certified for card verification"
19
+ }
20
+
21
+ CARD_CODE_ERRORS = %w( N S )
22
+
23
+ AVS_MESSAGES = {
24
+ "A" => "Street address matches billing information, zip/postal code does not",
25
+ "B" => "Address information not provided for address verification check",
26
+ "E" => "Address verification service error",
27
+ "G" => "Non-U.S. card-issuing bank",
28
+ "N" => "Neither street address nor zip/postal match billing information",
29
+ "P" => "Address verification not applicable for this transaction",
30
+ "R" => "Payment gateway was unavailable or timed out",
31
+ "S" => "Address verification service not supported by issuer",
32
+ "U" => "Address information is unavailable",
33
+ "W" => "9-digit zip/postal code matches billing information, street address does not",
34
+ "X" => "Street address and 9-digit zip/postal code matches billing information",
35
+ "Y" => "Street address and 5-digit zip/postal code matches billing information",
36
+ "Z" => "5-digit zip/postal code matches billing information, street address does not",
37
+ }
38
+
39
+ AVS_ERRORS = %w( A E N R W Z )
40
+
41
+ PAYMENT_GATEWAY_RESPONSES = {
42
+ "P01" => "AVS Mismatch Failure",
43
+ "P02" => "CVV2 Mismatch Failure",
44
+ "P21" => "Transaction may not be marked",
45
+ "P30" => "Test Tran. Bad Card",
46
+ "P35" => "Test Tran. Problem",
47
+ "P40" => "Username already exists",
48
+ "P41" => "Username is blank",
49
+ "P50" => "Fraud Screen Failure",
50
+ "P51" => "Missing PIN Code",
51
+ "P52" => "Invalid Bank Acct. No.",
52
+ "P53" => "Invalid Bank Routing No.",
53
+ "P54" => "Invalid/Missing Check No.",
54
+ "P55" => "Invalid Credit Card No.",
55
+ "P56" => "Invalid CVV2/CVC2 No.",
56
+ "P57" => "Expired. CC Exp. Date",
57
+ "P58" => "Missing Data",
58
+ "P59" => "Missing Email Address",
59
+ "P60" => "Zip Code does not match Billing State.",
60
+ "P61" => "Invalid Billing Zip Code",
61
+ "P62" => "Zip Code does not match Shipping State.",
62
+ "P63" => "Invalid Shipping Zip Code",
63
+ "P64" => "Invalid Credit Card CVV2/CVC2 Format.",
64
+ "P65" => "Maximum number of attempts has been exceeded.",
65
+ "P66" => "Credit Card number has been flagged and can not be used to access this service.",
66
+ "P67" => "IP Address is on Blocked List.",
67
+ "P68" => "Billing country does not match ipaddress country.",
68
+ "P69" => "US based ipaddresses are currently blocked.",
69
+ "P70" => "Credit Cards issued from this bank are currently not being accepted.",
70
+ "P71" => "Credit Cards issued from this bank are currently not being accepted.",
71
+ "P72" => "Daily volume exceeded.",
72
+ "P73" => "Too many transactions within allotted time.",
73
+ "P91" => "Missing/incorrect password",
74
+ "P92" => "Account not configured for mobil administration",
75
+ "P93" => "IP Not registered to username.",
76
+ "P94" => "Mode not permitted for this account.",
77
+ "P95" => "Currently Blank",
78
+ "P96" => "Currently Blank",
79
+ "P97" => "Processor not responding",
80
+ "P98" => "Missing merchant/publisher name",
81
+ "P99" => "Currently Blank"
82
+ }
83
+
84
+ TRANSACTIONS = {
85
+ :authorization => 'auth',
86
+ :purchase => 'auth',
87
+ :capture => 'mark',
88
+ :void => 'void',
89
+ :refund => 'return',
90
+ :credit => 'newreturn'
91
+ }
92
+
93
+ SUCCESS_CODES = [ 'pending', 'success' ]
94
+ FAILURE_CODES = [ 'badcard', 'fraud' ]
95
+
96
+ self.default_currency = 'USD'
97
+ self.supported_countries = ['US']
98
+ self.supported_cardtypes = [:visa, :master, :american_express, :discover]
99
+ self.homepage_url = 'http://www.plugnpay.com/'
100
+ self.display_name = "Plug'n Pay"
101
+
102
+ def initialize(options = {})
103
+ requires!(options, :login, :password)
104
+ @options = options
105
+ super
106
+ end
107
+
108
+ def purchase(money, creditcard, options = {})
109
+ post = PlugnpayPostData.new
110
+
111
+ add_amount(post, money, options)
112
+ add_creditcard(post, creditcard)
113
+ add_addresses(post, options)
114
+ add_invoice_data(post, options)
115
+ add_customer_data(post, options)
116
+
117
+ post[:authtype] = 'authpostauth'
118
+ commit(:authorization, post)
119
+ end
120
+
121
+ def authorize(money, creditcard, options = {})
122
+ post = PlugnpayPostData.new
123
+
124
+ add_amount(post, money, options)
125
+ add_creditcard(post, creditcard)
126
+ add_addresses(post, options)
127
+ add_invoice_data(post, options)
128
+ add_customer_data(post, options)
129
+
130
+ post[:authtype] = 'authonly'
131
+ commit(:authorization, post)
132
+ end
133
+
134
+ def capture(money, authorization, options = {})
135
+ post = PlugnpayPostData.new
136
+
137
+ post[:orderID] = authorization
138
+
139
+ add_amount(post, money, options)
140
+ add_customer_data(post, options)
141
+
142
+ commit(:capture, post)
143
+ end
144
+
145
+ def void(authorization, options = {})
146
+ post = PlugnpayPostData.new
147
+
148
+ post[:orderID] = authorization
149
+ post[:txn_type] = 'auth'
150
+
151
+ commit(:void, post)
152
+ end
153
+
154
+ def credit(money, identification_or_creditcard, options = {})
155
+ post = PlugnpayPostData.new
156
+ add_amount(post, money, options)
157
+
158
+ if identification_or_creditcard.is_a?(String)
159
+ deprecated CREDIT_DEPRECATION_MESSAGE
160
+ refund(money, identification_or_creditcard, options)
161
+ else
162
+ add_creditcard(post, identification_or_creditcard)
163
+ add_addresses(post, options)
164
+ add_customer_data(post, options)
165
+
166
+ commit(:credit, post)
167
+ end
168
+ end
169
+
170
+ def refund(money, reference, options = {})
171
+ post = PlugnpayPostData.new
172
+ add_amount(post, money, options)
173
+ post[:orderID] = reference
174
+ commit(:refund, post)
175
+ end
176
+
177
+ private
178
+ def commit(action, post)
179
+ response = parse( ssl_post(URL, post_data(action, post)) )
180
+
181
+ success = SUCCESS_CODES.include?(response[:finalstatus])
182
+ message = success ? 'Success' : message_from(response)
183
+
184
+ Response.new(success, message, response,
185
+ :test => test?,
186
+ :authorization => response[:orderid],
187
+ :avs_result => { :code => response[:avs_code] },
188
+ :cvv_result => response[:cvvresp]
189
+ )
190
+ end
191
+
192
+ def parse(body)
193
+ body = CGI.unescape(body)
194
+ results = {}
195
+ body.split('&').collect { |e| e.split('=') }.each do |key,value|
196
+ results[key.downcase.to_sym] = normalize(value.to_s.strip)
197
+ end
198
+
199
+ results.delete(:publisher_password)
200
+ results[:avs_message] = AVS_MESSAGES[results[:avs_code]] if results[:avs_code]
201
+ results[:card_code_message] = CARD_CODE_MESSAGES[results[:cvvresp]] if results[:cvvresp]
202
+
203
+ results
204
+ end
205
+
206
+ def post_data(action, post)
207
+ post[:mode] = TRANSACTIONS[action]
208
+ post[:convert] = 'underscores'
209
+ post[:app_level] = 0
210
+ post[:publisher_name] = @options[:login]
211
+ post[:publisher_password] = @options[:password]
212
+
213
+ post.to_s
214
+ end
215
+
216
+ def add_creditcard(post, creditcard)
217
+ post[:card_number] = creditcard.number
218
+ post[:card_cvv] = creditcard.verification_value
219
+ post[:card_exp] = expdate(creditcard)
220
+ post[:card_name] = creditcard.name.slice(0..38)
221
+ end
222
+
223
+ def add_customer_data(post, options)
224
+ post[:email] = options[:email]
225
+ post[:dontsndmail] = 'yes' unless options[:send_email_confirmation]
226
+ post[:ipaddress] = options[:ip]
227
+ end
228
+
229
+ def add_invoice_data(post, options)
230
+ post[:shipping] = amount(options[:shipping]) unless options[:shipping].blank?
231
+ post[:tax] = amount(options[:tax]) unless options[:tax].blank?
232
+ end
233
+
234
+ def add_addresses(post, options)
235
+ if address = options[:billing_address] || options[:address]
236
+ post[:card_address1] = address[:address1]
237
+ post[:card_zip] = address[:zip]
238
+ post[:card_city] = address[:city]
239
+ post[:card_country] = address[:country]
240
+ post[:phone] = address[:phone]
241
+
242
+ case address[:country]
243
+ when 'US', 'CA'
244
+ post[:card_state] = address[:state]
245
+ else
246
+ post[:card_state] = 'ZZ'
247
+ post[:card_prov] = address[:state]
248
+ end
249
+ end
250
+
251
+ if shipping_address = options[:shipping_address] || address
252
+ post[:shipname] = shipping_address[:name]
253
+ post[:address1] = shipping_address[:address1]
254
+ post[:address2] = shipping_address[:address2]
255
+ post[:city] = shipping_address[:city]
256
+
257
+ case shipping_address[:country]
258
+ when 'US', 'CA'
259
+ post[:state] = shipping_address[:state]
260
+ else
261
+ post[:state] = 'ZZ'
262
+ post[:province] = shipping_address[:state]
263
+ end
264
+
265
+ post[:country] = shipping_address[:country]
266
+ post[:zip] = shipping_address[:zip]
267
+ end
268
+ end
269
+
270
+ def add_amount(post, money, options)
271
+ post[:card_amount] = amount(money)
272
+ post[:currency] = options[:currency] || currency(money)
273
+ end
274
+
275
+ # Make a ruby type out of the response string
276
+ def normalize(field)
277
+ case field
278
+ when "true" then true
279
+ when "false" then false
280
+ when "" then nil
281
+ when "null" then nil
282
+ else field
283
+ end
284
+ end
285
+
286
+ def message_from(results)
287
+ PAYMENT_GATEWAY_RESPONSES[results[:resp_code]]
288
+ end
289
+
290
+ def expdate(creditcard)
291
+ year = sprintf("%.4i", creditcard.year)
292
+ month = sprintf("%.2i", creditcard.month)
293
+
294
+ "#{month}/#{year[-2..-1]}"
295
+ end
296
+ end
297
+ end
298
+ end
@@ -0,0 +1,219 @@
1
+ # This class implements the Psigate gateway for the ActiveMerchant module.
2
+ # Psigate = http://www.psigate.com/ The class is currently set up to use
3
+ # the psigate test server while rails is in testing or developement mode.
4
+ # The real server will be used while in production mode.
5
+ #
6
+ # Modifications by Sean O'Hara ( sohara at sohara dot com )
7
+ #
8
+ # Usage for a PreAuth (authorize) is as follows:
9
+ #
10
+ # twenty = 2000
11
+ # gateway = PsigateGateway.new(
12
+ # :login => 'teststore',
13
+ # :password => 'psigate1234'
14
+ # )
15
+ #
16
+ # creditcard = CreditCard.new(
17
+ # :number => '4242424242424242',
18
+ # :month => 8,
19
+ # :year => 2006,
20
+ # :first_name => 'Longbob',
21
+ # :last_name => 'Longsen'
22
+ # )
23
+ # response = @gateway.authorize(twenty, creditcard,
24
+ # :order_id => 1234,
25
+ # :billing_address => {
26
+ # :address1 => '123 fairweather Lane',
27
+ # :address2 => 'Apt B',
28
+ # :city => 'New York',
29
+ # :state => 'NY',
30
+ # :country => 'U.S.A.',
31
+ # :zip => '10010'
32
+ # },
33
+ # :email => 'jack@yahoo.com'
34
+ # )
35
+
36
+ require 'rexml/document'
37
+
38
+ module ActiveMerchant #:nodoc:
39
+ module Billing #:nodoc:
40
+
41
+ class PsigateGateway < Gateway
42
+ TEST_URL = 'https://dev.psigate.com:7989/Messenger/XMLMessenger'
43
+ LIVE_URL = 'https://secure.psigate.com:7934/Messenger/XMLMessenger'
44
+
45
+ self.supported_cardtypes = [:visa, :master, :american_express]
46
+ self.supported_countries = ['CA']
47
+ self.homepage_url = 'http://www.psigate.com/'
48
+ self.display_name = 'Psigate'
49
+
50
+ SUCCESS_MESSAGE = 'Success'
51
+ FAILURE_MESSAGE = 'The transaction was declined'
52
+
53
+ def initialize(options = {})
54
+ requires!(options, :login, :password)
55
+ @options = options
56
+ super
57
+ end
58
+
59
+ # Psigate PreAuth
60
+ def authorize(money, creditcard, options = {})
61
+ requires!(options, :order_id)
62
+ options.update({ :CardAction => "1" })
63
+ commit(money, creditcard, options)
64
+ end
65
+
66
+ # Psigate Sale
67
+ def purchase(money, creditcard, options = {})
68
+ requires!(options, :order_id)
69
+ options.update({ :CardAction => "0" })
70
+ commit(money, creditcard, options)
71
+ end
72
+
73
+ # Psigate PostAuth
74
+ def capture(money, authorization, options = {})
75
+ options.update({ :CardAction => "2", :order_id => authorization })
76
+ commit(money, nil, options)
77
+ end
78
+
79
+
80
+ # Psigate Credit
81
+ def credit(money, authorization, options = {})
82
+ deprecated CREDIT_DEPRECATION_MESSAGE
83
+ refund(money, authorization, options)
84
+ end
85
+
86
+ def refund(money, authorization, options = {})
87
+ options.update({ :CardAction => "3", :order_id => authorization })
88
+ commit(money, nil, options)
89
+ end
90
+
91
+ private
92
+
93
+ def commit(money, creditcard, options = {})
94
+ response = parse(ssl_post(test? ? TEST_URL : LIVE_URL, post_data(money, creditcard, options)))
95
+
96
+ Response.new(successful?(response), message_from(response), response,
97
+ :test => test?,
98
+ :authorization => response[:orderid],
99
+ :avs_result => { :code => response[:avsresult] },
100
+ :cvv_result => response[:cardidresult]
101
+ )
102
+ end
103
+
104
+ def successful?(response)
105
+ response[:approved] == "APPROVED"
106
+ end
107
+
108
+ def parse(xml)
109
+ response = {:message => "Global Error Receipt", :complete => false}
110
+
111
+ xml = REXML::Document.new(xml)
112
+ xml.elements.each('//Result/*') do |node|
113
+
114
+ response[node.name.downcase.to_sym] = normalize(node.text)
115
+
116
+ end unless xml.root.nil?
117
+
118
+ response
119
+ end
120
+
121
+ def post_data(money, creditcard, options)
122
+ xml = REXML::Document.new
123
+ xml << REXML::XMLDecl.new
124
+ root = xml.add_element("Order")
125
+
126
+ for key, value in parameters(money, creditcard, options)
127
+ root.add_element(key.to_s).text = value if value
128
+ end
129
+
130
+ xml.to_s
131
+ end
132
+
133
+ # Set up the parameters hash just once so we don't have to do it
134
+ # for every action.
135
+ def parameters(money, creditcard, options = {})
136
+ params = {
137
+ # General order paramters
138
+ :StoreID => @options[:login],
139
+ :Passphrase => @options[:password],
140
+ :TestResult => options[:test_result],
141
+ :OrderID => options[:order_id],
142
+ :UserID => options[:user_id],
143
+ :Phone => options[:phone],
144
+ :Fax => options[:fax],
145
+ :Email => options[:email],
146
+
147
+ # Credit Card paramaters
148
+ :PaymentType => "CC",
149
+ :CardAction => options[:CardAction],
150
+
151
+ # Financial paramters
152
+ :CustomerIP => options[:ip],
153
+ :SubTotal => amount(money),
154
+ :Tax1 => options[:tax1],
155
+ :Tax2 => options[:tax2],
156
+ :ShippingTotal => options[:shipping_total],
157
+ }
158
+
159
+ if creditcard
160
+ exp_month = sprintf("%.2i", creditcard.month) unless creditcard.month.blank?
161
+ exp_year = creditcard.year.to_s[2,2] unless creditcard.year.blank?
162
+ card_id_code = creditcard.verification_value.blank? ? nil : "1"
163
+
164
+ params.update(
165
+ :CardNumber => creditcard.number,
166
+ :CardExpMonth => exp_month,
167
+ :CardExpYear => exp_year,
168
+ :CardIDCode => card_id_code,
169
+ :CardIDNumber => creditcard.verification_value
170
+ )
171
+ end
172
+
173
+ if address = options[:billing_address] || options[:address]
174
+ params[:Bname] = address[:name] || creditcard.name
175
+ params[:Baddress1] = address[:address1] unless address[:address1].blank?
176
+ params[:Baddress2] = address[:address2] unless address[:address2].blank?
177
+ params[:Bcity] = address[:city] unless address[:city].blank?
178
+ params[:Bprovince] = address[:state] unless address[:state].blank?
179
+ params[:Bpostalcode] = address[:zip] unless address[:zip].blank?
180
+ params[:Bcountry] = address[:country] unless address[:country].blank?
181
+ params[:Bcompany] = address[:company] unless address[:company].blank?
182
+ end
183
+
184
+ if address = options[:shipping_address]
185
+ params[:Sname] = address[:name] || creditcard.name
186
+ params[:Saddress1] = address[:address1] unless address[:address1].blank?
187
+ params[:Saddress2] = address[:address2] unless address[:address2].blank?
188
+ params[:Scity] = address[:city] unless address[:city].blank?
189
+ params[:Sprovince] = address[:state] unless address[:state].blank?
190
+ params[:Spostalcode] = address[:zip] unless address[:zip].blank?
191
+ params[:Scountry] = address[:country] unless address[:country].blank?
192
+ params[:Scompany] = address[:company] unless address[:company].blank?
193
+ end
194
+
195
+ return params
196
+ end
197
+
198
+ def message_from(response)
199
+ if response[:approved] == "APPROVED"
200
+ return SUCCESS_MESSAGE
201
+ else
202
+ return FAILURE_MESSAGE if response[:errmsg].blank?
203
+ return response[:errmsg].gsub(/[^\w]/, ' ').split.join(" ").capitalize
204
+ end
205
+ end
206
+
207
+ # Make a ruby type out of the response string
208
+ def normalize(field)
209
+ case field
210
+ when "true" then true
211
+ when "false" then false
212
+ when "" then nil
213
+ when "null" then nil
214
+ else field
215
+ end
216
+ end
217
+ end
218
+ end
219
+ end