Commit | Line | Data |
---|---|---|
d2545e26 PN |
1 | <?php |
2 | /* | |
3 | +--------------------------------------------------------------------+ | |
a30c801b | 4 | | Copyright CiviCRM LLC. All rights reserved. | |
d2545e26 | 5 | | | |
a30c801b TO |
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 | | |
d2545e26 PN |
9 | +--------------------------------------------------------------------+ |
10 | */ | |
11 | ||
12 | /** | |
13 | * This api exposes CiviCRM Contribution Payment records. | |
14 | * | |
15 | * @package CiviCRM_APIv3 | |
16 | */ | |
17 | ||
18 | /** | |
19 | * Retrieve a set of financial transactions which are payments. | |
20 | * | |
21 | * @param array $params | |
22 | * Input parameters. | |
23 | * | |
24 | * @return array | |
25 | * Array of financial transactions which are payments, if error an array with an error id and error message | |
f5269434 | 26 | * |
27 | * @throws \CiviCRM_API3_Exception | |
d2545e26 PN |
28 | */ |
29 | function civicrm_api3_payment_get($params) { | |
d2aeabca MW |
30 | $params['is_payment'] = TRUE; |
31 | $contributionID = $params['entity_id'] ?? NULL; | |
32 | ||
33 | // In order to support contribution id we need to do an extra lookup. | |
34 | if ($contributionID) { | |
35 | $eftParams = [ | |
36 | 'entity_id' => $contributionID, | |
37 | 'entity_table' => 'civicrm_contribution', | |
38 | 'options' => ['limit' => 0], | |
39 | 'financial_trxn_id.is_payment' => 1, | |
40 | ]; | |
41 | $eft = civicrm_api3('EntityFinancialTrxn', 'get', $eftParams)['values']; | |
42 | if (empty($eft)) { | |
43 | return civicrm_api3_create_success([], $params, 'Payment', 'get'); | |
44 | } | |
45 | foreach ($eft as $entityFinancialTrxn) { | |
46 | $params['financial_trxn_id']['IN'][] = $entityFinancialTrxn['financial_trxn_id']; | |
47 | } | |
c4204541 | 48 | } |
d2aeabca MW |
49 | |
50 | $financialTrxn = civicrm_api3('FinancialTrxn', 'get', array_merge($params, ['sequential' => FALSE]))['values']; | |
51 | if ($contributionID) { | |
52 | foreach ($financialTrxn as &$values) { | |
53 | $values['contribution_id'] = $contributionID; | |
d2545e26 | 54 | } |
d2aeabca MW |
55 | } |
56 | elseif (!empty($financialTrxn)) { | |
57 | $entityFinancialTrxns = civicrm_api3('EntityFinancialTrxn', 'get', ['financial_trxn_id' => ['IN' => array_keys($financialTrxn)], 'entity_table' => 'civicrm_contribution', 'options' => ['limit' => 0]])['values']; | |
58 | foreach ($entityFinancialTrxns as $entityFinancialTrxn) { | |
59 | $financialTrxn[$entityFinancialTrxn['financial_trxn_id']]['contribution_id'] = $entityFinancialTrxn['entity_id']; | |
d2545e26 PN |
60 | } |
61 | } | |
d2aeabca MW |
62 | |
63 | return civicrm_api3_create_success($financialTrxn, $params, 'Payment', 'get'); | |
d2545e26 PN |
64 | } |
65 | ||
66 | /** | |
67 | * Delete a payment. | |
68 | * | |
69 | * @param array $params | |
70 | * Input parameters. | |
71 | * | |
d2545e26 PN |
72 | * @return array |
73 | * Api result array | |
f5269434 | 74 | * |
75 | * @throws \CiviCRM_API3_Exception | |
d2545e26 | 76 | */ |
1c31aa41 | 77 | function civicrm_api3_payment_delete($params) { |
d2545e26 PN |
78 | return civicrm_api3('FinancialTrxn', 'delete', $params); |
79 | } | |
80 | ||
81 | /** | |
82 | * Cancel/Refund a payment for a Contribution. | |
83 | * | |
84 | * @param array $params | |
85 | * Input parameters. | |
86 | * | |
d2545e26 PN |
87 | * @return array |
88 | * Api result array | |
df29ccff | 89 | * |
90 | * @throws \CiviCRM_API3_Exception | |
91 | * @throws API_Exception | |
d2545e26 | 92 | */ |
1c31aa41 | 93 | function civicrm_api3_payment_cancel($params) { |
cf8f0fff | 94 | $eftParams = [ |
d2545e26 PN |
95 | 'entity_table' => 'civicrm_contribution', |
96 | 'financial_trxn_id' => $params['id'], | |
d8a1b674 | 97 | 'return' => ['entity', 'amount', 'entity_id', 'financial_trxn_id.check_number'], |
cf8f0fff | 98 | ]; |
d2545e26 | 99 | $entity = civicrm_api3('EntityFinancialTrxn', 'getsingle', $eftParams); |
d2545e26 | 100 | |
2561fc11 | 101 | $paymentParams = [ |
102 | 'total_amount' => -$entity['amount'], | |
103 | 'contribution_id' => $entity['entity_id'], | |
d2aeabca | 104 | 'trxn_date' => $params['trxn_date'] ?? 'now', |
df29ccff | 105 | 'cancelled_payment_id' => $params['id'], |
d8a1b674 | 106 | 'check_number' => $entity['financial_trxn_id.check_number'] ?? NULL, |
2561fc11 | 107 | ]; |
d2545e26 | 108 | |
2561fc11 | 109 | foreach (['trxn_id', 'payment_instrument_id'] as $permittedParam) { |
110 | if (isset($params[$permittedParam])) { | |
111 | $paymentParams[$permittedParam] = $params[$permittedParam]; | |
112 | } | |
113 | } | |
114 | $result = civicrm_api3('Payment', 'create', $paymentParams); | |
115 | return civicrm_api3_create_success($result['values'], $params, 'Payment', 'cancel'); | |
d2545e26 PN |
116 | } |
117 | ||
118 | /** | |
119 | * Add a payment for a Contribution. | |
120 | * | |
121 | * @param array $params | |
122 | * Input parameters. | |
123 | * | |
d2545e26 PN |
124 | * @return array |
125 | * Api result array | |
a494d7a3 | 126 | * |
a494d7a3 | 127 | * @throws \CRM_Core_Exception |
128 | * @throws \CiviCRM_API3_Exception | |
d2545e26 | 129 | */ |
1c31aa41 | 130 | function civicrm_api3_payment_create($params) { |
b4c48831 | 131 | if (empty($params['skipCleanMoney'])) { |
132 | foreach (['total_amount', 'net_amount', 'fee_amount'] as $field) { | |
133 | if (isset($params[$field])) { | |
134 | $params[$field] = CRM_Utils_Rule::cleanMoney($params[$field]); | |
135 | } | |
136 | } | |
137 | } | |
6cc6cb8c | 138 | if (!empty($params['payment_processor'])) { |
139 | // I can't find evidence this is passed in - I was gonna just remove it but decided to deprecate as I see getToFinancialAccount | |
140 | // also anticipates it. | |
141 | CRM_Core_Error::deprecatedFunctionWarning('passing payment_processor is deprecated - use payment_processor_id'); | |
142 | $params['payment_processor_id'] = $params['payment_processor']; | |
143 | } | |
d2545e26 | 144 | // Check if it is an update |
de6c59ca | 145 | if (!empty($params['id'])) { |
d2545e26 PN |
146 | $amount = $params['total_amount']; |
147 | civicrm_api3('Payment', 'cancel', $params); | |
148 | $params['total_amount'] = $amount; | |
149 | } | |
0c9b306a | 150 | $trxn = CRM_Financial_BAO_Payment::create($params); |
5625fdf0 | 151 | |
cf8f0fff | 152 | $values = []; |
d2545e26 PN |
153 | _civicrm_api3_object_to_array_unique_fields($trxn, $values[$trxn->id]); |
154 | return civicrm_api3_create_success($values, $params, 'Payment', 'create', $trxn); | |
155 | } | |
156 | ||
157 | /** | |
158 | * Adjust Metadata for Create action. | |
159 | * | |
160 | * The metadata is used for setting defaults, documentation & validation. | |
161 | * | |
162 | * @param array $params | |
163 | * Array of parameters. | |
164 | */ | |
165 | function _civicrm_api3_payment_create_spec(&$params) { | |
cf8f0fff CW |
166 | $params = [ |
167 | 'contribution_id' => [ | |
7c31ae57 | 168 | 'api.required' => 1, |
d1987324 | 169 | 'title' => ts('Contribution ID'), |
d2545e26 | 170 | 'type' => CRM_Utils_Type::T_INT, |
e2887a3c | 171 | // We accept order_id as an alias so that we can chain like |
172 | // civicrm_api3('Order', 'create', ['blah' => 'blah', 'contribution_status_id' => 'Pending', 'api.Payment.create => ['total_amount' => 5]] | |
173 | 'api.aliases' => ['order_id'], | |
cf8f0fff CW |
174 | ], |
175 | 'total_amount' => [ | |
7c31ae57 | 176 | 'api.required' => 1, |
d1987324 | 177 | 'title' => ts('Total Payment Amount'), |
d2545e26 | 178 | 'type' => CRM_Utils_Type::T_FLOAT, |
cf8f0fff | 179 | ], |
f5269434 | 180 | 'fee_amount' => [ |
181 | 'title' => ts('Fee Amount'), | |
182 | 'type' => CRM_Utils_Type::T_FLOAT, | |
183 | ], | |
cf8f0fff | 184 | 'payment_processor_id' => [ |
a494d7a3 | 185 | 'name' => 'payment_processor_id', |
d2545e26 | 186 | 'type' => CRM_Utils_Type::T_INT, |
a494d7a3 | 187 | 'title' => ts('Payment Processor'), |
188 | 'description' => ts('Payment Processor for this payment'), | |
189 | 'where' => 'civicrm_financial_trxn.payment_processor_id', | |
190 | 'table_name' => 'civicrm_financial_trxn', | |
191 | 'entity' => 'FinancialTrxn', | |
192 | 'bao' => 'CRM_Financial_DAO_FinancialTrxn', | |
193 | 'localizable' => 0, | |
194 | 'FKClassName' => 'CRM_Financial_DAO_PaymentProcessor', | |
cf8f0fff CW |
195 | ], |
196 | 'id' => [ | |
d1987324 | 197 | 'title' => ts('Payment ID'), |
d2545e26 | 198 | 'type' => CRM_Utils_Type::T_INT, |
cf8f0fff CW |
199 | 'api.aliases' => ['payment_id'], |
200 | ], | |
2561fc11 | 201 | 'trxn_date' => [ |
4c68d684 | 202 | 'title' => ts('Payment Date'), |
2561fc11 | 203 | 'type' => CRM_Utils_Type::T_DATE + CRM_Utils_Type::T_TIME, |
4c68d684 | 204 | 'api.default' => 'now', |
205 | 'api.required' => TRUE, | |
2561fc11 | 206 | ], |
bd981689 | 207 | 'is_send_contribution_notification' => [ |
208 | 'title' => ts('Send out notifications based on contribution status change?'), | |
209 | 'description' => ts('Most commonly this equates to emails relating to the contribution, event, etcwhen a payment completes a contribution'), | |
210 | 'type' => CRM_Utils_Type::T_BOOLEAN, | |
211 | 'api.default' => TRUE, | |
212 | ], | |
a494d7a3 | 213 | 'payment_instrument_id' => [ |
214 | 'name' => 'payment_instrument_id', | |
215 | 'type' => CRM_Utils_Type::T_INT, | |
216 | 'title' => ts('Payment Method'), | |
217 | 'description' => ts('FK to payment_instrument option group values'), | |
218 | 'where' => 'civicrm_financial_trxn.payment_instrument_id', | |
219 | 'table_name' => 'civicrm_financial_trxn', | |
220 | 'entity' => 'FinancialTrxn', | |
221 | 'bao' => 'CRM_Financial_DAO_FinancialTrxn', | |
222 | 'localizable' => 0, | |
223 | 'html' => [ | |
224 | 'type' => 'Select', | |
225 | ], | |
226 | 'pseudoconstant' => [ | |
227 | 'optionGroupName' => 'payment_instrument', | |
228 | 'optionEditPath' => 'civicrm/admin/options/payment_instrument', | |
229 | ], | |
230 | ], | |
231 | 'card_type_id' => [ | |
232 | 'name' => 'card_type_id', | |
233 | 'type' => CRM_Utils_Type::T_INT, | |
234 | 'title' => ts('Card Type ID'), | |
235 | 'description' => ts('FK to accept_creditcard option group values'), | |
236 | 'where' => 'civicrm_financial_trxn.card_type_id', | |
237 | 'table_name' => 'civicrm_financial_trxn', | |
238 | 'entity' => 'FinancialTrxn', | |
239 | 'bao' => 'CRM_Financial_DAO_FinancialTrxn', | |
240 | 'localizable' => 0, | |
241 | 'html' => [ | |
242 | 'type' => 'Select', | |
243 | ], | |
244 | 'pseudoconstant' => [ | |
245 | 'optionGroupName' => 'accept_creditcard', | |
246 | 'optionEditPath' => 'civicrm/admin/options/accept_creditcard', | |
247 | ], | |
248 | ], | |
249 | 'trxn_result_code' => [ | |
250 | 'name' => 'trxn_result_code', | |
251 | 'type' => CRM_Utils_Type::T_STRING, | |
252 | 'title' => ts('Transaction Result Code'), | |
253 | 'description' => ts('processor result code'), | |
254 | 'maxlength' => 255, | |
255 | 'size' => CRM_Utils_Type::HUGE, | |
256 | 'where' => 'civicrm_financial_trxn.trxn_result_code', | |
257 | 'table_name' => 'civicrm_financial_trxn', | |
258 | 'entity' => 'FinancialTrxn', | |
259 | 'bao' => 'CRM_Financial_DAO_FinancialTrxn', | |
260 | 'localizable' => 0, | |
261 | ], | |
262 | 'trxn_id' => [ | |
263 | 'name' => 'trxn_id', | |
264 | 'type' => CRM_Utils_Type::T_STRING, | |
265 | 'title' => ts('Transaction ID'), | |
266 | 'description' => ts('Transaction id supplied by external processor. This may not be unique.'), | |
267 | 'maxlength' => 255, | |
268 | 'size' => 10, | |
269 | 'where' => 'civicrm_financial_trxn.trxn_id', | |
270 | 'table_name' => 'civicrm_financial_trxn', | |
271 | 'entity' => 'FinancialTrxn', | |
272 | 'bao' => 'CRM_Financial_DAO_FinancialTrxn', | |
273 | 'localizable' => 0, | |
274 | 'html' => [ | |
275 | 'type' => 'Text', | |
276 | ], | |
277 | ], | |
9ed56e2d MW |
278 | 'order_reference' => [ |
279 | 'name' => 'order_reference', | |
280 | 'type' => CRM_Utils_Type::T_STRING, | |
281 | 'title' => 'Order Reference', | |
282 | 'description' => 'Payment Processor external order reference', | |
283 | 'maxlength' => 255, | |
284 | 'size' => 25, | |
285 | 'where' => 'civicrm_financial_trxn.order_reference', | |
286 | 'table_name' => 'civicrm_financial_trxn', | |
287 | 'entity' => 'FinancialTrxn', | |
288 | 'bao' => 'CRM_Financial_DAO_FinancialTrxn', | |
289 | 'localizable' => 0, | |
290 | 'html' => [ | |
291 | 'type' => 'Text', | |
292 | ], | |
293 | ], | |
a494d7a3 | 294 | 'check_number' => [ |
295 | 'name' => 'check_number', | |
296 | 'type' => CRM_Utils_Type::T_STRING, | |
297 | 'title' => ts('Check Number'), | |
298 | 'description' => ts('Check number'), | |
299 | 'maxlength' => 255, | |
300 | 'size' => 6, | |
301 | 'where' => 'civicrm_financial_trxn.check_number', | |
302 | 'table_name' => 'civicrm_financial_trxn', | |
303 | 'entity' => 'FinancialTrxn', | |
304 | 'bao' => 'CRM_Financial_DAO_FinancialTrxn', | |
305 | 'localizable' => 0, | |
306 | 'html' => [ | |
307 | 'type' => 'Text', | |
308 | ], | |
309 | ], | |
310 | 'pan_truncation' => [ | |
311 | 'name' => 'pan_truncation', | |
312 | 'type' => CRM_Utils_Type::T_STRING, | |
d849e301 | 313 | 'title' => ts('PAN Truncation'), |
a494d7a3 | 314 | 'description' => ts('Last 4 digits of credit card'), |
315 | 'maxlength' => 4, | |
316 | 'size' => 4, | |
317 | 'where' => 'civicrm_financial_trxn.pan_truncation', | |
318 | 'table_name' => 'civicrm_financial_trxn', | |
319 | 'entity' => 'FinancialTrxn', | |
320 | 'bao' => 'CRM_Financial_DAO_FinancialTrxn', | |
321 | 'localizable' => 0, | |
322 | 'html' => [ | |
323 | 'type' => 'Text', | |
324 | ], | |
325 | ], | |
cf8f0fff | 326 | ]; |
d2545e26 PN |
327 | } |
328 | ||
329 | /** | |
330 | * Adjust Metadata for Get action. | |
331 | * | |
332 | * The metadata is used for setting defaults, documentation & validation. | |
333 | * | |
334 | * @param array $params | |
335 | * Array of parameters determined by getfields. | |
336 | */ | |
337 | function _civicrm_api3_payment_get_spec(&$params) { | |
cf8f0fff CW |
338 | $params = [ |
339 | 'contribution_id' => [ | |
4c68d684 | 340 | 'title' => ts('Contribution ID'), |
d2545e26 | 341 | 'type' => CRM_Utils_Type::T_INT, |
cf8f0fff | 342 | ], |
cf8f0fff | 343 | 'entity_id' => [ |
4c68d684 | 344 | 'title' => ts('Entity ID'), |
d2545e26 | 345 | 'type' => CRM_Utils_Type::T_INT, |
cf8f0fff CW |
346 | 'api.aliases' => ['contribution_id'], |
347 | ], | |
c4204541 | 348 | 'trxn_id' => [ |
4c68d684 | 349 | 'title' => ts('Transaction ID'), |
b6cb0554 | 350 | 'description' => ts('Transaction id supplied by external processor. This may not be unique.'), |
c4204541 | 351 | 'type' => CRM_Utils_Type::T_STRING, |
352 | ], | |
6298cd65 MW |
353 | 'order_reference' => [ |
354 | 'title' => ts('Order Reference'), | |
355 | 'description' => ts('Payment Processor external order reference'), | |
356 | 'type' => CRM_Utils_Type::T_STRING, | |
357 | ], | |
4c68d684 | 358 | 'trxn_date' => [ |
359 | 'title' => ts('Payment Date'), | |
360 | 'type' => CRM_Utils_Type::T_TIMESTAMP, | |
361 | ], | |
f5269434 | 362 | 'financial_trxn_id' => [ |
363 | 'title' => ts('Payment ID'), | |
b6cb0554 | 364 | 'description' => ts('The ID of the record in civicrm_financial_trxn'), |
f5269434 | 365 | 'type' => CRM_Utils_Type::T_INT, |
366 | 'api.aliases' => ['payment_id', 'id'], | |
367 | ], | |
cf8f0fff | 368 | ]; |
d2545e26 PN |
369 | } |
370 | ||
371 | /** | |
372 | * Adjust Metadata for Delete action. | |
373 | * | |
374 | * The metadata is used for setting defaults, documentation & validation. | |
375 | * | |
376 | * @param array $params | |
377 | * Array of parameters. | |
378 | */ | |
379 | function _civicrm_api3_payment_delete_spec(&$params) { | |
cf8f0fff CW |
380 | $params = [ |
381 | 'id' => [ | |
7c31ae57 | 382 | 'api.required' => 1, |
d2545e26 PN |
383 | 'title' => 'Payment ID', |
384 | 'type' => CRM_Utils_Type::T_INT, | |
cf8f0fff CW |
385 | 'api.aliases' => ['payment_id'], |
386 | ], | |
387 | ]; | |
d2545e26 PN |
388 | } |
389 | ||
390 | /** | |
391 | * Adjust Metadata for Cancel action. | |
392 | * | |
393 | * The metadata is used for setting defaults, documentation & validation. | |
394 | * | |
395 | * @param array $params | |
396 | * Array of parameters. | |
397 | */ | |
398 | function _civicrm_api3_payment_cancel_spec(&$params) { | |
cf8f0fff CW |
399 | $params = [ |
400 | 'id' => [ | |
7c31ae57 | 401 | 'api.required' => 1, |
d2545e26 PN |
402 | 'title' => 'Payment ID', |
403 | 'type' => CRM_Utils_Type::T_INT, | |
cf8f0fff CW |
404 | 'api.aliases' => ['payment_id'], |
405 | ], | |
2561fc11 | 406 | 'trxn_date' => [ |
407 | 'title' => 'Cancel Date', | |
408 | 'type' => CRM_Utils_Type::T_DATE + CRM_Utils_Type::T_TIME, | |
409 | ], | |
cf8f0fff | 410 | ]; |
d2545e26 | 411 | } |
a79d2ec2 | 412 | |
413 | /** | |
414 | * Send a payment confirmation. | |
415 | * | |
416 | * @param array $params | |
417 | * Input parameters. | |
418 | * | |
419 | * @return array | |
420 | * @throws Exception | |
421 | */ | |
422 | function civicrm_api3_payment_sendconfirmation($params) { | |
423 | $allowedParams = [ | |
44a2f017 | 424 | 'from', |
a79d2ec2 | 425 | 'id', |
44a2f017 | 426 | 'check_permissions', |
a79d2ec2 | 427 | ]; |
428 | $input = array_intersect_key($params, array_flip($allowedParams)); | |
429 | // use either the contribution or membership receipt, based on whether it’s a membership-related contrib or not | |
430 | $result = CRM_Financial_BAO_Payment::sendConfirmation($input); | |
431 | return civicrm_api3_create_success([ | |
432 | $params['id'] => [ | |
433 | 'is_sent' => $result[0], | |
434 | 'subject' => $result[1], | |
435 | 'message_txt' => $result[2], | |
436 | 'message_html' => $result[3], | |
7c31ae57 SL |
437 | ], |
438 | ]); | |
a79d2ec2 | 439 | } |
440 | ||
441 | /** | |
442 | * Adjust Metadata for sendconfirmation action. | |
443 | * | |
444 | * The metadata is used for setting defaults, documentation & validation. | |
445 | * | |
446 | * @param array $params | |
447 | * Array of parameters determined by getfields. | |
448 | */ | |
449 | function _civicrm_api3_payment_sendconfirmation_spec(&$params) { | |
cf8f0fff | 450 | $params['id'] = [ |
a79d2ec2 | 451 | 'api.required' => 1, |
452 | 'title' => ts('Payment ID'), | |
453 | 'type' => CRM_Utils_Type::T_INT, | |
cf8f0fff | 454 | ]; |
44a2f017 | 455 | $params['from_email_address'] = [ |
456 | 'title' => ts('From email; an email string or the id of a valid email'), | |
457 | 'type' => CRM_Utils_Type::T_STRING, | |
458 | ]; | |
6ac768e7 | 459 | $params['is_send_contribution_notification'] = [ |
460 | 'title' => ts('Send any event or contribution confirmations triggered by this payment'), | |
461 | 'description' => ts('If this payment completes a contribution it may mean receipts will go out according to busines logic if thie is set to TRUE'), | |
462 | 'type' => CRM_Utils_Type::T_BOOLEAN, | |
463 | 'api.default' => 0, | |
464 | ]; | |
a79d2ec2 | 465 | } |