I had working code in my server, that verified in-app purchases.
There are already 2 days, that my verification started give me a bad response.
{
"error": {
"errors": [
{
"domain": "global",
"reason": "invalid",
"message": "Invalid Value"
}
],
"code": 400,
"message": "Invalid Value"
}
}
Nothing changed on my side.
(P.S. I'm able to get an access token via refresh, so, I assume I have no problems with my credentials).
Here is the code, that worked OK before.
$product_sku = $_REQUEST['product_sku'];
$transaction_id = $_REQUEST['transaction_id'];
$transaction_time = $_REQUEST['transaction_time'];
$purchase_data = #$_REQUEST['purchase_data'];
$market = $_REQUEST['market'];
$verified = false;
$test_purchase = false;
if (isset($product_sku) && isset($transaction_id) && isset($transaction_time) && isset($market)) {
// If it's GOOGLE
if ($market == '2') {
// verifies if the IAB is correct
if (isset($purchase_data) && $purchase_data != "") {
// Getting necessary data for verification
$client_id = file_get_contents('google_play_developer_api_client_id');
$client_secret = file_get_contents('google_play_developer_api_client_secret');
$refresh_token = file_get_contents('google_play_developer_api_refresh_token');
$refresh_token_url = 'https://accounts.google.com/o/oauth2/token';
$verification_url = "https://www.googleapis.com/androidpublisher/v3/applications/mypackage/purchases/products/" . $product_sku . "/tokens/" . $purchase_data;
// Preparing for the REFRESH_TOKEN request. This need to be changed after Memcache enabling.
// Will be needed to store the ACCESS_TOKEN in the Memcache for the expiration time and after expiring get new ACCESS_TOKEN with REFRESH_TOKEN
// constructing the necessary data for Google authentication
$data_array = array(
"grant_type" => "refresh_token",
"client_id" => $client_id,
"client_secret" => $client_secret,
"refresh_token" => $refresh_token
);
// replacing '\/' with '/' as after json_encode() the '/' in the array values will be replaced with '\/'
$data_array = str_replace("\/", "/", json_encode($data_array));
// contracting Headers for the REFRESH_TOKEN request
$headers = array(
'APIKEY: 111111111111111111111',
'Content-Type: application/json'
);
// making REFRESH_TOKEN request and getting the new ACCESS_TOKEN
$make_call = callAPI('POST', $refresh_token_url, $data_array, $headers);
$response = json_decode($make_call, true);
if (array_key_exists("access_token", $response)) {
$accessToken = $response["access_token"];
// preparing for the Verification request
// adding necessary headers
array_push($headers, "Authorization: OAuth " . $accessToken, "Accept: application/json");
// making Verification request and getting the receipt from Google
$make_call = callAPI('GET', $verification_url, false, $headers);
$receipt = json_decode($make_call, true);
if (array_key_exists("purchaseState", $receipt)) {
// checking for the test purchase or for the purchase made using promo code.
// if purchaseType exists in the receipt the it is test purchase or the purchase made using promo code
// purchaseType = 0 -> Test Purchase, purchaseType = 1 -> Purchase made using promo code
if (array_key_exists("purchaseType", $receipt)) {
$purchaseType = $receipt["purchaseType"];
$test_purchase = $purchaseType == 0;
}
// Getting the purchaseState from the receipt.
// purchaseState = 0 -> Successfull purchase, purchaseState = 0 -> Canceled purchase
$purchaseState = $receipt["purchaseState"];
// Getting Order Id from the receipt
$order_id = $receipt["orderId"];
// Getting Purchase Time from the receipt. Time in millis from the Unix Epoch
$purchaseTimeMillis = $receipt["purchaseTimeMillis"];
// Verifying the purchase
// Verification is failed for any of the following reasons
// 1. Test purchase or the purchase made using promo code
// 2. Canceled Purchase
// 3. If the order id from receipt and the transaction id from the mobile app are different
// 4. If the PurchaseTime from the receipt and the Transaction Time from the mobile are different
// If all conditions are true, the purchase is verified.
$verified = ($purchaseState == 0 && $order_id == $transaction_id && $purchaseTimeMillis == $transaction_time);
} elseif(!array_key_exists("error", $receipt)){
// Something went wrong, let's set the verified to true, so we don't know if it is cheating
$verified = true;
}
} else {
// Something went wrong, let's set the verified to true, so we don't know if it is cheat
$verified = true;
}
}
} else {
// Changed this, while adding verification for other platforms
$verified = true;
}
$verified = $verified ? 1 : 0;
$test_purchase = $test_purchase ? 1 : 0;
// Updating verified and test Purchase fields in the payment_transaction table
// The default value is 1, so no need for updating , if the payment is verified
if ($verified == 0 || $test_purchase == 1) {
dbQuery("UPDATE payment_transaction SET verified=$verified, test_purchase=$test_purchase WHERE user_id=$user_id AND txnid='$transaction_id'", $user_id);
}
$output['status'] = 'ok';
$output['verified'] = $verified;
$output['test_purchase'] = $test_purchase;
}
echo json_encode($output);
function callAPI($method, $url, $data = false, $headers = null)
{
$curl = curl_init();
switch ($method) {
case "POST":
curl_setopt($curl, CURLOPT_POST, 1);
if ($data)
curl_setopt($curl, CURLOPT_POSTFIELDS, $data);
break;
case "GET":
if ($data)
$url = sprintf("%s?%s", $url, http_build_query($data));
}
// OPTIONS:
curl_setopt($curl, CURLOPT_URL, $url);
if ($headers) {
curl_setopt($curl, CURLOPT_HTTPHEADER, $headers);
}
curl_setopt($curl, CURLOPT_HTTPHEADER, $headers);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($curl, CURLOPT_HTTPAUTH, CURLAUTH_BASIC);
// EXECUTE:
$result = curl_exec($curl);
if (! $result) {
die("Connection Failure");
}
curl_close($curl);
return $result;
}
?>
Any Ideas what may be the reason for the bad response?
I have tried to generate a new refresh token, but the result is the same. (
Ok. I found the problem. The PurchaseToken was incorrect in my case.
BTW, the Error Code 400 means that the authentication is ok , but some data is invalid. In my case, it was the PurchaseToken.
Related
I am using a class to send GCM based Push Notification from PHP. I downloaded this class from https://www.phpclasses.org/package/8987-PHP-Send-push-notifications-to-Android-and-iOS-devices.html
All things are working as expected but as the number of Android users has crossed 3K now sending push notification is taking very long time. It takes around 2 to 2 and a half hours to send Push Notification.
And I cannot refresh the page to even close the browser otherwise the operation gets aborted.
How can I increase the speed of sending Push Notification from my script.
The important part of code that I am using for sending Push Notification is give below:
if (isset($_POST['sendmessage']) && !empty($_POST['sendmessage'])) {
$errorvalid = array();
$success = TRUE;
$requiredFields = array("subject_notify" => "Please Enter Notify Subject.", "subject_main" => "Please Enter Main Subject.", "msg" => "Please Enter Message");
foreach ($requiredFields as $fld => $msg) {
$v = $_POST[$fld];
if (empty($v)) {
$success = false;
$errorvalid[$fld] = $msg;
} else {
$errorvalid[$fld] = '';
$$fld = $v;
}
}
if($success)
{
$get_result = mysql_query("SELECT ps_mobile_id, ps_service_type FROM push_service", $con);
$row_result = mysql_fetch_assoc($get_result);
$totalRows_row_result = mysql_num_rows($get_result);
echo "Total Records: ".$totalRows_row_result;
echo "<br/>";
//Set parameters to hold time out error
set_time_limit(0);
error_reporting(E_ALL);
//ob_implicit_flush(TRUE);
//ob_end_flush();
if($totalRows_row_result > 0) {
$push = new pushmessage();
do {
$MobID = $row_result['ps_mobile_id'];
$MobType = $row_result['ps_service_type'];
echo "Mobile ID: ".$MobID;
echo "<br/>";
if($MobType == 1)
{
//Android
$params = array("pushtype"=>"android", "msg"=>$msg, "registration_id"=>$MobID, "subject_main"=>$subject_main, "subject_notify"=>$subject_notify, );
$rtn = $push->sendMessage($params);
//Push the message
$rtn = $push->sendMessage($params);
}
else
{
//iOS
//$params = array("pushtype"=>"android", "msg"=>$msg, "registration_id"=>$MobID, //"subject_main"=>$subject_main, "subject_notify"=>$subject_notify, );
//$rtn = $push->sendMessage($params);
//Push the message
//$rtn = $push->sendMessage($params);
}
echo "<br/>";
print_r($rtn);
echo "<br/>";
//ob_flush(); //Push data to Browser
}while ($row_result = mysql_fetch_assoc($get_result));
//header("Location: index.php");
echo "<h2>Completed Sending Pusht Message</h2>";
echo "<br/><br/>";
echo "Rediricting.... Please wait....";
echo "<br/><br/>";
echo '<meta http-equiv="refresh" content="3;url=http://mypresence.in/pushtibooks/pushmsg/" />';
}
else
{
echo "NO Data";
}
}
}
TIA
Yogi Yang
You are sending push notification one by one . That's why it takes too much time. You can send group message using device id. Check this documentation .
Use below code for sending push notification to android. Same way you can do this on iOS also.
//For andriod
$get_result = mysql_query("SELECT ps_mobile_id FROM push_service where ps_service_type = 1", $con);
// $row_result = mysql_fetch_assoc($get_result);
$totalRows_row_result = mysql_num_rows($get_result);
$MobIDs=array();
while($row = mysql_fetch_assoc($get_result)){
$MobIDs[] = $row;
}
$params = array("pushtype"=>"android", "msg"=>$msg, "subject_main"=>$subject_main, "subject_notify"=>$subject_notify, );
$rtn = $push->sendMessageAndroid($MobIDs, $params)
and sendMessageAndroid($registration_id, $params)
public $androidAuthKey = "Android Auth Key Here";
public $iosApnsCert = "./certification/xxxxx.pem";
/**
* For Android GCM
* $params["msg"] : Expected Message For GCM
*/
private function sendMessageAndroid($registration_id, $params) {
$this->androidAuthKey = "Android Auth Key Here";//Auth Key Herer
## data is different from what your app is programmed
$data = array(
'registration_ids' => array($registration_id),
'data' => array(
'gcm_msg' => $params["msg"]
)
);
$headers = array(
"Content-Type:application/json",
"Authorization:key=".$this->androidAuthKey
);
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, "https://android.googleapis.com/gcm/send");
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($data));
$result = curl_exec($ch);
//result sample {"multicast_id":6375780939476727795,"success":1,"failure":0,"canonical_ids":0,"results":[{"message_id":"0:1390531659626943%6cd617fcf9fd7ecd"}]}
//http://developer.android.com/google/gcm/http.html // refer error code
curl_close($ch);
$rtn["code"] = "000";//means result OK
$rtn["msg"] = "OK";
$rtn["result"] = $result;
return $rtn;
}
Please note that: Don't send more than 1000 device id per request. If you have more than 1000 users. then slice your MobIDs with a size less than 1000
I want to use mediawiki api to retrieve some informations with a symfony project, i want tu use curl to fo api calls,
I tried with
$ch=curl_init();
$postfield = "action=query&titles=Watch&prop=langlinks&lllimit=20";
$url = "https://en.wikipedia.org/w/api.php"; //url to wiki's api
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $postfield);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
$output = curl_exec($ch);
var_dump($output);
curl_close($ch);
but it does not work, it gives me boolean false as result
Here's a good example of using the PHP API using cURL from WikiMedia itself.
First, logging in:
/**
* Configuration
* -------------------------------------------------
*/
// Start session
session_start();
// Login
$app['username'] = "Example";
$app['password'] = "mypassword";
// Version
$app["version"] = "0.0.1-dev";
// Last modified
date_default_timezone_set("UTC");
$app["lastmod"] = date("Y-m-d H:i", getlastmod()) . " UTC"; // Example: 2010-04-15 18:09 UTC
// User-Agent used for loading external resources
$app["useragent"] = "My First Tool " . $app["version"] . " (LastModified: " . $app["lastmod"] . ") Contact: myfirsttool (at) example (.) com";
// Cookie file for the session
$app["cookiefile"] = tempnam("/tmp", "CURLCOOKIE");
// cURL to avoid repeating ourselfs
$app["curloptions"] =
array(
CURLOPT_COOKIEFILE => $app["cookiefile"],
CURLOPT_COOKIEJAR => $app["cookiefile"],
CURLOPT_RETURNTRANSFER => 1,
CURLOPT_USERAGENT => $app["useragent"],
CURLOPT_POST => true
);
$app["apiURL"] = "http://www.mediawiki.org/w/api.php";
Then to do the login using cookies:
/**
* Login
* -------------------------------------------------
*/
// Info: http://www.mediawiki.org/wiki/API:Login
$postdata = http_build_query([
"action" => "login",
"format" => "php",
"lgname" => $app["username"],
"lgpassword" => $app["password"],
]);
$ch = curl_init();
curl_setopt_array($ch, $app["curloptions"]);
curl_setopt($ch, CURLOPT_URL, $app["apiURL"]);
curl_setopt($ch, CURLOPT_POSTFIELDS, $postdata);
$result = unserialize(curl_exec($ch));
if(curl_errno($ch)){
$curl_error = "Error 003: " . curl_error($ch);
}
curl_close($ch);
//print_r($result);//die;//DEBUG
// Basic error check + Confirm token
if ($curl_error){
$domain_error = $curl_error;
} else if ($result["login"]["result"] == "NeedToken") {
if (!empty($result["login"]["token"])) {
$_SESSION["logintoken"] = $result["login"]["token"];
$postdata = http_build_query([
"action" => "login",
"format" => "php",
"lgname" => $app["username"],
"lgpassword" => $app["password"],
"lgtoken" => $_SESSION["logintoken"],
]);
$ch = curl_init();
curl_setopt_array($ch, $app["curloptions"]);
curl_setopt($ch, CURLOPT_URL, $app["apiURL"]);
curl_setopt($ch, CURLOPT_POSTFIELDS, $postdata);
$result = unserialize(curl_exec($ch));
if(curl_errno($ch)){
$curl_error = "Error 004: " . curl_error($ch);
}
curl_close($ch);
//print_r($result);//die;//DEBUG
} else {
$other_error = "Error 006: Token error.";
}
}
// Check for all documented errors
// Source: http://www.mediawiki.org/wiki/API:Login#Errors
// Date: 2010-04-17
if ($curl_error){
$domain_error = $curl_error;
} else if ($result["login"]["result"] == "Success") {
$_SESSION["login_result"] = $result["login"]["result"];
$_SESSION["login_lguserid"] = $result["login"]["lguserid"];
$_SESSION["login_lgusername"] = $result["login"]["lgusername"];
} else if ($result["login"]["result"] == "NeedToken") {
$other_error = "Error 005: Token error.";
} else if ($result["login"]["result"] == "NoName") {
$username_error = "The username can not be blank";
} else if ($result["login"]["result"] == "Illegal") {
$username_error = "You provided an illegal username";
} else if ($result["login"]["result"] == "NotExists") {
$username_error = "The username you provided doesn't exist";
} else if ($result["login"]["result"] == "EmptyPass") {
$password_error = "The password can not be blank";
} else if ($result["login"]["result"] == "WrongPass" || $result["login"]["result"] == "WrongPluginPass") {
$password_error = "The password you provided is incorrect";
} else if ($result["login"]["result"] == "CreateBlocked") {
$username_error = "Autocreation was blocked from this IP address";
} else if ($result["login"]["result"] == "Throttled") {
$other_error = "You've logged in too many times in a short time. Try again later.";
} else if ($result["login"]["result"] == "mustbeposted") {
$other_error = "Error 004: Logindata was not send correctly";
} else if ($result["login"]["result"] == "Blocked") {
$username_error = "This account is blocked.";
} else if ($result["login"]["result"]){
$other_error = "Error 001: An unknown event occurred.";
} else {
$other_error = "Error 002: An unknown event occurred.";
}
// The tool you use may log or display the variables:
// $other_error, $username_error and $password_error in the appropiate place
// Such as near a login form, or in a specific debug/logfile
// by default the errors are not outputted
if($_SESSION["login_result"] !== "Success"){
die("Login error. Have you defined app[username] and app[password] ?");
}
Example of building a query:
/**
* Get userinfo
* -------------------------------------------------
*/
$postdata = http_build_query([
"action" => "query",
"format" => "php",
"meta" => "userinfo",
"uiprop" => "rights|hasmsg",
]);
$ch = curl_init();
curl_setopt_array($ch, $app["curloptions"]);
curl_setopt($ch, CURLOPT_URL, $app["apiURL"]);
curl_setopt($ch, CURLOPT_POSTFIELDS, $postdata);
$result = unserialize(curl_exec($ch));
if(curl_errno($ch)){
Death("Error 003: " . curl_error($ch),"API connection failed.");
}
curl_close($ch);
//print_r($result);//die;//DEBUG
// Check for usermessages
if (isset($result['query']['userinfo']['messages'])) {
$api['hasmsg'] = true;
$api['hasmsghtml'] = '<div class="usermessage">You have new messages !</div>';
} else {
// User does not have new messages
}
And finally, how to clean up the session:
// Delete the cookie file
unlink($app["cookiefile"]);
// Destroy the session
session_destroy();
// End this file
die($output);
I tried that, and it works either
public function callWiki($url)
{
$ch = curl_init();
curl_setopt_array($ch, array(
CURLOPT_URL => $url,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_SSL_VERIFYPEER => false,
CURLOPT_SSL_VERIFYHOST => 2
));
$result = curl_exec($ch);
curl_close($ch);
return $result;
}
public function getAllCategories()
{
$api = 'https://en.wikipedia.org/w/api.php? action=query&titles=watch&prop=categories&format=json';
//get query result
$api_response = $this->callWiki($api);
$results = json_decode($api_response, true);
}
I followed all these steps.
https://developers.google.com/+/web/signin/
I have client id and client secret.
I got access token now, how can I get user profile and email with access token? And how to check whether user logged in or not?
Using OAuth2, you can request permissions through the scope parameter. (Documentation.) I imagine the scopes you want are https://www.googleapis.com/auth/userinfo.email and https://www.googleapis.com/auth/userinfo.profile.
Then, it's a simple matter to get the profile info once you've obtained your access token. (I assume you've been able to redeem the returned authorization code for an access token?) Just make a get request to https://www.googleapis.com/oauth2/v1/userinfo?access_token={accessToken}, which returns a JSON array of profile data, including email:
{
"id": "00000000000000",
"email": "fred.example#gmail.com",
"verified_email": true,
"name": "Fred Example",
"given_name": "Fred",
"family_name": "Example",
"picture": "https://lh5.googleusercontent.com/-2Sv-4bBMLLA/AAAAAAAAAAI/AAAAAAAAABo/bEG4kI2mG0I/photo.jpg",
"gender": "male",
"locale": "en-US"
}
No guarantees, but try this:
$url = "https://www.googleapis.com/oauth2/v1/userinfo";
$request = apiClient::$io->makeRequest($client->sign(new apiHttpRequest($url, 'GET')));
if ((int)$request->getResponseHttpCode() == 200) {
$response = $request->getResponseBody();
$decodedResponse = json_decode($response, true);
//process user info
} else {
$response = $request->getResponseBody();
$decodedResponse = json_decode($response, true);
if ($decodedResponse != $response && $decodedResponse != null && $decodedResponse['error']) {
$response = $decodedResponse['error'];
}
}
}
try this
$accessToken = 'access token';
$userDetails = file_get_contents('https://www.googleapis.com/oauth2/v1/userinfo?access_token=' . $accessToken);
$userData = json_decode($userDetails);
if (!empty($userData)) {
$googleUserId = '';
$googleEmail = '';
$googleVerified = '';
$googleName = '';
$googleUserName = '';
if (isset($userData->id)) {
$googleUserId = $userData->id;
}
if (isset($userData->email)) {
$googleEmail = $userData->email;
$googleEmailParts = explode("#", $googleEmail);
$googleUserName = $googleEmailParts[0];
}
if (isset($userData->verified_email)) {
$googleVerified = $userData->verified_email;
}
if (isset($userData->name)) {
$googleName = $userData->name;
}
} else {
echo "Not logged In";
}
You just add this line into your scope
Open your Application.cfc and then add this code
<cfset request.oauthSettings =
{scope = "https://www.googleapis.com/auth/userinfo.email+https://www.googleapis.com/auth/userinfo.profile",
client_id = "Your-id",
client_secret = "your-secret",
redirect_uri = "redirect-page",
state = "optional"} />
Now you can get email from function that you can call like this
<cfscript>
public function getProfile(accesstoken) {
var h = new com.adobe.coldfusion.http();
h.setURL("https://www.googleapis.com/oauth2/v1/userinfo");
h.setMethod("get");
h.addParam(type="header",name="Authorization",value="OAuth #accesstoken#");
h.addParam(type="header",name="GData-Version",value="3");
h.setResolveURL(true);
var result = h.send().getPrefix();
return deserializeJSON(result.filecontent.toString());
}
</cfscript>
<cfoutput>
<cfset show = getProfile(session.ga_accessToken)>
<cfdump var="#show#">
</cfoutput>
Hope this can Help many of people to solve this . :)
$access_token = 'your access token';
$headers = array('Content-Type: Application/json');
$endpoint = "https://www.googleapis.com/oauth2/v1/userinfo?access_token=".$access_token;
$soap_do = curl_init();
curl_setopt($soap_do, CURLOPT_URL, $endPoint);
curl_setopt($soap_do, CURLOPT_RETURNTRANSFER, true);
curl_setopt($soap_do, CURLOPT_HTTPHEADER, $header);
curl_setopt($soap_do, CURLOPT_FAILONERROR, true);
$result = curl_exec($soap_do);
I have stored the customers paypal email address in database and I want to send them money using that email address. I am using PHP.
Anyone please suggest how to do that.
I was looking for the same issue, here's what is working for me.
Tested in 'sandbox' mode and using NVP (instead of SOAP).
Your server must support CURL, in order to verify it use:
<?php
echo 'curl extension/module loaded/installed: ';
echo ( !extension_loaded('curl')) ? 'no' : 'yes';
echo "<br />\n";
phpinfo(INFO_MODULES); // just to be sure
?>
If is not loaded or installed ask to your hostmaster or get it here, otherwise go ahead:
<?php
// code modified from source: https://cms.paypal.com/cms_content/US/en_US/files/developer/nvp_MassPay_php.txt
// documentation: https://cms.paypal.com/us/cgi-bin/?cmd=_render-content&content_ID=developer/howto_api_masspay
// sample code: https://cms.paypal.com/us/cgi-bin/?cmd=_render-content&content_ID=developer/library_code
// eMail subject to receivers
$vEmailSubject = 'PayPal payment';
/** MassPay NVP example.
*
* Pay one or more recipients.
*/
// For testing environment: use 'sandbox' option. Otherwise, use 'live'.
// Go to www.x.com (PayPal Integration center) for more information.
$environment = 'sandbox'; // or 'beta-sandbox' or 'live'.
/**
* Send HTTP POST Request
*
* #param string The API method name
* #param string The POST Message fields in &name=value pair format
* #return array Parsed HTTP Response body
*/
function PPHttpPost($methodName_, $nvpStr_)
{
global $environment;
// Set up your API credentials, PayPal end point, and API version.
// How to obtain API credentials:
// https://cms.paypal.com/us/cgi-bin/?cmd=_render-content&content_ID=developer/e_howto_api_NVPAPIBasics#id084E30I30RO
$API_UserName = urlencode('my_api_username');
$API_Password = urlencode('my_api_password');
$API_Signature = urlencode('my_api_signature');
$API_Endpoint = "https://api-3t.paypal.com/nvp";
if("sandbox" === $environment || "beta-sandbox" === $environment)
{
$API_Endpoint = "https://api-3t.$environment.paypal.com/nvp";
}
$version = urlencode('51.0');
// Set the curl parameters.
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $API_Endpoint);
curl_setopt($ch, CURLOPT_VERBOSE, 1);
// Turn off the server and peer verification (TrustManager Concept).
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_POST, 1);
// Set the API operation, version, and API signature in the request.
$nvpreq = "METHOD=$methodName_&VERSION=$version&PWD=$API_Password&USER=$API_UserName&SIGNATURE=$API_Signature$nvpStr_";
// Set the request as a POST FIELD for curl.
curl_setopt($ch, CURLOPT_POSTFIELDS, $nvpreq);
// Get response from the server.
$httpResponse = curl_exec($ch);
if( !$httpResponse)
{
exit("$methodName_ failed: " . curl_error($ch) . '(' . curl_errno($ch) .')');
}
// Extract the response details.
$httpResponseAr = explode("&", $httpResponse);
$httpParsedResponseAr = array();
foreach ($httpResponseAr as $i => $value)
{
$tmpAr = explode("=", $value);
if(sizeof($tmpAr) > 1)
{
$httpParsedResponseAr[$tmpAr[0]] = $tmpAr[1];
}
}
if((0 == sizeof($httpParsedResponseAr)) || !array_key_exists('ACK', $httpParsedResponseAr))
{
exit("Invalid HTTP Response for POST request($nvpreq) to $API_Endpoint.");
}
return $httpParsedResponseAr;
}
// Set request-specific fields.
$emailSubject = urlencode($vEmailSubject);
$receiverType = urlencode('EmailAddress');
$currency = urlencode('USD'); // or other currency ('GBP', 'EUR', 'JPY', 'CAD', 'AUD')
// Receivers
// Use '0' for a single receiver. In order to add new ones: (0, 1, 2, 3...)
// Here you can modify to obtain array data from database.
$receivers = array(
0 => array(
'receiverEmail' => "user1#paypal.com",
'amount' => "20.00",
'uniqueID' => "id_001", // 13 chars max
'note' => " payment of commissions"), // I recommend use of space at beginning of string.
1 => array(
'receiverEmail' => "user2#paypal.com",
'amount' => "162.38",
'uniqueID' => "A47-92w", // 13 chars max, available in 'My Account/Overview/Transaction details' when the transaction is made
'note' => " payoff of what I owed you" // space again at beginning.
)
);
$receiversLenght = count($receivers);
// Add request-specific fields to the request string.
$nvpStr="&EMAILSUBJECT=$emailSubject&RECEIVERTYPE=$receiverType&CURRENCYCODE=$currency";
$receiversArray = array();
for($i = 0; $i < $receiversLenght; $i++)
{
$receiversArray[$i] = $receivers[$i];
}
foreach($receiversArray as $i => $receiverData)
{
$receiverEmail = urlencode($receiverData['receiverEmail']);
$amount = urlencode($receiverData['amount']);
$uniqueID = urlencode($receiverData['uniqueID']);
$note = urlencode($receiverData['note']);
$nvpStr .= "&L_EMAIL$i=$receiverEmail&L_Amt$i=$amount&L_UNIQUEID$i=$uniqueID&L_NOTE$i=$note";
}
// Execute the API operation; see the PPHttpPost function above.
$httpParsedResponseAr = PPHttpPost('MassPay', $nvpStr);
if("SUCCESS" == strtoupper($httpParsedResponseAr["ACK"]) || "SUCCESSWITHWARNING" == strtoupper($httpParsedResponseAr["ACK"]))
{
exit('MassPay Completed Successfully: ' . print_r($httpParsedResponseAr, true));
}
else
{
exit('MassPay failed: ' . print_r($httpParsedResponseAr, true));
}
?>
Good luck!
What you're looking for is DoMassPay from the PayPal official code samples, not easy to guess that name :P
They have added sample code to their website:
https://cms.paypal.com/cms_content/US/en_US/files/developer/nvp_MassPay_php.txt
I have stored the customers paypal email address in database and I want to send them money using that email address. I am using PHP.
Anyone please suggest how to do that.
I was looking for the same issue, here's what is working for me.
Tested in 'sandbox' mode and using NVP (instead of SOAP).
Your server must support CURL, in order to verify it use:
<?php
echo 'curl extension/module loaded/installed: ';
echo ( !extension_loaded('curl')) ? 'no' : 'yes';
echo "<br />\n";
phpinfo(INFO_MODULES); // just to be sure
?>
If is not loaded or installed ask to your hostmaster or get it here, otherwise go ahead:
<?php
// code modified from source: https://cms.paypal.com/cms_content/US/en_US/files/developer/nvp_MassPay_php.txt
// documentation: https://cms.paypal.com/us/cgi-bin/?cmd=_render-content&content_ID=developer/howto_api_masspay
// sample code: https://cms.paypal.com/us/cgi-bin/?cmd=_render-content&content_ID=developer/library_code
// eMail subject to receivers
$vEmailSubject = 'PayPal payment';
/** MassPay NVP example.
*
* Pay one or more recipients.
*/
// For testing environment: use 'sandbox' option. Otherwise, use 'live'.
// Go to www.x.com (PayPal Integration center) for more information.
$environment = 'sandbox'; // or 'beta-sandbox' or 'live'.
/**
* Send HTTP POST Request
*
* #param string The API method name
* #param string The POST Message fields in &name=value pair format
* #return array Parsed HTTP Response body
*/
function PPHttpPost($methodName_, $nvpStr_)
{
global $environment;
// Set up your API credentials, PayPal end point, and API version.
// How to obtain API credentials:
// https://cms.paypal.com/us/cgi-bin/?cmd=_render-content&content_ID=developer/e_howto_api_NVPAPIBasics#id084E30I30RO
$API_UserName = urlencode('my_api_username');
$API_Password = urlencode('my_api_password');
$API_Signature = urlencode('my_api_signature');
$API_Endpoint = "https://api-3t.paypal.com/nvp";
if("sandbox" === $environment || "beta-sandbox" === $environment)
{
$API_Endpoint = "https://api-3t.$environment.paypal.com/nvp";
}
$version = urlencode('51.0');
// Set the curl parameters.
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $API_Endpoint);
curl_setopt($ch, CURLOPT_VERBOSE, 1);
// Turn off the server and peer verification (TrustManager Concept).
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_POST, 1);
// Set the API operation, version, and API signature in the request.
$nvpreq = "METHOD=$methodName_&VERSION=$version&PWD=$API_Password&USER=$API_UserName&SIGNATURE=$API_Signature$nvpStr_";
// Set the request as a POST FIELD for curl.
curl_setopt($ch, CURLOPT_POSTFIELDS, $nvpreq);
// Get response from the server.
$httpResponse = curl_exec($ch);
if( !$httpResponse)
{
exit("$methodName_ failed: " . curl_error($ch) . '(' . curl_errno($ch) .')');
}
// Extract the response details.
$httpResponseAr = explode("&", $httpResponse);
$httpParsedResponseAr = array();
foreach ($httpResponseAr as $i => $value)
{
$tmpAr = explode("=", $value);
if(sizeof($tmpAr) > 1)
{
$httpParsedResponseAr[$tmpAr[0]] = $tmpAr[1];
}
}
if((0 == sizeof($httpParsedResponseAr)) || !array_key_exists('ACK', $httpParsedResponseAr))
{
exit("Invalid HTTP Response for POST request($nvpreq) to $API_Endpoint.");
}
return $httpParsedResponseAr;
}
// Set request-specific fields.
$emailSubject = urlencode($vEmailSubject);
$receiverType = urlencode('EmailAddress');
$currency = urlencode('USD'); // or other currency ('GBP', 'EUR', 'JPY', 'CAD', 'AUD')
// Receivers
// Use '0' for a single receiver. In order to add new ones: (0, 1, 2, 3...)
// Here you can modify to obtain array data from database.
$receivers = array(
0 => array(
'receiverEmail' => "user1#paypal.com",
'amount' => "20.00",
'uniqueID' => "id_001", // 13 chars max
'note' => " payment of commissions"), // I recommend use of space at beginning of string.
1 => array(
'receiverEmail' => "user2#paypal.com",
'amount' => "162.38",
'uniqueID' => "A47-92w", // 13 chars max, available in 'My Account/Overview/Transaction details' when the transaction is made
'note' => " payoff of what I owed you" // space again at beginning.
)
);
$receiversLenght = count($receivers);
// Add request-specific fields to the request string.
$nvpStr="&EMAILSUBJECT=$emailSubject&RECEIVERTYPE=$receiverType&CURRENCYCODE=$currency";
$receiversArray = array();
for($i = 0; $i < $receiversLenght; $i++)
{
$receiversArray[$i] = $receivers[$i];
}
foreach($receiversArray as $i => $receiverData)
{
$receiverEmail = urlencode($receiverData['receiverEmail']);
$amount = urlencode($receiverData['amount']);
$uniqueID = urlencode($receiverData['uniqueID']);
$note = urlencode($receiverData['note']);
$nvpStr .= "&L_EMAIL$i=$receiverEmail&L_Amt$i=$amount&L_UNIQUEID$i=$uniqueID&L_NOTE$i=$note";
}
// Execute the API operation; see the PPHttpPost function above.
$httpParsedResponseAr = PPHttpPost('MassPay', $nvpStr);
if("SUCCESS" == strtoupper($httpParsedResponseAr["ACK"]) || "SUCCESSWITHWARNING" == strtoupper($httpParsedResponseAr["ACK"]))
{
exit('MassPay Completed Successfully: ' . print_r($httpParsedResponseAr, true));
}
else
{
exit('MassPay failed: ' . print_r($httpParsedResponseAr, true));
}
?>
Good luck!
What you're looking for is DoMassPay from the PayPal official code samples, not easy to guess that name :P
They have added sample code to their website:
https://cms.paypal.com/cms_content/US/en_US/files/developer/nvp_MassPay_php.txt