PayPal API - Initiate Monthly Bill? - paypal

If I have an "Automatic Billing" button setup on my site, which API can be used to set the variable billing amount and initiate the bill? Want I the API to do is described here: https://developer.paypal.com/docs/classic/paypal-payments-standard/integration-guide/manage-billing-plans/
I can't find this specifically anywhere but I'm not sure if it's lost in the different terminology between the PayPal API docs and the front-end - I say that because it's seems there is no such thing as Automated Billing in the API docs!

If you're wanting to use the REST API then look at Billing Plans.
If you want to use the Classic API look at Recurring Paymments.

To further the accepted answer, I could not achieve what I wanted - it seems that "Automatic Billing" cannot be triggered via an API. You need to create a billing plan, then create an agreement based on the plan, then execute the agreement.
From Andrew's answer, first I got an access token. In my cURLless environment, I did this:
//sandbox
$clientid = "AbFnq7P52jf6AUWpu.....";
$secret = "ECfJRJBDnA26VVNAq.....";
$url = 'https://api.sandbox.paypal.com/v1/oauth2/token';
$auth = base64_encode($clientid . ":" . $secret);
$data = array(
'grant_type' => 'client_credentials'
);
$options = array(
'http' => array(
'header' => "Authorization: Basic {$auth}\r\nAccept: application/json\r\nAccept-Language: en_US\r\n",
'method' => 'POST',
'content' => http_build_query($data)
)
);
$context = stream_context_create($options);
$result = file_get_contents($url, false, $context);
$arr = json_decode($result, true);
echo "<pre>"; print_r($arr); echo "</pre>";
$accesstoken = $arr['access_token'];
Then followed the "Integration Steps" https://developer.paypal.com/docs/integration/direct/billing-plans-and-agreements/#integration-steps
I made my cURLless API calls like this (create plan example):
$url = 'https://api.sandbox.paypal.com/v1/payments/billing-plans/';
$options = array(
'http' => array(
'header' => "Authorization: Bearer {$accesstoken}\r\nContent-Type: application/json\r\n",
'method' => 'POST',
'content' => '{
"name": "Test Plan",
"description": "My first test plan",
"type": "INFINITE",
"payment_definitions": [
{
"name": "Regular payment definition",
"type": "REGULAR",
"type":"REGULAR",
"frequency":"Month",
"amount":{
"currency":"AUD",
"value":"100.00"
},
"cycles":"0",
"charge_models":[
{
"type":"TAX",
"amount":{
"currency":"AUD",
"value":"0.00"
}
},
{
"type":"SHIPPING",
"amount":{
"currency":"AUD",
"value":"0.00"
}
}
],
"frequency_interval":"1"
}
],
"merchant_preferences": {
"setup_fee": {
"value": "0",
"currency": "AUD"
},
"return_url": "http://www.paypal.com",
"cancel_url": "http://www.paypal.com/cancel",
"auto_bill_amount": "YES",
"initial_fail_amount_action": "CONTINUE",
"max_fail_attempts": "0"
}
}'
)
);
$context = stream_context_create($options);
$result = file_get_contents($url, false, $context);
$arr = json_decode($result, true);
echo "<pre>"; print_r($arr); echo "</pre>";
Hopefully these snippets will save someone the hours I spent!

Related

Adding solines to acumatica using rest Api

Am trying to create a sales order in acumatica using rest API with more than one soline but am able to create only one soline, below see my code
I would like to create one sales order with all cart items as solines for that particular sales order in acumatica.
if (isset($_SESSION['cart'])) {
foreach($_SESSION['cart'] as $row) {
if ($row['qty'] != 0) {
$product = $row['product'];
echo $product.
"<br>";
curl_setopt_array($curl, array(
CURLOPT_URL => "https://xxxxxxx.com/myinstance/entity/PLUS/17.200.001/SalesOrder",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_COOKIESESSION => 1,
CURLOPT_COOKIEFILE => $temp_data,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "PUT",
CURLOPT_POSTFIELDS => "{\r\n \"OrderType\" : {value : \"SO\" } ,\r\n \"CustomerID\" : {value : \"C000000002\" },\r\n \"webItems\" : {value : \"$product\" },\r\n\"webQty\" : {value : \"1\" },\r\n\"WebTaxCat\" : {value : \"TAXABLE\" },\r\n}",
CURLOPT_HTTPHEADER => array("cache-control: no-cache", "content-type: application/json", "postman-token: 5248821b-91e9-5800-bd9c-b4c9775c6c5a"),
));
$response = curl_exec($curl);
$err = curl_error($curl);
if ($err) {
echo "cURL Error #:".$err;
} else {
echo $response;
}
}
}
}
Looking at your code you seems to have created your own endpoint or extended the default endpoint.
Though looking at the structure of the body that you are passing through the detail information seems to be on the same level as the top level entity.
If you created your own endpoint from scratch, I would recommend that you take a look at the Sales Order entity from default endpoint and its Details sub entity.
As normally, you should have a details object inside of the Sales Order node that can contain an array of details information.
If I was using the default endpoint I could pass the following JSON body to the address :
localhost/191u03/entity/Default/18.200.001/SalesOrder
{
"CustomerID": {"value": "ABARTENDE"},
"Details":
[
{
"InventoryID": {"value": "AACOMPUT01"},
"OrderQty": {"value": 5}
},
{
"InventoryID": {"value": "AALEGO500"},
"OrderQty": {"value": 50}
}
]
}
This will create a Sales Order with 2 So Lines.
Though if you want to add more line to an existing order then you should only need to mention the key fields of the top level entity and then the details information that you would want to add.
In the case of the Sales Order, the key fields are the OrderType and the OrderNbr.
If you have the time, I would recommend that you take a look at the Acumatica help website section about working with the contract based API: https://help-2019r1.acumatica.com/(W(5))/Help?ScreenId=ShowWiki&pageid=1c767ad9-da6d-4047-bc93-6970ad469504

What is this? (Facebook Offline Conversions API) Error #21009 - The data set upload is temporarily not ready

We have been uploading to Facebook's Offline Conversion API for the past 3 weeks with no issues. Suddenly, Facebook is returning this error:
(#21009) The data set upload is temporarily not ready.
See below code for full JSON payload.
Our Auth Token is still valid. (e.g. Not expired, still valid)
According to this tool: https://developers.facebook.com/tools/debug/accesstoken/
# I had to remove these fields for privacy reasons
define('FACEBOOK_APP_ACCESS_TOKEN', 'YOUR TOKEN HERE');
define('FACEBOOK_PIXEL_OFFLINE_EVENT_SET_ID', 'YOUR PIXEL ID HERE');
# Be sure to change the email/name fields accordingly
$event_name='test-upload';
$data = array();
$data["match_keys"] = array();
$data["match_keys"]['email'] = hash('sha256', 'bob.ross#example.com');
$data["match_keys"]['fn'] = hash('sha256', 'bob');
$data["match_keys"]['ln'] = hash('sha256', 'ross');
$data["match_keys"]['gen'] = hash('sha256', 'm');
$data["event_time"] = time();
$data["event_name"] = $event_name;
$data["currency"] = "USD";
$data["value"] = '0.00';
// Turn Data to JSON
$data_json = json_encode(array($data));
// Fill available fields
$fields = array();
$fields['access_token'] = FACEBOOK_APP_ACCESS_TOKEN;
$fields['upload_tag'] = $event_name . '-' . time(); // You should set a tag here (feel free to adjust)
$fields['data'] = $data_json;
$url = 'https://graph.facebook.com/v3.2/' . FACEBOOK_PIXEL_OFFLINE_EVENT_SET_ID . '/events';
$curl = curl_init($url);
curl_setopt_array($curl, array(
// Replace with your offline_event_set_id
CURLOPT_URL => 'https://graph.facebook.com/v3.2/' . FACEBOOK_PIXEL_OFFLINE_EVENT_SET_ID . '/events',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => http_build_query($fields),
CURLOPT_HTTPHEADER => array(
"cache-control: no-cache",
//"content-type: multipart/form-data",
"Accept: application/json" ),
));
$response = curl_exec($curl);
curl_close($curl);
echo $response;
Expected result from Facebook:
{"id":"36485444079550","num_processed_entries":1}
Actual result from Facebook
{
"error": {
"message": "(#21009) The data set upload is temporarily not ready.",
"type": "OAuthException",
"code": 21009,
"fbtrace_id": "GeofD5QsXdI"
}
}
I would add a comment instead of an "answer" but I don't quite have the points yet. The commenters on the Facebook thread (https://developers.facebook.com/support/bugs/1052442614962359/) have had this magically resolve overnight, and I experienced the same (problem happening and no explanation, then magical resolution and no explanation). It seems like Facebook may have fixed whatever was causing the issue.

Trying to get latest page status via Facebook PHP SDK with a cron

I'm trying to pull the latest status from a Facebook page with the PHP SDK then insert it as a post into my website via a cron job, but seem to be stuck on the access token part. Here's what I have so far:
require 'facebook-php-sdk-master/src/facebook.php';
require 'wp-load.php';
// I replaced these obviously
$facebook = new Facebook(array(
'appId' => FB_APP_ID,
'secret' => FB_SECRET,
));
try {
$feed = $facebook->api('/322522705880/feed?limit=1');
} catch (FacebookApiException $e) {
error_log($e);
}
Then I use $feed['data'][0]['description'] etc to create the post with. However, the only time I can get $feed to have any data is when I reinstall a Facebook Wordpress plugin that must activate an access token some how because it will then work for a few hours, and then stop. I can't find any info anywhere at all on how I would generate one of my own from a script, https://developers.facebook.com/docs/reference/php/facebook-getAccessToken/ doesn't really provide any helpful info. If anyone can point me in the right direction, that would be great. The wordpress plugin is doing this somehow, I just need to know how to replicate it.
I did some poking around in the plugin and found this
$token = false;
if (!$token) {
// Get temporary token
$token = $this->model->fb->getAccessToken();
if (!$token) return false;
// Exchange it for the actual long-term token
$url = "https://graph.facebook.com/oauth/access_token?client_id={$app_id}&client_secret={$app_secret}&grant_type=fb_exchange_token&fb_exchange_token={$token}";
$page = wp_remote_get($url, array(
'method' => 'GET',
'timeout' => '5',
'redirection' => '5',
'user-agent' => 'wdfb',
'blocking' => true,
'compress' => false,
'decompress' => true,
'sslverify' => false
));
if(is_wp_error($page)) return false; // Request fail
if ((int)$page['response']['code'] != 200) return false; // Request fail
parse_str($page['body'], $response);
$token = isset($response['access_token']) ? $response['access_token'] : false;
if (!$token) return false;
}
But that gives me "No user access token specified" and I'm not sure how to use or get a user access token for that?
All you need to have for this is an application token. You can "build" an app access token using your app_id and app_secret:
access_token=APP_ID|APP_SECRET
That's a pipe character | between the two values.
Once you have this, you can just make a request to an endpoint like this:
https://graph.facebook.com/cocacola/feed?limit=1&access_token=APP_ID|APP_SECRET
The response will be something like this:
{
"data": [
{
"id": "40796308305_10152854866613306",
"from": {
"name": "Verone Diedericks",
"id": "100003842548992"
},
"to": {
"data": [
{
"category": "Food/beverages",
"name": "Coca-Cola",
"id": "40796308305"
}
]
},
"message": "Vony nd kimo or just vony",
"privacy": {
"value": ""
},
"type": "status",
"created_time": "2013-11-26T20:13:11+0000",
"updated_time": "2013-11-26T20:13:11+0000"
}
],
"paging": {
"previous": "https://graph.facebook.com/40796308305/feed?limit=1&access_token=163586277060593|Rtsz7h6IiHu7Uva9D5S4VW0FKu8&since=1385496791&__previous=1",
"next": "https://graph.facebook.com/40796308305/feed?limit=1&access_token=163586277060593|Rtsz7h6IiHu7Uva9D5S4VW0FKu8&until=1385496790"
}
}

Unexpected error when tyring to get the payment transactions of a user

I always get an error when tyring to get the payment transactions of a user.
{
"error": {
"message": "An unexpected error has occurred. Please retry your request later.",
"type": "OAuthException",
"code": 2
}
}
I tried several approaches:
// approach 1
$response = $app['facebook']->api('/'.$app['user']['fbUserID'].'/payment_transactions', 'GET', [
//'request_id' => $order['requestID'],
'access_token' => $app['fb.app_id'].'|'.$app['fb.app_secret']
]);
// approach 2
$url = 'https://graph.facebook.com/'.$app['user']['fbUserID'].'/payment_transactions?fields=id&access_token='.$app['fb.app_id'].'|'.$app['fb.app_secret'];
$ch = curl_init();
$options = [
CURLOPT_URL => $url,
CURLOPT_RETURNTRANSFER => 1,
CURLOPT_CONNECTTIMEOUT => 10,
CURLOPT_TIMEOUT => 60,
CURLOPT_HTTPHEADER => array('Expect:'),
CURLOPT_CAINFO => DIR.'/vendor/facebook/php-sdk/src/fb_ca_chain_bundle.crt'
];
curl_setopt_array($ch, $options);
$result = curl_exec($ch);
curl_close($ch);
// approach 3
// like 2 but with a fresh access token
$appAccessToken = explode('=', file_get_contents('https://graph.facebook.com/oauth/access_token?client_id='.$app['fb.app_id'].'&client_secret='.$app['fb.app_secret'].'&grant_type=client_credentials'))[1];
Even in the Graph API Explorer I get this error. Only if I use the commandline it works:
$ curl 'https://graph.facebook.com/........./payment_transactions?access_token=.......|.........'
The user is an test user which is also a payment tester and made successfull test-purchases. The Local Currency Payments Breaking Changes are disabled.
What am I doing wrong?
You need to use an app access token to GET from that endpoint. See https://developers.facebook.com/docs/graph-api/reference/user#payment_transactions for details.

Register Achievement ok, Create Achievement Returns false

I've just started implementing FB Achievements for my Game. I'm using the PHP SDK for my app.
I've successfully registered an Achievement using the following code from my class which subclasses the PHP SDK class:
$URL = 'apps.facebook.com/<app_name>/ach1.html';
$AppID = $this->getAppId();
$Params = array('achievement' => $URL);
$res = $this->api($AppID.'/achievements', 'POST', $Params);
I can confirm this has been created via the Graph API Explorer:
{
"data": [
{
"url": "http://apps.facebook.com/<app_name>/ach1.html",
"type": "game.achievement",
"title": "Tutorial",
"image": [
{
"url": "<app_img_url>/1-ach.jpg"
}
],
"description": "Tutorial Completed",
"site_name": "<app_name>",
"data": {
"points": 1
},
"updated_time": "2012-07-13T16:05:44+0000",
"id": "<id>",
"application": {
"id": "<app_id>",
"name": "<app_name>",
"url": "https://www.facebook.com/apps/application.php?id=<app_id>"
},
"context": {
"display_order": 0
}
}
]
}
However when I try to create an achievement for myself it returns false:
$URL = 'apps.facebook.com/<app_name>/ach1.html';
$UserID = 100000466230867;
$AccessToken = $this->getApplicationAccessToken();
$Params = array('access_token' => $AccessToken,
'method' => 'post',
'achievement' => $URL);
$res = $this->api($UserID.'/achievements', 'POST', $Params);
The result is "boolean false". No error code is returned. Am I doing something obviously or fundamentally wrong here? I've tried providing a 'display_order' of value 1 and 0 aswell.
I can confirm I've granted the publish_actions permission aswell.
permissions:Array ( [data] => Array ( [0] => Array ( [installed] => 1 [email] => 1 [publish_actions] => 1 [bookmarked] => 1 ) ) )
My app is correctly configured as a game aswell.
Any help greatly appreciated!!
Cheers
If the app is in sandbox mode, take it out.
Ensure the user has authorised & hasn't removed the app
'false' usually means 'Person or page whose access token you're using can't see the data you're asking for',
This happens most often for blocked users, apps in sandbox mode, deleted content, etc
In this case, i suspect the app can't see / interact with the user (if this a test user created via the app settings interface or API this is especially likely as test users have some strange privacy quirks)