PHP Xero API is creating duplicate overpayment entries (BankTransaction) - php

We are creating overpayments via the PHP Xero API.
In some cases, the overpayments are being duplicated.
Here is the code we are using:
<?php
$endpoint = 'https://api.xero.com/api.xro/2.0/BankTransactions';
$headers = array(
"Content-Type: application/json",
"Xero-tenant-id: " . $xero_access['tenant_id'],
"Authorization: Bearer " . $xero_access['token'],
);
$postFields = array(
"Type" => "RECEIVE-OVERPAYMENT",
'Contact' => ['ContactID' => $contactID],
'BankAccount' => ['accountID' => $xero_settings['account_id']],
'LineAmountTypes' => 'NoTax',
'LineItems' => [0 => [
'Description' => 'Customer Credit',
'LineAmount' => $price
]]
);
try {
$ch = #curl_init();
#curl_setopt($ch, CURLOPT_URL, $endpoint);
#curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
#curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
#curl_setopt($ch, CURLOPT_POST, 1);
#curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($postFields, JSON_PRETTY_PRINT));
$response = #curl_exec($ch);
$status_code = #curl_getinfo($ch, CURLINFO_HTTP_CODE);
error_log($status_code);
error_log($response);
} finally {
#curl_close($ch);
}
?>
I am not quite sure why the transactions are being duplicated or even if it is a network issue, or something in the code above.
Is there a way to make these API calls unique and make sure a request is not sent twice?
Thanks

Could you raise a case with Xero Support and include:
Your client id, the name of the connect tenant, the date and time of a call with duplication (and your timezone), the details of the overpayment eg the contact name, date and amount

Related

Separate Notifications do not appear on a same device subscribed to a topic

when i push multiple notifications in a loop via api subscribed to topic using FCM, the previous notification replaced by new notification on my android device. Is there a way to push multiple notifications separately. I am using PHP Curl request.
foreach ($result as $item)
{
$message = array
(
'body' => "Details:".$item['tagid'],
'title' => "Tag:".$item['event'],
'key1' => "NotificationActivity"
);
$fields = array(
'to' => '/topics/all',
'data' => array
(
'message' => $message
),
);
$headers = array
(
'Authorization: key=' . API_ACCESS_KEY,
'Content-Type: application/json'
);
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'https://fcm.googleapis.com/fcm/send');
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($fields));
$result = curl_exec($ch);
curl_close($ch);
}
There was problem on my Firebase service. Not identifying notification on id basis.
Problem was, I was passing 0 in id field.
notificationManager.notify(0 /* ID of notification */, notificationBuilder.build());
After setting unique id of each notification, it's working:
notificationManager.notify(id /* ID of notification */, notificationBuilder.build());

I need help creating an endpoint that can receive json data

I have created a php file that sends json data to an external url. Their API requires that I have a page on my website that receives the json responses for processing. The one that sends json data works well. I need help with the second php page that should process it
$Url="http://example.com/submit.php";
$date = date_create();
$UserID=7;
$Password='';//<-password written here
$Timestamp=date_timestamp_get($date);
$token=$UserID.$Password.$Timestamp;
$data_string = array();
$data_string = array(
"AuthDetails" => array(
array(
"UserID" => $UserID,
"Token" => md5($token),
"Timestamp"=>$Timestamp
)
),
"MessageType"=> array(
"3"
),
"BatchType"=>array(
"0"
),
"SourceAddr"=>array(
"Example"
),
"MessagePayload"=> array(
array(
"Text" => "Sample text message by Example :)"
)
),
"DestinationAddr" => array(
array(
'MSISDN'=>'254701000000',
'LinkID'=>''
)
),
"DeliveryRequest" => array(
array(
'EndPoint'=>'',//<-URL that receives the response
'Correlator'=>md5(uniqid())
)
)
);
$data_string=json_encode($data_string);
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $Url);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "POST");
curl_setopt($ch, CURLOPT_POSTFIELDS, $data_string);
curl_setopt($ch, CURLOPT_HTTPHEADER, array(
'Content-Type: application/json',
'Content-Length: ' . strlen($data_string),
)
);
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_TIMEOUT, 20);
$output = curl_exec($ch);
if(curl_errno($ch)){
echo 'Request Error:' . curl_error($ch);
}
curl_close($ch);
return $output;
Ok this is going to be a bit generic but it should put you on the right path.
So you have to write a script that will process the response from them i.e. your end-point for this circle of events.
So lets call it my-enpoint.php
So in the message you send to them you put the address of this new script into this parameter
"DeliveryRequest" => array(
array(
'EndPoint'=>'http://www.example.com/my-endpoint.php',
'Correlator'=>md5(uniqid())
Now your script my-endpoint.php I am assuming they have said how they will return their reply, probably as POST variable. You process their reply basically like you would a submitted form from your own site.
So for example if their reply is POSTed
<?php
// initial testing to see what comes back from them
// as this wont be associated with a browser
// dump their reply to a file so you can see whats there
file_put_contents('reply.txt', print_r($_POST, true), FILE_APPEND);
?>
With the info you have provided this is about a much as I can do.

How to access Atlassian using PHP

I want to fetch content from my Atlassian with username and password.
The URL typically looks like:
http://my-own-site.atlassian.net/wiki/pages/viewpage.action?spaceKey=TO&title=Any-Wiki-Title
Is it possible to use PHP CURL to fetch content from this page?
So far I am only getting 401 auth reqd error.
I have looked through Stackoverflow and all I am getting is how to access basic atlassian.com and bitbucket.org pages.
With this code in php, you can create Confluence Pages:
<?php
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, "http://localhost:8090/rest/api/content/");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, "{\"type\":\"page\",\"title\":\"**inserttitle**\",\"space\":{\"key\":\"**insertspace**\"},\"ancestors\":[{\"type\":\"page\",\"id\":**insertancestor**}],\"body\":{\"storage\":{\"value\":\"<p>This is a new page</p>\",\"representation\":\"storage\"}}}");
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_USERPWD, "**insertusername**" . ":" . "**insertpassword**");
$headers = array();
$headers[] = "Content-Type: application/json";
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
$result = curl_exec($ch);
if (curl_errno($ch)) {
echo 'Error:' . curl_error($ch);
}
curl_close ($ch);
?>
And with this code, you can get content from Confluence:
<?php
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, "http://localhost:8090/rest/api/content/**insertid**");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "GET");
curl_setopt($ch, CURLOPT_USERPWD, "**insertusername**" . ":" . "**insertpassword**");
$headers = array();
$headers[] = "Content-Type: application/json";
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
$result = curl_exec($ch);
if (curl_errno($ch)) {
echo 'Error:' . curl_error($ch);
}
curl_close ($ch);
?>
echo $result;
Modify the parameter. I marked the words with insert*
Yes, it is certainly possible to access Atlassian products using PHP and cURL. I do it all the time to create/modify Jira issues
You will have to find/write a library (or set of libraries) which will allow you to access REST API calls. In my case, I wrote a base REST library which can then be inherited to create Jira, Confluence, any other REST service libraries
Search the Atlassian documentation site to find the REST API for the product you're using (Confluence in your case I would guess)
Don't forget that the REST API uses GET, POST, PUT and DELETE methods so your library will need to handle all of these
With regards to your error, I *think* your login will need to be allowed access to the API calls
To retrieve any existing content properties for a piece of content, use url as https://your-domain.atlassian.net/wiki/rest/api/content/{content_ID}
$curl = curl_init();
$post = array(
"id" => "{content_ID}",
"type" => "{content_ID}", //Ex. page
"title" => "{content_Title}",
"space" => ["key" => "{spaces_key}"],
"body" => ["storage" => ["value" => "<p>Here comes the other text</p>", "representation" => "storage"]],
"version" => ["number" => 15]
);
curl_setopt_array($curl, array(
CURLOPT_URL => "https://your-domain.atlassian.net/wiki/rest/api/content/{content_ID}?expand=metadata.properties.myprop,space,body.view,version,container",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 300,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "GET",
CURLOPT_POSTFIELDS => json_encode($post),
CURLOPT_HTTPHEADER => array(
"authorization: Basic {base64 of (username:password)}",
"content-type: application/json",
'Accept: application/json'
),
));
$result = curl_exec($curl);
curl_close($curl);

Php curl json post returns error

I am trying a little script to create and update domain names using Digital Ocean api v2 here - https://developers.digitalocean.com/documentation/v2/#update-a-domain-record
For some reason the response from the server is that I am missing record type.
Here is my code:
$headers = array(
'Content-Type:application/json',
'Authorization: Bearer ' . file_get_contents('token.txt') );
$rawdata = array(
'type' => 'A',
'name' => 'sub',
'data' => '162.10.66.0',
'priority' => null,
'port' => null,
'weight' => null
);
$postdata = json_encode($rawdata);
$ch = curl_init(); // initiate curl
$url = "https://api.digitalocean.com/v2/domains/mydomain.org/records";
curl_setopt($ch, CURLOPTURL,$url);
curl_setopt($ch, CURLOPTPOST, true);
curl_setopt($ch, CURLOPTPOSTFIELDS, $postdata);
curl_setopt($ch, CURLOPTRETURNTRANSFER, true);
curl_setopt($ch, CURLOPTHTTPHEADER, $headers);
$output = curlexec ($ch); // execute
curl_close ($ch); // close curl handle
vardump($output); // show output
This is the error
string(81) "{"id":"unprocessable_entity","message":"Record type is not included in the list"}"
What am I missing here?
It's not a PHP error, it's an error return by the webservice you're calling. Check their documentation to see if you're sending the right stuff to them.

MailChimp API: Batch Check Subscription Status

What's the best way to check a batch of email addresses and whether or not they are subscribed to a particular list? My current method is making an API call for each email address, but this becomes very slow when the count becomes > 50.
I'm using V2.0, using PHP methods since I'm developing on CakePHP.
//Determine MailChimp Subscription
$args = array(
'id' => $this->apiKeys['mailchimp_list_ID'],
'emails' => array(1 => array('email' => $customer['User']['username']))
);
$mailChimpQuery = $this->mailChimp('member-info', $args);
$mailChimpStatus = ($mailChimpQuery['success_count'] == 1 ? 1 : 0);
$customer['Customer']['subscribed'] = $mailChimpStatus;
The mailChimp call in another Controller is:
public function mailChimp($action, $args=array()) {
$args['apikey'] = $this->apiKeys['mailchimp_api'];
$url = 'https://us8.api.mailchimp.com/2.0/lists/' . $action .'.json';
if (function_exists('curl_init') && function_exists('curl_setopt')){
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-Type: application/json'));
curl_setopt($ch, CURLOPT_USERAGENT, 'PHP-MCAPI/2.0');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_TIMEOUT, 10);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($args));
$result = curl_exec($ch);
curl_close($ch);
} else {
$json_data = json_encode($args);
$result = file_get_contents($url, null, stream_context_create(array(
'http' => array(
'protocol_version' => 1.1,
'user_agent' => 'PHP-MCAPI/2.0',
'method' => 'POST',
'header' => "Content-type: application/json\r\n".
"Connection: close\r\n" .
"Content-length: " . strlen($json_data) . "\r\n",
'content' => $json_data,
),
)));
}
return $result ? json_decode($result, true) : false;
}
FYI, I came up with my own solution:
Create an array of all the email addresses in the database
Create a for-loop that takes segments of 50 email addresses from that array and runs a batch check using member-info (https://apidocs.mailchimp.com/api/2.0/lists/member-info.php)
Manipulate the return array from the API call to extract only the email address and whether or not it's subscribed to the list.
Within the for-loop, add each 50 email addresses return values into a new array and then by the end of it; you'll have an array of all the email addresses in your database with a corresponding true/false value depending on whether or not they are subscribed to the list.
Good luck!

Categories