Braintree push notification is not working - php

I have used the Sandbox account of Braintree for recurring subscriptions. The verification of the webhook end URL is succeeded.But I didn't get any push notifications to my server even after successful completion of the subscription. I am using PHP environment to fetch the POST details. Below is the code segment I have used.
<?php
require_once(app_classes.'DB.Class.php');
require_once(app_classes.'util.Class.php');
require_once app_classes.'braintree/lib/Braintree.php';
Braintree_Configuration::environment(bt_environment);
Braintree_Configuration::merchantId(bt_merchant_id);
Braintree_Configuration::publicKey(bt_public_key);
Braintree_Configuration::privateKey(bt_private_key);
if(
isset($_POST["bt_signature"]) &&
isset($_POST["bt_payload"])
) {
$webhookNotification = Braintree_WebhookNotification::parse(
$_POST["bt_signature"], $_POST["bt_payload"]
);
$message = "[Webhook Received " . $webhookNotification->timestamp->format('Y-m-d H:i:s') . "] "
. "Kind: " . $webhookNotification->kind . " | "
. "Subscription: " . $webhookNotification->subscription->id . "\n";
$subDetails = array( 'data' => $message );
DB::insert('subscription_notifications', $subDetails);
}
return 200;
?>
The server has SSL certificate. Please let me know if any thing I need to do to get it working.

Finally I got the solution. This was the issue related with SSL certificate. The connection get closed with an HTTP status of 599 for all the attempts to POST. This is happened because of the intermediate certificate was missing in the server. We added the certificate .Now I can access the push notifications from Braintree.

Related

Why has DocuSign EventNotification stopped working?

In 2017 I integrated DocuSign with a website using the Official DocuSign PHP Client (https://github.com/docusign/docusign-php-client).
I took the example code and modified it so that it registered an EventNotification which would call back to the website once the signing process is complete. Code below.
require_once('docusign-php-client/autoload.php');
$username = "XXXXX";
$password = "XXXXX";
$integrator_key = "XXXXX";
// change to production (www.docusign.net) before going live
$host = "https://www.docusign.net/restapi";
// create configuration object and configure custom auth header
$config = new DocuSign\eSign\Configuration();
$config->setHost($host);
$config->addDefaultHeader("X-DocuSign-Authentication", "{\"Username\":\"" . $username . "\",\"Password\":\"" . $password . "\",\"IntegratorKey\":\"" . $integrator_key . "\"}");
// instantiate a new docusign api client
$apiClient = new DocuSign\eSign\Client\ApiClient($config);
$accountId = null;
try {
//*** STEP 1 - Login API: get first Account ID and baseURL
$authenticationApi = new DocuSign\eSign\Api\AuthenticationApi($apiClient);
$options = new \DocuSign\eSign\Api\AuthenticationApi\LoginOptions();
$loginInformation = $authenticationApi->login($options);
if (isset($loginInformation) && count($loginInformation) > 0) {
$loginAccount = $loginInformation->getLoginAccounts()[0];
$host = $loginAccount->getBaseUrl();
$host = explode("/v2", $host);
$host = $host[0];
// UPDATE configuration object
$config->setHost($host);
// instantiate a NEW docusign api client (that has the correct baseUrl/host)
$apiClient = new DocuSign\eSign\Client\ApiClient($config);
if (isset($loginInformation)) {
$accountId = $loginAccount->getAccountId();
if (!empty($accountId)) {
//*** STEP 2 - Signature Request from a Template
// create envelope call is available in the EnvelopesApi
$envelopeApi = new DocuSign\eSign\Api\EnvelopesApi($apiClient);
// assign recipient to template role by setting name, email, and role name. Note that the
// template role name must match the placeholder role name saved in your account template.
$templateRole = new DocuSign\eSign\Model\TemplateRole();
$templateRole->setEmail($vars['client_email']['value']);
//$templateRole->setEmail("robbielewis#me.com");
$templateRole->setName($vars['client_name']['value']);
$templateRole->setRoleName("Signee");
// pre-populate text tabs
$tabFields = array();
foreach ($vars as $var) {
$tabField = new \DocuSign\eSign\Model\Text();
$tabField->setTabLabel($var['label']);
$tabField->setValue($var['value']);
$tabFields[] = $tabField;
}
$tabs = new DocuSign\eSign\Model\Tabs();
$tabs->setTextTabs($tabFields);
$templateRole->setTabs($tabs);
// create event notification webhook
$envelope_events = [
(new \DocuSign\eSign\Model\EnvelopeEvent())->setEnvelopeEventStatusCode("sent"),
(new \DocuSign\eSign\Model\EnvelopeEvent())->setEnvelopeEventStatusCode("delivered"),
(new \DocuSign\eSign\Model\EnvelopeEvent())->setEnvelopeEventStatusCode("completed"),
(new \DocuSign\eSign\Model\EnvelopeEvent())->setEnvelopeEventStatusCode("declined"),
(new \DocuSign\eSign\Model\EnvelopeEvent())->setEnvelopeEventStatusCode("voided"),
(new \DocuSign\eSign\Model\EnvelopeEvent())->setEnvelopeEventStatusCode("sent"),
(new \DocuSign\eSign\Model\EnvelopeEvent())->setEnvelopeEventStatusCode("sent")
];
$recipient_events = [
(new \DocuSign\eSign\Model\RecipientEvent())->setRecipientEventStatusCode("Sent"),
(new \DocuSign\eSign\Model\RecipientEvent())->setRecipientEventStatusCode("Delivered"),
(new \DocuSign\eSign\Model\RecipientEvent())->setRecipientEventStatusCode("Completed"),
(new \DocuSign\eSign\Model\RecipientEvent())->setRecipientEventStatusCode("Declined"),
(new \DocuSign\eSign\Model\RecipientEvent())->setRecipientEventStatusCode("AuthenticationFailed"),
(new \DocuSign\eSign\Model\RecipientEvent())->setRecipientEventStatusCode("AutoResponded")
];
$event_notification = new \DocuSign\eSign\Model\EventNotification();
$event_notification->setUrl("https://www.XXXXX.com/wp-content/plugins/XXXXX/XXXXX.php?action=docusign-callback");
$event_notification->setLoggingEnabled("true");
$event_notification->setRequireAcknowledgment("true");
$event_notification->setUseSoapInterface("false");
$event_notification->setIncludeCertificateWithSoap("false");
$event_notification->setSignMessageWithX509Cert("false");
$event_notification->setIncludeDocuments("true");
$event_notification->setIncludeEnvelopeVoidReason("true");
$event_notification->setIncludeTimeZone("true");
$event_notification->setIncludeSenderAccountAsCustomField("true");
$event_notification->setIncludeDocumentFields("true");
$event_notification->setIncludeCertificateOfCompletion("true");
$event_notification->setEnvelopeEvents($envelope_events);
$event_notification->setRecipientEvents($recipient_events);
// instantiate a new envelope object and configure settings
$envelop_definition = new DocuSign\eSign\Model\EnvelopeDefinition();
$envelop_definition->setEmailSubject("Please review and sign your booking contract");
$envelop_definition->setTemplateId("XXXXX");
$envelop_definition->setTemplateRoles(array($templateRole));
$envelop_definition->setEventNotification($event_notification);
// set envelope status to "sent" to immediately send the signature request
$envelop_definition->setStatus("sent");
// optional envelope parameters
$options = new \DocuSign\eSign\Api\EnvelopesApi\CreateEnvelopeOptions();
$options->setCdseMode(null);
$options->setMergeRolesOnDraft(null);
// create and send the envelope (aka signature request)
$envelop_summary = $envelopeApi->createEnvelope($accountId, $envelop_definition, $options);
if (!empty($envelop_summary)) {
echo "Contract sent at " . date('d/m/Y H:i:s') .' to '.$templateRole->getEmail();
}
}
}
}
} catch (DocuSign\eSign\ApiException $ex) {
echo "Exception: " . $ex->getMessage() . "\n";
file_put_contents('XXXXX.log', "\n\n" . date('d/m/Y H:i:s') . ' - Docusign API error ' . $ex->getMessage(), FILE_APPEND);
wp_mail('XXXXX', 'Docusign API error', date('d/m/Y H:i:s') . ' - Docusign API error: ' . $ex->getMessage());
}
This worked fine for a couple of years until recently we stopped getting the EventNotification request to our server from Docusign when the envelope is signed. The envelope is still created successfully and sent to the recipient.
Things I have tried to resolve the issue:
Created many test envelopes using my script and signed them
Monitored the access logs on the server for any http requests following the signing of an envelope that was created by the script, nothing received
Updated the DocuSign PHP Client to the latest version
Enabled logging in DocuSign and checked that the EventNotification request is being received by DocuSign when the envelope is created, see here: https://pastebin.com/xbS338Hx
Contacted my host to ensure that there is no hardware firewall that could be preventing the server receiving HTTP requests from DocuSign
Turned off Cloudflare DNS proxy to make sure that it isn't blocking the request to the server
Contacted DocuSign Support who said to post here as they cannot provide assistance with code issues.
What else can I try to pinpoint the cause of this issue?
Using DocuSign Connect Failures screen in DocuSign Admin I was able to see failed connections in the list.
https://www.XXXXX.com/wp-content/plugins/sXXXXX/XXXXX.php?action=docusign-callback :: Error - The remote server returned an error: (403) Forbidden.
It turned out to be iThemes Security Plugin for Wordpress denying the requests. I disabled the plugin and republished the most recent failed request in DocuSign Admin. The request came through successfully.

Auto-renewable subscriptions for iOS: How to get Server-side receipt validation?

I just finish to developp my app, create my Apple organization account, create all I need on the iTunes connect side, but my problem now, is to develop the server-side receipt validation (because the Validating Receipts Locally seems to have some potential man in the middle security problems).
...
// Load the receipt from the app bundle.
NSURL *receiptURL = [[NSBundle mainBundle] appStoreReceiptURL];
NSData *receipt = [NSData dataWithContentsOfURL:receiptURL];
if (!receipt) { /* No local receipt -- handle the error. */ }
/* ... Send the receipt data to your server ... */
...
I well-understanded the process of the validation as described on that picture:
My main problem is I am not a big expert about server's question, and if you have some examples of what I have to code for the receipt verification and what technologie I have to use (PHP, Angular, or else...).
(First example: On that ticket, is the code on the server side is enough to accomplish that verification?)
(Second example: Is that process is good with the sending of the UDID and the receipt coded in Base64 to the server with a JSON, the server ask to the app store, the app store send ok, and the server send ok to the app. If it is the good process, I can do it easily. Ticket 2
Thanks in advance.
Here is my solution:
I use my server to validate my the receipt like this:
https://github.com/aporat/store-receipt-validator
use ReceiptValidator\iTunes\Validator as iTunesValidator;
$validator = new iTunesValidator(iTunesValidator::ENDPOINT_PRODUCTION); // Or iTunesValidator::ENDPOINT_SANDBOX if sandbox testing
$receiptBase64Data = 'ewoJ
......
OVG8xTlNCRmRHTXZSMDFVSWpzS2ZRPT0iOwoJImVudmlyb25tZW50IiA9ICJTYW5kYm94IjsKCSJwb2QiID0gIjEwMCI7Cgkic2lnbmluZy1zdGF0dXMiID0gIjAiOwp9';
try {
$response = $validator->setReceiptData($receiptBase64Data)->validate();
// $sharedSecret = '1234...'; // Generated in iTunes Connect's In-App Purchase menu
// $response = $validator->setSharedSecret($sharedSecret)->setReceiptData($receiptBase64Data)->validate(); // use setSharedSecret() if for recurring subscriptions
} catch (Exception $e) {
echo 'got error = ' . $e->getMessage() . PHP_EOL;
}
if ($response->isValid()) {
echo 'Receipt is valid.' . PHP_EOL;
echo 'Receipt data = ' . print_r($response->getReceipt()) . PHP_EOL;
} else {
echo 'Receipt is not valid.' . PHP_EOL;
echo 'Receipt result code = ' . $response->getResultCode() . PHP_EOL;
}
And the WS on my server send me okay or not.
(For the local process on the iPad which is not advisable, you can find it here : I'm getting 21004 as status value in reply from apple's sandbox server testing auto-renewable subscriptions in ios?)

cURL error during making API call. cURL Error Number:[60] SSL certificate prob: self signed certificate in certificate chain

Good Day, I am new to server settings. I am currently using laravel 5.4 to integrate my quickbooks app on my live server http://qb.dagnum.com/connect but I continue to get this error
(1/1) SdkException
cURL error during making API call. cURL Error Number:[60] with error:[SSL certificate problem: self signed certificate in certificate chain]
I added the package using 'composer require quickbooks/v3-php-sdk'. the server has SSL certificated Installed as well but still my getting the error.
my code:
use App\Http\Controllers\Controller;
use QuickBooksOnline\API\DataService\DataService;
class Auth2Controller extends Controller
{
public function index()
{
$dataService = DataService::Configure(array(
'auth_mode' => 'oauth2',
'ClientID' => "Q0lCkcEshsGMHOEula2r5RKc2yhxvMsYEpKN1lw1WZwyfd1Si6",
'ClientSecret' => "gE0F9hLgwx9OBzRpNxyOvWJH6L2fIhzAwBugPJHq",
'accessTokenKey' => 'eyJlbmMiOiJBMTI4Q0JDLUhTMjU2IiwiYWxnIjoiZGlyIn0..4z4Assj4x1qt8H4DtQco6A.nmV2jTxaDMVdFWEUO16q5qhbd5aD6U-U-RYnSNywqg-HPC_3_jvwpMJU1a1S5X-PgPUy60WvVy_8p1awY7kIoFzTV4IhdFLrZpYtBUGCjcsvjxWeOSgP6oCayBEmCv7zzabtgB6vxU46jQqKX2IXYUGPPtyYO64hrgELFR4SKUK6boZiVnh8z19gnvsReKMmIINA3-NgC6QJqMRp6HWgzCa9RuDN9tCtrAK2dy5xmJRNSNgdv_gyg1bfdX4l4b30fLPzFk31fsTT9NTJq9PuGtdTsvUuCj7Hme6HPldD9TKYRXWU8TKrQQrQWEpdlbPr6F3rhP6IdmCv9t1XH_WzF_1IseRUoYhiTUjubig-j8gzwajIdYQTzpJQKJ92QiAEyt8k40WWg0v69hEC0w7WRBuUE-IJ50xWypqS_P28IWt1G14rovZ97soGOteSik-41g1icR2zxfNhXGq7zO7oU5B8r-ej5Pb52T0MCMktgd6y32bqwo2pcEzblL2bZs7DZ7LDx5peY4TIfGW21crTE6xjhRr7LdqB8K505pRqIOP20eaRgwtGHLZ3bdBt1_negw2AGjc409BM0nLzzmODxr3yo-YdGwkcOjm5QgbGAsrnpoSo9tSpxPHoN0vMRneRdsKCd6CZG5M1OIOMuj7spkm442tvwiAMCx2Fh-STG6fMnhOq7l_f8NW_3kscxtF2.obQxJKjPfi1KlaQQ_OUoNg',
'refreshTokenKey' => "L011509163184Q0K7DT40SVXhJXAfyoj6B6EbSr3Ty64yVvF5A",
'QBORealmID' => "123145857569084",
'baseUrl' => "https://sandbox-quickbooks.api.intuit.com"
));
$dataService->setMinorVersion("9");
$CompanyInfo = $dataService->getCompanyInfo();
$error = $dataService->getLastError();
if ($error != null) {
echo "The Status code is: " . $error->getHttpStatusCode() . "\n";
echo "The Helper message is: " . $error->getOAuthHelperError() . "\n";
echo "The Response message is: " . $error->getResponseBody() . "\n";
echo "The Intuit Helper message is: IntuitErrorType:{" . $error->getIntuitErrorType() . "} IntuitErrorCode:{" . $error->getIntuitErrorCode() . "} IntuitErrorMessage:{" . $error->getIntuitErrorMessage() . "} IntuitErrorDetail:{" . $error->getIntuitErrorDetail() . "}";
}
}
I also saw the curl function
private function setSSL(&$curl_opt, $verifySSL){
if($verifySSL){
$curl_opt[CURLOPT_SSL_VERIFYPEER] = true;
$curl_opt[CURLOPT_SSL_VERIFYHOST] = 2;
$curl_opt[CURLOPT_CAINFO] = dirname(dirname(__FILE__)) . "/OAuth/OAuth2/certs/apiintuitcom.pem"; //Pem certification Key Path
}
}
tried to replace
$curl_opt[CURLOPT_CAINFO] = dirname(dirname(__FILE__)) . "/OAuth/OAuth2/certs/apiintuitcom.pem";
to `$curl_opt[CURLOPT_CAINFO] ="/home/servername/public_html/quickbooks_app/resources/cert/cacert.pem";`
but I get this error
Http Status Code:[401] Http Response Body are null or Empty.
What should I do to fix this please..
I've dropped the apiintuitcom.pem file that comes with the SDK and started using the cacert.pem that you can find on PHP_OAuth2.0 example app. I was also using a wrong baseUrl but I changed with yours. That fixed the bug for me. My setSSL method looks like this now:
private function setSSL(&$curl_opt, $verifySSL){
if($verifySSL){
$curl_opt[CURLOPT_SSL_VERIFYPEER] = true;
$curl_opt[CURLOPT_SSL_VERIFYHOST] = 2;
$curl_opt[CURLOPT_CAINFO] = dirname(dirname(__FILE__)) . "/OAuth/OAuth2/certs/cacert.pem"; //Pem certification Key Path
}
}
My $dataService is pretty much the same as yours.
you go to /vendor/quickbooks/v3-php-sdk/src/Core/HttpClients and edit CurlHttpClient.php
find
// $curl_opt[CURLOPT_CAINFO] = dirname(dirname(__FILE__)) . "/OAuth/OAuth2/certs/apiintuitcom.pem"; //Pem certification Key Path
change it to
' $curl_opt[CURLOPT_CAINFO] ="/home/folder/public_html/quickbooks_app/resources/cert/cacert.pem";
note: you can put your cacert.pem anywhere just change the address where you link it.
you can get cacert.pem on this site https://curl.haxx.se/docs/caextract.html

magento - integrating paypal adaptive payments (chained payments)

I am currently working on integrating paypal's chained payment method into magento.
https://cms.paypal.com/ca/cgi-bin/?cmd=_render-content&content_ID=developer/e_howto_api_APIntro
The payment flow would be:
buyer pays seller's paypal account -> pp adaptive payment gateway -> 85% goes to seller's paypal, 15% goes to site's default paypal account (buyer not aware of this split).
I already have the api function take takes 2 paypal accounts (seller's & site's default), and payment amount, and am looking to integrate this.
Has anyone integrated adaptive payments before, or point me to where I should integrate this logic? Would I overwrite one of the functions in /app/code/core/Mage/paypal ?
I basically need to get the total cost in the current shopping cart, and the paypal email of the current store, and pass that over to my function.
First of all you need to create a seprate payment method for magento i would suggest to create a payment module for it after that you need to signup in to the paypal sandbox account . i am attaching sample code for adaptive payment integration also some useful links for the flow how it will work
ini_set("track_errors", true);
//set PayPal Endpoint to sandbox
$sandbox="";
$API_AppID = XXXXXXXXXXXXXXXXXXX;//your adaptive payment app Id
//value for check sandbox enable or disable
$sandboxstatus=1;
if($sandboxstatus==1){
$sandbox="sandbox.";
$API_AppID="APP-80W284485P519543T";
}
$url = trim("https://svcs.".$sandbox."paypal.com/AdaptivePayments/Pay");
//PayPal API Credentials
$API_UserName = XXXXXXXXXXXXXXXXXXX;//TODO
$API_Password = XXXXXXXXXXXXXXXXXXX;//TODO
$API_Signature = XXXXXXXXXXXXXXXXXXX;//TODO
//Default App ID for Sandbox
$API_RequestFormat = "NV";
$API_ResponseFormat = "NV";
$bodyparams = array (
"requestEnvelope.errorLanguage" => "en_US",
"actionType" => "PAY",
"currencyCode" => "USD",//currency Code
"cancelUrl" => "",// cancle url
"returnUrl" => "paymentsuccess",//return url
"ipnNotificationUrl" => "paymentnotify"//notification url that return all data related to payment
);
$finalcart=array(
array('paypalid'=>"partner1",'price'=>50),
array('paypalid'=>"partner2",'price'=>50),
array('paypalid'=>"partner3",'price'=>50),
array('paypalid'=>"partner4",'price'=>50),
array('paypalid'=>"partner5",'price'=>50)
);
$i=0;
foreach($finalcart as $partner){
$temp=array("receiverList.receiver($i).email"=>$partner['paypalid'],"receiverList.receiver($i).amount"=>$partner['price']);
$bodyparams+=$temp;
$i++;
}
// convert payload array into url encoded query string
$body_data = http_build_query($bodyparams, "", chr(38));
try{
//create request and add headers
$params = array("http" => array(
"method" => "POST",
"content" => $body_data,
"header" => "X-PAYPAL-SECURITY-USERID: " . $API_UserName . "\r\n" .
"X-PAYPAL-SECURITY-SIGNATURE: " . $API_Signature . "\r\n" .
"X-PAYPAL-SECURITY-PASSWORD: " . $API_Password . "\r\n" .
"X-PAYPAL-APPLICATION-ID: " . $API_AppID . "\r\n" .
"X-PAYPAL-REQUEST-DATA-FORMAT: " . $API_RequestFormat . "\r\n" .
"X-PAYPAL-RESPONSE-DATA-FORMAT: " . $API_ResponseFormat . "\r\n"
));
//create stream context
$ctx = stream_context_create($params);
//open the stream and send request
$fp = #fopen($url, "r", false, $ctx);
//get response
$response = stream_get_contents($fp);
//check to see if stream is open
if ($response === false) {
throw new Exception("php error message = " . "$php_errormsg");
}
//close the stream
fclose($fp);
//parse the ap key from the response
$keyArray = explode("&", $response);
foreach ($keyArray as $rVal){
list($qKey, $qVal) = explode ("=", $rVal);
$kArray[$qKey] = $qVal;
}
//set url to approve the transaction
$payPalURL = "https://www.".$sandbox."paypal.com/webscr?cmd=_ap-payment&paykey=" . $kArray["payKey"];
//print the url to screen for testing purposes
If ( $kArray["responseEnvelope.ack"] == "Success") {
echo '<p><a id="paypalredirect" href="' . $payPalURL . '"> Click here if you are not redirected within 10 seconds...</a> </p>';
echo '<script type="text/javascript">
function redirect(){
document.getElementById("paypalredirect").click();
}
setTimeout(redirect, 2000);
</script>';
}
else {
echo 'ERROR Code: ' . $kArray["error(0).errorId"] . " <br/>";
echo 'ERROR Message: ' . urldecode($kArray["error(0).message"]) . " <br/>";
}
}
catch(Exception $e) {
echo "Message: ||" .$e->getMessage()."||";
}
you may ignore the module flow but you can follow the steps for setting up the sandbox account for paypal payment hope it will help
You're probably going to need to write a completely new payment module for that. From what I've seen (and I'll admit it's been a little bit since I've looked at it in detail) the current PayPal integration in Magento does not support chained payments.
You could still extend the existing PayPal module(s) if you want, but you'll need to write the API requests to handle the adaptive payments calls accordingly. Again, there aren't any existing functions that you would simply override in your extended module. You'll just need to create your own from the start.
If the latest version of Magento added some adaptive payments then I could be wrong on that. If that's the case, you'd probably see something in the /paypal directory directly referring to it, and you can study the functions in there to see what you could override with your own. That said, if they've already adaptive payments included as a payment module then you really shouldn't need to customize it in code.

Send push notification to a group

I am not sure how to send a push notification to multiple tokens. With my script it seems to only send a push notification to one... as per Apple it would be better to have one open connection and keep it open and send messages when needed. Not sure how to do it on my php server...
$payload['aps'] = array('alert' => "New Cave report for ".$caveName,'badge' => 1, 'sound' => 'default');
$payload['condition'] = array('conditionID' => $ccID, 'caveName' => $caveName);
$payload = json_encode($payload);
// Connection Part
$apnsHost = 'gateway.sandbox.push.apple.com';
$apnsPort = 2195;
$apnsCert = '/var/www/web543/files/apns-dev.pem';
if (!file_exists($apnsCert) )
{
echo "Certification file not found!";
} else
{
$streamContext = stream_context_create();
stream_context_set_option($streamContext,'ssl','local_cert',$apnsCert);
$apns = stream_socket_client('ssl://' . $apnsHost . ':' . $apnsPort,$error,$errorString,2,STREAM_CLIENT_CONNECT,$streamContext);
if ( !$apns )
{
echo "Connection Failed!".$errorString;
} else
{
$db->query("SELECT DISTINCT token FROM notifications WHERE userID != '{$userID}'");
if ($db->num_rows()>0)
{
while ($db->next_record())
{
$apnsMessage = chr(0) . chr(0) . chr(32) . pack('H*', str_replace(' ', '', $db->f('token'))) . chr(0) . chr(strlen($payload)) . $payload;
if ( fwrite($apns, $apnsMessage) === FALSE )
{
echo "Can not write";
}
}
}
}
fclose($apns);
}
some output of $apnsMessage
Token: 5a984922e19eab54f78fd54e24d5b02a3d30ccdbbeee34aadbdacaa687ee1261 Message: Z˜I"áž«T÷ÕN$Õ°*=0ÌÛ¾î4ªÛÚʦ‡îa†{"aps":{"alert":"New Cave report for Test Entry","badge":1,"sound":"default"},"condition":{"conditionID":"1","caveName":"Test Entry"}}
Token: c607acc70bd4885bf56f3b4827523023bf93a1d644626768ab0304bb3b4414dc Message: ƬÇÔˆ[õo;H'R0#¿“¡ÖDbgh«»;D܆{"aps":{"alert":"New Cave report for Test Entry","badge":1,"sound":"default"},"condition":{"conditionID":"1","caveName":"Test Entry"}}
Token: 785ec3128972bd3d4c3e6fa1eeead97b73b0696e2361339a2467e6ba775b83ea Message: x^Ér½=L>o¡îêÙ{s°in#a3š$gæºw[ƒê†{"aps":{"alert":"New Cave report for Test Entry","badge":1,"sound":"default"},"condition":{"conditionID":"1","caveName":"Test Entry"}}
Token: c592487e3c71e921d0b7a825b66ed5e58070fee709131535ac391f14febbcfdc Message: Å’H~Token: 061bc20ba3a0fc17c689e052b42b5789f502a52d43180ea114e3212077045315 Message: £ üƉàR´+W‰õ¥-C¡ã! wS†{"aps":{"alert":"New Cave report for Test Entry","badge":1,"sound":"default"},"condition":{"conditionID":"1","caveName":"Test Entry"}}
Token: 26fb66fef67a122ca456f106363115285d4d7156e7c8ab6e51bd5bfa9bab2d03 Message: &ûfþöz,¤Vñ61(]MqVçÈ«nQ½[ú›«-†{"aps":{"alert":"New Cave report for Test Entry","badge":1,"sound":"default"},"condition":{"conditionID":"1","caveName":"Test Entry"}}
Ok. I found the problem.
When compiling as Debug it will send only on the first device when using the DEV certification. If I use Deployment like Ad-Hoc I have to use the Prod Servers and Prod Certificates.
Now everything works.
I think you have to run this script in loop according to the count of token.
Means first get the token array and then according to the count make a loop. Then take one device token from the index 0 and run this script. Then selcect another token at index 1 and then run again this script.
To send push notification to multiple device you have connect each time to apple server and close connection and again open and send.This is the process.
Yeah you should not be making and tearing down the socket connection every time you need to send the push. Once you establish the socket connection, you can write as many as push messages you want to any number of devices.
What is the exact problem that you are observing? Is your socket connection getting dropped?
Have a look at this question if you need additional help : How to send Push Notification to multiple devices?

Categories