i'm sending notification to who visited my website and accepted for sending desktop notifications to them. I'm taking theirs registration id and making request to gcm api.
BUT
I can not send Notificaiton title,message and icon.
Here is my PHP class taked from GCM with PHP (Google Cloud Messaging)
class GCMPushMessage {
var $url = 'https://android.googleapis.com/gcm/send';
var $serverApiKey = "";
var $devices = array();
/*
Constructor
#param $apiKeyIn the server API key
*/
function GCMPushMessage($apiKeyIn){
$this->serverApiKey = $apiKeyIn;
}
/*
Set the devices to send to
#param $deviceIds array of device tokens to send to
*/
function setDevices($deviceIds){
if(is_array($deviceIds)){
$this->devices = $deviceIds;
} else {
$this->devices = array($deviceIds);
}
}
/*
Send the message to the device
#param $message The message to send
#param $data Array of data to accompany the message
*/
function send($message, $data = false){
if(!is_array($this->devices) || count($this->devices) == 0){
$this->error("No devices set");
}
if(strlen($this->serverApiKey) < 8){
$this->error("Server API Key not set");
}
$fields = array(
'registration_ids' => $this->devices,
'notification' => array( "message" => $message ),
);
if(is_array($data)){
foreach ($data as $key => $value) {
$fields['data'][$key] = $value;
}
}
$headers = array(
'Authorization: key=' . $this->serverApiKey,
'Content-Type: application/json'
);
// Open connection
$ch = curl_init();
// Set the url, number of POST vars, POST data
curl_setopt( $ch, CURLOPT_URL, $this->url );
curl_setopt( $ch, CURLOPT_POST, true );
curl_setopt( $ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt( $ch, CURLOPT_RETURNTRANSFER, true );
curl_setopt( $ch, CURLOPT_POSTFIELDS, json_encode( $fields ) );
// Avoids problem with https certificate
curl_setopt( $ch, CURLOPT_SSL_VERIFYHOST, false);
curl_setopt( $ch, CURLOPT_SSL_VERIFYPEER, false);
// Execute post
$result = curl_exec($ch);
// Close connection
curl_close($ch);
return $result;
}
function error($msg){
echo "Android send notification failed with error:";
echo "\t" . $msg;
exit(1);
}
}
Here is my notification.php file
$apiKey = "MY_API_KEY";
$devices = array('eBLwIaqdgOs:APA91bG-6Ry1gN1wg2jI3WOpgpQg2bxE1NxgJCBXxzE188GF46JuPO1DkWw-OiKswRr2y0K6xX8k4RKGOHqnub0zgoqgX22I1TDxOAWHrNoTn9XoRMWywARrWAq1zD78fAz3H9VcnqSW');
$message = "The message to send";
$gcpm = new GCMPushMessage($apiKey);
$gcpm->setDevices($devices);
$response = $gcpm->send($message, array('title' => 'Test title'));
echo $response;
And here is my sw.js file (service worker)
'use strict';
console.log('Started', self);
self.addEventListener('install', function(event) {
self.skipWaiting();
console.log('Installed', event);
});
self.addEventListener('activate', function(event) {
console.log('Activated', event);
});
// TODO
function showNotification(title, body, icon, data) {
console.log('showNotification');
var notificationOptions = {
body: body,
icon: icon ? icon : '/images/touch/chrome-touch-icon-192x192.png',
tag: 'simple-push-demo-notification',
data: data
};
return self.registration.showNotification(title, notificationOptions);
}
self.addEventListener('push', function(event) {
console.log('Received a push message', event);
if (event.data) {
console.log('message data', event.data);
console.log('message data', event.data.text);
var output = event.data.text();
console.log(output);
}
showNotification("My Title","My Message");
});
When i requsted to my notification.php file a notification appears to me or which registration id i wrote with the title My Title and message My Message
As you can see thesee datas are coming from sw.js but i wont to send them via php because they are dynamic variables i'll get them from user input.
Help me with that please. Thank you.
Related
I'm sending a request to an API that sends back a response to a page/url (response.php). Details from this response are stored in a db table as well as the page's session id. Obtaining the data stored in the db with the session id as the reference value returns null because I noticed the session id sent to the db alongside the response body changes each time making it different to session ids from all other pages in the folder (processor.php, app.js, fromdb.php) which are similar each other. How do I handle the issue seeing as I need the device from which the button that initiated the process got clicked to be able to receive an alert with some details based on data saved to db, on whether their payment was successful or not.
The js page that initiates action when a button is clicked:
if (document.readyState == 'loading') {
document.addEventListener('DOMContentLoaded',ready);
}else{
ready()
}
function ready() {
var btn = document.getElementById('sub')
btn.addEventListener('click',btnClicked)
console.log("ready")
}
function btnClicked() {
let amount = document.getElementById('Amt').value;
let phone = document.getElementById('Number').value;
let name = document.getElementById('Name').value;
//using ajax post data
$.ajax({
url: "http://localhost/textEditor/processor.php",
method: "POST",
data: {
amount: amount,
phone: phone,
name: name
},
});
getResult();
}
async function getResult() {
//using ajx Get method to obtain data from db echoed on fromdb.php page
return await setTimeout($.ajax({
url: "http://localhost/textEditor/fromdb.php",
method: "GET",
success: function(data) {
console.log("The data is:", data)
}
}), 5000)
}
Below is page that makes request to the API and provides callbackurl on which response is sent:
<!-- processor.php -->
<?php
session_start();
$sess_id = session_id();
include_once "db.te.php";
// if (isset($_POST['submit'])) {
date_default_timezone_set('Africa/Nairobi');
$Passkey = 'bfb279f9aa9bdbcf158e97dd71a467cd2e0c893059b10f78e6b72ada1ed2c919';
$Amount= $_POST['amount'];
$BusinessShortCode = '174379';
$PartyA =$_POST['phone'];
$AccountReference =$_POST['name'];
$TransactionDesc = 'test';
$Timestamp =date('YmdHis');
$Password = base64_encode($BusinessShortCode.$Passkey.$Timestamp);
$headers=['Content-Type:application/json; charset=utf8'];
$initiate_url='https://sandbox.safaricom.co.ke/mpesa/stkpush/v1/processrequest';
$callBackURL ='https://c28d-197-231-178-65.ngrok.io/textEditor/response.php';
// ------------------------------
function newAccessToken() {
$ConsumerKey = 'uhsjjsjbVGatHuJKK';
$ConsumerSecret = 'Yh29KHAY17LKjahh';
$credentials = base64_encode($ConsumerKey.":".$ConsumerSecret);
$url = "https://sandbox.safaricom.co.ke/oauth/v1/generate?grant_type=client_credentials";
$curl = curl_init();
curl_setopt($curl, CURLOPT_URL, $url);
curl_setopt($curl, CURLOPT_HTTPHEADER, array("Authorization: Basic ".$credentials,"Content-Type:application/json"));
curl_setopt($curl, CURLOPT_HEADER, false);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
$curl_response = curl_exec($curl);
$access_token=json_decode($curl_response);
curl_close($curl);
return $access_token->access_token;
}
$curl = curl_init();
curl_setopt($curl, CURLOPT_URL, $initiate_url);
curl_setopt($curl, CURLOPT_HTTPHEADER, array('Content-Type:application/json','Authorization:Bearer '.newAccessToken()));
$curl_post_data = array(
'BusinessShortCode' =>$BusinessShortCode,
'Password' => $Password,
'Timestamp' => $Timestamp,
'TransactionType' => 'CustomerPayBillOnline',
'Amount' => $Amount,
'PartyA' => $PartyA,
'PartyB' => $BusinessShortCode,
'PhoneNumber' => $PartyA,
'CallBackURL' => $callBackURL,
'AccountReference' => $AccountReference,
'TransactionDesc' => $TransactionDesc
);
$data_string = json_encode($curl_post_data);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
curl_setopt($curl, CURLOPT_POST, true);
curl_setopt($curl, CURLOPT_POSTFIELDS, $data_string);
$curl_response = curl_exec($curl);
curl_close($curl);
// }
The callbackurl page where response is sent and inserted into db:
<!-- callbackurl: response.php, page where response body is sent to the db alongside its session id-->
<?php
include_once "db.te.php";
session_start();
$sess_id = session_id();
$homepage = file_get_contents('php://input');
$nowNow = json_decode($homepage);
if ($nowNow->Body->stkCallback->ResultCode==0) {
$Items = $nowNow->Body->stkCallback->CallbackMetadata->Item;
foreach($Items as $Item) {
if ($Item->Name =='MpesaReceiptNumber') {
$MpesaReceiptNumber = $Item->Value;
}
}
}else{
$ResultCode = $nowNow->Body->stkCallback->ResultCode;
$MerchantRequestID = $nowNow->Body->stkCallback->MerchantRequestID;
$CheckoutRequestID = $nowNow->Body->stkCallback->CheckoutRequestID;
$ResultDesc = $nowNow->Body->stkCallback->ResultDesc;
$sql = "SELECT * FROM duka;";
$stmt = mysqli_stmt_init($conn);
if (!mysqli_stmt_prepare($stmt, $sql)) {
echo "SQL statement failed 1!";
}else{
mysqli_stmt_execute($stmt);
$result = mysqli_stmt_get_result($stmt);
$rowCount = mysqli_num_rows($result);
$sql = "INSERT INTO duka(ResultCode, MerchantReqID, CheckoutReqID, ResultDesc, SessionId) VALUES (?,?,?,?,?);";
if (!mysqli_stmt_prepare($stmt, $sql)) {
echo "SQL statement failed 2!";
}else{
mysqli_stmt_bind_param($stmt,"sssss", $ResultCode, $MerchantRequestID,$CheckoutRequestID,$ResultDesc,$sess_id);
mysqli_stmt_execute($stmt);
}
}
}
Selecting data from db and sending it to the js page to be logged:
<!-- fromdb.php -->
<?php
include_once "db.te.php";
session_start();
$sess_id = session_id();
//retrieving data from db where Session ID is equal to this page's session ID
$sql="SELECT * FROM duka WHERE SessionId = $sess_id;";
$result = mysqli_query($conn, $sql);
$resultCheck=mysqli_num_rows($result);
if ($resultCheck > 0) {
while ($row = mysqli_fetch_assoc($result)) {
$data = $row["CheckoutReqID"];
}
}
//value to be printed using console.log following an ajax get method
echo json_encode($data);
If you set a cookie for the id, instead of the session, you'll be able to maintain the id in the callback url.
I created a Push messages program, it use firebase.google.com.
If a send push message via javascript the message is perfect, but if I send push message with Php curl the message do not same what I wrote in php file.
If I send via Php curl, the message will be what I wrote in service-worker.js.
Why is it?
Php code
function send_push_message($subscription){
if (empty($subscription)) return FALSE;
$ch = curl_init();
switch ($subscription["browser"]){
case "firefox":
curl_setopt($ch, CURLOPT_URL, "https://updates.push.services.mozilla.com/push/".$subscription["id"] );
curl_setopt($ch, CURLOPT_PUT, TRUE);
curl_setopt($ch, CURLOPT_HTTPHEADER, array( "TTL: 86400" ) );
curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
break;
case "chrome":
/**
* https://console.firebase.google.com
* http://stackoverflow.com/questions/37427709/firebase-messaging-where-to-get-server-key
*/
// API access key from Google API's Console
define( 'API_ACCESS_KEY', '<API_SZERVER_KULCSOM>' );
$registrationIds = array($_GET["id"]);
// prep the bundle
$msg = array
(
'message' => 'My text',
'title' => 'This is a title. title',
'subtitle' => 'This is a subtitle. subtitle',
'tickerText' => 'Ticker text here...Ticker text here...Ticker text here',
'vibrate' => 1,
'sound' => 1
);
$fields = array
(
'registration_ids' => $registrationIds,
'data' => $msg
);
$headers = array
(
'Authorization: key=' . API_ACCESS_KEY,
'Content-Type: application/json'
);
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, "https://gcm-http.googleapis.com/gcm/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));
$response = curl_exec($ch);
echo $response;
if($response === false){
echo 'Hiba: '.curl_error($ch);
}else{
echo 'Siker';
}
curl_close($ch);
break;
}
}
$tomb["browser"] = "chrome";
$tomb["id"] = $_GET["id"];
if(isset($_GET["id"])){
send_push_message($tomb);
}
service-worker.js
self.addEventListener('push', function(event) {
var title = 'xxxxxx';
var body = 'Szerbusz YYY';
var icon = '/images/icon-192x192.png';
var tag = 'simple-push-demo-notification-tag';
event.waitUntil(
self.registration.showNotification(title, {
body: body,
icon: icon,
tag: tag
})
);
});
Thank You
Thank You,
I do not send message when visitor sign up, via javascript.
I send message for example 5 days later via Php Curl.
Send message will be that what I wrote javascript. When I send message, I use only Php curl 5 days later!
Why is $msg value in Php curl, if don't use that?
Thanks
I have the following JavaScript that sends parameters to a PHP file:
function getOutput()
{
$.ajax({
url:'myPHPFile.php',
data:{APIKey:$APIKey,Password:$APIPass,Alias:$Alias,DataCenter:$DataCenter},
type:'POST',
complete: function (response) {
$('#output').html(response.responseText);
},
error: function ()
{
$('#output').html('Bummer: there was an error!');
}
});
return response.responseText;
}`
Which changes the following HTML to the output of the PHP file:
test
Here is the PHP
<?php
// echo nl2br("\nIntializing api.php \n");
// DATA SECTION
$APIKey = $_POST["APIKey"];
$APIPass = $_POST["Password"];
$AccountAlias = $_POST["Alias"];
$dataCenter = $_POST["DataCenter"];
$data = array(
"APIKey" => $APIKey,
"Password" => $APIPass,
);
$url_send = 'https://api.ctl.io/REST/Auth/Logon/';
$json_data = json_encode($data);
function sendPostData($url, $post, $cook = null){
// echo "Beginning sendPostData($url, $post, $cook)";
$ch = curl_init($url);
$headers= array('Accept: application/json','Content-Type: application/json');
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_HEADER, 1);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "POST");
curl_setopt($ch, CURLOPT_POSTFIELDS,$post);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
if (!empty($cook))
{
curl_setopt($ch, CURLOPT_HTTPHEADER, array('Accept: application/json','Content-Type: application/json','Cookie:'.$cook));
}
$result = curl_exec($ch);
curl_close($ch); // Seems like good practice
return $result;
};
$myresult = sendPostData($url_send, $json_data);
// print_r ($myresult);
$decodedresult = json_decode($myresult);
// print_r ($decodedresult);
'/reply-(.*?)-private/';
preg_match_all('/Tier3(.*?)path=/', $myresult, $matches);
$cookies = array();
foreach($matches[0] as $item)
{
parse_str($item, $cookie);
$cookies = array_merge($cookies, $cookie);
}
$prefix = 'Tier3.API.Cookie=';
$cookie = implode(" ",$matches[0]);
// Call the customer server list
$data = array(
'AccountAlias' => $AccountAlias,
'Location' => $dataCenter
);
$data_url = 'https://api.ctl.io/REST/Server/GetAllServersForAccountHierarchy/';
$data_string = json_encode($data);
$dataResult = sendPostData($data_url,$data_string, $cookie);
print_r($dataResult);
return $dataResult;
`
How can I get the $dataResult PHP array into a javascript variable so I can parse it? It is a big JSON response from an API.
Thanks.
Ajax calls are (normally) asynchronous, this means that the return response.responseText; will be executed immediately and should even raise an error related to response being undefined.
You'll have the response in the complete event of the ajax call and is inside there where you should go on with the execution of the script. jQuery will parse the JSON automatically and response will be the resulting object.
At the other side, the PHP script should just print the result of json_encode() and nothing else in order for the response to be valid JSON.
how to create a post with request in php or javascript for steam web API
Example post:
https://api.steampowered.com/IEconService/CancelTradeOffer/v1/?key=STEAM_API_KEY&tradeofferid=TRADE_OFFER_ID
when i use it in a browser i get:
Method Not Allowed
This API must be called with a HTTP POST request
In C# this was written as:
private bool CancelTradeOffer(ulong tradeofferid)
{
string options = string.Format("?key={0}&tradeofferid={1}", ApiKey, tradeofferid);
string url = String.Format(BaseUrl, "CancelTradeOffer", "v1", options);
Debug.WriteLine(url);
string response = SteamWeb.Fetch(url, "POST", null, null, false);
dynamic json = JsonConvert.DeserializeObject(response);
if (json == null || json.success != "1")
{
return false;
}
return true;
}
If you are using jQuery then there is a very handy function to do this.
$.post( "http://api.example.com/get-some-value", { name: "John", time: "2pm" })
.done(function( data ) {
alert( "Data Loaded: " + data );
});
But be careful about cross domain ajax when calling it from JS.
EDIT
For the comment.
You have to include jQuery into your page and then you can call anything within the very useful and handy $( document ).ready() that jQuery supplies.
$(document).ready(function(){
$.post( "http://api.example.com/get-some-value", { name: "John", time: "2pm" })
.done(function( data ) {
alert( "Data Loaded: " + data );
});
})
UPDATE:
Try this:
$url = 'https://api.steampowered.com/IEconService/CancelTradeOffer/v1/';
$postData = array();
$postData['key'] = $STEAM_API_KEY;
$postData['tradeofferid'] = $TRADE_OFFER_ID;
$parameters=json_encode($postData);
$headers = array( "Accept-Encoding: gzip",
"Content-Type: application/json");
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_HEADER, 1);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ch, CURLOPT_RETURNTRANSFER,1);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $parameters);
$resultt = curl_exec($ch);
var_dump($resultt);
curl_close($ch);
Or use this as a function to POST values
function httpPost($url,$params)
{
$postData = '';
//create name value pairs seperated by &
foreach($params as $k => $v)
{
$postData .= $k . '='.$v.'&';
}
rtrim($postData, '&');
$ch = curl_init();
curl_setopt($ch,CURLOPT_URL,$url);
curl_setopt($ch,CURLOPT_RETURNTRANSFER,true);
curl_setopt($ch,CURLOPT_HEADER, false);
curl_setopt($ch, CURLOPT_POST, count($postData));
curl_setopt($ch, CURLOPT_POSTFIELDS, $postData);
$output=curl_exec($ch);
curl_close($ch);
return $output;
}
Final Answer:
PHP Curl Post, works OK :)
Please give credits to WD :)
$url = 'http://api.steampowered.com/IEconService/CancelTradeOffer/v1/';
$postData = array();
$postData['key'] = ""; // insert variable
$postData['tradeofferid'] = ""; // insert variable
$fields = '';
foreach($postData as $key => $value) {
$fields .= $key . '=' . $value . '&';
}
rtrim($fields, '&');
$post = curl_init();
curl_setopt($post, CURLOPT_URL, $url);
curl_setopt($post, CURLOPT_POST, count($postData));
curl_setopt($post, CURLOPT_POSTFIELDS, $fields);
curl_setopt($post, CURLOPT_RETURNTRANSFER, 1);
$result = curl_exec($post);
var_dump($result);
curl_close($post);
jQuery Post, works OK :)
Please give credits to SRC :)
<script src="jquery-1.11.1.min.js"></script>
<script>
$(document).ready(function(){
$.post( "http://api.steampowered.com/IEconService/CancelTradeOffer/v1/", { key: "SteamApiKey", tradeofferid: "TradeOfferID" })
//This part does not work -- but is not needed to post data
//.done(function( data ) {
// alert( "Data Loaded: " + data );
//});
})
</script>
To Check Trade Offer status in PHP use:
//Check if trade offer was canceled
//Get File and avoid error if the server is down
$CheckTradeOfferID = ""; // add variable
$BotSteamApiKey = ""; // add variable
if (!$data = #file_get_contents("https://api.steampowered.com/IEconService/GetTradeOffer/v1/?key=".$BotSteamApiKey."&tradeofferid=".$CheckTradeOfferID."&format=json")) {
print 'Steam Api is Down';
} else {
$json=json_decode($data,true);
$TradeOffersResponse = $json['response'];
if (empty($TradeOffersResponse)) {
print "Trade Offer ID not found!!!";
}else{
$trade_offer_state = $json['response']['offer']['trade_offer_state'];
$TRANSLATE_Trade_Offer_State = "Unknown";
if($trade_offer_state == "1"){ $TRANSLATE_Trade_Offer_State = "Invalid"; }
if($trade_offer_state == "2"){ $TRANSLATE_Trade_Offer_State = "Trade Offer Sent"; }
if($trade_offer_state == "3"){ $TRANSLATE_Trade_Offer_State = "Trade Offer Accepted"; }
if($trade_offer_state == "4"){ $TRANSLATE_Trade_Offer_State = "The User Sent A Counter Offer"; }
if($trade_offer_state == "5"){ $TRANSLATE_Trade_Offer_State = "Trade Offer not accepted before the expiration date"; }
if($trade_offer_state == "6"){ $TRANSLATE_Trade_Offer_State = "The sender cancelled the offer"; }
if($trade_offer_state == "7"){ $TRANSLATE_Trade_Offer_State = "User Declined the Trade Offer"; }
if($trade_offer_state == "8"){ $TRANSLATE_Trade_Offer_State = "Some of the items in the offer are no longer available"; }
print $TRANSLATE_Trade_Offer_State;
}
}
I read this question and this one. They both said (a year ago) that recurring payments via the REST API was in the works. On my client's website, customers need to be able to pay either
in full (all at once — e.g., $1200 at check out)
in installments ($1200 over 6 months at $200 per month)
It is crucial that his website be notified when a customer pays. I have currently set this up for option #1:
app.get("/cart/checkout/paypal", isLoggedIn, isVerified, function (req, res) {
var user = req.user;
var paymentDetails = {
"intent": "sale",
"payer": { "payment_method": "paypal"},
"redirect_urls": {
"return_url": "http://localhost:5000/cart/checkout/success",
"cancel_url": "http://localhost:5000/cart"
},
"transactions": [
{ "amount": { "total": user.cart.finalPrice.toFixed(2), "currency": "USD"},
"description": "You are being billed for " + user.cart.finalPrice.toFixed(2)}
]
};
paypal.payment.create(paymentDetails, function (err, payment) {
if (err) console.log(err);
else {
if (payment.payer.payment_method === "paypal") {
req.session.paymentId = payment.id;
var redirectURL;
for (var i = 0; i < payment.links.length; i++) {
var link = payment.links[i];
if (link.method === "REDIRECT") redirectURL = link.href;
}
res.redirect(redirectURL);
}
}
})
})
Then, the "return_url" (/cart/checkout/success) grabs all the correct session info and my database processes it.
app.get("/cart/checkout/success", isLoggedIn, isVerified, function (req, res) {
var user = req.user,
paymentId = req.session.paymentId,
payerId = req.param("PayerID"),
details = { "payer_id": payerId };
...
Is there a similar setup for option #2 (recurring payments). If not, is there a way for PayPal to notify my server every time a user has paid an installment with the outstanding balance and amount paid/etc.?
Yes, there is now a way to do subscriptions within the new REST API. See the documentation.
OK, first you need to set the Client ID and secret you get from PayPal.
I have both a testing and live environment
All {xxx} are my private application variables
public function __construct()
{
$this->sandbox = {sandbox};
if($this->sandbox)
{
$this->host = 'https://api.sandbox.paypal.com';
$this->clientId = {clientIdSandbox};
$this->clientSecret = {clientSecretSandbox};
}
else
{
$this->host = 'https://api.paypal.com';
$this->clientId = {clientId};
$this->clientSecret = {clientSecret};
}
$this->get_access_token();
}
I then go and get the access token
private function get_access_token()
{
$curl = curl_init($this->host.'/v1/oauth2/token');
curl_setopt($curl, CURLOPT_POST, true);
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($curl, CURLOPT_USERPWD, $this->clientId . ":" . $this->clientSecret);
curl_setopt($curl, CURLOPT_HEADER, false);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
curl_setopt($curl, CURLOPT_POSTFIELDS, 'grant_type=client_credentials');
$response = curl_exec( $curl );
if (empty($response))
{
echo "NO RESPONSE for $url for function ".__FUNCTION__;
print_r(curl_getinfo($curl));
die(curl_error($curl));
curl_close($curl); // close cURL handler
}
else
{
$info = curl_getinfo($curl);
curl_close($curl); // close cURL handler
if($info['http_code'] != 200 && $info['http_code'] != 201 )
{
echo "Received error: " . $info['http_code']. "\n";
echo "Raw response:".$response."\n";
die();
}
}
$jsonResponse = json_decode( $response );
$this->token = $jsonResponse->access_token;
$this->expires = time()+$jsonResponse->expires_in;
}
This then stores the access data in the classes properties
You then need three more sections. Create the subscription template, then retrieve the agreement, then create the agreement for the client.
In this method I send over the data Name, Desc, Period, Interval and Price. However you can just fill in manually. This will create the subscription that you can now sell.
public function create_subscription($name, $desc, $period, $interval, $price)
{
$data = array(
'name' => $name,
'description' => $desc,
'type' => 'INFINITE',
'payment_definitions' => array(
0 => array (
'name' => 'Payment Definition-1',
'type' => 'REGULAR',
'frequency' => $period,
'frequency_interval' => $interval,
'amount' => array(
'value' => $price,
'currency' => 'EUR',
),
'cycles' => '0',
),
),
'merchant_preferences' => array(
'return_url'=>{return_url},
'cancel_url'=>{cancel_url},
'auto_bill_amount' => 'YES',
'initial_fail_amount_action' => 'CONTINUE',
'max_fail_attempts' => '0',
),
);
$data=json_encode($data);
$url = $this->host.'/v1/payments/billing-plans';
return $this->make_post_call($url, $data);
}
From the above method you will get in return an id, use that for the method below to collect the data of the subscription and store it
public function retrieve_agreement($id)
{
$url = $this->host.'/v1/payments/billing-agreements/'.$id;
return $this->make_get_call($url);
}
This method will allow you to allocate and agreement to a client.
You will need the id of the aggreement with some data for you to be able add to the description.
public function create_agreement($subId, $data, $product)
{
$paypalId = ($this->sandbox) ? $product->paypal_test_sub_id : $product->paypal_sub_id;
$startDate = date('c', strtotime('+10 MINUTE'));
$data = array (
'name'=>'Subscription for subscription::'.$subId,
'description'=>{company}.' Subscription - ' . $data . ' - '.$product->name.' - '.$product->price .'€',
'start_date'=>$startDate,
'plan'=>array(
'id'=>$paypalId,
),
'payer'=>array(
'payment_method'=>'paypal',
),
'override_merchant_preferences'=>array(
'return_url'=>{return_url}.$subId.'/',
'cancel_url'=>{cancel_url}.$subId.'/',
),
);
$data=json_encode($data);
$url = $this->host.'/v1/payments/billing-agreements';
$response = $this->make_post_call($url, $data);
header("location:".$response['links'][0]['href']);
//return $response;
}
The return_url is the url that the end user will be sent to to complete the aggreement. I than use that to pass to the method below
public function execute_agreement($token)
{
$data=json_encode('');
$url = $this->host.'/v1/payments/billing-agreements/'.$token.'/agreement-execute';
return $response = $this->make_post_call($url, $data);
}
You will then need to create a scheduled task to use the retrieve_agreement method and see if a subscription has been cancelled or not.
This is a brief explanation.
if you require more please let me know.
Get and Post
private function make_post_call($url, $postdata)
{
$curl = curl_init($url);
curl_setopt($curl, CURLOPT_POST, true);
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($curl, CURLOPT_HEADER, false);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
curl_setopt($curl, CURLOPT_HTTPHEADER, array(
'Authorization: Bearer '.$this->token,
'Accept: application/json',
'Content-Type: application/json'
));
curl_setopt($curl, CURLOPT_POSTFIELDS, $postdata);
$response = curl_exec( $curl );
if (empty($response))
{
echo "NO RESPONSE for $url for function ".__FUNCTION__;
print_r(curl_getinfo($curl));
die(curl_error($curl));
curl_close($curl); // close cURL handler
}
else
{
$info = curl_getinfo($curl);
curl_close($curl); // close cURL handler
if($info['http_code'] != 200 && $info['http_code'] != 201 )
{
echo "Received error: " . $info['http_code']. "\n";
echo "Raw response:".$response."\n";
die();
}
}
$jsonResponse = json_decode($response, TRUE);
return $jsonResponse;
}
private function make_get_call($url)
{
$curl = curl_init($url);
curl_setopt($curl, CURLOPT_POST, false);
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($curl, CURLOPT_HEADER, false);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
curl_setopt($curl, CURLOPT_HTTPHEADER, array(
'Authorization: Bearer '.$this->token,
'Accept: application/json',
'Content-Type: application/json'
));
$response = curl_exec( $curl );
if (empty($response))
{
echo "NO RESPONSE for $url for function ".__FUNCTION__;
print_r(curl_getinfo($curl));
die(curl_error($curl));
curl_close($curl); // close cURL handler
}
else
{
$info = curl_getinfo($curl);
//echo "Time took: " . $info['total_time']*1000 . "ms\n";
curl_close($curl); // close cURL handler
if($info['http_code'] != 200 && $info['http_code'] != 201 )
{
echo "Received error: " . $info['http_code']. "\n";
echo "Raw response:".$response."\n";
die();
}
}
$jsonResponse = json_decode($response, TRUE);
return $jsonResponse;
}
I would recommend staying away from the REST API for now. It's just not complete yet, and the Classic API gives you so much more flexibility.
I'd go with Express Checkout with Recurring Payments, and then you'll want to use Instant Payment Notification (IPN) to handle processing payments, canceled profiles, etc.
IPN notifications will actually be triggered for any transaction that ever hits your account, so you can automate the processing of payments, refunds, disputes, subscriptions, etc. You can update your database, send email notifications, or anything else you need to automate based on these transaction types.
IPN is one of the most valuable tools PayPal provides, yet it's also one of the most underutilized.