fix expired credit card
[civicrm-core.git] / tests / phpunit / CRM / Contribute / Form / Contribution / ConfirmTest.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 /**
13 * Test APIv3 civicrm_contribute_* functions
14 *
15 * @package CiviCRM_APIv3
16 * @subpackage API_Contribution
17 * @group headless
18 */
19 class CRM_Contribute_Form_Contribution_ConfirmTest extends CiviUnitTestCase {
20
21 /**
22 * Clean up DB.
23 *
24 * @throws \CRM_Core_Exception
25 */
26 public function tearDown(): void {
27 $this->quickCleanUpFinancialEntities();
28 parent::tearDown();
29 }
30
31 /**
32 * CRM-21200: Test that making online payment for pending contribution
33 * doesn't overwrite the contribution details
34 *
35 * @throws \CiviCRM_API3_Exception
36 * @throws \CRM_Core_Exception
37 */
38 public function testPayNowPayment(): void {
39 $individualID = $this->individualCreate();
40 $paymentProcessorID = $this->paymentProcessorCreate(['payment_processor_type_id' => 'Dummy']);
41 CRM_Core_Config::singleton()->userPermissionClass->permissions = [];
42
43 // create a contribution page which is later used to make pay-later contribution
44 $contributionPageID1 = $this->createContributionPage(['payment_processor' => $paymentProcessorID]);
45
46 // create pending contribution
47 $contribution = $this->callAPISuccess('Contribution', 'create', [
48 'contact_id' => $individualID,
49 'financial_type_id' => 'Campaign Contribution',
50 'currency' => 'USD',
51 'total_amount' => 100.00,
52 'contribution_status_id' => 'Pending',
53 'contribution_page_id' => $contributionPageID1,
54 'source' => 'backoffice pending contribution',
55 ]);
56
57 // create a contribution page which is later used to make online payment for pending contribution
58 $contributionPageID2 = $this->createContributionPage(['payment_processor' => $paymentProcessorID]);
59
60 /* @var CRM_Contribute_Form_Contribution_Confirm $form*/
61 $form = $this->getFormObject('CRM_Contribute_Form_Contribution_Confirm');
62 $form->_id = $contributionPageID2;
63
64 $form->_paymentProcessor = [
65 'id' => $paymentProcessorID,
66 'billing_mode' => CRM_Core_Payment::BILLING_MODE_FORM,
67 'object' => Civi\Payment\System::singleton()->getById($paymentProcessorID),
68 'is_recur' => FALSE,
69 'payment_instrument_id' => CRM_Core_PseudoConstant::getKey('CRM_Contribute_BAO_Contribution', 'payment_instrument_id', 'Credit card'),
70 ];
71 $form->_values = [
72 'id' => $contributionPageID2,
73 ];
74 $form->_params = [
75 'contribution_id' => $contribution['id'],
76 'credit_card_number' => 4111111111111111,
77 'cvv2' => 234,
78 'credit_card_exp_date' => [
79 'M' => 2,
80 'Y' => CRM_Utils_Time::date('Y') + 1,
81 ],
82 'credit_card_type' => 'Visa',
83 'email-5' => 'test@test.com',
84 'total_amount' => 100.00,
85 'payment_processor_id' => $paymentProcessorID,
86 'amount' => 100,
87 'tax_amount' => 0.00,
88 'year' => 2021,
89 'month' => 2,
90 'currencyID' => 'USD',
91 'is_pay_later' => 0,
92 'invoiceID' => '6e443672a9bb2198cc12f076aed70e7a',
93 'is_quick_config' => 1,
94 'description' => $contribution['values'][$contribution['id']]['source'],
95 'skipLineItem' => 0,
96 'frequency_interval' => 1,
97 'frequency_unit' => 'month',
98 ];
99
100 $processConfirmResult = $form->processConfirm(
101 $form->_params,
102 $individualID,
103 CRM_Core_PseudoConstant::getKey('CRM_Contribute_BAO_Contribution', 'financial_type_id', 'Campaign Contribution'),
104 0, FALSE
105 );
106
107 // Make sure that certain parameters are set on return from processConfirm
108 $this->assertEquals('Campaign Contribution', CRM_Core_PseudoConstant::getName('CRM_Contribute_BAO_Contribution', 'financial_type_id', $processConfirmResult['financial_type_id']));
109
110 // Based on the processed contribution, complete transaction which update the contribution status based on payment result.
111 if (!empty($processConfirmResult['contribution'])) {
112 $this->callAPISuccess('contribution', 'completetransaction', [
113 'id' => $processConfirmResult['contribution']->id,
114 'trxn_date' => date('Y-m-d'),
115 'payment_processor_id' => $paymentProcessorID,
116 ]);
117 }
118
119 $contribution = $this->callAPISuccessGetSingle('Contribution', [
120 'id' => $form->_params['contribution_id'],
121 'return' => [
122 'contribution_page_id',
123 'contribution_status',
124 'contribution_source',
125 ],
126 ]);
127
128 // check that contribution page ID isn't changed
129 $this->assertEquals($contributionPageID1, $contribution['contribution_page_id']);
130 // check that paid later information is present in contribution's source
131 $this->assertRegExp("/Paid later via page ID: $contributionPageID2/", $contribution['contribution_source']);
132 // check that contribution status is changed to 'Completed' from 'Pending'
133 $this->assertEquals('Completed', $contribution['contribution_status']);
134
135 // Delete contribution.
136 // @todo - figure out why & document properly. If this is just to partially
137 // re-use some test set up then split into 2 tests.
138 $this->callAPISuccess('contribution', 'delete', [
139 'id' => $processConfirmResult['contribution']->id,
140 ]);
141
142 //Process on behalf contribution.
143 unset($form->_params['contribution_id']);
144 $form->_contactID = $form->_values['related_contact'] = $form->_params['onbehalf_contact_id'] = $individualID;
145 $organizationID = $this->organizationCreate();
146 $form->_params['contact_id'] = $organizationID;
147 $this->callAPISuccess('Relationship', 'create', [
148 'contact_id_a' => $individualID,
149 'contact_id_b' => $organizationID,
150 'relationship_type_id' => 5,
151 'is_current_employer' => 1,
152 ]);
153
154 $form->_params['onbehalf_contact_id'] = $individualID;
155 $form->_values['id'] = $contributionPageID1;
156 $form->processConfirm(
157 $form->_params,
158 $organizationID,
159 CRM_Core_PseudoConstant::getKey('CRM_Contribute_BAO_Contribution', 'financial_type_id', 'Campaign Contribution'),
160 0, TRUE
161 );
162 //check if contribution is created on org.
163 $contribution = $this->callAPISuccessGetSingle('Contribution', [
164 'contact_id' => $organizationID,
165 ]);
166
167 $activity = $this->callAPISuccessGetSingle('Activity', [
168 'source_record_id' => $contribution['id'],
169 'contact_id' => $form->_params['onbehalf_contact_id'],
170 'activity_type_id' => 'Contribution',
171 'return' => 'target_contact_id',
172 ]);
173 $this->assertEquals([$form->_params['contact_id']], $activity['target_contact_id']);
174 $this->assertEquals($individualID, $activity['source_contact_id']);
175 $repeatContribution = $this->callAPISuccess('Contribution', 'repeattransaction', [
176 'original_contribution_id' => $contribution['id'],
177 'contribution_status_id' => 'Pending',
178 'api.Payment.create' => [
179 'total_amount' => 100,
180 'payment_processor_id' => $paymentProcessorID,
181 ],
182 ]);
183 $activity = $this->callAPISuccessGetSingle('Activity', [
184 'source_record_id' => $repeatContribution['id'],
185 'activity_type_id' => 'Contribution',
186 'return' => ['target_contact_id', 'source_contact_id'],
187 ]);
188 $this->assertEquals([$organizationID], $activity['target_contact_id']);
189 $this->assertEquals($individualID, $activity['source_contact_id']);
190 }
191
192 /**
193 * @param array $params
194 *
195 * @return mixed
196 * @throws \CRM_Core_Exception
197 */
198 protected function createContributionPage(array $params): int {
199 return (int) $this->callAPISuccess('ContributionPage', 'create', array_merge([
200 'title' => 'Test Contribution Page',
201 'financial_type_id' => 'Campaign Contribution',
202 'currency' => 'USD',
203 'financial_account_id' => 1,
204 'is_active' => 1,
205 'is_allow_other_amount' => 1,
206 'min_amount' => 20,
207 'max_amount' => 2000,
208 ], $params))['id'];
209 }
210
211 }