CiviCRM Community Forums (archive)

*

News:

Have a question about CiviCRM?
Get it answered quickly at the new
CiviCRM Stack Exchange Q+A site

This forum was archived on 25 November 2017. Learn more.
How to get involved.
What to do if you think you've found a bug.



  • CiviCRM Community Forums (archive) »
  • Old sections (read-only, deprecated) »
  • Developer Discussion »
  • APIs and Hooks (Moderator: Donald Lobo) »
  • API addition: civicrm_contribute_transact()
Pages: [1]

Author Topic: API addition: civicrm_contribute_transact()  (Read 1060 times)

Chris Burgess

  • Ask me questions
  • ****
  • Posts: 675
  • Karma: 59
API addition: civicrm_contribute_transact()
March 30, 2010, 01:49:04 pm
To process transactions coming in from external forms, using CiviCRM payment processor.

Should record contributions against contact records, as per a normal CiviCRM transaction.

Edit: CRM-6040

Code: [Select]
<?php

/**
 * Process a transaction and record it against the contact.
 * 
 * @param  array   $params           (reference ) input parameters
 *
 * @return array (reference )        contribution of created or updated record (or a civicrm error)
 * @static void
 * @access public
 * 
 */
function civicrm_contribute_transact($params) {
  
civicrm_initialize( );
  require 
'api/v2/Contribute.php' ;

  if ( empty( 
$params ) ) {
    return 
civicrm_create_error( ts( 'No input parameters present' ) );
  }
  
  if ( ! 
is_array( $params ) ) {
    return 
civicrm_create_error( ts( 'Input parameters is not an array' ) );
  }
  
  
$values  = array( );

  require_once 
'CRM/Contribute/BAO/Contribution.php';
  
$error = _civicrm_contribute_format_params( $params, $values );
  if ( 
civicrm_error( $error ) ) {
    return 
$error;
  }

  
$required = array( 
    
'amount', 
  ) ;
  foreach ( 
$required as $key ) {
    if ( !isset(
$params[$key]) ) {
      return 
civicrm_create_error("Missing parameter $key: civicrm_contribute_transact() requires a parameter '$key'.");
    }
  }

  
// allow people to omit some values for convenience
  
$defaults = array(
    
// 'payment_processor_id' => NULL /* we could retrieve the default processor here, but only if it's missing to avoid an extra lookup */
    
'payment_processor_mode' => 'live',
  ) ;
  
$params = array_merge($defaults, $params) ;

  
// clean up / adjust some values which 
  
if ( !isset($params['total_amount']) ) {
    
$params['total_amount'] = $params['amount'] ;
  }
  if ( !isset(
$params['net_amount']) ) {
    
$params['net_amount'] = $params['amount'] ;
  }
  if ( !isset(
$params['receive_date']) ) {
    
$params['receive_date'] = date('Y-m-d');
  }
  if ( !isset(
$params['invoiceID']) && isset($params['invoice_id']) ) {
      
$params['invoiceID'] = $params['invoice_id'] ;
  }

  require_once 
'CRM/Core/BAO/PaymentProcessor.php';
  
$paymentProcessor = CRM_Core_BAO_PaymentProcessor::getPayment( $params['payment_processor_id'],
                                                                 
$params['payment_processor_mode'] );
  if ( 
civicrm_error($paymentProcessor) ) {
    return 
$paymentProcessor ;
  }

  require_once 
'CRM/Core/Payment.php';
  
$payment =& CRM_Core_Payment::singleton( $params['payment_processor_mode'], 'Contribute', $paymentProcessor );
  if ( 
civicrm_error($payment) ) {
    return 
$payment ;
  }

  
$transaction = $payment->doDirectPayment($params);
  if ( 
civicrm_error($transaction) ) {
    return 
$transaction ;
  }

  
// but actually, $payment->doDirectPayment() doesn't return a
  // CRM_Core_Error by itself
  
if ( get_class($transaction) == 'CRM_Core_Error' ) {
      
$errs = $transaction->getErrors() ;
      if ( !empty(
$errs) ) {
          
$last_error = array_shift($errs) ;
          return 
CRM_Core_Error::createApiError($last_error['message']);
      }
  }

  require_once 
'api/v2/Contribute.php' ;
  
$contribution = civicrm_contribution_add($params);
  return 
$contribution ;
}
« Last Edit: March 30, 2010, 02:00:39 pm by xurizaemon »
@xurizaemon ● www.fuzion.co.nz

SarahG (FountainTribe)

  • Ask me questions
  • ****
  • Posts: 782
  • Karma: 29
  • CiviCRM version: 4.4.7
  • CMS version: Drupal 6, Drupal 7
  • MySQL version: 5.5
  • PHP version: 5.3
Re: API addition: civicrm_contribute_transact()
March 30, 2010, 05:56:31 pm
This should definitely record a transaction against a contact record.  I think it could create a security hole otherwise.  ie some malicious person manages to get a PHP script on the server, they could post refund-type transactions with no obvious audit trail.  Or it could just be a sloppy coder.

A hypothetical question, under what situation would someone want to process a payment with CiviCRM yet NOT want a contribution record stored?
Did I help you? Please donate to the Civi-Make-It-Happen campaign  CiviCRM for mobile devices! 

Chris Burgess

  • Ask me questions
  • ****
  • Posts: 675
  • Karma: 59
Re: API addition: civicrm_contribute_transact()
March 30, 2010, 06:55:56 pm
I agree that it should record a transaction (and in its current form it does).

I don't think it helps to "secure" the API against a malicious PHP script or sloppy coders. If you have either of those problems, some checks in the API ain't gonna help you much ...

Are all transactions contributions?

(I don't have an example use case for wanting a transaction but not recording a contribution record.)
@xurizaemon ● www.fuzion.co.nz

Pages: [1]
  • CiviCRM Community Forums (archive) »
  • Old sections (read-only, deprecated) »
  • Developer Discussion »
  • APIs and Hooks (Moderator: Donald Lobo) »
  • API addition: civicrm_contribute_transact()

This forum was archived on 2017-11-26.