Bonjour à toutes et à tous,
Je suis là aujourd'hui pour vous demander votre aide, car là... comment vous dire que je suis un peu perdu...
Alors je vous explique: j'ai suivi le tutoriel de Grafikart pour permettre de faire des achats via Paypal, mais il se trouve que je suis confronté à un problème... Le lien est bel et bien généré, redirection vers l'api de Paypal fonctionnelle, paiement effectué, mais paypal ne passe pas par la fonction notify (notify_url) et va directement à la fonction success().
Je précise tout de même que je travaille en local, sur Wamp, mais que mes test qui nécessite que le site soit en ligne, je met camp en mode « online », donc l'adresse de mon site, est l'adresse IP de ma box.
Voici le code:
app/Controllers/PaypalController.php
<?php
/**
* Fonction du traitement du paiement sur paypal
* @author ZalewSki <zalewski.dev@gmail.com>
* @package app/Controller
*/
class PaypalController extends AppController {
public $name = 'Paypal';
public $uses = array('User', 'Transaction');
public function notify() {
$email_account = Configure::read('Paypal.mail');
$req = 'cmd=_notify-validate';
foreach ($_POST as $key => $value) {
$value = urlencode(stripslashes($value));
$req .= "&$key=$value";
}
$header = "POST /cgi-bin/webscr HTTP/1.0\r\n";
$header .= "Content-Type: application/x-www-form-urlencoded\r\n";
$header .= "Content-Length: " . strlen($req) . "\r\n\r\n";
$fp = fsockopen('ssl://www.' . Configure::read('Paypal.sandbox') . 'paypal.com', 443, $errno, $errstr, 30);
$item_name = $_POST['item_name'];
$item_number = $_POST['item_number'];
$payment_status = $_POST['payment_status'];
$payment_amount = $_POST['mc_gross'];
$payment_tax = $_POST['tax'];
$payment_ht = $payment_amount - $payment_tax;
$payment_currency = $_POST['mc_currency'];
$address = $_POST['address_street'];
$country = $_POST['address_country'];
$city = $_POST['address_city'];
$name = $_POST['address_name'];
$txn_id = $_POST['txn_id'];
$receiver_email = $_POST['receiver_email'];
$payer_email = $_POST['payer_email'];
parse_str($_POST['custom'], $custom);
$this->log($_POST, 'paypal'); die();
if($fp) {
fputs($fp, $header . $req);
while(!feof($fp)) {
$res = fgets($fp, 1024);
if(strcmp($res, "VERIFIED") == 0) {
// Vérifier que $payment_status a la valeur "Completed"
if($payment_status == 'Completed') {
if($email_account == $receiver_email) {
if(($custom['action'] == 'subscribe')) {
$points = $custom['points'];
if($payment_ht == Configure::read("Credits.prices.$points")) {
$user = $this->User->findById($custom['uid']);
if($user) {
$this->Transaction->save(array(
'price' => $payment_ht,
'tax' => $payment_tax,
'txnid' => $txn_id,
'user_id' => $custom['uid'],
'action' => 'subscribe',
'amount' => $points,
'name' => $name,
'country' => $country,
'city' => $city,
'address' => $address
));
$slack = new Slack\Notifier(new Slack\Client(Configure::read('Slack.team'), Configure::read('Slack.token')));
$message = new Slack\Message\Message();
$attachment = new Slack\Message\MessageAttachment();
$field1 = new Slack\Message\MessageField();
$field2 = new Slack\Message\MessageField();
$field1-> setTitle("15 000 Points VIP (15 EUR)")
-> setValue("Achat effectué par ZalewSki (Administrateur), via PayPal \n (Achat enregistré dans la base de donnée)")
-> setShort(true);
$field2-> setTitle("Environnement & Debug")
-> setValue(Configure::read('debug') == 0 ? 'production' : 'development' . " - " . Configure::read('debug'))
-> setShort(true);
$attachment-> addField($field1)
-> addField($field2)
-> setColor('#F0C300')
-> setPretext('Nouveau crédit effectué')
-> setTitle('Crédit #17 - 15 000 Points VIP (Voir Détails)')
-> setMrkdwnIn(array($field1, $field2))
-> setTitleLink('http://standblock.fr/admin/credit/17');
$message-> addAttachment($attachment);
$message-> setChannel(Configure::read('Slack.infos.channel'))
-> setIconEmoji(Configure::read('Slack.infos.icon'))
-> setUsername('StandBlock | Informations')
-> enableLinkNames(Configure::read('Slack.linkNames'));
$slack->notify($message);
}
} else {
$this->log('Paiement de ' . $item_name . ' (' . $item_number . '. Erreur: ' . $payment_ht . ' ne correspond pas !', 'paypal_errors');
}
}
}
} else {
// Statut de paiement: Échec
}
exit();
} elseif(strcmp($res, "INVALID") == 0) {
// Transaction invalide
}
}
fclose($fp);
}
}
}
app/Model/Transaction.php
<?php
/**
* Transaction paypal
* @author ZalewSki <zalewski.dev@gmail.com>
* @package app/Model
*/
class Transaction extends AppModel {
public $useTable = "transactions";
public function requestPaypal($price, $name, $custom) {
$request = array(
'METHOD' => 'BMCreateButton',
'VERSION' => '87',
'USER' => Configure::read('Paypal.USER'),
'PWD' => Configure::read('Paypal.PWD'),
'SIGNATURE' => Configure::read('Paypal.SIGNATURE'),
'BUTTONCODE' => 'HOSTED',
'BUTTONTYPE' => 'BUYNOW',
'BUTTONSUBTYPE' => 'SERVICES',
'L_BUTTONVAR0' => 'business=' . Configure::read('Paypal.mail'),
'L_BUTTONVAR1' => 'item_name=' . $name,
'L_BUTTONVAR2' => 'amount=' . $price,
'L_BUTTONVAR3' => 'currency_code=EUR',
'L_BUTTONVAR4' => 'no_note=1',
'L_BUTTONVAR5' => 'notify_url=http://78.240.109.75/website/paypal/notify',
'L_BUTTONVAR6' => 'return=' . Router::url('/paypal/success', true),
'L_BUTTONVAR7' => 'cancel=' . Router::url('/paypal/cancel', true),
'L_BUTTONVAR8' => 'custom=' . $custom
);
$request = http_build_query($request);
$curlOptions = array(
CURLOPT_URL => 'https://api-3t.' . Configure::read('Paypal.sandbox') . 'paypal.com/nvp',
CURLOPT_VERBOSE => 1,
CURLOPT_SSL_VERIFYPEER => false,
CURLOPT_SSL_VERIFYHOST => 2,
CURLOPT_CAINFO => APP . 'Certificates' . DS . 'cacert.pem',
CURLOPT_RETURNTRANSFER => 1,
CURLOPT_POSTFIELDS => $request
);
$ch = curl_init();
curl_setopt_array($ch, $curlOptions);
$response = curl_exec($ch);
//debug($response); die();
if(curl_errno($ch)) {
debug(curl_error($ch)); die();
return false;
} else {
curl_close($ch);
parse_str($response, $responseA);
//debug($responseA); die();
return $responseA['EMAILLINK'];
}
}
}
app/Controllers/UsersController.php (juste la fonction qui appelle le Model etc...)
<?php
public function membre_checkout($id = null) {
if(!$this->Auth->user('id') OR !$id)
throw new NotFoundException();
$article = $this->Credit->findById($id);
if(!$article)
throw new NotFoundException();
$this->set(compact('article'));
$points = $article['Credit']['item'];
$uid = $this->Auth->user('id');
if($article['Credit']['id'] == $id) {
$custom = 'uid=' . $uid . '&points=' . $points;
$price = number_format($article['Credit']['price'], 2);
$name = $points . ' ' . $article['Credit']['type'];
$this->loadModel('Transaction');
$PPurl = $this->Transaction->requestPaypal($price, $name, $custom);
$this->set(compact('PPurl'));
}
}
PS: Je ne compte pas m'arrêter à Paypal, je compte ajouter PayementWall également.
Voilà, il me semble vous avoir tout donné. En espérant que l'un de vous va pouvoir m'aider.
Cordialement, Cyril.