Commit | Line | Data |
---|---|---|
0dbefed3 EM |
1 | <?php |
2 | ||
0dbefed3 EM |
3 | /** |
4 | * Class CRM_Core_Payment_PayPalProIPNTest | |
acb109b7 | 5 | * @group headless |
0dbefed3 EM |
6 | */ |
7 | class CRM_Core_Payment_AuthorizeNetIPNTest extends CiviUnitTestCase { | |
8 | protected $_contributionID; | |
9 | protected $_invoiceID = 'c2r9c15f7be20b4f3fef1f77e4c37424'; | |
10 | protected $_financialTypeID = 1; | |
11 | protected $_contactID; | |
12 | protected $_contributionRecurID; | |
13 | protected $_contributionPageID; | |
14 | protected $_paymentProcessorID; | |
15 | ||
00be9182 | 16 | public function setUp() { |
0dbefed3 | 17 | parent::setUp(); |
034efa4e | 18 | $this->_paymentProcessorID = $this->paymentProcessorAuthorizeNetCreate(array('is_test' => 0)); |
0dbefed3 EM |
19 | $this->_contactID = $this->individualCreate(); |
20 | $contributionPage = $this->callAPISuccess('contribution_page', 'create', array( | |
21 | 'title' => "Test Contribution Page", | |
22 | 'financial_type_id' => $this->_financialTypeID, | |
23 | 'currency' => 'USD', | |
24 | 'payment_processor' => $this->_paymentProcessorID, | |
481312d9 | 25 | 'max_amount' => 1000, |
26 | 'receipt_from_email' => 'gaia@the.cosmos', | |
27 | 'receipt_from_name' => 'Pachamama', | |
28 | 'is_email_receipt' => TRUE, | |
0dbefed3 EM |
29 | )); |
30 | $this->_contributionPageID = $contributionPage['id']; | |
31 | } | |
32 | ||
00be9182 | 33 | public function tearDown() { |
0dbefed3 EM |
34 | $this->quickCleanUpFinancialEntities(); |
35 | } | |
39b959db | 36 | |
0495f30c | 37 | /** |
38 | * Ensure recurring contributions from Contribution Pages | |
39 | * with receipt turned off don't send a receipt. | |
40 | */ | |
41 | public function testIPNPaymentRecurNoReceipt() { | |
42 | $mut = new CiviMailUtils($this, TRUE); | |
43 | // Turn off receipts in contribution page. | |
44 | $api_params = array( | |
45 | 'id' => $this->_contributionPageID, | |
46 | 'is_email_receipt' => FALSE, | |
47 | ); | |
48 | $this->callAPISuccess('contributionPage', 'update', $api_params); | |
49 | ||
50 | // Create initial recurring payment and initial contribution. | |
51 | // Note - we can't use setupRecurringPaymentProcessorTransaction(), which | |
52 | // would be convenient because it does not fully mimic the real user | |
53 | // experience. Using setupRecurringPaymentProcessorTransaction() doesn't | |
54 | // specify is_email_receipt so it is always set to 1. We need to more | |
55 | // closely mimic what happens with a live transaction to test that | |
56 | // is_email_receipt is not set to 1 if the originating contribution page | |
57 | // has is_email_receipt set to 0. | |
58 | $form = new CRM_Contribute_Form_Contribution(); | |
59 | $form->_mode = 'Live'; | |
60 | $contribution = $form->testSubmit(array( | |
61 | 'total_amount' => 200, | |
62 | 'financial_type_id' => 1, | |
63 | 'receive_date' => date('m/d/Y'), | |
64 | 'receive_date_time' => date('H:i:s'), | |
65 | 'contact_id' => $this->_contactID, | |
66 | 'contribution_status_id' => 1, | |
67 | 'credit_card_number' => 4444333322221111, | |
68 | 'cvv2' => 123, | |
69 | 'credit_card_exp_date' => array( | |
70 | 'M' => 9, | |
71 | 'Y' => 2025, | |
72 | ), | |
73 | 'credit_card_type' => 'Visa', | |
74 | 'billing_first_name' => 'Junko', | |
75 | 'billing_middle_name' => '', | |
76 | 'billing_last_name' => 'Adams', | |
77 | 'billing_street_address-5' => time() . ' Lincoln St S', | |
78 | 'billing_city-5' => 'Maryknoll', | |
79 | 'billing_state_province_id-5' => 1031, | |
80 | 'billing_postal_code-5' => 10545, | |
81 | 'billing_country_id-5' => 1228, | |
82 | 'frequency_interval' => 1, | |
83 | 'frequency_unit' => 'month', | |
84 | 'installments' => '', | |
85 | 'hidden_AdditionalDetail' => 1, | |
86 | 'hidden_Premium' => 1, | |
87 | 'payment_processor_id' => $this->_paymentProcessorID, | |
88 | 'currency' => 'USD', | |
89 | 'source' => 'bob sled race', | |
90 | 'contribution_page_id' => $this->_contributionPageID, | |
91 | 'is_recur' => TRUE, | |
92 | ), CRM_Core_Action::ADD); | |
93 | ||
94 | $this->_contributionID = $contribution->id; | |
95 | $this->_contributionRecurID = $contribution->contribution_recur_id; | |
96 | $recur_params = array( | |
97 | 'id' => $this->_contributionRecurID, | |
98 | 'return' => 'processor_id', | |
99 | ); | |
100 | $processor_id = civicrm_api3('ContributionRecur', 'getvalue', $recur_params); | |
101 | // Process the initial one. | |
102 | $IPN = new CRM_Core_Payment_AuthorizeNetIPN( | |
103 | $this->getRecurTransaction(array('x_subscription_id' => $processor_id)) | |
104 | ); | |
105 | $IPN->main(); | |
106 | ||
107 | // Now send a second one (authorize seems to treat first and second contributions | |
108 | // differently. | |
109 | $IPN = new CRM_Core_Payment_AuthorizeNetIPN($this->getRecurSubsequentTransaction( | |
110 | array('x_subscription_id' => $processor_id) | |
111 | )); | |
112 | $IPN->main(); | |
113 | ||
114 | // There should not be any email. | |
115 | $mut->assertMailLogEmpty(); | |
116 | } | |
0dbefed3 EM |
117 | |
118 | /** | |
100fef9d | 119 | * Test IPN response updates contribution_recur & contribution for first & second contribution |
0dbefed3 | 120 | */ |
00be9182 | 121 | public function testIPNPaymentRecurSuccess() { |
0dbefed3 | 122 | $this->setupRecurringPaymentProcessorTransaction(); |
8f234057 | 123 | $IPN = new CRM_Core_Payment_AuthorizeNetIPN($this->getRecurTransaction()); |
124 | $IPN->main(); | |
0dbefed3 EM |
125 | $contribution = $this->callAPISuccess('contribution', 'getsingle', array('id' => $this->_contributionID)); |
126 | $this->assertEquals(1, $contribution['contribution_status_id']); | |
127 | $this->assertEquals('6511143069', $contribution['trxn_id']); | |
128 | // source gets set by processor | |
129 | $this->assertTrue(substr($contribution['contribution_source'], 0, 20) == "Online Contribution:"); | |
130 | $contributionRecur = $this->callAPISuccess('contribution_recur', 'getsingle', array('id' => $this->_contributionRecurID)); | |
131 | $this->assertEquals(5, $contributionRecur['contribution_status_id']); | |
8f234057 | 132 | $IPN = new CRM_Core_Payment_AuthorizeNetIPN($this->getRecurSubsequentTransaction()); |
133 | $IPN->main(); | |
92915c55 | 134 | $contribution = $this->callAPISuccess('contribution', 'get', array( |
39b959db SL |
135 | 'contribution_recur_id' => $this->_contributionRecurID, |
136 | 'sequential' => 1, | |
137 | )); | |
0dbefed3 EM |
138 | $this->assertEquals(2, $contribution['count']); |
139 | $this->assertEquals('second_one', $contribution['values'][1]['trxn_id']); | |
4a1ba425 | 140 | $this->assertEquals(date('Y-m-d'), date('Y-m-d', strtotime($contribution['values'][1]['receive_date']))); |
0dbefed3 EM |
141 | } |
142 | ||
f4aff12e JP |
143 | /** |
144 | * Test payment processor is correctly assigned for the IPN payment. | |
145 | */ | |
146 | public function testIPNPaymentRecurSuccessMultiAuthNetProcessor() { | |
147 | //Create and set up recur payment using second instance of AuthNet Processor. | |
148 | $this->_paymentProcessorID2 = $this->paymentProcessorAuthorizeNetCreate(array('name' => 'Authorize2', 'is_test' => 0)); | |
149 | $this->setupRecurringPaymentProcessorTransaction(array('payment_processor_id' => $this->_paymentProcessorID2)); | |
150 | ||
151 | //Call IPN with processor id. | |
152 | $IPN = new CRM_Core_Payment_AuthorizeNetIPN($this->getRecurTransaction(array('processor_id' => $this->_paymentProcessorID2))); | |
153 | $IPN->main(); | |
154 | $contribution = $this->callAPISuccess('contribution', 'getsingle', array('id' => $this->_contributionID)); | |
155 | $this->assertEquals(1, $contribution['contribution_status_id']); | |
156 | $this->assertEquals('6511143069', $contribution['trxn_id']); | |
157 | // source gets set by processor | |
158 | $this->assertTrue(substr($contribution['contribution_source'], 0, 20) == "Online Contribution:"); | |
159 | $contributionRecur = $this->callAPISuccess('contribution_recur', 'getsingle', array('id' => $this->_contributionRecurID)); | |
160 | $this->assertEquals(5, $contributionRecur['contribution_status_id']); | |
161 | } | |
162 | ||
4a1ba425 | 163 | /** |
164 | * Test IPN response updates contribution_recur & contribution for first & second contribution | |
165 | */ | |
166 | public function testIPNPaymentRecurSuccessSuppliedReceiveDate() { | |
167 | $this->setupRecurringPaymentProcessorTransaction(); | |
168 | $IPN = new CRM_Core_Payment_AuthorizeNetIPN($this->getRecurTransaction()); | |
169 | $IPN->main(); | |
170 | $contribution = $this->callAPISuccess('contribution', 'getsingle', array('id' => $this->_contributionID)); | |
171 | $this->assertEquals(1, $contribution['contribution_status_id']); | |
172 | $this->assertEquals('6511143069', $contribution['trxn_id']); | |
173 | // source gets set by processor | |
174 | $this->assertTrue(substr($contribution['contribution_source'], 0, 20) == "Online Contribution:"); | |
175 | $contributionRecur = $this->callAPISuccess('contribution_recur', 'getsingle', array('id' => $this->_contributionRecurID)); | |
176 | $this->assertEquals(5, $contributionRecur['contribution_status_id']); | |
177 | $IPN = new CRM_Core_Payment_AuthorizeNetIPN(array_merge(array('receive_date' => '1 July 2010'), $this->getRecurSubsequentTransaction())); | |
178 | $IPN->main(); | |
179 | $contribution = $this->callAPISuccess('contribution', 'get', array( | |
180 | 'contribution_recur_id' => $this->_contributionRecurID, | |
181 | 'sequential' => 1, | |
182 | )); | |
183 | $this->assertEquals(2, $contribution['count']); | |
184 | $this->assertEquals('second_one', $contribution['values'][1]['trxn_id']); | |
185 | $this->assertEquals('2010-07-01', date('Y-m-d', strtotime($contribution['values'][1]['receive_date']))); | |
186 | } | |
187 | ||
8c15aab2 | 188 | /** |
100fef9d | 189 | * Test IPN response updates contribution_recur & contribution for first & second contribution |
8c15aab2 | 190 | */ |
00be9182 | 191 | public function testIPNPaymentMembershipRecurSuccess() { |
8c15aab2 | 192 | $this->setupMembershipRecurringPaymentProcessorTransaction(); |
8f234057 | 193 | $IPN = new CRM_Core_Payment_AuthorizeNetIPN($this->getRecurTransaction()); |
194 | $IPN->main(); | |
8c15aab2 EM |
195 | $contribution = $this->callAPISuccess('contribution', 'getsingle', array('id' => $this->_contributionID)); |
196 | $this->assertEquals(1, $contribution['contribution_status_id']); | |
197 | $this->assertEquals('6511143069', $contribution['trxn_id']); | |
198 | // source gets set by processor | |
199 | $this->assertTrue(substr($contribution['contribution_source'], 0, 20) == "Online Contribution:"); | |
200 | $contributionRecur = $this->callAPISuccess('contribution_recur', 'getsingle', array('id' => $this->_contributionRecurID)); | |
201 | $this->assertEquals(5, $contributionRecur['contribution_status_id']); | |
8f234057 | 202 | $IPN = new CRM_Core_Payment_AuthorizeNetIPN($this->getRecurSubsequentTransaction()); |
203 | $IPN->main(); | |
92915c55 | 204 | $contribution = $this->callAPISuccess('contribution', 'get', array( |
39b959db SL |
205 | 'contribution_recur_id' => $this->_contributionRecurID, |
206 | 'sequential' => 1, | |
207 | )); | |
8c15aab2 | 208 | $this->assertEquals(2, $contribution['count']); |
9bee639f JM |
209 | // Ensure both contributions are coded as credit card contributions. |
210 | $this->assertEquals(1, $contribution['values'][0]['payment_instrument_id']); | |
211 | $this->assertEquals(1, $contribution['values'][1]['payment_instrument_id']); | |
8c15aab2 | 212 | $this->assertEquals('second_one', $contribution['values'][1]['trxn_id']); |
6c6e6187 | 213 | $this->callAPISuccessGetSingle('membership_payment', array('contribution_id' => $contribution['values'][1]['id'])); |
92915c55 | 214 | $this->callAPISuccessGetSingle('line_item', array( |
39b959db SL |
215 | 'contribution_id' => $contribution['values'][1]['id'], |
216 | 'entity_table' => 'civicrm_membership', | |
217 | )); | |
8c15aab2 EM |
218 | } |
219 | ||
0dbefed3 | 220 | /** |
481312d9 | 221 | * Test IPN response mails don't leak. |
0dbefed3 | 222 | */ |
481312d9 | 223 | public function testIPNPaymentMembershipRecurSuccessNoLeakage() { |
224 | $mut = new CiviMailUtils($this, TRUE); | |
225 | $this->setupMembershipRecurringPaymentProcessorTransaction(array('is_email_receipt' => TRUE)); | |
226 | $this->addProfile('supporter_profile', $this->_contributionPageID); | |
5d6cf648 JM |
227 | $this->addProfile('honoree_individual', $this->_contributionPageID, 'soft_credit'); |
228 | ||
229 | $this->callAPISuccess('ContributionSoft', 'create', [ | |
230 | 'contact_id' => $this->individualCreate(), | |
231 | 'contribution_id' => $this->_contributionID, | |
232 | 'soft_credit_type_id' => 'in_memory_of', | |
233 | 'amount' => 200, | |
234 | ]); | |
235 | ||
481312d9 | 236 | $IPN = new CRM_Core_Payment_AuthorizeNetIPN($this->getRecurTransaction()); |
237 | $IPN->main(); | |
238 | $mut->checkAllMailLog(array( | |
239 | 'Membership Type: General', | |
240 | 'Mr. Anthony Anderson II" <anthony_anderson@civicrm.org>', | |
241 | 'Amount: $ 200.00', | |
242 | 'Membership Start Date:', | |
243 | 'Supporter Profile', | |
244 | 'First Name: Anthony', | |
245 | 'Last Name: Anderson', | |
246 | 'Email Address: anthony_anderson@civicrm.org', | |
5d6cf648 | 247 | 'Honor', |
481312d9 | 248 | 'This membership will be automatically renewed every', |
249 | 'Dear Mr. Anthony Anderson II', | |
250 | 'Thanks for your auto renew membership sign-up', | |
5d6cf648 | 251 | 'In Memory of', |
481312d9 | 252 | )); |
253 | $mut->clearMessages(); | |
254 | $this->_contactID = $this->individualCreate(array('first_name' => 'Antonia', 'prefix_id' => 'Mrs.', 'email' => 'antonia_anderson@civicrm.org')); | |
255 | $this->_invoiceID = uniqid(); | |
256 | ||
5d6cf648 JM |
257 | // Note, the second contribution is not in honor of anyone and the |
258 | // receipt should not mention honor at all. | |
481312d9 | 259 | $this->setupMembershipRecurringPaymentProcessorTransaction(array('is_email_receipt' => TRUE)); |
260 | $IPN = new CRM_Core_Payment_AuthorizeNetIPN($this->getRecurTransaction(array('x_trans_id' => 'hers'))); | |
261 | $IPN->main(); | |
262 | ||
263 | $mut->checkAllMailLog(array( | |
264 | 'Membership Type: General', | |
265 | 'Mrs. Antonia Anderson II', | |
266 | 'antonia_anderson@civicrm.org', | |
267 | 'Amount: $ 200.00', | |
268 | 'Membership Start Date:', | |
269 | 'Transaction #: hers', | |
270 | 'Supporter Profile', | |
271 | 'First Name: Antonia', | |
272 | 'Last Name: Anderson', | |
273 | 'Email Address: antonia_anderson@civicrm.org', | |
274 | 'This membership will be automatically renewed every', | |
275 | 'Dear Mrs. Antonia Anderson II', | |
276 | 'Thanks for your auto renew membership sign-up', | |
277 | )); | |
278 | ||
5d6cf648 JM |
279 | $shouldNotBeInMailing = array( |
280 | 'Honor', | |
281 | 'In Memory of', | |
282 | ); | |
283 | $mails = $mut->getAllMessages('raw'); | |
284 | foreach ($mails as $mail) { | |
285 | $mut->checkMailForStrings(array(), $shouldNotBeInMailing, '', $mail); | |
286 | } | |
481312d9 | 287 | $mut->stop(); |
288 | $mut->clearMessages(); | |
289 | } | |
290 | ||
c198e59d | 291 | /** |
292 | * Test IPN response mails don't leak. | |
293 | */ | |
294 | public function testIPNPaymentMembershipRecurSuccessNoLeakageOnlineThenOffline() { | |
295 | $mut = new CiviMailUtils($this, TRUE); | |
296 | $this->setupMembershipRecurringPaymentProcessorTransaction(array('is_email_receipt' => TRUE)); | |
297 | $this->addProfile('supporter_profile', $this->_contributionPageID); | |
298 | $IPN = new CRM_Core_Payment_AuthorizeNetIPN($this->getRecurTransaction()); | |
299 | $IPN->main(); | |
300 | $mut->checkAllMailLog(array( | |
301 | 'Membership Type: General', | |
302 | 'Mr. Anthony Anderson II" <anthony_anderson@civicrm.org>', | |
303 | 'Amount: $ 200.00', | |
304 | 'Membership Start Date:', | |
305 | 'Supporter Profile', | |
306 | 'First Name: Anthony', | |
307 | 'Last Name: Anderson', | |
308 | 'Email Address: anthony_anderson@civicrm.org', | |
309 | 'This membership will be automatically renewed every', | |
310 | 'Dear Mr. Anthony Anderson II', | |
311 | 'Thanks for your auto renew membership sign-up', | |
312 | )); | |
313 | ||
314 | $this->_contactID = $this->individualCreate(array('first_name' => 'Antonia', 'prefix_id' => 'Mrs.', 'email' => 'antonia_anderson@civicrm.org')); | |
315 | $this->_invoiceID = uniqid(); | |
316 | $this->_contributionPageID = NULL; | |
317 | ||
318 | $this->setupMembershipRecurringPaymentProcessorTransaction(array('is_email_receipt' => TRUE)); | |
b13d4a61 | 319 | $mut->clearMessages(); |
c198e59d | 320 | $IPN = new CRM_Core_Payment_AuthorizeNetIPN($this->getRecurTransaction(array('x_trans_id' => 'hers'))); |
321 | $IPN->main(); | |
322 | ||
323 | $mut->checkAllMailLog(array( | |
324 | 'Membership Type: General', | |
325 | 'Mrs. Antonia Anderson II', | |
326 | 'antonia_anderson@civicrm.org', | |
327 | 'Amount: $ 200.00', | |
328 | 'Membership Start Date:', | |
329 | 'Transaction #: hers', | |
330 | 'This membership will be automatically renewed every', | |
331 | 'Dear Mrs. Antonia Anderson II', | |
332 | 'Thanks for your auto renew membership sign-up', | |
c7e7164f | 333 | ), |
334 | array( | |
335 | 'First Name: Anthony', | |
336 | 'First Name: Antonia', | |
337 | 'Last Name: Anderson', | |
338 | 'Supporter Profile', | |
339 | 'Email Address: antonia_anderson@civicrm.org', | |
340 | )); | |
c198e59d | 341 | |
342 | $mut->stop(); | |
343 | $mut->clearMessages(); | |
344 | } | |
345 | ||
481312d9 | 346 | /** |
347 | * Get detail for recurring transaction. | |
348 | * | |
349 | * @param array $params | |
350 | * Additional parameters. | |
351 | * | |
352 | * @return array | |
353 | * Parameters like AuthorizeNet silent post paramters. | |
354 | */ | |
355 | public function getRecurTransaction($params = array()) { | |
356 | return array_merge(array( | |
0dbefed3 EM |
357 | "x_amount" => "200.00", |
358 | "x_country" => 'US', | |
359 | "x_phone" => "", | |
360 | "x_fax" => "", | |
361 | "x_email" => "me@gmail.com", | |
362 | "x_description" => "lots of money", | |
363 | "x_type" => "auth_capture", | |
364 | "x_ship_to_first_name" => "", | |
365 | "x_ship_to_last_name" => "", | |
366 | "x_ship_to_company" => "", | |
367 | "x_ship_to_address" => "", | |
368 | "x_ship_to_city" => "", | |
369 | "x_ship_to_state" => "", | |
370 | "x_ship_to_zip" => "", | |
371 | "x_ship_to_country" => "", | |
372 | "x_tax" => "0.00", | |
373 | "x_duty" => "0.00", | |
374 | "x_freight" => "0.00", | |
375 | "x_tax_exempt" => "FALSE", | |
376 | "x_po_num" => "", | |
377 | "x_MD5_Hash" => "1B7C0C5B4DEDD9CAD0636E35E22FC594", | |
378 | "x_cvv2_resp_code" => "", | |
379 | "x_cavv_response" => "", | |
380 | "x_test_request" => "false", | |
481312d9 | 381 | "x_subscription_id" => $this->_contactID, |
0dbefed3 EM |
382 | "x_subscription_paynum" => "1", |
383 | 'x_first_name' => 'Robert', | |
384 | 'x_zip' => '90210', | |
385 | 'x_state' => 'WA', | |
386 | 'x_city' => 'Dallas', | |
387 | 'x_address' => '41 My ST', | |
388 | 'x_invoice_num' => $this->_contributionID, | |
389 | 'x_cust_id' => $this->_contactID, | |
390 | 'x_company' => 'nowhere@civicrm.org', | |
391 | 'x_last_name' => 'Roberts', | |
392 | 'x_account_number' => 'XXXX5077', | |
393 | 'x_card_type' => 'Visa', | |
394 | 'x_method' => 'CC', | |
395 | 'x_trans_id' => '6511143069', | |
396 | 'x_auth_code' => '123456', | |
397 | 'x_avs_code' => 'Z', | |
398 | 'x_response_reason_text' => 'This transaction has been approved.', | |
399 | 'x_response_reason_code' => '1', | |
21dfd5f5 | 400 | 'x_response_code' => '1', |
481312d9 | 401 | ), $params); |
0dbefed3 EM |
402 | } |
403 | ||
404 | /** | |
405 | * @return array | |
406 | */ | |
0495f30c | 407 | public function getRecurSubsequentTransaction($params = array()) { |
0dbefed3 EM |
408 | return array_merge($this->getRecurTransaction(), array( |
409 | 'x_trans_id' => 'second_one', | |
410 | 'x_MD5_Hash' => 'EA7A3CD65A85757827F51212CA1486A8', | |
0495f30c | 411 | ), $params); |
0dbefed3 | 412 | } |
96025800 | 413 | |
0dbefed3 | 414 | } |