3575a24e761fde1a86b469c1e11c1cf2b800fc6f
[civicrm-core.git] / tests / phpunit / CRM / Core / Payment / AuthorizeNetTest.php
1 <?php
2 /*
3 +--------------------------------------------------------------------+
4 | CiviCRM version 4.7 |
5 +--------------------------------------------------------------------+
6 | Copyright CiviCRM LLC (c) 2004-2017 |
7 +--------------------------------------------------------------------+
8 | This file is a part of CiviCRM. |
9 | |
10 | CiviCRM is free software; you can copy, modify, and distribute it |
11 | under the terms of the GNU Affero General Public License |
12 | Version 3, 19 November 2007 and the CiviCRM Licensing Exception. |
13 | |
14 | CiviCRM is distributed in the hope that it will be useful, but |
15 | WITHOUT ANY WARRANTY; without even the implied warranty of |
16 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. |
17 | See the GNU Affero General Public License for more details. |
18 | |
19 | You should have received a copy of the GNU Affero General Public |
20 | License and the CiviCRM Licensing Exception along |
21 | with this program; if not, contact CiviCRM LLC |
22 | at info[AT]civicrm[DOT]org. If you have questions about the |
23 | GNU Affero General Public License or the licensing of CiviCRM, |
24 | see the CiviCRM license FAQ at http://civicrm.org/licensing |
25 +--------------------------------------------------------------------+
26 */
27
28 /**
29 * Class CRM_Core_Payment_AuthorizeNetTest
30 * @group headless
31 */
32 class CRM_Core_Payment_AuthorizeNetTest extends CiviUnitTestCase {
33
34 public function setUp() {
35 parent::setUp();
36 $this->_paymentProcessorID = $this->paymentProcessorAuthorizeNetCreate();
37
38 $this->processor = Civi\Payment\System::singleton()->getById($this->_paymentProcessorID);
39 $this->_financialTypeId = 1;
40
41 // for some strange unknown reason, in batch mode this value gets set to null
42 // so crude hack here to avoid an exception and hence an error
43 $GLOBALS['_PEAR_ERRORSTACK_OVERRIDE_CALLBACK'] = array();
44 }
45
46 public function tearDown() {
47 $this->quickCleanUpFinancialEntities();
48 }
49
50 /**
51 * Create a single post dated payment as a recurring transaction.
52 *
53 * Test works but not both due to some form of caching going on in the SmartySingleton
54 */
55 public function testCreateSingleNowDated() {
56 $firstName = 'John_' . substr(sha1(rand()), 0, 7);
57 $lastName = 'Smith_' . substr(sha1(rand()), 0, 7);
58 $nameParams = array('first_name' => $firstName, 'last_name' => $lastName);
59 $contactId = $this->individualCreate($nameParams);
60
61 $invoiceID = sha1(rand());
62 $amount = rand(100, 1000) . '.00';
63
64 $contributionRecurParams = array(
65 'contact_id' => $contactId,
66 'amount' => $amount,
67 'currency' => 'USD',
68 'frequency_unit' => 'week',
69 'frequency_interval' => 1,
70 'installments' => 2,
71 'start_date' => date('Ymd'),
72 'create_date' => date('Ymd'),
73 'invoice_id' => $invoiceID,
74 'contribution_status_id' => 2,
75 'is_test' => 1,
76 'payment_processor_id' => $this->_paymentProcessorID,
77 );
78 $recur = CRM_Contribute_BAO_ContributionRecur::add($contributionRecurParams);
79
80 $contributionParams = array(
81 'contact_id' => $contactId,
82 'financial_type_id' => $this->_financialTypeId,
83 'receive_date' => date('Ymd'),
84 'total_amount' => $amount,
85 'invoice_id' => $invoiceID,
86 'currency' => 'USD',
87 'contribution_recur_id' => $recur->id,
88 'is_test' => 1,
89 'contribution_status_id' => 2,
90 );
91 $contribution = $this->callAPISuccess('Contribution', 'create', $contributionParams);
92
93 $params = array(
94 'qfKey' => '08ed21c7ca00a1f7d32fff2488596ef7_4454',
95 'hidden_CreditCard' => 1,
96 'billing_first_name' => $firstName,
97 'billing_middle_name' => "",
98 'billing_last_name' => $lastName,
99 'billing_street_address-5' => '8 Hobbitton Road',
100 'billing_city-5' => 'The Shire',
101 'billing_state_province_id-5' => 1012,
102 'billing_postal_code-5' => 5010,
103 'billing_country_id-5' => 1228,
104 'credit_card_number' => '4007000000027',
105 'cvv2' => 123,
106 'credit_card_exp_date' => array(
107 'M' => 10,
108 'Y' => 2019,
109 ),
110 'credit_card_type' => 'Visa',
111 'is_recur' => 1,
112 'frequency_interval' => 1,
113 'frequency_unit' => 'month',
114 'installments' => 12,
115 'financial_type_id' => $this->_financialTypeId,
116 'is_email_receipt' => 1,
117 'from_email_address' => "{$firstName}.{$lastName}@example.com",
118 'receive_date' => date('Ymd'),
119 'receipt_date_time' => '',
120 'payment_processor_id' => $this->_paymentProcessorID,
121 'price_set_id' => '',
122 'total_amount' => $amount,
123 'currency' => 'USD',
124 'source' => "Mordor",
125 'soft_credit_to' => '',
126 'soft_contact_id' => '',
127 'billing_state_province-5' => 'IL',
128 'state_province-5' => 'IL',
129 'billing_country-5' => 'US',
130 'country-5' => 'US',
131 'year' => 2019,
132 'month' => 10,
133 'ip_address' => '127.0.0.1',
134 'amount' => 7,
135 'amount_level' => 0,
136 'currencyID' => 'USD',
137 'pcp_display_in_roll' => "",
138 'pcp_roll_nickname' => "",
139 'pcp_personal_note' => "",
140 'non_deductible_amount' => "",
141 'fee_amount' => "",
142 'net_amount' => "",
143 'invoiceID' => $invoiceID,
144 'contribution_page_id' => "",
145 'thankyou_date' => NULL,
146 'honor_contact_id' => NULL,
147 'first_name' => $firstName,
148 'middle_name' => '',
149 'last_name' => $lastName,
150 'street_address' => '8 Hobbiton Road',
151 'city' => 'The Shire',
152 'state_province' => 'IL',
153 'postal_code' => 5010,
154 'country' => 'US',
155 'contributionType_name' => 'My precious',
156 'contributionType_accounting_code' => '',
157 'contributionPageID' => '',
158 'email' => "{$firstName}.{$lastName}@example.com",
159 'contactID' => $contactId,
160 'contributionID' => $contribution->id,
161 'contributionTypeID' => $this->_financialTypeId,
162 'contributionRecurID' => $recur->id,
163 );
164
165 // turn verifySSL off
166 Civi::settings()->set('verifySSL', '0');
167 $this->doPayment($params);
168 // turn verifySSL on
169 Civi::settings()->set('verifySSL', '0');
170
171 // if subscription was successful, processor_id / subscription-id must not be null
172 $this->assertDBNotNull('CRM_Contribute_DAO_ContributionRecur', $recur->id, 'processor_id',
173 'id', 'Failed to create subscription with Authorize.'
174 );
175
176 // cancel it or the transaction will be rejected by A.net if the test is re-run
177 $subscriptionID = CRM_Core_DAO::getFieldValue('CRM_Contribute_DAO_ContributionRecur', $recur->id, 'processor_id');
178 $message = '';
179 $result = $this->processor->cancelSubscription($message, array('subscriptionId' => $subscriptionID));
180 $this->assertTrue($result, 'Failed to cancel subscription with Authorize.');
181 }
182
183 /**
184 * Create a single post dated payment as a recurring transaction.
185 */
186 public function testCreateSinglePostDated() {
187 $start_date = date('Ymd', strtotime("+ 1 week"));
188
189 $firstName = 'John_' . substr(sha1(rand()), 0, 7);
190 $lastName = 'Smith_' . substr(sha1(rand()), 0, 7);
191 $nameParams = array('first_name' => $firstName, 'last_name' => $lastName);
192 $contactId = $this->individualCreate($nameParams);
193
194 $ids = array('contribution' => NULL);
195 $invoiceID = sha1(rand());
196 $amount = rand(100, 1000) . '.00';
197
198 $contributionRecurParams = array(
199 'contact_id' => $contactId,
200 'amount' => $amount,
201 'currency' => 'USD',
202 'frequency_unit' => 'month',
203 'frequency_interval' => 1,
204 'installments' => 3,
205 'start_date' => $start_date,
206 'create_date' => date('Ymd'),
207 'invoice_id' => $invoiceID,
208 'contribution_status_id' => 2,
209 'is_test' => 1,
210 'payment_processor_id' => $this->_paymentProcessorID,
211 );
212 $recur = CRM_Contribute_BAO_ContributionRecur::add($contributionRecurParams, $ids);
213
214 $contributionParams = array(
215 'contact_id' => $contactId,
216 'financial_type_id' => $this->_financialTypeId,
217 'receive_date' => $start_date,
218 'total_amount' => $amount,
219 'invoice_id' => $invoiceID,
220 'currency' => 'USD',
221 'contribution_recur_id' => $recur->id,
222 'is_test' => 1,
223 'contribution_status_id' => 2,
224 );
225
226 $contribution = $this->callAPISuccess('contribution', 'create', $contributionParams);
227
228 $params = array(
229 'qfKey' => '00ed21c7ca00a1f7d555555596ef7_4454',
230 'hidden_CreditCard' => 1,
231 'billing_first_name' => $firstName,
232 'billing_middle_name' => "",
233 'billing_last_name' => $lastName,
234 'billing_street_address-5' => '8 Hobbitton Road',
235 'billing_city-5' => 'The Shire',
236 'billing_state_province_id-5' => 1012,
237 'billing_postal_code-5' => 5010,
238 'billing_country_id-5' => 1228,
239 'credit_card_number' => '4007000000027',
240 'cvv2' => 123,
241 'credit_card_exp_date' => array(
242 'M' => 11,
243 'Y' => 2019,
244 ),
245 'credit_card_type' => 'Visa',
246 'is_recur' => 1,
247 'frequency_interval' => 1,
248 'frequency_unit' => 'month',
249 'installments' => 3,
250 'financial_type_id' => $this->_financialTypeId,
251 'is_email_receipt' => 1,
252 'from_email_address' => "{$firstName}.{$lastName}@example.com",
253 'receive_date' => $start_date,
254 'receipt_date_time' => '',
255 'payment_processor_id' => $this->_paymentProcessorID,
256 'price_set_id' => '',
257 'total_amount' => $amount,
258 'currency' => 'USD',
259 'source' => "Mordor",
260 'soft_credit_to' => '',
261 'soft_contact_id' => '',
262 'billing_state_province-5' => 'IL',
263 'state_province-5' => 'IL',
264 'billing_country-5' => 'US',
265 'country-5' => 'US',
266 'year' => 2019,
267 'month' => 10,
268 'ip_address' => '127.0.0.1',
269 'amount' => 70,
270 'amount_level' => 0,
271 'currencyID' => 'USD',
272 'pcp_display_in_roll' => "",
273 'pcp_roll_nickname' => "",
274 'pcp_personal_note' => "",
275 'non_deductible_amount' => "",
276 'fee_amount' => "",
277 'net_amount' => "",
278 'invoice_id' => "",
279 'contribution_page_id' => "",
280 'thankyou_date' => NULL,
281 'honor_contact_id' => NULL,
282 'invoiceID' => $invoiceID,
283 'first_name' => $firstName,
284 'middle_name' => 'bob',
285 'last_name' => $lastName,
286 'street_address' => '8 Hobbiton Road',
287 'city' => 'The Shire',
288 'state_province' => 'IL',
289 'postal_code' => 5010,
290 'country' => 'US',
291 'contributionType_name' => 'My precious',
292 'contributionType_accounting_code' => '',
293 'contributionPageID' => '',
294 'email' => "{$firstName}.{$lastName}@example.com",
295 'contactID' => $contactId,
296 'contributionID' => $contribution['id'],
297 'contributionTypeID' => $this->_financialTypeId,
298 'contributionRecurID' => $recur->id,
299 );
300
301 // if cancel-subscription has been called earlier 'subscriptionType' would be set to cancel.
302 // to make a successful call for another trxn, we need to set it to something else.
303 $smarty = CRM_Core_Smarty::singleton();
304 $smarty->assign('subscriptionType', 'create');
305
306 // turn verifySSL off
307 Civi::settings()->set('verifySSL', '0');
308 $this->doPayment($params);
309 // turn verifySSL on
310 Civi::settings()->set('verifySSL', '0');
311
312 // if subscription was successful, processor_id / subscription-id must not be null
313 $this->assertDBNotNull('CRM_Contribute_DAO_ContributionRecur', $recur->id, 'processor_id',
314 'id', 'Failed to create subscription with Authorize.'
315 );
316
317 // cancel it or the transaction will be rejected by A.net if the test is re-run
318 $subscriptionID = CRM_Core_DAO::getFieldValue('CRM_Contribute_DAO_ContributionRecur', $recur->id, 'processor_id');
319 $message = '';
320 $result = $this->processor->cancelSubscription($message, array('subscriptionId' => $subscriptionID));
321 $this->assertTrue($result, 'Failed to cancel subscription with Authorize.');
322 }
323
324 /**
325 * Process payment against the Authorize.net test server.
326 *
327 * Skip the test if the server is unresponsive.
328 *
329 * @param array $params
330 *
331 * @throws PHPUnit_Framework_SkippedTestError
332 */
333 public function doPayment($params) {
334 try {
335 $this->processor->doPayment($params);
336 }
337 catch (Exception $e) {
338 $this->assertTrue((strpos($e->getMessage(), 'E00001: Internal Error Occurred.') !== FALSE),
339 'AuthorizeNet failed for unknown reason.' . $e->getMessage());
340 $this->markTestSkipped('AuthorizeNet test server is not in a good mood so we can\'t test this right now');
341 }
342 }
343
344 }