Get invoice data with Xero API - Private App - php

I am trying to build an online form that a user can enter their invoice number, the webserver will then interface with the Xero API to GET the invoice details and populate some additional fields for payment.
I have already got the form logic built and in place however I have no clue of how to start with the Xero API.
I've created a private app and have the required keys but I cannot find any documentation on how to actually go about setting up the API call in PHP.
Any help would be much appreciated.
**** UPDATE ****
I was able to get the API working using the following:
function GetInvData ($InvNumber) {
try {
$config = [
'oauth' => [
'consumer_key' => 'REDACTED',
'rsa_private_key' => 'REDACTED',
],
];
$xero = new PrivateApplication($config);
//$invoice = $xero->load(\XeroPHP\Models\Accounting\Invoice::class)->where('InvoiceNumber',$InvNumber)->execute();
$invoice = $xero->load('Accounting\Invoice')
->where('InvoiceNumber',$InvNumber)
->execute();
}
catch(\Exception $ex) {
var_dump($ex);
}
return ($invoice);
}
However what is returned is the most complex piece of JSON I have ever laid eyes on.... Probably not saying much.
All I need to be able to extract is the the Invoice Amount, The Customer name and Their email address, can anybody assist with this?
XeroPHP\Remote\Collection Object
(
[_associated_objects:protected] =>
[storage:ArrayObject:private] => Array
(
[0] => XeroPHP\Models\Accounting\Invoice Object
(
[_data:protected] => Array
(
[Type] => ACCREC
[Contact] => XeroPHP\Models\Accounting\Contact Object
(
[_data:protected] => Array
(
[ContactID] => cf6eef48-cda3-4862-8518-4d631ea54c1c
[ContactNumber] =>
[AccountNumber] =>
[ContactStatus] =>
[Name] => REDACTED
[FirstName] =>
[LastName] =>
[EmailAddress] =>
[SkypeUserName] =>
[ContactPersons] =>
[BankAccountDetails] =>
[TaxNumber] =>
[AccountsReceivableTaxType] =>
[AccountsPayableTaxType] =>
[Addresses] =>
[Phones] =>
[IsSupplier] =>
[IsCustomer] =>
[DefaultCurrency] =>
[XeroNetworkKey] =>
[SalesDefaultAccountCode] =>
[PurchasesDefaultAccountCode] =>
[SalesTrackingCategories] =>
[PurchasesTrackingCategories] =>
[TrackingCategoryName] =>
[TrackingCategoryOption] =>
[PaymentTerms] =>
[UpdatedDateUTC] =>
[ContactGroups] =>
[Website] =>
[BrandingTheme] =>
[BatchPayments] =>
[Discount] =>
[Balances] =>
[HasAttachments] =>
)
[_dirty:protected] => Array
(
)
[_associated_objects:protected] => Array
(
[Contact] => XeroPHP\Models\Accounting\Invoice Object
*RECURSION*
)
[_application:protected] =>
)
[LineItems] =>
[Date] => DateTime Object
(
[date] => 2019-03-05 00:00:00.000000
[timezone_type] => 3
[timezone] => Australia/Melbourne
)
[DueDate] => DateTime Object
(
[date] => 2019-03-12 00:00:00.000000
[timezone_type] => 3
[timezone] => Australia/Melbourne
)
[LineAmountTypes] => Exclusive
[InvoiceNumber] => Inv-1521
[Reference] => Feb 2019
[BrandingThemeID] => c560d364-0331-4677-a529-8ce702559165
[Url] =>
[CurrencyCode] => AUD
[CurrencyRate] => 1
[Status] => AUTHORISED
[SentToContact] => 1
[ExpectedPaymentDate] =>
[PlannedPaymentDate] =>
[SubTotal] => 2150
[TotalTax] => 215
[Total] => 2365
[TotalDiscount] =>
[InvoiceID] => f5cfaed4-db9b-41f3-94e5-a025c2bc898a
[HasAttachments] =>
[Payments] =>
[Prepayments] =>
[Overpayments] =>
[AmountDue] => 2365
[AmountPaid] => 0
[FullyPaidOnDate] =>
[AmountCredited] => 0
[UpdatedDateUTC] => DateTime Object
(
[date] => 2019-03-05 00:32:01.813000
[timezone_type] => 3
[timezone] => UTC
)
[CreditNotes] =>
)
[_dirty:protected] => Array
(
)
[_associated_objects:protected] => Array
(
)
[_application:protected] => XeroPHP\Application\PrivateApplication Object
(
[config:protected] => Array
(
[xero] => Array
(
[site] => https://api.xero.com
[base_url] => https://api.xero.com
[core_version] => 2.0
[payroll_version] => 1.0
[file_version] => 1.0
[model_namespace] => \XeroPHP\Models
)
[oauth] => Array
(
[signature_method] => RSA-SHA1
[signature_location] => header
[authorize_url] => https://api.xero.com/oauth/Authorize
[request_token_path] => oauth/RequestToken
[access_token_path] => oauth/AccessToken
[consumer_key] => REDACTED
[rsa_private_key] => REDACTED
[token] => REDACTED
)
[curl] => Array
(
[10018] => XeroPHP
[78] => 30
[13] => 20
[64] => 2
[81] => 2
[52] =>
[10004] =>
[10006] =>
[10102] =>
)
)
[oauth_client:protected] => XeroPHP\Remote\OAuth\Client Object
(
[config:XeroPHP\Remote\OAuth\Client:private] => Array
(
[signature_method] => RSA-SHA1
[signature_location] => header
[authorize_url] => https://api.xero.com/oauth/Authorize
[request_token_path] => oauth/RequestToken
[access_token_path] => oauth/AccessToken
[consumer_key] => REDACTED
[rsa_private_key] => REDACTED
[token] => REDACTED
)
[token_secret:XeroPHP\Remote\OAuth\Client:private] =>
[verifier:XeroPHP\Remote\OAuth\Client:private] =>
)
)
)
)
)

You're pretty much asking how to do the whole thing which people don't take kindly to here. Good job getting the API call done, it might take a while before you completely understand what goes on with each line but it's not required.
Now that you've got that part done you just need to work with the data that Xero gives you back, well rather what xero-php (which is the library you're using) gives you back. What you've posted is not JSON, it's just a dump (text representation) of the data as it exists as an object in your code.
That object is a Collection of Invoices, but it's just a singular invoice in your case. It will always return a Collection even if you have really specific search queries, but you can always make yourself a little check to make sure the Collection only has one invoice if you're only expecting one.
So, for what you actually want (Invoice Amount, The Customer name and Their email address), here's the next lines of code.
Invoice Amount:
$invoice->Invoices[0]->Total;
Customer Name:
$invoice->Invoices[0]->Contact->Name;
Email Address:
$invoice->Invoices[0]->Contact->EmailAddress;
Invoices[0] is used to grab the first Invoice in the Collection, so it assumes there's only one. Hopefully that points you in the right direction.

Ended up Getting it working with the following:
function GetInvData ($InvNumber) {
global $xero;
$return = array('AmountDue' => null, 'Customer' => null, 'EmailAddress' => null);
try {
//throw new Exception("Test");
$invoices = $xero->load(Accounting\Invoice::class)
->where('InvoiceNumber',$InvNumber)
->where('Status', 'AUTHORISED')
->execute();
$invoice = $invoices->first();
if(empty($invoice)){
$return = '';
}
else {
$invoiceCount = count($invoice);
if($invoiceCount > 1) {
throw new \Exception("Managed to find [" . $invoiceCount . "] with Invoice ID [" . $InvNumber . "]. Expected this to be unique.");
}
$contact = $invoice->getContact();
$return['AmountDue'] = $invoice->getAmountDue();
$return['Customer'] = $contact->getName();
$return['EmailAddress'] = $contact->getEmailAddress();
}
}
catch(\Exception $ex) {
$return = LogException($ex);
}
return $return;
}
Thanks everyone for the assistance.

Related

Capture status after making a stripe api charge

I am looking for the php code syntax to capture if the call was successful or failed to stripe API. I need to capture one of the objects property to determine this but I am not sure what the best approach is.
Here's a sample response from a successful ACH api charge. I am looking for the php code syntax to capture if call was successful or failed
Stripe\Charge Object
(
[id] => py_1EFlRJBuwnzOEo57Poikh194
[object] => charge
[amount] => 50
[amount_refunded] => 0
[application] =>
[application_fee] =>
[application_fee_amount] =>
[balance_transaction] => txn_1EFlRJBuwnzOEo57dupt8SWp
[captured] => 1
[created] => 1553015365
[currency] => usd
[customer] => cus_Ec6cAdg6N2yYcF
[description] =>
[destination] =>
[dispute] =>
[failure_code] =>
[failure_message] =>
[fraud_details] => Array
(
)
[invoice] =>
[livemode] =>
[metadata] => Stripe\StripeObject Object
(
)
[on_behalf_of] =>
[order] =>
[outcome] => Stripe\StripeObject Object
(
[network_status] => approved_by_network
[reason] =>
[risk_level] => not_assessed
[seller_message] => Payment complete.
[type] => authorized
)
[paid] =>
[payment_intent] =>
[receipt_email] =>
[receipt_number] =>
[receipt_url] => https://pay.stripe.com/receipts/acct_1E8sOiBuwnzOEo57/py_1EFlRJBuwnzOEo57Poikh194/rcpt_EjDtGP7iknHI9RCBJ3iUODNC6bVBVyM
[refunded] =>
[refunds] => Stripe\Collection Object
(
[object] => list
[data] => Array
(
)
[has_more] =>
[total_count] => 0
[url] => /v1/charges/py_1EFlRJBuwnzOEo57Poikh194/refunds
)
[review] =>
[shipping] =>
[source] => Stripe\BankAccount Object
(
[id] => ba_1E8sTZBuwnzOEo57MKqXEvb7
[object] => bank_account
[account_holder_name] => Rassi Stern
[account_holder_type] => individual
[bank_name] => STRIPE TEST BANK
[country] => US
[currency] => usd
[customer] => cus_Ec6cAdg6N2yYcF
[fingerprint] => 9l7up0pswCYSO7eu
[last4] => 6789
[metadata] => Stripe\StripeObject Object
(
)
[routing_number] => 110000000
[status] => verified
)
[source_transfer] =>
[statement_descriptor] =>
[status] => pending
[transfer_data] =>
[transfer_group] =>
)
Are you using the Stripe PHP library?
I implemented something like this:
try {
$charge = \Stripe\Charge::create(array(
"amount" => $amount, // in pence - min 30p
"currency" => $currency,
"description" => $description,
"statement_descriptor" => $statementDescriptor,
"source" => $token,
"metadata" => array (
'code' => $code
),
"receipt_email" => $email
));
$success = true;
} catch(\Stripe\Error\Card $e) {
$success = false;
// Some other stuff to capture the reason for failure and tell the user etc.
}
If you're not using their library, it's probably worth investigating it: there are a lot of varying reasons why a payment could succeed or fail, so looking through that massive Charge Object for the answer may not 100% yield the results you want.
You can fetch the value of the "paid" OR "status" parameters from the charge object.
$success = json_encode($charge->paid); // Expected value = true
$success = json_encode($charge->status); // Expected value = succeeded
Then you can do your check:
if($success) { // or $success == "succeeded" depending on which array key you go for.
// Payment succeeded! Do something...
} else {
print_r(json_encode($charge->failure_message));
// Do something else...
}
The code may also work without json_encode(), I've found that my code is less buggy by using json_encode.
This is as per the Stripe API Docs: https://stripe.com/docs/api/charges/create

Access created_on from response object - get file action PODIO API

Hello folks I'm trying to access the created_on object using code below but it is not working, I'm getting incorrect date January 1, 1970 12:00. Also tried
$item = PodioItem::get($item_id);
$file_id = "";
$created_on = "";
foreach ($item->files as $file) {
echo date('F j, Y h:i',strtotime($file->created_on))."<br>";
}
Below is the response object from print_r($file,true), I can access the other object without any issue like $file->file_id, $file->link. What I'm trying to accomplish is store the created_on data in a variable then create a function to check and grab the latest date, then grab the file_id of it.
PodioFile Object
[__attributes:PodioObject:private] => Array
(
[file_id] => 464714088
[link] => https://files.podio.com/464714088
[perma_link] =>
[thumbnail_link] =>
[hosted_by] => podio
[name] => KEjj4UQSUV.PDF
[description] =>
[mimetype] => application/pdf
[size] => 785849
[created_on] => 2017-12-08 23:03:36
[rights] => Array
(
[0] => download
[1] => view
[2] => delete
[3] => update
)
PodioFile Object
(
[__attributes:PodioObject:private] => Array
(
[file_id] => 464716575
[link] => https://files.podio.com/464716575
[perma_link] =>
[thumbnail_link] =>
[hosted_by] => podio
[name] => IiaCfJjwws.PDF
[description] =>
[mimetype] => application/pdf
[size] => 785849
[created_on] => 2017-12-08 23:15:30
[rights] => Array
(
[0] => download
[1] => view
[2] => delete
[3] => update
)
PodioFile Object
(
[__attributes:PodioObject:private] => Array
(
[file_id] => 464728331
[link] => https://files.podio.com/464728331
[perma_link] =>
[thumbnail_link] =>
[hosted_by] => podio
[name] => g6cmAeUCiV.PDF
[description] =>
[mimetype] => application/pdf
[size] => 785849
[created_on] => 2017-12-08 23:49:15
[rights] => Array
(
[0] => download
[1] => view
[2] => delete
[3] => update
)
Luckily found the answer on sample provided here - https://hotexamples.com/examples/-/PodioItem/filter/php-podioitem-filter-method-examples.html
date_format($file->created_on, 'Y/m/d H:i:s') did the trick

Bigcommerce API PHP library will not create a customer with custom form_fields

I'm using the Bigcommerce php library to create customers through the API, which works fine, but I get {"status":400,"message":"The field 'name' is invalid."} back when I try adding the form_fields array of objects to the call. Is it possible to include these in a createCustomer call?
Here's basically what I'm trying to do:
$customer_object = array(
"email" => $email,
"first_name" => $first_name,
"last_name" => $last_name,
"_authentication" => array(
"password" => $password
)
);
$form_fields = array();
if(!empty($occupation)) {
$obj = (object) array("name" => "Occupation", "value" => $occupation);
array_push($form_fields, $obj);
}
$customer_object["form_fields"] = $form_fields;
$response = Bigcommerce::createCustomer(json_encode($customer_object));
Also, here's what a Bigcommerce customer record looks like:
Bigcommerce\Api\Resources\Customer Object
(
[ignoreOnCreate:protected] => Array
(
[0] => id
)
[ignoreOnUpdate:protected] => Array
(
[0] => id
)
[fields:protected] => stdClass Object
(
[id] => 34
[company] => Company Name
[first_name] => John
[last_name] => doe
[email] => email#example.com
[phone] => 123-456-7890
[date_created] => Tue, 19 Jul 2016 23:40:14 +0000
[date_modified] => Wed, 10 Aug 2016 17:39:28 +0000
[store_credit] => 0.0000
[registration_ip_address] =>
[customer_group_id] => 6
[notes] =>
[tax_exempt_category] =>
[reset_pass_on_login] =>
[accepts_marketing] =>
[addresses] => stdClass Object
(
[url] => https://example.com/api/v2/customers/34/addresses.json
[resource] => /customers/34/addresses
)
[form_fields] => Array
(
[0] => stdClass Object
(
[name] => Occupation
[value] => Developer
)
)
)
[id:protected] => 34
[ignoreIfZero:protected] => Array
(
)
[fieldMap:protected] => Array
(
)
)
Form_fields are currently GET only and they are only available in stores with a specific "store experiment" turned on. This has been omitted from our documentation, so we will work on updating that to provide better clarity.
You can email me at alyss#bigcommerce.com to have the GET supported enabled for your store.

Can't get recurrence API Google Calendar PHP

I am trying to get the recurrence of an event with the Google Calendar API in PHP, and it doesn't show me the recurrence.
The following code is the code I'm using:
$params = array(
'orderBy' => 'startTime',
'singleEvents' => true,
'timeMin' => date('c'),
);
$listarEventos = $service->events->listEvents($calendar_id, $params);
foreach ($listarEventos->getItems() as $i){
echo "<pre>";
echo $i->recurrence;
print_r($i);
echo "</pre>";
echo "<br>";
}
And I am obtaining this type of objects:
Google_Service_Calendar_Event Object
(
[collection_key:protected] => recurrence
[internal_gapi_mappings:protected] => Array
(
)
[anyoneCanAddSelf] =>
[attendeesType:protected] => Google_Service_Calendar_EventAttendee
[attendeesDataType:protected] => array
[attendeesOmitted] =>
[colorId] =>
[created] => 2015-06-01T07:34:46.000Z
[creatorType:protected] => Google_Service_Calendar_EventCreator
[creatorDataType:protected] =>
[description] =>
[endType:protected] => Google_Service_Calendar_EventDateTime
[endDataType:protected] =>
[endTimeUnspecified] =>
[etag] => "286628817348xxxx"
[extendedPropertiesType:protected] => Google_Service_Calendar_EventExtendedProperties
[extendedPropertiesDataType:protected] =>
[gadgetType:protected] => Google_Service_Calendar_EventGadget
[gadgetDataType:protected] =>
[guestsCanInviteOthers] =>
[guestsCanModify] =>
[guestsCanSeeOtherGuests] =>
[hangoutLink] =>
[htmlLink] => https://www.google.com/calendar/event?eid=czlqcW9uNmg1aGV0cTBwYXRrcnIxc2dqc3MgcHJ1ZWJhY2FsZW5kYXJpbxxxxxt
[iCalUID] => s9jqon6h5hetq0patkrr1sgjss#google.com
[id] => s9jqon6h5hetq0patkrr1sxxxxx
[kind] => calendar#event
[location] => Gra
[locked] =>
[organizerType:protected] => Google_Service_Calendar_EventOrganizer
[organizerDataType:protected] =>
[originalStartTimeType:protected] => Google_Service_Calendar_EventDateTime
[originalStartTimeDataType:protected] =>
[privateCopy] =>
[recurrence] =>
[recurringEventId] =>
[remindersType:protected] => Google_Service_Calendar_EventReminders
[remindersDataType:protected] =>
[sequence] => 0
[sourceType:protected] => Google_Service_Calendar_EventSource
[sourceDataType:protected] =>
[startType:protected] => Google_Service_Calendar_EventDateTime
[startDataType:protected] =>
[status] => confirmed
[summary] => Prueba recurrencia
[transparency] =>
[updated] => 2015-06-01T07:34:46.742Z
[visibility] =>
[modelData:protected] => Array
(
[creator] => Array
(
[email] => xxxx#gmail.com
[displayName] => Prueba Calendario
[self] => 1
)
[organizer] => Array
(
[email] => xxxxx#gmail.com
[displayName] => Prueba Calendario
[self] => 1
)
[start] => Array
(
[dateTime] => 2015-06-19T03:01:00+02:00
[timeZone] => Europe/Madrid
)
[end] => Array
(
[dateTime] => 2015-06-19T09:03:00+02:00
[timeZone] => Europe/Madrid
)
[reminders] => Array
(
[useDefault] => 1
)
)
[processed:protected] => Array
(
)
)
I have to say that I store the recurrence with the following code:
$event->setRecurrence(array('RRULE:FREQ='.$FREQ.';INTERVAL='.$INTERVAL));
And I have proved that the event is recurrent, so I donĀ“t know why I can't get the recurrence.
Thanks a lot!
You won't get recurrence if you're using 'singleEvents' => true.
Documentation (https://developers.google.com/google-apps/calendar/v3/reference/events/list) says:
singleEvents boolean Whether to expand recurring events into instances and only return single one-off events and instances of recurring events, but not the underlying recurring events themselves. Optional. The default is False.
I have solved the question. You won't get the recurrence if you doesn't get the event with something like this:
$event = $service->events->get('primary', "recurringEventId");
Once you have $event, you can use:
$preevent->recurrence[0]
Thanks to Xeron for the answer.

Extract data from Array/Object in PHP?

First off, I'm new to PHP and coding in general, so this might be quite an obvious answer.
I'm currently working with the Strava API, and I'm trying to extract data from an Array/Object which is the result of the following API call:
$recentactivities = $api->get('athlete/activities', array('per_page' => 100));
which returns:
Array (
[1] => stdClass Object (
[id] => XXXX
[resource_state] => 2
[external_id] => XXXX
[upload_id] => XXXX
[athlete] => stdClass Object (
[id] => XXXX
[resource_state] => 1
)
[name] => Let\'s see if I can remember how to do this cycling malarkey...
[distance] => 11858.3
[moving_time] => 1812
[elapsed_time] => 2220
[total_elevation_gain] => 44
[type] => Ride
[start_date] => 2014-07-12T13:48:17Z
[start_date_local] => 2014-07-12T14:48:17Z
[timezone] => (
GMT+00:00
) Europe/London
[start_latlng] => Array (
[0] => XXXX
[1] => XXXX
)
[end_latlng] => Array (
[0] => XXXX
[1] => -XXXX
)
[location_city] => XXXX
[location_state] => England
[location_country] => United Kingdom
[start_latitude] => XXXX
[start_longitude] => XXXXX
[achievement_count] => 4
[kudos_count] => 1
[comment_count] => 0
[athlete_count] => 1
[photo_count] => 0
[map] => stdClass Object (
[id] => a164894160
[summary_polyline] => XXXX
[resource_state] => 2
)
[trainer] =>
[commute] =>
[manual] =>
[private] =>
[flagged] =>
[gear_id] => b739244
[average_speed] => 6.544
[max_speed] => 10.8
[average_cadence] => 55.2
[average_temp] => 29
[average_watts] => 99.3
[kilojoules] => 179.9
[device_watts] =>
[average_heartrate] => 191.2
[max_heartrate] => 200
[truncated] =>
[has_kudoed] =>
)
This repeats for the most recent activities.
I'm attempting to extract average_heartrate, which I can do for a single object using the following:
$recentactivities[1]->average_heartrate;
but I'd like to extract all instances of average_heartrate from the Array. I've tried to use a foreach statement, but to be honest, I have no idea where to start.
Any help would be much appreciated.
It's actually pretty simple you can indeed use a foreach loop:
foreach($myArray as $obj){
//$obj is an object so:
if(isset($obj->average_heartrate)){
echo $obj->average_heartrate;
}
}
With this code you iterate through your array with objects and save the wanted array within an array so you can work further with it.
$heartrateArray = array(); // create a new array
//iterate through it with an foreach
foreach($recentactivities as $activity){
// save the average_heartrate as a value under a new key in the array
$heartrateArray[] = $activity->average_heartrate;
}

Categories