public function cancelPreAuth($preauthId) { try { $preAuth = \GoCardless_PreAuthorization::find($preauthId); $preAuthStatus = $preAuth->cancel(); return $preAuthStatus->status == 'cancelled'; } catch (\GoCardless_ApiException $e) { \Log::error($e); return false; } }
/** ** WHMCS method to capture payments ** This method is triggered by WHMCS in an attempt to capture a PreAuth payment ** ** @param array $params Array of paramaters parsed by WHMCS **/ function gocardless_capture($params) { # create GoCardless DB if it hasn't already been created gocardless_createdb(); # grab the gateway information from WHMCS $gateway = getGatewayVariables('gocardless'); # Send the relevant API information to the GoCardless class for future processing gocardless_set_account_details($params); # check against the database if the bill relevant to this invoice has already been created $existing_payment_query = select_query('mod_gocardless', 'resource_id', array('invoiceid' => $params['invoiceid'])); $existing_payment = mysql_fetch_assoc($existing_payment_query); # check if any rows have been returned or if the returned result is empty. # If no rows were returned, the bill has not already been made for this invoice # If a row was returned but the resource ID is empty, the bill has not been completed # we have already raised a bill with GoCardless (in theory) if (!mysql_num_rows($existing_payment_query) || empty($existing_payment['resource_id'])) { #MOD-START #Use PreAuth table $userid_query = select_query('tblinvoices', 'userid', array('id' => $params['invoiceid'])); $userid_result = mysql_fetch_array($userid_query); if (!empty($userid_result['userid'])) { $userid = $userid_result['userid']; $preauth_query = select_query('mod_gocardless_preauth', 'subscriptionid', array('userid' => $userid)); $preauth_result = mysql_fetch_array($preauth_query); if (!empty($preauth_result['subscriptionid'])) { $preauthid = $preauth_result['subscriptionid']; } } #MOD-END # now we are out of the loop, check if we have been able to get the PreAuth ID if (isset($preauthid)) { # we have found the PreAuth ID, so get it from GoCardless and process a new bill $pre_auth = GoCardless_PreAuthorization::find($preauthid); # check the preauth returned something if ($pre_auth) { # Create a bill with the $pre_auth object try { $bill = $pre_auth->create_bill(array('amount' => $params['amount'], 'name' => "Invoice #" . $params['invoiceid'])); } catch (Exception $e) { # we failed to create a new bill, lets update mod_gocardless to alert the admin why payment hasnt been received, # log this in the transaction log and exit out update_query('mod_gocardless', array('payment_failed' => 1), array('invoiceid' => $params['invoiceid'])); logTransaction($params['paymentmethod'], "Failed to create GoCardless bill against pre-authorization " . $preauthid . " for invoice " . $params['invoiceid'] . ": " . print_r($e, true) . print_r($bill, true), 'Failed'); return array('status' => 'error', 'rawdata' => $e); } # check that the bill has been created if ($bill->id) { # check if the bill already exists in the database, if it does we will just update the record # if not, we will create a new record and record the transaction if (!mysql_num_rows($existing_payment_query)) { # Add the bill ID to the table and mark the transaction as pending insert_query('mod_gocardless', array('invoiceid' => $params['invoiceid'], 'billcreated' => 1, 'resource_id' => $bill->id, 'preauth_id' => $pre_auth->id)); if ($gateway['instantpaid'] == on) { # The Instant Activation option is on, so add to the Gateway Log and log a transaction on the invoice addInvoicePayment($params['invoiceid'], $bill->id, $bill->amount, $bill->gocardless_fees, $gateway['paymentmethod']); logTransaction($gateway['paymentmethod'], 'Bill of ' . $bill->amount . ' raised and logged for invoice ' . $params['invoiceid'] . ' with GoCardless ID ' . $bill->id, 'Successful'); return array('status' => 'success', 'rawdata' => print_r($bill, true)); } else { # Instant Activation is off, so just add to the gateway log and wait before marking as paid until web hook arrives logTransaction($gateway['paymentmethod'], 'Bill of ' . $bill->amount . ' raised for invoice ' . $params['invoiceid'] . ' with GoCardless ID ' . $bill->id, 'Successful'); return array('status' => 'pending', 'rawdata' => print_r($bill, true)); } } else { # update the table with the bill ID update_query('mod_gocardless', array('billcreated' => 1, 'resource_id' => $bill->id), array('invoiceid' => $params['invoiceid'])); } } } else { # PreAuth could not be verified logTransaction($gateway['paymentmethod'], 'The pre-authorization specified for invoice ' . $params['invoiceid'] . ' (' . $preauthid . ') does not seem to exist - something has gone wrong, or the customer needs to set up their Direct Debit again.', 'Incomplete'); return array('status' => 'error', 'rawdata' => array('message' => 'The pre-authorization ID was found for invoice ' . $params['invoiceid'] . ' but it could not be fetched.')); } } else { # we couldn't find the PreAuthID meaning at this point all we can do is give up! # the client will have to setup a new preauth to begin recurring payments again # or pay using an alternative method logTransaction($gateway['paymentmethod'], 'No pre-authorization found when trying to raise payment for invoice ' . $params['invoiceid'] . ' - something has gone wrong, or the customer needs to set up their Direct Debit again.', 'Incomplete'); return array('status' => 'error', 'rawdata' => array('message' => 'No pre-authorisation ID found in WHMCS for invoice ' . $params['invoiceid'])); } } else { # WHMCS is trying to collect the bill but one has already been created - this happens because the bill is not mark as 'paid' # until a web hook is received by default, so WHMCS thinks it still needs to collect. # logTransaction('GoCardless', 'Bill already created - awaiting update via web hook...' . "\nBill ID: " . $existing_payment['resource_id'], 'Pending'); # return array('status' => 'Bill already created - awaiting update via web hook...', 'rawdata' => # array('message' => 'Bill already created - awaiting update via web hook...')); return array('status' => 'pending', 'rawdata' => array('message' => 'The bill has already been created for invoice ' . $params['invoiceid'])); } }
public function gocardless_complete() { $flash_success = $this->session->flashdata(__FUNCTION__ . '_success'); if ($flash_success) { $this->session->keep_flashdata('notice'); return redirect('order'); } //get going with Go Cardless require_once APPPATH . '/third_party/GoCardless.php'; GoCardless::$environment = config_item('gocardless_environment'); GoCardless::set_account_details(config_item('gocardless_account')); //we've come back from Go Cardless //finalize the process $confirm_params = array('resource_uri' => $this->input->get('resource_uri'), 'resource_id' => $this->input->get('resource_id'), 'resource_type' => $this->input->get('resource_type'), 'signature' => $this->input->get('signature'), 'state' => $this->input->get('state')); // Returns the confirmed resource if successful, otherwise throws an exception $confirm_result = GoCardless::confirm_resource($confirm_params); if (!$confirm_result) { $this->flash->set('error', 'There was an error processing with Go Cardless.', TRUE); return redirect('bill/view/' . $this->input->get('state')); } //check what to do now //var_export($this->input->get()); die(); if ($this->input->get('resource_type') == 'bill') { //a single bill was paid, update it $this->load->model('order_model'); $result = $this->order_model->mark_bill_paid($this->input->get('state'), 'Go Cardless'); //send the user on if (!$result) { $this->flash->set('error', 'The payment was taken, but an error occured updating the bill. Please contact website staff.', TRUE); } else { $this->flash->set(__FUNCTION__ . '_success', TRUE, TRUE); $this->flash->set('notice', 'Thank you for paying with Go Cardless.', TRUE); } return redirect('order'); } else { if ($this->input->get('resource_type') == 'pre_authorization') { //Go Cardless is authorized to take payments. //make a note $this->load->model('order_model'); $this->order_model->gc_save_preauth_id($this->session->userdata('u_id'), $this->input->get('resource_id')); //Pay a bill we were on? if (is_numeric($this->input->get('state')) && $this->input->get('state') > 0) { //get the bill to pay. $this->load->model('order_model'); $bill = $this->order_model->get_bill($this->input->get('state')); if (isset($bill)) { //pay the bill we were on... $pre_auth = GoCardless_PreAuthorization::find($this->input->get('resource_id')); $gc_bill = $pre_auth->create_bill(array('name' => 'Bill #' . $bill['b_id'], 'amount' => $bill['b_price'])); } //send the user on if (!$gc_bill) { $this->flash->set('error', 'Go Cardless was authorised for futue payments, but an error occured paying this bill.', TRUE); } else { //after authorizing bill was paid, update it $this->load->model('order_model'); $result = $this->order_model->mark_bill_paid($this->input->get('state'), 'Go Cardless'); //send the user on if (!$result) { $this->flash->set('error', 'Payment was taken, but an error occured updating the bill. Please contact website staff.', TRUE); } else { $this->flash->set('notice', 'Thank you for paying with Go Cardless. Future payments will be made automatically.', TRUE); } } return redirect('order'); } else { $this->flash->set('success', 'Go Cardless has been set up for future bills.', TRUE); return redirect('order'); //send them where? } } else { $this->flash->set('error', 'Payment process not recognised.', TRUE); return redirect('order'); } } }
/** ** WHMCS method to capture payments ** This method is triggered by WHMCS in an attempt to capture a PreAuth payment ** ** @param array $params Array of paramaters parsed by WHMCS **/ function gocardless_capture($params) { # create GoCardless DB if it hasn't already been created gocardless_createdb(); # Send the relevant API information to the GoCardless class for future processing gocardless_set_account_details($params); # check against the database if the bill relevant to this invoice has already been created $existing_payment_query = select_query('mod_gocardless', 'resource_id', array('invoiceid' => $params['invoiceid'])); $existing_payment = mysql_fetch_assoc($existing_payment_query); # check if any rows have been returned or if the returned result is empty. # If no rows were returned, the bill has not already been made for this invoice # If a row was returned but the resource ID is empty, the bill has not been completed # we have already raised a bill with GoCardless (in theory) if (!mysql_num_rows($existing_payment_query) || empty($existing_payment['resource_id'])) { # query the database to get the relid of all invoice items $invoice_item_query = select_query('tblinvoiceitems', 'relid', array('invoiceid' => $params['invoiceid'], 'type' => 'Hosting')); # loop through each returned (each invoice item) and attempt to find a subscription ID while ($invoice_item = mysql_fetch_assoc($invoice_item_query)) { $package_query = select_query('tblhosting', 'subscriptionid', array('id' => $invoice_item['relid'])); $package = mysql_fetch_assoc($package_query); # if we have found a subscriptionID, store it in $preauthid if (!empty($package['subscriptionid'])) { $preauthid = $package['subscriptionid']; } } # now we are out of the loop, check if we have been able to get the PreAuth ID if (isset($preauthid)) { # we have found the PreAuth ID, so get it from GoCardless and process a new bill $pre_auth = GoCardless_PreAuthorization::find($preauthid); # check the preauth returned something if ($pre_auth) { # Create a bill with the $pre_auth object try { $bill = $pre_auth->create_bill(array('amount' => $params['amount'])); } catch (Exception $e) { # we failed to create a new bill, lets update mod_gocardless to alert the admin why payment hasnt been received, # log this in the transaction log and exit out update_query('mod_gocardless', array('payment_failed' => 1), array('invoiceid' => $params['invoiceid'])); logTransaction($params['paymentmethod'], "Failed to create GoCardless bill: " . print_r($e, true) . print_r($bill, true), 'Failed'); return array('status' => 'error', 'rawdata' => $e); } # check that the bill has been created if ($bill->id) { # check if the bill already exists in the database, if it does we will just update the record # if not, we will create a new record and record the transaction if (!mysql_num_rows($existing_payment_query)) { # Add the bill ID to the table and mark the transaction as pending insert_query('mod_gocardless', array('invoiceid' => $params['invoiceid'], 'billcreated' => 1, 'resource_id' => $bill->id, 'preauth_id' => $pre_auth->id)); logTransaction('GoCardless', 'Transaction initiated successfully, confirmation will take 2-5 days' . "\nPreAuth: " . $pre_auth->id . "\nBill ID: " . $bill->id, 'Pending'); return array('status' => 'Bill Created', 'rawdata' => $bill); } else { # update the table with the bill ID update_query('mod_gocardless', array('billcreated' => 1, 'resource_id' => $bill->id), array('invoiceid' => $params['invoiceid'])); } } } else { # PreAuth could not be verified logTransaction('GoCardless', 'Pre-Authorisation could not be verified', 'Incomplete'); return array('status' => 'Pre-Authorisation could not be verified', 'rawdata' => array('message' => 'No pre-authorisation ID found in WHMCS')); } } else { # we couldn't find the PreAuthID meaning at this point all we can do is give up! # the client will have to setup a new preauth to begin recurring payments again # or pay using an alternative method logTransaction('GoCardless', 'No pre-authorisation found', 'Incomplete'); return array('status' => 'No Pre-auth Found', 'rawdata' => array('message' => 'No pre-authorisation ID found in WHMCS')); } } else { # WHMCS is trying to collect the bill but one has already been created - this happens because the bill is not mark as 'paid' # until a web hook is received by default, so WHMCS thinks it still needs to collect. logTransaction('GoCardless', 'Bill already created - awaiting update via web hook...' . "\nBill ID: " . $existing_payment['resource_id'], 'Pending'); return array('status' => 'Bill already created - awaiting update via web hook...', 'rawdata' => array('message' => 'Bill already created - awaiting update via web hook...')); } }
$pre_auth_url = GoCardless::new_pre_authorization_url($payment_details); echo ' · <a href="' . $pre_auth_url . '">New pre-authorized payment</a>'; // New bill $payment_details = array('amount' => '30.00', 'name' => 'Donation', 'user' => array('first_name' => 'Tom', 'last_name' => 'Blomfield', 'email' => '*****@*****.**')); $bill_url = GoCardless::new_bill_url($payment_details); echo ' · <a href="' . $bill_url . '">New bill</a></p>'; echo 'NB. The \'new bill\' link is also a demo of pre-populated user data'; echo '<h2>API calls</h2>'; echo 'GoCardless_Merchant::find(\'258584\')'; echo '<blockquote><pre>'; $merchant = GoCardless_Merchant::find('258584'); print_r($merchant); echo '</pre></blockquote>'; echo 'GoCardless_Merchant::find(\'258584\')->pre_authorizations()'; echo '<blockquote><pre>'; $preauths = GoCardless_Merchant::find('258584')->pre_authorizations(); print_r($preauths); echo '</pre></blockquote>'; echo 'GoCardless_PreAuthorization::find(\'992869\')->create_bill($bill_details)'; echo '<blockquote><pre>'; $pre_auth = GoCardless_PreAuthorization::find('013M018V0K'); $bill_details = array('amount' => '15.00'); $bill = $pre_auth->create_bill($bill_details); print_r($bill); echo '</pre></blockquote>'; echo 'validate webhook:'; echo '<blockquote><pre>'; $webhook_json = '{"payload":{"bills":[{"id":"880807"},{"status":"pending"},{"source_type":"subscription"},{"source_id":"21"},{"uri":"https:\\/\\/sandbox.gocardless.com\\/api\\/v1\\/bills\\/880807"}],"action":"created","resource_type":"bill","signature":"f25a611fb9afbc272ab369ead52109edd8a88cbb29a3a00903ffbce0ec6be5cb"}}'; $webhook = json_decode($webhook_json, true); var_dump(GoCardless::validate_webhook($webhook['payload'])); echo '</pre></blockquote>';
/** * Tries to auto pay a bill with Go Cardless, o e-mails the user, and updates the bill status as relevant * * @author GM * @param $b_id int the id of the bill * @param $u_id int the id of the user that needs to pay * @param $b_price float the price of the bill that we want to debit from them */ public function make_bill_due_and_pay($b_id, $u_id, $b_price) { //error avoidance if ($b_price <= 0) { return array('success' => FALSE, 'description' => 'Amount due must be positive, Bill #' . $b_id . ' not marked as due.'); } //have they authorised Go Cardless in the past? $pre_auth_id = $this->gc_get_preauth_id($u_id); if (!$pre_auth_id) { //set bill as due, e-mail them asking to pay $result = $this->change_bill_status($b_id, "Pending"); if ($result) { //email them about it $this->load->model('users_model'); $member = $this->users_model->get_user($u_id); $subject = config_item('site_name') . ' Payment is due. '; $message = '<p>Hello ' . $member['u_title'] . ' ' . $member['u_fname'] . ' ' . $member['u_sname'] . ',</p>'; $message .= '<p>Bill #' . $b_id . ', is now ready for you to pay.'; $message .= '<br />The amount for your recent delivery is <em>£' . $b_price . '</em>.'; $message .= '<br />You can view details of this bill and pay online at <a href="' . site_url('bill/view/' . $b_id) . '">' . site_url('bill/view/' . $b_id) . '</a>.</p>'; $message .= '<p>Thank you, <br /> ' . config_item('site_name') . '</p>'; $eq[] = array('eq_email' => $member['u_email'], 'eq_subject' => $subject, 'eq_body' => $message); // load emails queue model $this->load->model('emails_queue_model'); $this->emails_queue_model->set_queue($eq); return array('success' => TRUE, 'description' => 'The member has been notified that the bill is due.'); } else { return array('success' => FALSE, 'description' => 'The bill status could not be updated.'); } } else { //is Go Cardless working & enough? require_once APPPATH . '/third_party/GoCardless.php'; GoCardless::$environment = config_item('gocardless_environment'); GoCardless::set_account_details(config_item('gocardless_account')); $pre_auth = GoCardless_PreAuthorization::find($pre_auth_id); if (isset($pre_auth) && $pre_auth->status == 'active' && $pre_auth->remaining_amount >= $b_price) { //try paying it $bill_details = array('name' => 'Bill #' . $b_id, 'amount' => $b_price); $gc_bill = $pre_auth->create_bill($bill_details); if ($gc_bill) { //mark it as paid $result = $this->mark_bill_paid($b_id, 'Go Cardless Pre-Auth'); if (!$result) { return array('success' => FALSE, 'description' => 'Bill ' . $b_id . ' was paid, but an error caused it not to be marked as such.'); } else { return array('success' => TRUE, 'description' => 'The bill was paid through Go Cardless pre-authorisation.'); } } } //set bill as due, e-mail them asking to pay, because GC couldn't be used (or was not enough) $result = $this->change_bill_status($b_id, "Pending"); if ($result) { //email them about it $this->load->model('users_model'); $member = $this->users_model->get_user($u_id); $subject = config_item('site_name') . ' Payment is due. '; $message = '<p>Hello ' . $member['u_title'] . ' ' . $member['u_fname'] . ' ' . $member['u_sname'] . ',</p>'; $message .= '<p>Bill #' . $b_id . ', is now ready for you to pay.'; $message .= '<br />The amount for your recent delivery is <em>£' . $b_price . '</em>.'; $message .= '<br />On this occasion, we were unable to debit the amount from your bank through the Go Cardless system.'; $message .= '<br />You can view details of this bill and pay online at <a href="' . site_url('bill/view/' . $b_id) . '">' . site_url('bill/view/' . $b_id) . '</a>.</p>'; $message .= '<p>Thank you, <br /> ' . config_item('site_name') . '</p>'; $eq[] = array('eq_email' => $member['u_email'], 'eq_subject' => $subject, 'eq_body' => $message); // load emails queue model $this->load->model('emails_queue_model'); $this->emails_queue_model->set_queue($eq); return array('success' => TRUE, 'description' => 'The member has been notified that the bill is due.'); } else { return array('success' => FALSE, 'description' => 'The bill status could not be updated.'); } } }