Merge pull request #18148 from civicrm/5.29
[civicrm-core.git] / tests / phpunit / CRM / Core / Payment / AuthorizeNetTest.php
1 <?php
2 /*
3 +--------------------------------------------------------------------+
4 | Copyright CiviCRM LLC. All rights reserved. |
5 | |
6 | This work is published under the GNU AGPLv3 license with some |
7 | permitted exceptions and without any warranty. For full license |
8 | and copyright information, see https://civicrm.org/licensing |
9 +--------------------------------------------------------------------+
10 */
11
12 use Civi\Payment\PropertyBag;
13
14 /**
15 * Class CRM_Core_Payment_AuthorizeNetTest
16 * @group headless
17 */
18 class CRM_Core_Payment_AuthorizeNetTest extends CiviUnitTestCase {
19
20 use CRM_Core_Payment_AuthorizeNetTrait;
21
22 public function setUp() {
23 parent::setUp();
24 $this->_paymentProcessorID = $this->paymentProcessorAuthorizeNetCreate();
25
26 $this->processor = Civi\Payment\System::singleton()->getById($this->_paymentProcessorID);
27 $this->_financialTypeId = 1;
28
29 // for some strange unknown reason, in batch mode this value gets set to null
30 // so crude hack here to avoid an exception and hence an error
31 $GLOBALS['_PEAR_ERRORSTACK_OVERRIDE_CALLBACK'] = [];
32 }
33
34 public function tearDown() {
35 $this->quickCleanUpFinancialEntities();
36 }
37
38 /**
39 * Test doing a one-off payment.
40 *
41 * @throws \Civi\Payment\Exception\PaymentProcessorException
42 * @throws \CiviCRM_API3_Exception
43 */
44 public function testSinglePayment() {
45 $this->setupMockHandler();
46 $params = $this->getBillingParams();
47 $params['amount'] = 5.24;
48 $this->processor->doPayment($params);
49 $this->assertEquals($this->getExpectedSinglePaymentRequest(), $this->getRequestBodies()[0]);
50 }
51
52 /**
53 * Create a single post dated payment as a recurring transaction.
54 *
55 * Test works but not both due to some form of caching going on in the SmartySingleton
56 */
57 public function testCreateSingleNowDated() {
58 $this->isRecur = TRUE;
59 $this->setupMockHandler();
60 $firstName = 'John';
61 $lastName = "O\'Connor";
62 $nameParams = ['first_name' => 'John', 'last_name' => $lastName];
63 $contactId = $this->individualCreate($nameParams);
64
65 $invoiceID = 123456;
66 $amount = 7;
67
68 $recur = $this->callAPISuccess('ContributionRecur', 'create', [
69 'contact_id' => $contactId,
70 'amount' => $amount,
71 'currency' => 'USD',
72 'frequency_unit' => 'week',
73 'frequency_interval' => 1,
74 'installments' => 2,
75 'start_date' => date('Ymd'),
76 'create_date' => date('Ymd'),
77 'invoice_id' => $invoiceID,
78 'contribution_status_id' => 2,
79 'is_test' => 1,
80 'payment_processor_id' => $this->_paymentProcessorID,
81 ]);
82
83 $contribution = $this->callAPISuccess('Contribution', 'create', [
84 'contact_id' => $contactId,
85 'financial_type_id' => 'Donation',
86 'receive_date' => date('Ymd'),
87 'total_amount' => $amount,
88 'invoice_id' => $invoiceID,
89 'currency' => 'USD',
90 'contribution_recur_id' => $recur['id'],
91 'is_test' => 1,
92 'contribution_status_id' => 2,
93 ]);
94
95 $billingParams = $this->getBillingParams();
96
97 $params = array_merge($billingParams, [
98 'qfKey' => '08ed21c7ca00a1f7d32fff2488596ef7_4454',
99 'hidden_CreditCard' => 1,
100 'is_recur' => 1,
101 'frequency_interval' => 1,
102 'frequency_unit' => 'month',
103 'installments' => 12,
104 'financial_type_id' => $this->_financialTypeId,
105 'is_email_receipt' => 1,
106 'from_email_address' => 'john.smith@example.com',
107 'receive_date' => date('Ymd'),
108 'receipt_date_time' => '',
109 'payment_processor_id' => $this->_paymentProcessorID,
110 'price_set_id' => '',
111 'total_amount' => $amount,
112 'currency' => 'USD',
113 'source' => 'Mordor',
114 'soft_credit_to' => '',
115 'soft_contact_id' => '',
116 'billing_state_province-5' => 'IL',
117 'state_province-5' => 'IL',
118 'billing_country-5' => 'US',
119 'country-5' => 'US',
120 'year' => 2025,
121 'month' => 9,
122 'ip_address' => '127.0.0.1',
123 'amount' => 7,
124 'amount_level' => 0,
125 'currencyID' => 'USD',
126 'pcp_display_in_roll' => '',
127 'pcp_roll_nickname' => '',
128 'pcp_personal_note' => '',
129 'non_deductible_amount' => '',
130 'fee_amount' => '',
131 'net_amount' => '',
132 'invoiceID' => $invoiceID,
133 'contribution_page_id' => '',
134 'thankyou_date' => NULL,
135 'honor_contact_id' => NULL,
136 'first_name' => $firstName,
137 'middle_name' => '',
138 'last_name' => $lastName,
139 'street_address' => '8 Hobbiton Road',
140 'city' => 'The Shire',
141 'state_province' => 'IL',
142 'postal_code' => 5010,
143 'country' => 'US',
144 'contributionType_name' => 'My precious',
145 'contributionType_accounting_code' => '',
146 'contributionPageID' => '',
147 'email' => 'john.smith@example.com',
148 'contactID' => $contactId,
149 'contributionID' => $contribution['id'],
150 'contributionTypeID' => $this->_financialTypeId,
151 'contributionRecurID' => $recur['id'],
152 ]);
153
154 // turn verifySSL off
155 Civi::settings()->set('verifySSL', '0');
156 $this->processor->doPayment($params);
157 // turn verifySSL on
158 Civi::settings()->set('verifySSL', '0');
159
160 // if subscription was successful, processor_id / subscription-id must not be null
161 $this->assertDBNotNull('CRM_Contribute_DAO_ContributionRecur', $recur['id'], 'processor_id',
162 'id', 'Failed to create subscription with Authorize.'
163 );
164
165 $requests = $this->getRequestBodies();
166 $this->assertEquals($this->getExpectedRequest($contactId, date('Y-m-d')), $requests[0]);
167 $header = $this->getRequestHeaders()[0];
168 $this->assertEquals(['apitest.authorize.net'], $header['Host']);
169 $this->assertEquals(['text/xml; charset=UTF8'], $header['Content-Type']);
170
171 $this->assertEquals([
172 CURLOPT_RETURNTRANSFER => TRUE,
173 CURLOPT_SSL_VERIFYPEER => Civi::settings()->get('verifySSL'),
174 ], $this->container[0]['options']['curl']);
175 }
176
177 /**
178 * Create a single post dated payment as a recurring transaction.
179 */
180 public function testCreateSinglePostDated() {
181 $this->isRecur = TRUE;
182 $this->setupMockHandler();
183 $start_date = date('Ymd', strtotime('+ 1 week'));
184
185 $firstName = 'John';
186 $lastName = "O'Connor";
187 $nameParams = ['first_name' => $firstName, 'last_name' => $lastName];
188 $contactId = $this->individualCreate($nameParams);
189
190 $invoiceID = 123456;
191 $amount = 70.23;
192
193 $contributionRecurParams = [
194 'contact_id' => $contactId,
195 'amount' => $amount,
196 'currency' => 'USD',
197 'frequency_unit' => 'month',
198 'frequency_interval' => 1,
199 'installments' => 3,
200 'start_date' => $start_date,
201 'create_date' => date('Ymd'),
202 'invoice_id' => $invoiceID,
203 'contribution_status_id' => '',
204 'is_test' => 1,
205 'payment_processor_id' => $this->_paymentProcessorID,
206 ];
207 $recur = $this->callAPISuccess('ContributionRecur', 'create', $contributionRecurParams);
208
209 $contributionParams = [
210 'contact_id' => $contactId,
211 'financial_type_id' => $this->_financialTypeId,
212 'receive_date' => $start_date,
213 'total_amount' => $amount,
214 'invoice_id' => $invoiceID,
215 'currency' => 'USD',
216 'contribution_recur_id' => $recur['id'],
217 'is_test' => 1,
218 'contribution_status_id' => 2,
219 ];
220
221 $contribution = $this->callAPISuccess('Contribution', 'create', $contributionParams);
222
223 $params = [
224 'qfKey' => '00ed21c7ca00a1f7d555555596ef7_4454',
225 'hidden_CreditCard' => 1,
226 'billing_first_name' => $firstName,
227 'billing_middle_name' => '',
228 'billing_last_name' => $lastName,
229 'billing_street_address-5' => '8 Hobbitton Road',
230 'billing_city-5' => 'The Shire',
231 'billing_state_province_id-5' => 1012,
232 'billing_postal_code-5' => 5010,
233 'billing_country_id-5' => 1228,
234 'credit_card_number' => '4007000000027',
235 'cvv2' => 123,
236 'credit_card_exp_date' => [
237 'M' => 11,
238 'Y' => 2022,
239 ],
240 'credit_card_type' => 'Visa',
241 'is_recur' => 1,
242 'frequency_interval' => 1,
243 'frequency_unit' => 'month',
244 'installments' => 3,
245 'financial_type_id' => $this->_financialTypeId,
246 'is_email_receipt' => 1,
247 'from_email_address' => "{$firstName}.{$lastName}@example.com",
248 'receive_date' => $start_date,
249 'receipt_date_time' => '',
250 'payment_processor_id' => $this->_paymentProcessorID,
251 'price_set_id' => '',
252 'total_amount' => $amount,
253 'currency' => 'USD',
254 'source' => 'Mordor',
255 'soft_credit_to' => '',
256 'soft_contact_id' => '',
257 'billing_state_province-5' => 'IL',
258 'state_province-5' => 'IL',
259 'billing_country-5' => 'US',
260 'country-5' => 'US',
261 'year' => 2022,
262 'month' => 10,
263 'ip_address' => '127.0.0.1',
264 'amount' => 70.23,
265 'amount_level' => 0,
266 'currencyID' => 'USD',
267 'pcp_display_in_roll' => '',
268 'pcp_roll_nickname' => '',
269 'pcp_personal_note' => '',
270 'non_deductible_amount' => '',
271 'fee_amount' => '',
272 'net_amount' => '',
273 'invoice_id' => '',
274 'contribution_page_id' => '',
275 'thankyou_date' => NULL,
276 'honor_contact_id' => NULL,
277 'invoiceID' => $invoiceID,
278 'first_name' => $firstName,
279 'middle_name' => 'bob',
280 'last_name' => $lastName,
281 'street_address' => '8 Hobbiton Road',
282 'city' => 'The Shire',
283 'state_province' => 'IL',
284 'postal_code' => 5010,
285 'country' => 'US',
286 'contributionPageID' => '',
287 'email' => 'john.smith@example.com',
288 'contactID' => $contactId,
289 'contributionID' => $contribution['id'],
290 'contributionRecurID' => $recur['id'],
291 ];
292
293 // if cancel-subscription has been called earlier 'subscriptionType' would be set to cancel.
294 // to make a successful call for another trxn, we need to set it to something else.
295 $smarty = CRM_Core_Smarty::singleton();
296 $smarty->assign('subscriptionType', 'create');
297
298 $this->processor->doPayment($params);
299
300 // if subscription was successful, processor_id / subscription-id must not be null
301 $this->assertDBNotNull('CRM_Contribute_DAO_ContributionRecur', $recur['id'], 'processor_id',
302 'id', 'Failed to create subscription with Authorize.'
303 );
304
305 $response = $this->getResponseBodies();
306 $this->assertEquals($this->getExpectedRecurResponse(), $response[0], 3);
307 $requests = $this->getRequestBodies();
308 $this->assertEquals($this->getExpectedRequest($contactId, date('Y-m-d', strtotime($start_date)), 70.23, 3, 4007000000027, '2022-10'), $requests[0]);
309 }
310
311 /**
312 * Get the content that we expect to see sent out.
313 *
314 * @param int $contactID
315 * @param string $startDate
316 *
317 * @param int $amount
318 * @param int $occurrences
319 * @param int $cardNumber
320 * @param string $cardExpiry
321 *
322 * @return string
323 */
324 public function getExpectedRequest($contactID, $startDate, $amount = 7, $occurrences = 12, $cardNumber = 4444333322221111, $cardExpiry = '2025-09') {
325 return '<?xml version="1.0" encoding="utf-8"?>
326 <ARBCreateSubscriptionRequest xmlns="AnetApi/xml/v1/schema/AnetApiSchema.xsd">
327 <merchantAuthentication>
328 <name>4y5BfuW7jm</name>
329 <transactionKey>4cAmW927n8uLf5J8</transactionKey>
330 </merchantAuthentication>
331 <refId>123456</refId>
332 <subscription>
333 <paymentSchedule>
334 <interval>
335 <length>1</length>
336 <unit>months</unit>
337 </interval>
338 <startDate>' . $startDate . '</startDate>
339 <totalOccurrences>' . $occurrences . '</totalOccurrences>
340 </paymentSchedule>
341 <amount>' . $amount . '</amount>
342 <payment>
343 <creditCard>
344 <cardNumber>' . $cardNumber . '</cardNumber>
345 <expirationDate>' . $cardExpiry . '</expirationDate>
346 </creditCard>
347 </payment>
348 <order>
349 <invoiceNumber>1</invoiceNumber>
350 </order>
351 <customer>
352 <id>' . $contactID . '</id>
353 <email>john.smith@example.com</email>
354 </customer>
355 <billTo>
356 <firstName>John</firstName>
357 <lastName>O\'Connor</lastName>
358 <address>8 Hobbiton Road</address>
359 <city>The Shire</city>
360 <state>IL</state>
361 <zip>5010</zip>
362 <country>US</country>
363 </billTo>
364 </subscription>
365 </ARBCreateSubscriptionRequest>
366 ';
367 }
368
369 /**
370 * Get some basic billing parameters.
371 *
372 * @return array
373 */
374 protected function getBillingParams(): array {
375 return [
376 'billing_first_name' => 'John',
377 'billing_middle_name' => '',
378 'billing_last_name' => "O'Connor",
379 'billing_street_address-5' => '8 Hobbitton Road',
380 'billing_city-5' => 'The Shire',
381 'billing_state_province_id-5' => 1012,
382 'billing_postal_code-5' => 5010,
383 'billing_country_id-5' => 1228,
384 'credit_card_number' => '4444333322221111',
385 'cvv2' => 123,
386 'credit_card_exp_date' => [
387 'M' => 9,
388 'Y' => 2025,
389 ],
390 'credit_card_type' => 'Visa',
391 'year' => 2022,
392 'month' => 10,
393 ];
394 }
395
396 /**
397 * Test the update billing function.
398 */
399 public function testUpdateBilling() {
400 $this->setUpClient($this->getExpectedUpdateResponse());
401 $params = [
402 'qfKey' => '52e3078a34158a80b18d0e3c690c5b9f_2369',
403 'entryURL' => 'http://dmaster.local/civicrm/contribute/updatebilling?reset=1&amp;crid=2&amp;cid=202&amp;context=contribution',
404 'credit_card_number' => '4444333322221111',
405 'cvv2' => '123',
406 'credit_card_exp_date' => ['M' => '3', 'Y' => '2022'],
407 'credit_card_type' => 'Visa',
408 'first_name' => 'q',
409 'middle_name' => '',
410 'last_name' => 't',
411 'street_address' => 'y',
412 'city' => 'xyz',
413 'state_province_id' => '1587',
414 'postal_code' => '777',
415 'country_id' => '1006',
416 'state_province' => 'Bengo',
417 'country' => 'Angola',
418 'month' => '3',
419 'year' => '2022',
420 'subscriptionId' => 6656444,
421 'amount' => '6.00',
422 ];
423 $message = '';
424 $result = $this->processor->updateSubscriptionBillingInfo($message, $params);
425 $requests = $this->getRequestBodies();
426 $this->assertEquals('I00001: Successful.', $message);
427 $this->assertTrue($result);
428 $this->assertEquals($this->getExpectedUpdateRequest(), $requests[0]);
429 }
430
431 /**
432 * Test change subscription function.
433 *
434 * @throws \Civi\Payment\Exception\PaymentProcessorException
435 */
436 public function testChangeSubscription() {
437 $this->setUpClient($this->getExpectedUpdateResponse());
438 $params = [
439 'hidden_custom' => '1',
440 'hidden_custom_group_count' => ['' => 1],
441 'qfKey' => '38588554ecd5c01d5ecdedf3870d9100_7980',
442 'entryURL' => 'http://dmaster.local/civicrm/contribute/updaterecur?reset=1&amp;action=update&amp;crid=2&amp;cid=202&amp;context=contribution',
443 'amount' => '9.67',
444 'currency' => 'USD',
445 'installments' => '8',
446 'is_notify' => '1',
447 'financial_type_id' => '3',
448 '_qf_default' => 'UpdateSubscription:next',
449 '_qf_UpdateSubscription_next' => 'Save',
450 'id' => '2',
451 'subscriptionId' => 1234,
452 ];
453 $message = '';
454 $result = $this->processor->changeSubscriptionAmount($message, $params);
455 $requests = $this->getRequestBodies();
456 $this->assertEquals('I00001: Successful.', $message);
457 $this->assertTrue($result);
458 $this->assertEquals($this->getExpectedChangeSubscriptionRequest(), $requests[0]);
459 }
460
461 /**
462 * Get the expected request string for updateBilling.
463 *
464 * @return string
465 */
466 public function getExpectedUpdateRequest() {
467 return '<?xml version="1.0" encoding="utf-8"?>
468 <ARBUpdateSubscriptionRequest xmlns="AnetApi/xml/v1/schema/AnetApiSchema.xsd">
469 <merchantAuthentication>
470 <name>4y5BfuW7jm</name>
471 <transactionKey>4cAmW927n8uLf5J8</transactionKey>
472 </merchantAuthentication>
473 <subscriptionId>6656444</subscriptionId>
474 <subscription>
475 <payment>
476 <creditCard>
477 <cardNumber>4444333322221111</cardNumber>
478 <expirationDate>2022-03</expirationDate>
479 </creditCard>
480 </payment>
481 <billTo>
482 <firstName>q</firstName>
483 <lastName>t</lastName>
484 <address>y</address>
485 <city>xyz</city>
486 <state>Bengo</state>
487 <zip>777</zip>
488 <country>Angola</country>
489 </billTo>
490 </subscription>
491 </ARBUpdateSubscriptionRequest>
492 ';
493 }
494
495 /**
496 * Get the expected response string for update billing.
497 *
498 * @return string
499 */
500 public function getExpectedUpdateResponse() {
501 return 'HTTP/1.1 200 OK
502 Cache-Control: no-store
503 Pragma: no-cache
504 Content-Type: application/xml; charset=utf-8
505 X-OPNET-Transaction-Trace: a2_4345e2c4-e273-46be-8517-8e6c8c408f5c-11416-3580701
506 Access-Control-Allow-Credentials: true
507 Access-Control-Allow-Headers: x-requested-with,cache-control,content-type,origin,method,SOAPAction
508 Access-Control-Allow-Methods: PUT,OPTIONS,POST,GET
509 Access-Control-Allow-Origin: *
510 Strict-Transport-Security: max-age=31536000
511 X-Cnection: close
512 Date: Thu, 11 Jun 2020 23:19:48 GMT
513 Content-Length: 557
514
515 <?xml version="1.0" encoding="utf-8"?><resultCode>Ok</resultCode><message><code>I00001</code><text>Successful.</text>';
516 }
517
518 /**
519 * Get the expected outgoing request for changeSubscription.
520 *
521 * @return string
522 */
523 protected function getExpectedChangeSubscriptionRequest() {
524 return '<?xml version="1.0" encoding="utf-8"?>
525 <ARBUpdateSubscriptionRequest xmlns="AnetApi/xml/v1/schema/AnetApiSchema.xsd">
526 <merchantAuthentication>
527 <name>4y5BfuW7jm</name>
528 <transactionKey>4cAmW927n8uLf5J8</transactionKey>
529 </merchantAuthentication>
530 <subscriptionId>1234</subscriptionId>
531 <subscription>
532 <paymentSchedule>
533 <totalOccurrences>8</totalOccurrences>
534 </paymentSchedule>
535 <amount>9.67</amount>
536 </subscription>
537 </ARBUpdateSubscriptionRequest>
538 ';
539 }
540
541 /**
542 * Get the expected incoming response for changeSubscription.
543 *
544 * @return string
545 */
546 protected function getExpectedChangeSubscriptionResponse() {
547 return 'HTTP/1.1 200 OK
548 Cache-Control: no-store
549 Pragma: no-cache
550 Content-Type: application/xml; charset=utf-8
551 X-OPNET-Transaction-Trace: a2_e77aa7be-8f98-4f54-ba8a-e8a7f3d9e5ab-8400-7232961
552 Access-Control-Allow-Credentials: true
553 Access-Control-Allow-Headers: x-requested-with,cache-control,content-type,origin,method,SOAPAction
554 Access-Control-Allow-Methods: PUT,OPTIONS,POST,GET
555 Access-Control-Allow-Origin: *
556 Strict-Transport-Security: max-age=31536000
557 X-Cnection: close
558 Date: Fri, 12 Jun 2020 00:18:11 GMT
559 Content-Length: 492
560
561 <?xml version="1.0" encoding="utf-8"?><ARBUpdateSubscriptionResponse xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="AnetApi/xml/v1/schema/AnetApiSchema.xsd"><messages><resultCode>Ok</resultCode><message><code>I00001</code><text>Successful.</text></message></messages><profile><customerProfileId>1512214263</customerProfileId><customerPaymentProfileId>1512250079</customerPaymentProfileId></profile></ARBUpdateSubscriptionResponse>';
562 }
563
564 /**
565 * Setup the guzzle client, helper.
566 *
567 * @param string $response
568 */
569 protected function setUpClient($response) {
570 $this->createMockHandler([$response]);
571 $this->setUpClientWithHistoryContainer();
572 $this->processor->setGuzzleClient($this->getGuzzleClient());
573 }
574
575 /**
576 * @throws \Civi\Payment\Exception\PaymentProcessorException
577 */
578 public function testCancelRecurring() {
579 $this->setUpClient($this->getExpectedCancelResponse());
580 $propertyBag = new PropertyBag();
581 $propertyBag->setContributionRecurID(9);
582 $propertyBag->setIsNotifyProcessorOnCancelRecur(TRUE);
583 $propertyBag->setRecurProcessorID(6656333);
584 $this->processor->doCancelRecurring($propertyBag);
585 $requests = $this->getRequestBodies();
586 $this->assertEquals($this->getExpectedCancelRequest(), $requests[0]);
587 }
588
589 /**
590 * Get expected incoming cancel response.
591 *
592 * @return string
593 */
594 protected function getExpectedCancelResponse() {
595 return 'HTTP/1.1 200 OK
596 Cache-Control: no-store
597 Pragma: no-cache
598 Content-Type: application/xml; charset=utf-8
599 X-OPNET-Transaction-Trace: a2_e77aa7be-8f98-4f54-ba8a-e8a7f3d9e5ab-8400-7311552
600 Access-Control-Allow-Credentials: true
601 Access-Control-Allow-Headers: x-requested-with,cache-control,content-type,origin,method,SOAPAction
602 Access-Control-Allow-Methods: PUT,OPTIONS,POST,GET
603 Access-Control-Allow-Origin: *
604 Strict-Transport-Security: max-age=31536000
605 X-Cnection: close
606 Date: Fri, 12 Jun 2020 00:52:00 GMT
607 Content-Length: 361
608
609 <?xml version="1.0" encoding="utf-8"?><ARBCancelSubscriptionResponse xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="AnetApi/xml/v1/schema/AnetApiSchema.xsd"><messages><resultCode>Ok</resultCode><message><code>I00001</code><text>Successful.</text></message></messages></ARBCancelSubscriptionResponse>';
610 }
611
612 /**
613 * Get the expected outgoing cancel request.
614 *
615 * @return string
616 */
617 protected function getExpectedCancelRequest() {
618 return '<?xml version="1.0" encoding="utf-8"?>
619 <ARBCancelSubscriptionRequest xmlns="AnetApi/xml/v1/schema/AnetApiSchema.xsd">
620 <merchantAuthentication>
621 <name>4y5BfuW7jm</name>
622 <transactionKey>4cAmW927n8uLf5J8</transactionKey>
623 </merchantAuthentication>
624 <subscriptionId>6656333</subscriptionId>
625 </ARBCancelSubscriptionRequest>
626 ';
627
628 }
629
630 }