3 +--------------------------------------------------------------------+
4 | Copyright CiviCRM LLC. All rights reserved. |
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 +--------------------------------------------------------------------+
13 * Test APIv3 civicrm_contribute_* functions
15 * @package CiviCRM_APIv3
16 * @subpackage API_Contribution
19 class CRM_Contribute_Form_Contribution_ConfirmTest
extends CiviUnitTestCase
{
24 * @throws \CRM_Core_Exception
26 public function tearDown(): void
{
27 $this->quickCleanUpFinancialEntities();
32 * CRM-21200: Test that making online payment for pending contribution
33 * doesn't overwrite the contribution details
35 * @throws \CiviCRM_API3_Exception
36 * @throws \CRM_Core_Exception
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
= [];
43 // create a contribution page which is later used to make pay-later contribution
44 $contributionPageID1 = $this->createContributionPage(['payment_processor' => $paymentProcessorID]);
46 // create pending contribution
47 $contribution = $this->callAPISuccess('Contribution', 'create', [
48 'contact_id' => $individualID,
49 'financial_type_id' => 'Campaign Contribution',
51 'total_amount' => 100.00,
52 'contribution_status_id' => 'Pending',
53 'contribution_page_id' => $contributionPageID1,
54 'source' => 'backoffice pending contribution',
57 // create a contribution page which is later used to make online payment for pending contribution
58 $contributionPageID2 = $this->createContributionPage(['payment_processor' => $paymentProcessorID]);
60 /* @var CRM_Contribute_Form_Contribution_Confirm $form*/
61 $form = $this->getFormObject('CRM_Contribute_Form_Contribution_Confirm');
62 $form->_id
= $contributionPageID2;
64 $form->_paymentProcessor
= [
65 'id' => $paymentProcessorID,
66 'billing_mode' => CRM_Core_Payment
::BILLING_MODE_FORM
,
67 'object' => Civi\Payment\System
::singleton()->getById($paymentProcessorID),
69 'payment_instrument_id' => CRM_Core_PseudoConstant
::getKey('CRM_Contribute_BAO_Contribution', 'payment_instrument_id', 'Credit card'),
72 'id' => $contributionPageID2,
75 'contribution_id' => $contribution['id'],
76 'credit_card_number' => 4111111111111111,
78 'credit_card_exp_date' => [
80 'Y' => CRM_Utils_Time
::date('Y') +
1,
82 'credit_card_type' => 'Visa',
83 'email-5' => 'test@test.com',
84 'total_amount' => 100.00,
85 'payment_processor_id' => $paymentProcessorID,
90 'currencyID' => 'USD',
92 'invoiceID' => '6e443672a9bb2198cc12f076aed70e7a',
93 'is_quick_config' => 1,
94 'description' => $contribution['values'][$contribution['id']]['source'],
96 'frequency_interval' => 1,
97 'frequency_unit' => 'month',
100 $processConfirmResult = $form->processConfirm(
103 CRM_Core_PseudoConstant
::getKey('CRM_Contribute_BAO_Contribution', 'financial_type_id', 'Campaign Contribution'),
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']));
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,
119 $contribution = $this->callAPISuccessGetSingle('Contribution', [
120 'id' => $form->_params
['contribution_id'],
122 'contribution_page_id',
123 'contribution_status',
124 'contribution_source',
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']);
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
,
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,
154 $form->_params
['onbehalf_contact_id'] = $individualID;
155 $form->_values
['id'] = $contributionPageID1;
156 $form->processConfirm(
159 CRM_Core_PseudoConstant
::getKey('CRM_Contribute_BAO_Contribution', 'financial_type_id', 'Campaign Contribution'),
162 //check if contribution is created on org.
163 $contribution = $this->callAPISuccessGetSingle('Contribution', [
164 'contact_id' => $organizationID,
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',
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,
183 $activity = $this->callAPISuccessGetSingle('Activity', [
184 'source_record_id' => $repeatContribution['id'],
185 'activity_type_id' => 'Contribution',
186 'return' => ['target_contact_id', 'source_contact_id'],
188 $this->assertEquals([$organizationID], $activity['target_contact_id']);
189 $this->assertEquals($individualID, $activity['source_contact_id']);
193 * @param array $params
196 * @throws \CRM_Core_Exception
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',
203 'financial_account_id' => 1,
205 'is_allow_other_amount' => 1,
207 'max_amount' => 2000,