Reference CiviCRM contact ID in GoCardless UI
We inherited a client site that was running a customised version of GoCardless 1.7. One of the customisations was to enable recording of the CiviCRM contact ID in the GoCardless UI, which the client found useful. We're now upgrading to a non customised version of 1.9 but would quite like to add the feature to record CivICRM IDs in GoCardless since it seems useful for others as well, I'm thinking that this might be a useful addition to the extension.
Rich says:
definitely. GC allows up to 3 (from memory) key:values of metadata for subscriptions. I was thinking one of those keys should be civicrm and the data should be a JSON object with {contactId:123, contributionRecurId: 345}. it would live here: https://github.com/artfulrobot/uk.artfulrobot.civicrm.gocardless/blob/master/CRM/GoCardlessUtils.php#L216
I took a quick look and it wasn't clear to me how to access the contact or contribution recur id in ::completeRedirectFlowWithGoCardless()
.
Some background on the motivation.
I think that the code was necessary for the client because they were transferring direct debits from an old provider and the contact ID was useful to cross check which mandates were in GoCardless already.
In my experience with Stripe it is handy for debugging in development (and also when things go wrong in production).
For reference, in case it is useful, here is the (AGPL) code that had been implemented to update the mandate in the customised extension. Important to note that this code was broken and not actually doing what they wanted it to do (I think the reference to worldpay is some copypasta).
```diff
diff --git b/src/extensions/uk.artfulrobot.civicrm.gocardless/gocardless.php a/src/extensions/uk.artfulrobot.civicrm.gocardless/gocardless.php
index dde7b57..5d841be 100644
--- b/src/extensions/uk.artfulrobot.civicrm.gocardless/gocardless.php
+++ a/src/extensions/uk.artfulrobot.civicrm.gocardless/gocardless.php
@@ -221,6 +221,52 @@ function gocardless_civicrm_buildForm( $formName, &$form ) {
catch (Exception $e) {
CRM_Core_Error::fatal('Sorry there was an error setting up your Direct Debit. Please contact us so we can look into what went wrong.');
}
+
+ //MTL - START
+ //update the contact ID, membership ID and contribution ID against Worldpay
+ //update the mandate with custom ID - easy to update this way
+
+ //update mandate
+ try{
+ $mandateID = $result['subscription']->links->mandate;
+
+ if ($mandateID){
+ $result1 = civicrm_api3('Gocardless', 'updatemandate', array(
+ 'sequential' => 1,
+ 'mandate' => (string)$mandateID,
+ 'contactID' => (string)$params['contactID'],
+ 'membershipID' => (string)$params['membershipID'],
+ 'contributionID' => (string)$params['contributionID']
+ ));
+ }
+
+ //update subscription
+ $subscriptionID = $result['subscription']->id;
+ if ($subscriptionID){
+
+ $result2 = civicrm_api3('Gocardless', 'updatesubscription', array(
+ 'sequential' => 1,
+ 'subscription' => (string)$subscriptionID,
+ 'contributionRecurID' => (string)$params['contributionRecurID'],
+ 'membershipID' => (string)$params['membershipID'],
+ 'contributionID' => (string)$params['contributionID']
+ ));
+ }
+
+ //update subscription
+ $customerID = $result1['values']->links->customer;
+ if ($customerID){
+ $result3 = civicrm_api3('Gocardless', 'updatecustomer', array(
+ 'sequential' => 1,
+ 'customers' => (string)$customerID,
+ 'contactID' => (string)$params['contactID'],
+ ));
+
+ }
+ } catch (Exception $e) {
+ CRM_Core_Error::debug_log_message( 'ERROR = '. print_r('Details did not update correctly ',true), $out = false );
+ }
+ //MTL - END
}
<?php
/**
* Gocardless.Updatemandate API specification (optional)
* This is used for documentation and validation.
*
* @param array $spec description of fields supported by this API call
* @return void
* @see http://wiki.civicrm.org/confluence/display/CRMDOC/API+Architecture+Standards
*/
function _civicrm_api3_gocardless_Updatemandate_spec(&$spec) {
$spec['magicword']['api.required'] = 0;
}
/**
* Gocardless.Updatemandate API
*
* @param array $params
* @return array API result descriptor
* @see civicrm_api3_create_success
* @see civicrm_api3_create_error
* @throws API_Exception
*/
function civicrm_api3_gocardless_Updatemandate($params) {
//Now create the subscription against Gocardless
require 'vendor/autoload.php';
$client = CRM_GoCardlessUtils::getApi(APIMODE);
$return = $client->mandates()->update($params['mandate'], [
"params" => ['metadata' => ['civicrmID' => $params['contactID'],
'membershipID' => $params['membershipID'],
'contributionID' => $params['contributionID']
]
]]);
return civicrm_api3_create_success($return, $params, 'Gocardless', 'Updatemandate');
if (array_key_exists('magicword', $params) && $params['magicword'] == 'sesame') {
$returnValues = array( // OK, return several data rows
12 => array('id' => 12, 'name' => 'Twelve'),
34 => array('id' => 34, 'name' => 'Thirty four'),
56 => array('id' => 56, 'name' => 'Fifty six'),
);
// ALTERNATIVE: $returnValues = array(); // OK, success
// ALTERNATIVE: $returnValues = array("Some value"); // OK, return a single value
// Spec: civicrm_api3_create_success($values = 1, $params = array(), $entity = NULL, $action = NULL)
return civicrm_api3_create_success($returnValues, $params, 'NewEntity', 'NewAction');
} else {
throw new API_Exception(/*errorMessage*/ 'Everyone knows that the magicword is "sesame"', /*errorCode*/ 1234);
}
}
<?php
/**
* Gocardless.Updatesubscription API specification (optional)
* This is used for documentation and validation.
*
* @param array $spec description of fields supported by this API call
* @return void
* @see http://wiki.civicrm.org/confluence/display/CRMDOC/API+Architecture+Standards
*/
function _civicrm_api3_gocardless_Updatesubscription_spec(&$spec) {
$spec['magicword']['api.required'] = 0;
}
/**
* Gocardless.Updatesubscription API
*
* @param array $params
* @return array API result descriptor
* @see civicrm_api3_create_success
* @see civicrm_api3_create_error
* @throws API_Exception
*/
function civicrm_api3_gocardless_Updatesubscription($params) {
//Now create the subscription against Gocardless
require 'vendor/autoload.php';
$client = CRM_GoCardlessUtils::getApi(APIMODE);
$sql = "SELECT * FROM civicrm_value_gocardless_update_payment";
$dao = CRM_Core_DAO::executeQuery( $sql);
while ($dao->fetch()){
$entity_id = $dao->entity_id;
$sql_details = "select * from civicrm_contribution_recur
where id = {$entity_id}";
$dao_details = CRM_Core_DAO::executeQuery( $sql_details);
if ($dao_details->fetch()){
$subscription_id = $dao_details->trxn_id;
$amount = $dao_details->amount * 100;
if ($subscription_id){
$result = $client->subscriptions()->update($subscription_id, [
"params" => ["amount" => "{$amount}",
]]);
$subscription_id = '';
//delete the table if we have updated the record correctly
$sql_del = "Delete from civicrm_value_gocardless_update_payment where entity_id = ".$entity_id;
CRM_Core_DAO::executeQuery ( $sql_del );
}
}
}
return civicrm_api3_create_success($return, $params, 'Gocardless', 'Updatesubscription');
if (array_key_exists('magicword', $params) && $params['magicword'] == 'sesame') {
$returnValues = array( // OK, return several data rows
12 => array('id' => 12, 'name' => 'Twelve'),
34 => array('id' => 34, 'name' => 'Thirty four'),
56 => array('id' => 56, 'name' => 'Fifty six'),
);
// ALTERNATIVE: $returnValues = array(); // OK, success
// ALTERNATIVE: $returnValues = array("Some value"); // OK, return a single value
// Spec: civicrm_api3_create_success($values = 1, $params = array(), $entity = NULL, $action = NULL)
return civicrm_api3_create_success($returnValues, $params, 'NewEntity', 'NewAction');
} else {
throw new API_Exception(/*errorMessage*/ 'Everyone knows that the magicword is "sesame"', /*errorCode*/ 1234);
}
}
<?php
/**
* Gocardless.Updatecustomer API specification (optional)
* This is used for documentation and validation.
*
* @param array $spec description of fields supported by this API call
* @return void
* @see http://wiki.civicrm.org/confluence/display/CRMDOC/API+Architecture+Standards
*/
function _civicrm_api3_gocardless_Updatecustomer_spec(&$spec) {
$spec['magicword']['api.required'] = 0;
}
/**
* Gocardless.Updatecustomer API
*
* @param array $params
* @return array API result descriptor
* @see civicrm_api3_create_success
* @see civicrm_api3_create_error
* @throws API_Exception
*/
function civicrm_api3_gocardless_Updatecustomer($params) {
//Now create the subscription against Gocardless
require 'vendor/autoload.php';
$client = CRM_GoCardlessUtils::getApi(APIMODE);
//CRM_Core_Error::debug_log_message( 'client = '. print_r($client,true), $out = false );
$return = $client->customers()->update($params['customers'], [
"params" => ['metadata' => ['civicrm_ID' => $params['contactID']
]]]);
return civicrm_api3_create_success('OK', $params, 'Gocardless', 'Updatecustomer');
if (array_key_exists('magicword', $params) && $params['magicword'] == 'sesame') {
$returnValues = array( // OK, return several data rows
12 => array('id' => 12, 'name' => 'Twelve'),
34 => array('id' => 34, 'name' => 'Thirty four'),
56 => array('id' => 56, 'name' => 'Fifty six'),
);
// ALTERNATIVE: $returnValues = array(); // OK, success
// ALTERNATIVE: $returnValues = array("Some value"); // OK, return a single value
// Spec: civicrm_api3_create_success($values = 1, $params = array(), $entity = NULL, $action = NULL)
return civicrm_api3_create_success($returnValues, $params, 'NewEntity', 'NewAction');
} else {
throw new API_Exception(/*errorMessage*/ 'Everyone knows that the magicword is "sesame"', /*errorCode*/ 1234);
}
}