public function run($request)
 {
     $appType = $this->config()->appType;
     $oauthCallback = $this->config()->oauthCallback;
     $userAgent = $this->config()->userAgent;
     $consumerKey = $this->config()->consumerKey;
     $sharedSecret = $this->config()->sharedSecret;
     $privateKeyPath = BASE_PATH . $this->config()->privateKeyPath;
     $publicKeyPath = BASE_PATH . $this->config()->publicKeyPath;
     $signatures = array('consumer_key' => $consumerKey, 'shared_secret' => $sharedSecret, 'core_version' => '2.0', 'payroll_version' => '1.0');
     if ($appType == "Private" || $appType == "Partner") {
         $signatures['rsa_private_key'] = $privateKeyPath;
         $signatures['rsa_public_key'] = $publicKeyPath;
     }
     $XeroOAuth = new XeroOAuth(array_merge(array('application_type' => $appType, 'oauth_callback' => $oauthCallback, 'user_agent' => $userAgent), $signatures));
     $initialCheck = $XeroOAuth->diagnostics();
     $checkErrors = count($initialCheck);
     if ($checkErrors > 0) {
         // you could handle any config errors here, or keep on truckin if you like to live dangerously
         foreach ($initialCheck as $check) {
             echo 'Error: ' . $check . PHP_EOL;
         }
     } else {
         Session::set('Xero', array('oauth_token' => $XeroOAuth->config['consumer_key'], 'oauth_token_secret' => $XeroOAuth->config['shared_secret'], 'oauth_session_handle' => ''));
         $oauthSession['oauth_token'] = Session::get('Xero.oauth_token');
         $oauthSession['oauth_token_secret'] = Session::get('Xero.oauth_token_secret');
         $oauthSession['oauth_session_handle'] = Session::get('Xero.oauth_session_handle');
         if (isset($oauthSession['oauth_token'])) {
             $XeroOAuth->config['access_token'] = $oauthSession['oauth_token'];
             $XeroOAuth->config['access_token_secret'] = $oauthSession['oauth_token_secret'];
             $this->createInvoices($XeroOAuth);
             $this->createPayments($XeroOAuth);
         }
     }
 }
示例#2
0
 * consumer_secret: for partner applications, set to: s (cannot be blank)
 * rsa_private_key: application certificate private key - not needed for public applications
 * rsa_public_key: application certificate public cert - not needed for public applications
 */
include 'tests/testRunner.php';
$signatures = array('consumer_key' => 'YOURCONSUMERKEY', 'shared_secret' => 'YOURSECRET', 'core_version' => '2.0', 'payroll_version' => '1.0', 'file_version' => '1.0');
if (XRO_APP_TYPE == "Private" || XRO_APP_TYPE == "Partner") {
    $signatures['rsa_private_key'] = BASE_PATH . '/certs/privatekey.pem';
    $signatures['rsa_public_key'] = BASE_PATH . '/certs/publickey.cer';
}
if (XRO_APP_TYPE == "Partner") {
    $signatures['curl_ssl_cert'] = BASE_PATH . '/certs/entrust-cert-RQ3.pem';
    $signatures['curl_ssl_password'] = '******';
    $signatures['curl_ssl_key'] = BASE_PATH . '/certs/entrust-private-RQ3.pem';
}
$XeroOAuth = new XeroOAuth(array_merge(array('application_type' => XRO_APP_TYPE, 'oauth_callback' => OAUTH_CALLBACK, 'user_agent' => $useragent), $signatures));
$initialCheck = $XeroOAuth->diagnostics();
$checkErrors = count($initialCheck);
if ($checkErrors > 0) {
    // you could handle any config errors here, or keep on truckin if you like to live dangerously
    foreach ($initialCheck as $check) {
        echo 'Error: ' . $check . PHP_EOL;
    }
} else {
    $here = XeroOAuth::php_self();
    session_start();
    $oauthSession = retrieveSession();
    include 'tests/tests.php';
    if (isset($_REQUEST['oauth_verifier'])) {
        $XeroOAuth->config['access_token'] = $_SESSION['oauth']['oauth_token'];
        $XeroOAuth->config['access_token_secret'] = $_SESSION['oauth']['oauth_token_secret'];
<?php

require 'lib/XeroOAuth.php';
define('BASE_PATH', dirname(__FILE__));
define("XRO_APP_TYPE", "Private");
define("OAUTH_CALLBACK", "oob");
$useragent = "XeroOAuth-PHP Private App Test";
$signatures = array('consumer_key' => 'YOURCONSUMERKEY', 'shared_secret' => 'YOURSECRET', 'core_version' => '2.0', 'payroll_version' => '1.0');
if (XRO_APP_TYPE == "Private" || XRO_APP_TYPE == "Partner") {
    $signatures['rsa_private_key'] = BASE_PATH . '/certs/privatekey.pem';
    $signatures['rsa_public_key'] = BASE_PATH . '/certs/publickey.cer';
}
$XeroOAuth = new XeroOAuth(array_merge(array('application_type' => XRO_APP_TYPE, 'oauth_callback' => OAUTH_CALLBACK, 'user_agent' => $useragent), $signatures));
include 'tests/testRunner.php';
$initialCheck = $XeroOAuth->diagnostics();
$checkErrors = count($initialCheck);
if ($checkErrors > 0) {
    // you could handle any config errors here, or keep on truckin if you like to live dangerously
    foreach ($initialCheck as $check) {
        echo 'Error: ' . $check . PHP_EOL;
    }
} else {
    $session = persistSession(array('oauth_token' => $XeroOAuth->config['consumer_key'], 'oauth_token_secret' => $XeroOAuth->config['shared_secret'], 'oauth_session_handle' => ''));
    $oauthSession = retrieveSession();
    if (isset($oauthSession['oauth_token'])) {
        $XeroOAuth->config['access_token'] = $oauthSession['oauth_token'];
        $XeroOAuth->config['access_token_secret'] = $oauthSession['oauth_token_secret'];
        include 'tests/tests.php';
    }
    testLinks();
}
function isxwpe_add_xero_invoice_to_account()
{
    // Function to add invoices to xero account
    global $wpdb;
    // This if statement start when user complete checkout
    if (isset($_REQUEST['wpsc_action']) && $_REQUEST['wpsc_action'] == 'submit_checkout') {
        $samp_array = array();
        $results = $wpdb->get_results("SELECT * FROM {$wpdb->prefix}" . "xero_auth");
        // Collect auth credentials
        if (!empty($results)) {
            foreach ($results as $result) {
                if ($result->credential == 'application_key') {
                    $application_key = $result->value;
                }
                if ($result->credential == 'secret_key') {
                    $secret_key = $result->value;
                }
                if ($result->credential == 'redirect_url') {
                    $redirect_url = $result->value;
                }
                if ($result->credential == 'oauth_token') {
                    $oauth_token = $result->value;
                }
                if ($result->credential == 'oauth_verifier') {
                    $oauth_verifier = $result->value;
                }
                if ($result->credential == 'oauth_token_secret') {
                    $oauth_token_secret = $result->value;
                }
            }
        }
        $checkout_session_id = wpsc_get_customer_meta('checkout_session_id');
        // Find transaction Id
        $results = $wpdb->get_results("SELECT * FROM {$wpdb->prefix}" . "wpsc_purchase_logs", ARRAY_A);
        // Collect transaction details
        foreach ($results as $temp_results) {
            if ($temp_results['sessionid'] == $checkout_session_id) {
                $samp_array = $temp_results;
            }
        }
        if (!empty($samp_array)) {
            $purchase_id = $samp_array['id'];
            $total_price = $samp_array['totalprice'];
            $user_id = $samp_array['user_ID'];
            $user_email = '';
            $name = '';
            $user_details = $wpdb->get_results("SELECT * FROM {$wpdb->prefix}" . "wpsc_submited_form_data WHERE `log_id` = {$purchase_id}", ARRAY_A);
            foreach ($user_details as $user_data) {
                if (is_email($user_data['value'])) {
                    $user_email = $user_data['value'];
                }
                if (isset($user_data['form_id']) && $user_data['form_id'] == 2) {
                    $name = $name . $user_data['value'];
                }
                if (isset($user_data['form_id']) && $user_data['form_id'] == 3) {
                    $name = $name . ' ' . $user_data['value'];
                }
            }
        }
        $currency = $wpdb->get_results("SELECT * FROM {$wpdb->prefix}" . "options WHERE `option_name` ='currency_type'");
        $currency_id = $currency[0]->option_value;
        $currency_details = $wpdb->get_results("SELECT * FROM {$wpdb->prefix}" . "wpsc_currency_list WHERE id = {$currency_id}");
        $currency_code = $currency_details[0]->code;
        // Set currency code for xero same as currency on WPecommerse plugin
        $wpdb->get_results("SELECT * FROM {$wpdb->prefix}" . "wpsc_cart_contents WHERE purchaseid = {$purchase_id} ");
        // Select product details
        $purchased_items = $wpdb->get_results("SELECT * FROM {$wpdb->prefix}" . "wpsc_cart_contents WHERE purchaseid = {$purchase_id} ");
        $wp_wpsc_purchase_logs = $wpdb->get_results("SELECT * FROM {$wpdb->prefix}" . "wpsc_purchase_logs WHERE id = {$purchase_id} ");
        $wp_wpsc_purchase_log = $wp_wpsc_purchase_logs[0];
        $line_items = '';
        foreach ($purchased_items as $selected_items) {
            //print_r($purchased_items);
            $line_items .= '<LineItem>
				<Description>' . $selected_items->name . '</Description>
				<Quantity>' . $selected_items->quantity . '</Quantity>
				<TaxAmount>' . $selected_items->tax_charged . '</TaxAmount>
				<UnitAmount>' . $selected_items->price . '</UnitAmount>
			  </LineItem>';
        }
        require plugin_dir_path(__FILE__) . 'xero_library/lib/XeroOAuth.php';
        define("XRO_APP_TYPE", "Public");
        $useragent = "Xero-OAuth-PHP Public";
        define("OAUTH_CALLBACK", $redirect_url);
        $signatures = array('consumer_key' => $application_key, 'shared_secret' => $secret_key, 'core_version' => '2.0', 'payroll_version' => '1.0', 'file_version' => '1.0', 'access_token' => $oauth_token, 'access_token_secret' => $oauth_token_secret);
        $target_directorys = wp_upload_dir();
        $target_directory = $target_directorys['basedir'];
        if (XRO_APP_TYPE == "Private" || XRO_APP_TYPE == "Public") {
            $signatures['rsa_private_key'] = $target_directory . '/xero_invoice/private_keys/privatekey.pem';
            $signatures['rsa_public_key'] = $target_directory . '/xero_invoice/private_keys/publickey.cer';
        }
        $XeroOAuth = new XeroOAuth(array_merge(array('application_type' => XRO_APP_TYPE, 'oauth_callback' => OAUTH_CALLBACK, 'user_agent' => $useragent), $signatures));
        $initialCheck = $XeroOAuth->diagnostics();
        $today = date('Y-m-d');
        include plugin_dir_path(__FILE__) . 'tests/testRunner.php';
        $xml = "<Invoices>\n                      <Invoice>\n                        <Type>ACCREC</Type>\n\t\t\t\t\t\t<CurrencyCode>{$currency_code}</CurrencyCode>\n                        <Contact>\n                          <Name>{$name}</Name>\n\t\t\t\t\t\t  <EmailAddress>{$user_email}</EmailAddress>\n                        </Contact>\n                        <Date>{$today}</Date>\n                        <LineAmountTypes>Exclusive</LineAmountTypes>\n                        <LineItems>\n                          {$line_items}\n                       </LineItems>\n                     </Invoice>\n                   </Invoices>";
        //$myfile = fopen(WP_PLUGIN_DIR."/invoice-sync-for-xero-and-wpecommerce/XerSyncLog.txt", "w") or die("Unable to open file!");
        $response = $XeroOAuth->request('POST', $XeroOAuth->url('Invoices', 'core'), array(), $xml);
        if ($XeroOAuth->response['code'] == 200) {
            // Add transaction details to DB id transaction is success
            $invoice = $XeroOAuth->parseResponse($XeroOAuth->response['response'], $XeroOAuth->response['format']);
            $invoice_id = $invoice->Invoices[0]->Invoice->InvoiceNumber;
            $wpdb->insert("{$wpdb->prefix}" . "xero_history", array('session_id' => $checkout_session_id, 'purchase_id' => $purchase_id, 'invoice_id' => $invoice_id, 'user_email' => $user_email), array('%d', '%d', '%s', '%s'));
        } else {
            //outputError($XeroOAuth);
        }
    }
}
<?php

require 'lib/XeroOAuth.php';
define('BASE_PATH', dirname(__FILE__));
define("XRO_APP_TYPE", "Private");
define("OAUTH_CALLBACK", "oob");
$useragent = "XeroOAuth-PHP Private App Test";
$signatures = array('consumer_key' => 'CNHHGAYDW7XZZNXXWDWKATZYDWDJXO', 'shared_secret' => 'CJW0KPOAIG0C7DDVIUXA3V8GWNIABV', 'core_version' => '2.0', 'payroll_version' => '1.0', 'file_version' => '1.0');
if (XRO_APP_TYPE == "Private" || XRO_APP_TYPE == "Partner") {
    $signatures['rsa_private_key'] = BASE_PATH . '/certs/privatekey.pem';
    $signatures['rsa_public_key'] = BASE_PATH . '/certs/publickey.cer';
}
$XeroOAuth = new XeroOAuth(array_merge(array('application_type' => XRO_APP_TYPE, 'oauth_callback' => OAUTH_CALLBACK, 'user_agent' => $useragent), $signatures));
include 'tests/testRunner.php';
$initialCheck = $XeroOAuth->diagnostics();
$checkErrors = count($initialCheck);
if ($checkErrors > 0) {
    // you could handle any config errors here, or keep on truckin if you like to live dangerously
    foreach ($initialCheck as $check) {
        echo 'Error: ' . $check . PHP_EOL;
    }
} else {
    $session = persistSession(array('oauth_token' => $XeroOAuth->config['consumer_key'], 'oauth_token_secret' => $XeroOAuth->config['shared_secret'], 'oauth_session_handle' => ''));
    $oauthSession = retrieveSession();
    if (isset($oauthSession['oauth_token'])) {
        $XeroOAuth->config['access_token'] = $oauthSession['oauth_token'];
        $XeroOAuth->config['access_token_secret'] = $oauthSession['oauth_token_secret'];
        // include 'tests/xero_api.php';
        if ($event_type == "invoice_generated") {
            $response = $XeroOAuth->request('POST', $XeroOAuth->url('Invoices', 'core'), array(), $xml);
            if ($XeroOAuth->response['code'] == 200) {
    private function push_to_xero($id)
    {
        // Get data for sending customer details
        $customer = Customer::find($id);
        $contacts = $customer->customer_contacts;
        $contactsXML = '<ContactPersons>';
        foreach ($contacts as $contact) {
            $contactsXML .= '<ContactPerson>
							 <FirstName>' . $contact->first_name . '</FirstName>
							 <LastName>' . $contact->last_name . '</LastName>
							 <EmailAddress>' . $contact->email . '</EmailAddress>
							 </ContactPerson>';
        }
        $contactsXML .= '</ContactPersons>';
        if (count($contacts) > 0) {
            $first_name = $contacts[0]->first_name;
            $last_name = $contacts[0]->last_name;
            $email = $contacts[0]->email;
        } else {
            $first_name = '';
            $last_name = '';
            $email = '';
        }
        define('BASE_PATH', $_SERVER['DOCUMENT_ROOT']);
        define("XRO_APP_TYPE", "Private");
        define("OAUTH_CALLBACK", 'http://printflow.local:8000/');
        /* For Demo-Company
                define ( "OAUTH_CALLBACK", 'http://printflow.local:8000/' );
                $useragent = "Demo-Printflow";
        
                $signatures = array (
                    'consumer_key'     => 'NLOXKOEM8QUFCW9XCKWH7DQMARCWUW',
                    'shared_secret'    => 'YEACQD0QQ2R5X1YCBFV6LZKMMLIYRT',
                    // API versions
                    'core_version' => '2.0',
                    'payroll_version' => '1.0'
                );
                */
        $useragent = env('USER_AGENT');
        $signatures = array('consumer_key' => env('XERO_KEY'), 'shared_secret' => env('XERO_SECRET'), 'core_version' => '2.0', 'payroll_version' => '1.0');
        if (XRO_APP_TYPE == "Private" || XRO_APP_TYPE == "Partner") {
            $signatures['rsa_private_key'] = BASE_PATH . '/certs/privatekey.pem';
            $signatures['rsa_public_key'] = BASE_PATH . '/certs/publickey.cer';
        }
        $XeroOAuth = new \XeroOAuth(array_merge(array('application_type' => XRO_APP_TYPE, 'oauth_callback' => OAUTH_CALLBACK, 'user_agent' => $useragent), $signatures));
        $initialCheck = $XeroOAuth->diagnostics();
        $checkErrors = count($initialCheck);
        if ($checkErrors > 0) {
            // you could handle any config errors here, or keep on truckin if you like to live dangerously
            foreach ($initialCheck as $check) {
                echo 'Error: ' . $check . PHP_EOL;
            }
        } else {
            $session = $this->persistSession(array('oauth_token' => $XeroOAuth->config['consumer_key'], 'oauth_token_secret' => $XeroOAuth->config['shared_secret'], 'oauth_session_handle' => ''));
            $oauthSession = $this->retrieveSession();
            if (isset($oauthSession['oauth_token'])) {
                $XeroOAuth->config['access_token'] = $oauthSession['oauth_token'];
                $XeroOAuth->config['access_token_secret'] = $oauthSession['oauth_token_secret'];
                if (isset($_REQUEST)) {
                    if (!isset($_REQUEST['where'])) {
                        $_REQUEST['where'] = "";
                    }
                }
                if (isset($_REQUEST['wipe'])) {
                    session_destroy();
                    header("Location: {$here}");
                    // already got some credentials stored?
                } elseif (isset($_REQUEST['refresh'])) {
                    $response = $XeroOAuth->refreshToken($oauthSession['oauth_token'], $oauthSession['oauth_session_handle']);
                    if ($XeroOAuth->response['code'] == 200) {
                        $session = $this->persistSession($response);
                        $oauthSession = $this->retrieveSession();
                    } else {
                        $this->outputError($XeroOAuth);
                        if ($XeroOAuth->response['helper'] == "TokenExpired") {
                            $XeroOAuth->refreshToken($oauthSession['oauth_token'], $oauthSession['session_handle']);
                        }
                    }
                } elseif (isset($oauthSession['oauth_token']) && isset($_REQUEST)) {
                    $XeroOAuth->config['access_token'] = $oauthSession['oauth_token'];
                    $XeroOAuth->config['access_token_secret'] = $oauthSession['oauth_token_secret'];
                    $XeroOAuth->config['session_handle'] = $oauthSession['oauth_session_handle'];
                    $xml = '<Contacts>
							 <Contact>
							   <Name>' . $customer->customer_name . '</Name>
							   <FirstName>' . $first_name . '</FirstName>
							   <LastName>' . $last_name . '</LastName>
							   <EmailAddress>' . $email . '</EmailAddress>
							   <Addresses>
									<Address>
										<AddressType>POBOX</AddressType>
										<AttentionTo>' . $customer->postal_attention . '</AttentionTo>
										<AddressLine1>' . $customer->customer_name . '</AddressLine1>
										<AddressLine2>' . $customer->postal_street . '</AddressLine2>
										<AddressLine3> </AddressLine3>
										<AddressLine4> </AddressLine4>
										<City>' . $customer->postal_city . '</City>
										<Region>' . $customer->postal_state . '</Region>
										<PostalCode>' . $customer->postal_postcode . '</PostalCode>
										<Country>' . $customer->postal_country . '</Country>
									</Address>
									<Address>
										<AddressType>STREET</AddressType>
										<AttentionTo>' . $customer->postal_attention . '</AttentionTo>
										<AddressLine1>' . $customer->customer_name . '</AddressLine1>
										<AddressLine2>' . $customer->postal_street . '</AddressLine2>
										<AddressLine3> </AddressLine3>
										<AddressLine4> </AddressLine4>
										<City>' . $customer->postal_city . '</City>
										<Region>' . $customer->postal_state . '</Region>
										<PostalCode>' . $customer->postal_postcode . '</PostalCode>
										<Country>' . $customer->postal_country . '</Country>
									</Address>
							   </Addresses>
							   <Phones>
									<Phone>
										<PhoneType>DEFAULT</PhoneType>
										<PhoneNumber>' . $customer->tel_number . '</PhoneNumber>
										<PhoneAreaCode>' . $customer->tel_area . '</PhoneAreaCode>
										<PhoneCountryCode>' . $customer->tel_country . '</PhoneCountryCode>
									</Phone>
									<Phone>
										<PhoneType>MOBILE</PhoneType>
										<PhoneNumber>' . $customer->mobile_number . '</PhoneNumber>
										<PhoneAreaCode>' . $customer->mobile_area . '</PhoneAreaCode>
										<PhoneCountryCode>' . $customer->mobile_country . '</PhoneCountryCode>
									</Phone>
							   </Phones>
							   <Website>' . $customer->web_address . '</Website>
							 <IsCustomer>true</IsCustomer>
							   ' . $contactsXML . '
							 </Contact>
						   </Contacts>';
                    $response = $XeroOAuth->request('POST', $XeroOAuth->url('Contacts', 'core'), array(), $xml);
                    if ($XeroOAuth->response['code'] == 200) {
                        return 'OK';
                    } else {
                        $this->outputError($XeroOAuth);
                        return 'ERROR';
                    }
                }
            }
        }
        return 'ERROR';
    }
    public function send_invoice($id)
    {
        // Get data for sending invoice
        $quote_request = QuoteRequest::find($id);
        define('BASE_PATH', $_SERVER['DOCUMENT_ROOT']);
        define("XRO_APP_TYPE", "Private");
        define("OAUTH_CALLBACK", 'http://printflow.local:8000/');
        /* For Demo-Company
                define ( "OAUTH_CALLBACK", 'http://printflow.local:8000/' );
                $useragent = "Demo-Printflow";
        
                $signatures = array (
                    'consumer_key'     => 'PMNK76GMVNQLNK945E385MVIDCCMVQ',
                    'shared_secret'    => 'VUQPJDKRZ1ZUPRSBBHUZ3J8DOQTQEL',
                    // API versions
                    'core_version' => '2.0',
                    'payroll_version' => '1.0'
                );
                */
        $useragent = env('USER_AGENT');
        $signatures = array('consumer_key' => env('XERO_KEY'), 'shared_secret' => env('XERO_SECRET'), 'core_version' => '2.0', 'payroll_version' => '1.0');
        if (XRO_APP_TYPE == "Private" || XRO_APP_TYPE == "Partner") {
            $signatures['rsa_private_key'] = BASE_PATH . '/certs/privatekey.pem';
            $signatures['rsa_public_key'] = BASE_PATH . '/certs/publickey.cer';
        }
        $XeroOAuth = new \XeroOAuth(array_merge(array('application_type' => XRO_APP_TYPE, 'oauth_callback' => OAUTH_CALLBACK, 'user_agent' => $useragent), $signatures));
        $initialCheck = $XeroOAuth->diagnostics();
        $checkErrors = count($initialCheck);
        if ($checkErrors > 0) {
            // you could handle any config errors here, or keep on truckin if you like to live dangerously
            foreach ($initialCheck as $check) {
                echo 'Error: ' . $check . PHP_EOL;
            }
        } else {
            $session = $this->persistSession(array('oauth_token' => $XeroOAuth->config['consumer_key'], 'oauth_token_secret' => $XeroOAuth->config['shared_secret'], 'oauth_session_handle' => ''));
            $oauthSession = $this->retrieveSession();
            if (isset($oauthSession['oauth_token'])) {
                $XeroOAuth->config['access_token'] = $oauthSession['oauth_token'];
                $XeroOAuth->config['access_token_secret'] = $oauthSession['oauth_token_secret'];
                if (isset($_REQUEST)) {
                    if (!isset($_REQUEST['where'])) {
                        $_REQUEST['where'] = "";
                    }
                }
                if (isset($_REQUEST['wipe'])) {
                    session_destroy();
                    header("Location: {$here}");
                    // already got some credentials stored?
                } elseif (isset($_REQUEST['refresh'])) {
                    $response = $XeroOAuth->refreshToken($oauthSession['oauth_token'], $oauthSession['oauth_session_handle']);
                    if ($XeroOAuth->response['code'] == 200) {
                        $session = $this->persistSession($response);
                        $oauthSession = $this->retrieveSession();
                    } else {
                        $this->outputError($XeroOAuth);
                        if ($XeroOAuth->response['helper'] == "TokenExpired") {
                            $XeroOAuth->refreshToken($oauthSession['oauth_token'], $oauthSession['session_handle']);
                        }
                    }
                } elseif (isset($oauthSession['oauth_token']) && isset($_REQUEST)) {
                    $XeroOAuth->config['access_token'] = $oauthSession['oauth_token'];
                    $XeroOAuth->config['access_token_secret'] = $oauthSession['oauth_token_secret'];
                    $XeroOAuth->config['session_handle'] = $oauthSession['oauth_session_handle'];
                    $xml = '<Invoices>
							  <Invoice>
								<Type>ACCREC</Type>
								<Contact>
								  <Name>' . htmlspecialchars($quote_request->customer->customer_name) . '</Name>
								</Contact>
								<Status>DRAFT</Status>
								<Date>' . Carbon::now()->format('Y-m-d') . '</Date>
								<DueDate>' . Carbon::now()->addWeeks(2)->format('Y-m-d') . '</DueDate>
								<Reference>' . htmlspecialchars($quote_request->ref) . '-' . $id . '</Reference>
								<LineAmountTypes>Exclusive</LineAmountTypes>
								<LineItems>
								  <LineItem>
									<JobNo>' . $id . '</JobNo>
									<Title>' . htmlspecialchars($quote_request->title) . '</Title>
									<Description>' . htmlspecialchars($quote_request->title) . '</Description>
									<UnitAmount>' . $quote_request->job->job_item->price / $quote_request->job->job_item->quantity . '</UnitAmount>
									<GST>' . $quote_request->job->job_item->gst . '</GST>
									<AccountCode>230/</AccountCode>
									<TotalIncGST>' . $quote_request->job->job_item->total . '</TotalIncGST>
									<Quantity>' . $quote_request->job->job_item->quantity . '</Quantity>
									<PONumber>' . $id . '</PONumber>
								  </LineItem>';
                    if (!empty($quote_request->summary)) {
                        $xml .= '<LineItem>
									<Description>' . htmlspecialchars($quote_request->summary) . '</Description>
								  </LineItem>';
                    }
                    $xml .= '</LineItems>
							  </Invoice>
							</Invoices>';
                    $response = $XeroOAuth->request('POST', $XeroOAuth->url('Invoices', 'core'), array(), $xml);
                    if ($XeroOAuth->response['code'] == 200) {
                        // Set status = 'completed' job
                        $quote_request->status = 9;
                        $quote_request->save();
                        return 'OK';
                    } else {
                        $this->outputError($XeroOAuth);
                        return 'ERROR';
                    }
                }
            }
        }
        return 'ERROR';
    }