/** * Recevoir la notification paypal * du paiement * * @return array */ function bank_paypal_recoit_notification() { $valeurs = array(); foreach ($_POST as $key => $value) { $valeurs[$key] = $value; } spip_log('Paypal IPN' . var_export($valeurs, true), 'paypal'); if (!isset($valeurs['receiver_email']) or $valeurs['receiver_email'] != _PAYPAL_BUSINESS_USERNAME) { spip_log("receiver_email errone : POST :" . var_export($valeurs, true), 'paypal_invalid_IPN'); return array(0, false); } if (!isset($valeurs['invoice'])) { spip_log("pas de invoice specifie : POST :" . var_export($valeurs, true), 'paypal_invalid_IPN'); return array(0, false); } list($id_transaction, $transaction_hash) = explode('|', $valeurs['invoice']); if (!($row = sql_fetsel("*", "spip_transactions", "id_transaction=" . intval($id_transaction) . " AND transaction_hash=" . sql_quote($transaction_hash)))) { spip_log("id_transaction invalide : {$id_transaction}/hash{$transaction_hash} : POST :" . var_export($value, true), 'paypal_invalid_IPN'); return array(0, false); } if ($row['reglee'] == 'oui') { return array($id_transaction, true); } // cette transaction a deja ete reglee. double entree, on ne fait rien // verifier que le status est bien ok if (!isset($valeurs['payment_status']) or $valeurs['payment_status'] != 'Completed') { spip_log("Transaction {$id_transaction}:payment_status!=completed : POST :" . var_export($valeurs, true), 'paypal_invalid_IPN'); $message = "Votre règlement n'a pu être réalisé par Paypal"; return paypal_echec_transaction($id_transaction, $message); // erreur sur la transaction } // verifier que le numero de transaction au sens paypal // (=numero d'autorisation ici) est bien fourni if (!isset($valeurs['txn_id']) or !$valeurs['txn_id']) { spip_log("Transaction {$id_transaction}:pas de txn_id : POST :" . var_export($valeurs, true), 'paypal_invalid_IPN'); $message = "Nous n'avons reçu aucune autorisation de Paypal concernant votre règlement"; return paypal_echec_transaction($id_transaction, $message); // erreur sur la transaction } // verifier que le numero de transaction au sens paypal // (=numero d'autorisation ici) n'a pas deja ete utilise $autorisation_id = $valeurs['txn_id']; if ($id = sql_getfetsel("id_transaction", "spip_transactions", "autorisation_id=" . sql_quote($autorisation_id) . " AND mode='paypal'")) { // une transaction existe deja avec ce numero d'autorisation spip_log("Transaction {$id_transaction}:txn_id {$autorisation_id} deja utilise par {$id} : POST :" . var_export($valeurs, true), 'paypal_invalid_IPN'); $message = "Les informations concernant votre transaction {$id_transaction} sont erronées"; return paypal_echec_transaction($id_transaction, $message); // erreur sur la transaction } // enregistrer immediatement le present numero d'autorisation pour ne pas risquer des requetes simultanees sur le meme id sql_updateq("spip_transactions", array("autorisation_id" => $autorisation_id, "mode" => 'paypal'), "id_transaction=" . intval($id_transaction)); // une monnaie est-elle bien indique (et en EUR) ? if (!isset($valeurs['mc_currency']) or $valeurs['mc_currency'] != 'EUR') { spip_log("Transaction {$id_transaction}:devise incorrecte : POST :" . var_export($valeurs, true), 'paypal_invalid_IPN'); $message = "Les informations concernant votre transaction {$id_transaction} sont erronées"; return paypal_echec_transaction($id_transaction, $message); // erreur sur la transaction } // un montant est il bien renvoye ? if (!isset($valeurs['mc_gross']) or ($montant_regle = $valeurs['mc_gross']) != $row['montant']) { spip_log("Transaction {$id_transaction}:montant incorrect : POST :" . var_export($valeurs, true), 'paypal_invalid_IPN'); $message = "Les informations concernant votre transaction {$id_transaction} sont erronées"; return paypal_echec_transaction($id_transaction, $message); // erreur sur la transaction } // verifier que la notification vien bien de paypal ! if (!bank_paypal_verifie_notification($valeurs)) { spip_log("Transaction {$id_transaction}:reponse IPN!=VERIFIE : POST :" . var_export($valeurs, true), 'paypal_invalid_IPN'); $message = "Paypal n'a pu confirmer la validité de votre règlement concernant la transaction {$id_transaction}"; return paypal_echec_transaction($id_transaction, $message); // erreur sur la transaction } sql_updateq("spip_transactions", array("autorisation_id" => $autorisation_id, "mode" => 'paypal', "montant_regle" => $montant_regle, "date_paiement" => 'NOW()', "statut" => 'ok', "reglee" => 'oui'), "id_transaction=" . intval($id_transaction)); spip_log("simple_reponse : id_transaction {$id_transaction}, reglee", 'paypal'); $regler_transaction = charger_fonction('regler_transaction', 'bank'); $regler_transaction($id_transaction, "", $row); return array($id_transaction, true); }
/** * Recevoir la notification paypal * du paiement * * @return array */ function bank_paypal_recoit_notification() { $valeurs = array(); foreach ($_POST as $key => $value) { $valeurs[$key] = $value; } spip_log('Paypal IPN' . var_export($valeurs, true), 'paypal'); if (!isset($valeurs['receiver_email']) or $valeurs['receiver_email'] != _PAYPAL_BUSINESS_USERNAME) { spip_log("receiver_email errone : POST :" . var_export($valeurs, true), 'paypal_invalid_IPN'); return array(0, false); } if (!isset($valeurs['invoice'])) { spip_log("pas de invoice specifie : POST :" . var_export($valeurs, true), 'paypal_invalid_IPN'); return array(0, false); } list($id_transaction, $transaction_hash) = explode('|', $valeurs['invoice']); if (!($row = sql_fetsel("*", "spip_commandes_transactions", "id_transaction=" . intval($id_transaction) . " AND transaction_hash=" . sql_quote($transaction_hash)))) { spip_log("id_transaction invalide : {$id_transaction}/hash{$transaction_hash} : POST :" . var_export($value, true), 'paypal_invalid_IPN'); return array(0, false); } if ($row['reglee'] == 'oui') { return array($id_transaction, true); } // cette transaction a deja ete reglee. double entree, on ne fait rien // verifier que le status est bien ok if (!isset($valeurs['payment_status']) or $valeurs['payment_status'] != 'Completed') { spip_log("Transaction {$id_transaction}:payment_status!=completed : POST :" . var_export($valeurs, true), 'paypal_invalid_IPN'); $message = "Votre règlement n'a pu être réalisé par Paypal"; return paypal_echec_transaction($id_transaction, $message); // erreur sur la transaction } // verifier que le numero de transaction au sens paypal // (=numero d'autorisation ici) est bien fourni if (!isset($valeurs['txn_id']) or !$valeurs['txn_id']) { spip_log("Transaction {$id_transaction}:pas de txn_id : POST :" . var_export($valeurs, true), 'paypal_invalid_IPN'); $message = "Nous n'avons reçu aucune autorisation de Paypal concernant votre règlement"; return paypal_echec_transaction($id_transaction, $message); // erreur sur la transaction } // verifier que le numero de transaction au sens paypal // (=numero d'autorisation ici) n'a pas deja ete utilise $autorisation_id = $valeurs['txn_id']; if ($id = sql_getfetsel("id_transaction", "spip_commandes_transactions", "autorisation_id=" . sql_quote($autorisation_id) . " AND mode='paypal'")) { // une transaction existe deja avec ce numero d'autorisation spip_log("Transaction {$id_transaction}:txn_id {$autorisation_id} deja utilise par {$id} : POST :" . var_export($valeurs, true), 'paypal_invalid_IPN'); $message = "Les informations concernant votre transaction {$id_transaction} sont erronées"; return paypal_echec_transaction($id_transaction, $message); // erreur sur la transaction } // enregistrer immediatement le present numero d'autorisation pour ne pas risquer des requetes simultanees sur le meme id sql_updateq("spip_commandes_transactions", array("autorisation_id" => $autorisation_id, "mode" => 'paypal'), "id_transaction=" . intval($id_transaction)); // une monnaie est-elle bien indique (et en EUR) ? if (!isset($valeurs['mc_currency']) or $valeurs['mc_currency'] != 'EUR') { spip_log("Transaction {$id_transaction}:devise incorrecte : POST :" . var_export($valeurs, true), 'paypal_invalid_IPN'); $message = "Les informations concernant votre transaction {$id_transaction} sont erronées"; return paypal_echec_transaction($id_transaction, $message); // erreur sur la transaction } // un montant est il bien renvoye ? /* TODO problème d'arrondis sur les montants HT + TVA. Le total peut varier d'1 centime en plus ou en moins. Dans l'immédiat, on enlève cette vérification. A terme, il faudrait plutôt prendre comme base des prix TTC (au lieu des prix HT) et faire apparaitre les prix HT en différence de la TVA. */ if (!isset($valeurs['mc_gross'])) { spip_log("Transaction {$id_transaction}:montant incorrect : POST :" . var_export($valeurs, true), 'paypal_invalid_IPN'); $message = "Les informations concernant votre transaction {$id_transaction} sont erronées"; return paypal_echec_transaction($id_transaction, $message); // erreur sur la transaction } // le montant existe, on va tolérer une petite marge d'erreur, en raison des arrondis sur les calculs de TVA $montant_attendu = $row['montant']; $montant_regle = $valeurs['mc_gross']; $ecart_pourcentage = abs(($montant_attendu - $montant_regle) * 100 / $montant_attendu); if ($ecart_pourcentage > 0.05) { spip_log("Transaction {$id_transaction} : montant incorrect -- différence importante -- : POST :" . var_export($valeurs, true), 'paypal_invalid_IPN'); $message = "Les informations concernant votre transaction {$id_transaction} sont erronées"; return paypal_echec_transaction($id_transaction, $message); } // verifier que la notification vient bien de paypal ! if (!bank_paypal_verifie_notification($valeurs)) { spip_log("Transaction {$id_transaction}:reponse IPN!=VERIFIE : POST :" . var_export($valeurs, true), 'paypal_invalid_IPN'); $message = "Paypal n'a pu confirmer la validité de votre règlement concernant la transaction {$id_transaction}"; return paypal_echec_transaction($id_transaction, $message); // erreur sur la transaction } sql_updateq("spip_commandes_transactions", array("autorisation_id" => $autorisation_id, "mode" => 'paypal', "montant_regle" => $montant_regle, "date_paiement" => 'NOW()', "statut" => 'ok', "reglee" => 'oui'), "id_transaction=" . intval($id_transaction)); spip_log("simple_reponse : id_transaction {$id_transaction}, reglee", 'paypal'); // mise à jour de la commande $id_commande = sql_getfetsel("id_commande", "spip_commandes_transactions", "id_transaction=" . intval($id_transaction)); sql_updateq("spip_commandes", array("paiement" => "paypal", "statut" => "paye", "date_paiement" => 'NOW()'), "id_commande=" . intval($id_commande)); $regler_transaction = charger_fonction('regler_transaction', 'bank'); $regler_transaction($id_transaction, "", $row); return array($id_transaction, true); }