/** * Jamais appele directement dans le plugin bank/ * mais par une eventuelle methode abos/resilier d'un plugin externe * * @param string $uid * @param array|string $config * @return bool */ function presta_payzen_call_resilier_abonnement_dist($uid, $config = 'payzen') { include_spip('presta/payzen/lib/ws-v5/classes'); include_spip('presta/systempay/inc/systempay'); include_spip('inc/bank'); $trans = sql_fetsel("mode,pay_id", "spip_transactions", "abo_uid=" . sql_quote($uid) . " AND mode LIKE " . sql_quote($config . '%'), '', 'id_transaction', '0,1'); if (!is_array($config)) { $config = bank_config($trans['mode']); } $mode = $config['presta']; $vads = new PayzenWSv5($config); $response = new cancelSubscriptionResponse(); try { $response = $vads->cancelSubscription($trans['pay_id'], $uid); } catch (Exception $e) { spip_log($s = "call_resilier_abonnement : erreur " . $e->getMessage(), $mode . _LOG_ERREUR); return false; } if ($e = $response->cancelSubscriptionResult->commonResponse->responseCode) { spip_log($s = "call_resilier_abonnement {$uid} : erreur {$e} : " . $response->cancelSubscriptionResult->commonResponse->responseCodeDetail, $mode . _LOG_ERREUR); // 33 : Invalid Subscription => on est donc bien desabonne if ($e == 33) { return true; } else { return false; } } return true; }
/** * Appeler le presta bancaire si celui-ci dispose d'une methode dans son API pour resilier un abonnement * @param string $abonne_uid * @param string $mode_paiement * @return bool * renvoie false si le presta bancaire indique un echec, true dans tous les autres cas */ function abos_resilier_notify_bank($abonne_uid, $mode_paiement = null) { if (!$mode_paiement) { $mode_paiement = sql_getfetsel("mode", "spip_transactions", "abo_uid=" . sql_quote($abonne_uid, '', 'text'), "", "id_transaction DESC"); } spip_log("abos/resilier_notify_bank abonne_uid={$abonne_uid} mode={$mode_paiement}", "abos_resil"); $ok = true; // notifier au presta bancaire si besoin if ($mode_paiement and $abonne_uid) { include_spip("inc/bank"); if (!($config = bank_config($mode_paiement, true)) or !isset($config['presta']) or !($presta = $config['presta'])) { spip_log("abos/resilier_notify_bank presta inconnu pour mode={$mode_paiement}", "abos_resil" . _LOG_ERREUR); } if ($presta and $presta_resilier = charger_fonction('resilier_abonnement', "presta/{$presta}/call", true)) { $ok = $presta_resilier($abonne_uid); if (!$ok) { spip_log("Resiliation abo " . $abonne_uid . " refuse par le prestataire", 'abos_resil' . _LOG_ERREUR); } } else { spip_log("abos/resilier_notify_bank : pas de methode resilier_abonnement pour le presta {$presta}", "abos_resil" . _LOG_INFO_IMPORTANTE); } if (!$ok) { bank_simple_call_resilier_abonnement($abonne_uid, $mode_paiement); // TODO ajouter un message a l'abonnement pour le feedback user spip_log("Envoi email de desabo " . $abonne_uid . " au webmestre", 'abos_resil' . _LOG_INFO_IMPORTANTE); // neanmoins, si plus d'echeance prevue, on peut finir // (cas d'un abos deja resilie fin de mois qu'on veut forcer a resilier immediatement) // TODO eventuel } } return $ok; }
/** * Jamais appele directement dans le plugin bank/ * mais par une eventuelle methode abos/resilier d'un plugin externe * * @param string $uid * @param array|string $config * @return bool */ function presta_stripe_call_resilier_abonnement_dist($uid, $config = 'stripe') { include_spip('inc/bank'); $trans = sql_fetsel("mode, pay_id", "spip_transactions", "abo_uid=" . sql_quote($uid) . " AND mode LIKE " . sql_quote($config . '%'), '', 'id_transaction', '0,1'); if (!is_array($config)) { $config = bank_config($trans['mode']); } $mode = $config['presta']; // charger l'API Stripe avec la cle stripe_init_api($config); $erreur = $erreur_code = ''; try { if ($sub = \Stripe\Subscription::retrieve($uid)) { $res = $sub->cancel(); if ($res->status != 'canceled') { $erreur = 'cancel failed' . var_export((array) $res, true); } } else { $erreur = "unknown subscription"; } } catch (Exception $e) { if ($body = $e->getJsonBody()) { $err = $body['error']; list($erreur_code, $erreur) = stripe_error_code($err); } else { $erreur = $e->getMessage(); $erreur_code = 'error'; } } if ($erreur or $erreur_code) { spip_log($s = "call_resilier_abonnement {$uid} : erreur {$erreur_code} - {$erreur}", $mode . _LOG_ERREUR); return false; } return true; }
/** * Jamais appele directement dans le plugin bank/ * mais par une eventuelle methode abos/resilier d'un plugin externe * * @param string $uid * @param array|string $config * @return bool */ function presta_paybox_call_resilier_abonnement_dist($uid, $config = 'paybox') { include_spip('inc/bank'); if (!is_array($config)) { $mode = sql_getfetsel("mode", "spip_transactions", "abo_uid=" . sql_quote($uid) . " AND statut=" . sql_quote('ok') . " AND mode LIKE " . sql_quote($config . '%')); $config = bank_config($mode); } $args = "VERSION=001" . "&TYPE=001" . "&SITE=" . str_pad($config['PBX_SITE'], 7, "0", STR_PAD_LEFT) . "&MACH=" . str_pad($config['PBX_RANG'], 3, "0", STR_PAD_LEFT) . "&IDENTIFIANT=" . $config['PBX_IDENTIFIANT'] . "&ABONNEMENT=" . $uid; $url = paybox_url_resil($config) . "?" . $args; include_spip('inc/distant'); $reponse = recuperer_page($url); spip_log("uid:{$uid}, {$url}, reponse:{$reponse}", 'paybox_abos_resil'); parse_str($reponse, $res); if ($res['ACQ'] == 'OK' and $res['ABONNEMENT'] == $uid) { return true; } return false; }
function formulaires_encaisser_reglement_traiter_dist($id_transaction, $config) { include_spip('inc/bank'); if (is_string($config)) { $config = bank_config($config); } $mode = $config['presta']; $hash = sql_getfetsel("transaction_hash", "spip_transactions", "id_transaction=" . intval($id_transaction)); $autorisation_id = autorisation_suffixe(); if (strlen($autorisation_id) < 55) { $autorisation_id = _request('autorisation_id') . "|" . $autorisation_id; } include_spip('inc/bank'); $response = array('id_transaction' => $id_transaction, 'transaction_hash' => $hash, 'autorisation_id' => $autorisation_id); $sign = bank_sign_response_simple($mode, $response); foreach ($response as $k => $v) { set_request($k, $v); } set_request("sign", $sign); set_request("bankp", $mode . "-" . bank_config_id($config)); // on charge l'action et on l'appelle pour passer par tout le processus de paiement standard $bank_response = charger_fonction("bank_response", "action"); return array('message_ok' => $bank_response()); }
/** * Afficher l'inclusion attente reglement si elle existe, * en fonction du presta * @param string $mode * @param int $id_transaction * @param string $transaction_hash * @return string */ function bank_afficher_attente_reglement($mode, $id_transaction, $transaction_hash, $type) { include_spip('inc/bank'); $config = bank_config($mode); $presta = $config['presta']; if (trouver_fond("attente", "presta/{$presta}/payer/")) { return recuperer_fond("presta/{$presta}/payer/attente", array('id_transaction' => $id_transaction, 'transaction_hash' => $transaction_hash, 'config' => $config, 'type' => $type)); } return ""; }
function action_bank_response_dist($cancel = null, $auto = null, $presta = null) { $id_transaction = 0; $auto = $auto ? "auto" : ""; $result = false; // intercepter les retours depuis un presta // actif ou non (le paiement a ete fait en banque, on le decode dans tous les cas du moment qu'on sait le faire) if (!$presta) { $presta = _request('bankp'); } include_spip('inc/bank'); if ($presta and $config = bank_config($presta) and !isset($config['erreur'])) { $presta = $config['presta']; // en cas de renommage $test = ""; if (isset($config['mode_test']) and $config['mode_test']) { $test = "_test"; } if (!$auto or !($call_response = charger_fonction('autoresponse', "presta/{$presta}/call", true))) { $call_response = charger_fonction('response', "presta/{$presta}/call"); } if ($cancel) { define('_BANK_CANCEL_TRANSACTION', true); } // si on a recu un POST, le traduire en request_uri pour les logs et faciliter le code de certains modules $GLOBALS['BANK_REQUEST_URI'] = $_SERVER['REQUEST_URI']; if ($_SERVER['REQUEST_METHOD'] == 'POST') { $q = http_build_query($_POST); if (strpos($GLOBALS['BANK_REQUEST_URI'], "?") !== false) { $GLOBALS['BANK_REQUEST_URI'] .= "&{$q}"; } else { $GLOBALS['BANK_REQUEST_URI'] .= "?{$q}"; } } $inactif = ""; if (!$config['actif']) { $inactif = "(inactif) "; } spip_log('call_' . $auto . 'response ' . $inactif . ': ' . $GLOBALS['BANK_REQUEST_URI'], "{$presta}{$auto}{$test}"); list($id_transaction, $result) = $call_response($config); spip_log('call_' . $auto . 'response ' . $inactif . ': ' . "{$id_transaction}/{$result}", "{$presta}{$auto}{$test}"); } else { spip_log("Prestataire {$presta} inconnu", 'bank_response' . _LOG_ERREUR); } // fall back si le presta n'a rien renvoye de lisible // et qu'on a bien id=id_transaction;hash dans l'url if (!$result and !$id_transaction and $id = _request('id') and $id = explode(';', $id) and count($id) == 2 and $id_transaction = reset($id) and $hash = end($id)) { $id_transaction = sql_getfetsel("id_transaction", "spip_transactions", "id_transaction=" . intval($id_transaction) . " AND transaction_hash=" . sql_quote($hash)); if ($id_transaction) { $set = array('mode' => $presta, 'statut' => 'echec', 'message' => 'Transaction annulée'); sql_updateq("spip_transactions", $set, 'id_transaction=' . intval($id_transaction) . " AND statut=" . sql_quote('commande')); } } // notifier les reglement en echec/annule if (!$result and $id_transaction and $row = sql_fetsel('*', 'spip_transactions', 'id_transaction=' . intval($id_transaction))) { pipeline('trig_bank_reglement_en_echec', array('args' => array('statut' => 'echec', 'mode' => $row['mode'], 'type' => $row['abo_uid'] ? 'abo' : 'acte', 'id_transaction' => $id_transaction, 'row' => $row), 'data' => '')); } if (!$auto) { $abo = sql_getfetsel("abo_uid", "spip_transactions", "id_transaction=" . intval($id_transaction)); return redirige_apres_retour_transaction($presta, !$abo ? 'acte' : 'abo', $cancel ? false : $result, $id_transaction); } die; // mourir silencieusement }
/** * Afficher le bouton pour gerer/interrompre un abonnement * @param array|string $config * @param string $abo_uid * @return array|string */ function bank_affiche_gerer_abonnement($config, $abo_uid) { // $config de type string ? include_spip('inc/bank'); if (is_string($config)) { $config = bank_config($config, true); } if ($trans = sql_fetsel("*", "spip_transactions", $w = "abo_uid=" . sql_quote($abo_uid) . ' AND mode LIKE ' . sql_quote($config['presta'] . '%') . " AND " . sql_in('statut', array('ok', 'attente')), '', 'id_transaction')) { $config = bank_config($trans['mode']); $fond = "modeles/gerer_abonnement"; if (trouver_fond($f = "presta/" . $config['presta'] . "/payer/gerer_abonnement")) { $fond = $f; } return recuperer_fond($fond, array('presta' => $config['presta'], 'id_transaction' => $trans['id_transaction'], 'abo_uid' => $abo_uid)); } return ""; }
/** * Jamais appele directement dans le plugin bank/ * mais par une eventuelle methode abos/resilier d'un plugin externe * c'est une fallback quand le presta ne sait pas gerer le desabonnement en appel serveur * ou quand cela echoue * * @param string $uid * @param array|string $config * @return bool */ function bank_simple_call_resilier_abonnement($uid, $config) { include_spip('inc/bank'); if (!is_array($config)) { $mode = sql_getfetsel("mode", "spip_transactions", "abo_uid=" . sql_quote($uid) . " AND statut=" . sql_quote('ok') . " AND mode LIKE " . sql_quote($config . '%')); $config = bank_config($mode); } // on envoie un mail au webmestre avec reference pour que le webmestre aille faire la resiliation manuellement $sujet = "[" . $GLOBALS['meta']['nom_site'] . "] Demande Resiliation Abonnement " . $config['presta']; $message = "Abonne UID : {$uid}\nTransactions :\n"; $trans = sql_allfetsel("id_transaction,date_paiement,montant", "spip_transactions", "abo_uid=" . sql_quote($uid) . " AND statut=" . sql_quote('ok') . " AND mode LIKE " . sql_quote($config['presta'] . '%')); foreach ($trans as $tran) { $message .= "#" . $tran['id_transaction'] . " " . $tran['date_paiement'] . " " . affiche_monnaie($tran['montant']) . "\n"; } $envoyer_mail = charger_fonction("envoyer_mail", "inc"); $envoyer_mail($GLOBALS['meta']['email_webmaster'], $sujet, $message); return false; }
/** * il faut avoir un id_transaction et un transaction_hash coherents * pour se premunir d'une tentative d'appel exterieur * * @param int $id_transaction * @param string $transaction_hash * @param string $refabonne * @param string $ppps * fournit par Paybox lors de l'appel initial avec un ppps:U; * @param array $config * configuration paybox qui contient les infos de connexion directplus * @return string */ function presta_paybox_call_directplus_dist($id_transaction, $transaction_hash, $refabonne, $ppps, $config = null) { include_spip('inc/bank'); if (!$config) { $config = bank_config("paybox", true); } $config['mode'] .= "_dplus"; // pour les logs $mode = $config['mode']; if (!($row = sql_fetsel("*", "spip_transactions", "id_transaction=" . intval($id_transaction) . " AND transaction_hash=" . sql_quote($transaction_hash)))) { spip_log("Transaction inconnue {$id_transaction}/{$transaction_hash}", $mode . _LOG_ERREUR); return ""; } // securite : eviter de faire payer plusieurs fois une meme transaction si bug en amont if ($row['statut'] == 'ok') { spip_log("Transaction {$id_transaction}/{$transaction_hash} deja reglee", $mode . _LOG_INFO_IMPORTANTE); return ""; } if (!$row['id_auteur'] and isset($GLOBALS['visiteur_session']['id_auteur']) and $GLOBALS['visiteur_session']['id_auteur']) { sql_updateq("spip_transactions", array("id_auteur" => $row['id_auteur'] = $GLOBALS['visiteur_session']['id_auteur']), "id_transaction=" . intval($id_transaction)); } // recuperer l'email $mail = sql_getfetsel('email', "spip_auteurs", 'id_auteur=' . intval($row['id_auteur'])); // passage en centimes d'euros $montant = intval(round(100 * $row['montant'])); if (strlen($montant) < 10) { $montant = str_pad($montant, 10, '0', STR_PAD_LEFT); } // Affectation des parametres obligatoires $parm = array('VERSION' => '00104', 'SITE' => $config['PBX_SITE'], 'RANG' => $config['PBX_RANG'], 'IDENTIFIANT' => ''); // cas de PBX_RANG : paybox fournit 001 mais il faut envoyer 01 au serveur $parm['RANG'] = str_pad(intval($parm['RANG']), 2, '0', STR_PAD_LEFT); $parm['CLE'] = $config['DIRECT_PLUS_CLE']; $parm['DATEQ'] = date('dmYHis'); $parm['TYPE'] = _PAYBOX_DIRECTPLUS_AUTHDEBIT_ABONNE; $parm['DEVISE'] = "978"; $parm['REFERENCE'] = intval($id_transaction); $parm['ARCHIVAGE'] = intval($id_transaction); $parm['DIFFERE'] = '000'; $parm['NUMAPPEL'] = ''; $parm['NUMTRANS'] = ''; $parm['AUTORISATION'] = ''; $parm['MONTANT'] = $montant; $parm['REFABONNE'] = $refabonne; $ppps = explode(' ', $ppps); $parm['PORTEUR'] = str_pad($ppps[0], 19, ' ', STR_PAD_RIGHT); // NO CB $parm['DATEVAL'] = substr($ppps[1], 2) . substr($ppps[1], 0, 2); // VAL CB $parm['CVV'] = $ppps[2]; // CCV CB include_spip('inc/distant'); // numero de question incremental // dans spip_meta // on recommence si collision par concurence... $maxtry = 5; do { $num_question = intval(sql_getfetsel("valeur", "spip_meta", "nom=" . sql_quote('payboxnumquestion'))); $num_question++; ecrire_meta('payboxnumquestion', $num_question); $parm['NUMQUESTION'] = $num_question; #var_dump($parm); // requete en POST sur PAYBOX DIRECT PLUS $url = paybox_url_directplus($config); #spip_log("Appel de $url avec ".var_export($parm,true),$mode); $res = recuperer_page($url, false, false, 1048576, $parm); parse_str($res, $r); if ($r['CODEREPONSE'] == '00005') { spip_log("Collision Reponse : {$res}", $mode); // hum sleep(1); } else { spip_log("Reponse : {$res}", $mode); } } while ($r['CODEREPONSE'] == '00005' and $maxtry-- > 0); #var_dump($r); /* * array(10) { ["NUMTRANS"]=> string(10) "0000617104" ["NUMAPPEL"]=> string(10) "0000981593" ["NUMQUESTION"]=> string(10) "0000095720" ["SITE"]=> string(7) "1999888" ["RANG"]=> string(2) "99" ["AUTORISATION"]=> string(6) "XXXXXX" ["CODEREPONSE"]=> string(5) "00000" ["COMMENTAIRE"]=> string(27) "Demande trait?e avec succ?s" ["REFABONNE"]=> string(5) "95720" ["PORTEUR"]=> string(19) "SLDLrcsLMPC " } */ // renommons en coherence avec Paybox System $response = array('id_transaction' => $id_transaction, 'erreur' => $r['CODEREPONSE'], 'auth' => $r['AUTORISATION'], 'trans' => $r['NUMTRANS'], 'montant' => $parm['MONTANT'], 'abo' => $r['REFABONNE'], 'valid' => $ppps[1]); $call_response = charger_fonction('response', 'presta/paybox/call'); return $call_response($config, $response); }
function action_paypalexpress_checkoutpayment_dist($arg = null) { if (is_null($arg)) { $securiser_action = charger_fonction('securiser_action', 'inc'); $arg = $securiser_action(); } $arg = explode("-", $arg); $payerid = array_shift($arg); $mode = implode("-", $arg); include_spip("inc/bank"); $config = bank_config($mode); include_spip("presta/paypalexpress/inc/paypalexpress"); $res = bank_paypalexpress_checkoutpayment($payerid, $config); list($id_transaction, $success) = $res; include_spip("action/bank_response"); redirige_apres_retour_transaction("paypalexpress", "acte", $success, $id_transaction); }