Esempio n. 1
0
/**
 * il faut avoir un id_transaction et un transaction_hash coherents
 * pour se premunir d'une tentative d'appel exterieur
 *
 * @param array $config
 * @param null|array $response
 * @return array
 */
function presta_gratuit_call_response_dist($config, $response = null)
{
    $mode = $config['presta'];
    // recuperer la reponse en post et la decoder, en verifiant la signature
    if (!$response) {
        $response = bank_response_simple($mode);
    }
    if (!isset($response['id_transaction']) or !isset($response['transaction_hash'])) {
        return bank_transaction_invalide(0, array('mode' => $mode, 'erreur' => "id_transaction ou transaction_hash absent", 'log' => bank_shell_args($response)));
    }
    $id_transaction = $response['id_transaction'];
    $transaction_hash = $response['transaction_hash'];
    if (!($row = sql_fetsel('*', 'spip_transactions', 'id_transaction=' . intval($id_transaction)))) {
        return bank_transaction_invalide($id_transaction, array('mode' => $mode, 'erreur' => "transaction inconnue", 'log' => bank_shell_args($response)));
    }
    if ($transaction_hash != $row['transaction_hash']) {
        return bank_transaction_invalide($id_transaction, array('mode' => $mode, 'erreur' => "id_transaction {$id_transaction}, hash {$transaction_hash} non conforme", 'log' => bank_shell_args($response)));
    }
    // verifier que la commande a bien un total nul, sinon ce mode de paiement n'est pas autorise
    if (intval($row['montant']) > 0 or floatval($row['montant']) > 0.0) {
        return bank_transaction_invalide($id_transaction, array('mode' => $mode, 'erreur' => "id_transaction {$id_transaction}, montant " . $row['montant'] . ">0 interdit", 'log' => bank_shell_args($response)));
    }
    // OK, on peut accepter le reglement
    $set = array("mode" => $mode, "montant_regle" => $row['montant'], "date_paiement" => date('Y-m-d H:i:s'), "statut" => 'ok', "reglee" => 'oui');
    sql_updateq("spip_transactions", $set, "id_transaction=" . intval($id_transaction));
    spip_log("call_resonse : id_transaction {$id_transaction}, reglee", $mode);
    $regler_transaction = charger_fonction('regler_transaction', 'bank');
    $regler_transaction($id_transaction, array('row_prec' => $row));
    return array($id_transaction, true);
}
Esempio n. 2
0
/**
 * Verifier le statut d'une transaction lors du retour de l'internaute
 *
 * @param array $config
 * @param null|array $response
 * @return array
 */
function presta_paybox_call_response_dist($config, $response = null)
{
    include_spip('inc/bank');
    $mode = $config['presta'];
    if (!$response) {
        // recuperer la reponse en post et la decoder
        $response = paybox_response();
    }
    if (!$response) {
        return array(0, false);
    }
    if ($response['ETAT_PBX'] === 'PBX_RECONDUCTION_ABT') {
        // c'est un revouvellement initie par paybox
        // verifier qu'on a pas deja traite cette recurrence !
        if ($t2 = sql_fetsel("*", "spip_transactions", "autorisation_id=" . sql_quote($response['trans'] . "/" . $response['auth']))) {
            $response['id_transaction'] = $t2['id_transaction'];
        } elseif ($preparer_echeance = charger_fonction('preparer_echeance', 'abos', true)) {
            // on reinjecte le bon id de transaction ici si fourni
            if ($id_transaction = $preparer_echeance("uid:" . $response['abo'])) {
                $response['id_transaction'] = $id_transaction;
            } else {
                return bank_transaction_invalide(intval($response['id_transaction']) . 'PBX_RECONDUCTION_ABT', array('mode' => $mode, 'sujet' => 'Echec creation transaction echeance', 'erreur' => "uid:" . $response['abo'] . ' inconnu de $preparer_echeance', 'log' => bank_shell_args($response), 'update' => false, 'send_mail' => true));
            }
        }
    }
    // depouillement de la transaction
    list($id_transaction, $success) = paybox_traite_reponse_transaction($config, $response);
    if ($response['abo'] and $id_transaction) {
        // c'est un premier paiement d'abonnement, l'activer
        if ($response['ETAT_PBX'] !== 'PBX_RECONDUCTION_ABT' and $success) {
            // date de fin de mois de validite de la carte
            $date_fin = bank_date_fin_mois(2000 + intval(substr($response['valid'], 0, 2)), substr($response['valid'], 2, 2));
            #spip_log('response:'.var_export($response,true),$mode.'db');
            #spip_log('date_fin:'.$date_fin,$mode.'db');
            // id_transaction contient toute la trame IDB_xx deriere le numero
            // on ne retient que la valeur entiere
            $id_transaction = intval($id_transaction);
            if ($activer_abonnement = charger_fonction('activer_abonnement', 'abos', true)) {
                $activer_abonnement($id_transaction, $response['abo'], $mode, $date_fin);
            }
        }
        // c'est un renouvellement reussi, il faut repercuter sur l'abonnement
        if ($response['ETAT_PBX'] === 'PBX_RECONDUCTION_ABT' and $success) {
            if ($renouveler_abonnement = charger_fonction('renouveler_abonnement', 'abos', true)) {
                $renouveler_abonnement($id_transaction, $response['abo'], $mode);
            }
        }
        // c'est un renouvellement en echec, il faut le resilier
        if ($response['ETAT_PBX'] === 'PBX_RECONDUCTION_ABT' and !$success) {
            if ($resilier = charger_fonction('resilier', 'abos', true)) {
                $options = array('notify_bank' => false, 'immediat' => true, 'message' => "[bank] Transaction #{$id_transaction} refusee");
                $resilier("uid:" . $response['abo'], $options);
            }
        }
    }
    return array($id_transaction, $success);
}
Esempio n. 3
0
function paybox_shell_args($params)
{
    return bank_shell_args($params);
}
Esempio n. 4
0
/**
 * il faut avoir un id_transaction et un transaction_hash coherents
 * pour se premunir d'une tentative d'appel exterieur
 *
 * @param array $config
 * @param null|array $response
 * @return array
 */
function presta_credit_call_response_dist($config, $response = null)
{
    $mode = $config['presta'];
    // recuperer la reponse en post et la decoder, en verifiant la signature
    if (!$response) {
        $response = bank_response_simple($mode);
    }
    if (!isset($response['id_transaction']) or !isset($response['transaction_hash'])) {
        return bank_transaction_invalide(0, array('mode' => $mode, 'erreur' => "id_transaction ou transaction_hash absent", 'log' => bank_shell_args($response)));
    }
    $id_transaction = $response['id_transaction'];
    $transaction_hash = $response['transaction_hash'];
    if (!($row = sql_fetsel('*', 'spip_transactions', 'id_transaction=' . intval($id_transaction)))) {
        return bank_transaction_invalide($id_transaction, array('mode' => $mode, 'erreur' => "transaction inconnue", 'log' => bank_shell_args($response)));
    }
    if ($transaction_hash != $row['transaction_hash']) {
        return bank_transaction_invalide($id_transaction, array('mode' => $mode, 'erreur' => "id_transaction {$id_transaction}, hash {$transaction_hash} non conforme", 'log' => bank_shell_args($response)));
    }
    // Obtenir la devise.
    $auteur = $row['auteur'];
    include_spip('reservations_credits_fonctions');
    /*$credit = credit_client('', $row['auteur'], $devise);
    	spip_log("credit : $credit, montant $montant,auteur $auteur", 'credit');*/
    if ($id_reservation = $row['id_reservation']) {
        $donnees = sql_fetsel('spip_reservations_details.devise,reference,email,id_auteur', 'spip_reservations LEFT JOIN spip_reservations_details USING (id_reservation)', 'spip_reservations.id_reservation=' . $id_reservation);
        $devise = $donnees['devise'];
        $descriptif = _T('reservation_bank:paiement_reservation', array('id_reservation' => $id_reservation));
    } elseif ($id_commande = $row['id_commande']) {
        $devise = 'EUR';
        $descriptif = _T('reservation_bank:paiement_commande', array('id_commande' => $id_commande));
        $id_objet = $id_commande;
        $objet = 'commande';
    } else {
        return bank_transaction_invalide($id_transaction, array('mode' => $mode, 'erreur' => "id_transaction {$id_transaction}, hash {$transaction_hash} objet non connu", 'log' => bank_shell_args($response)));
    }
    // Si on trouve un crédit
    if (isset($row['auteur']) and $email = $row['auteur'] and $credit = credit_client('', $row['auteur'], $devise) and (intval($credit) >= 0 or floatval($var) >= 0.0)) {
        if (!($montant_reservations_detail_total = _request('montant_reservations_detail_total'))) {
            include_spip('inc/reservation_bank');
            $montant_reservations_detail_total = montant_reservations_detail_total($id_reservation);
        }
        $paiement_detail = array();
        foreach (array_keys($montant_reservations_detail_total) as $id_reservation_detail) {
            $paiement_detail[$id_reservation_detail] = _request('montant_reservations_detail_' . $id_reservation_detail);
        }
        if (!($montant_regle = array_sum($paiement_detail))) {
            $montant_regle = $transaction['montant'];
        }
        $set = array("mode" => $mode, "montant_regle" => $montant_regle, "date_paiement" => date('Y-m-d H:i:s'), "statut" => 'ok', "reglee" => 'oui');
        if (intval($credit) >= intval($row['montant']) or floatval($credit) >= floatval($row['montant'])) {
            // OK, on peut accepter le reglement
            $statut = 'reglée';
            $res = true;
        } else {
            // Le crédit n'est pas suffisant
            $set['montant_regle'] = $montant_regle;
            $set['statut'] = 'attente';
            $set['reglee'] = 'par';
            $statut = 'reglée acompte';
            $res = 'wait';
        }
        sql_updateq("spip_transactions", $set, "id_transaction=" . intval($id_transaction));
        spip_log("call_response : id_transaction {$id_transaction}, {$statut}", $mode);
        // Enregistrer un mouvement crédit
        $action = charger_fonction('editer_objet', 'action');
        $reference = $donnes['reference'];
        $set = array('type' => 'debit', 'email' => $email, 'descriptif' => $descriptif, 'id_reservation' => $id_reservation, 'id_objet' => $id_objet, 'objet' => $objet, 'montant' => $montant_regle, 'devise' => $donnees['devise']);
        $action('new', 'reservation_credit_mouvement', $set);
    } else {
        return bank_transaction_invalide($id_transaction, array('mode' => $mode, 'erreur' => "id_transaction {$id_transaction}, montant " . $row['montant'] . "> pas de crédit diponible", 'log' => bank_shell_args($response)));
    }
    $regler_transaction = charger_fonction('regler_transaction', 'bank');
    $regler_transaction($id_transaction, array('row_prec' => $row));
    return array($id_transaction, $res);
}
Esempio n. 5
0
/**
 * Traiter l'annulation d'une transaction
 *
 * @param array $config
 * @param int $id_transaction
 *     Identification de la transaction
 * @param array $response
 *     Réponse de la banque
 * @param array $row
 *     Ligne de transaction
 * @param bool|string $erreur
 *    Message d'erreur eventuel
 * @return array
**/
function cmcic_gerer_transaction_annulee($config, $id_transaction, $response, $row, $erreur = true)
{
    $mode = $config['presta'];
    $config_id = bank_config_id($config);
    if (isset($config['mode_test']) and $config['mode_test']) {
        $mode .= "_test";
    }
    // regarder si l'annulation n'arrive pas apres un reglement
    // (internaute qui a ouvert 2 fenetres de paiement)
    if ($row['reglee'] != 'oui') {
        $date_paiement = date('Y-m-d H:i:s');
        include_spip('inc/bank');
        return bank_transaction_echec($id_transaction, array('mode' => $mode, 'config_id' => $config_id, 'date_paiement' => $date_paiement, 'code_erreur' => $response['motifrefus'], 'erreur' => $erreur === true ? "" : $erreur, 'log' => bank_shell_args($response)));
    }
    return array($id_transaction, true);
}
Esempio n. 6
0
/**
 * Traiter la reponse
 * @param array $config
 * @param array $response
 * @return array
 */
function systempay_traite_reponse_transaction($config, $response)
{
    #var_dump($response);
    $mode = $config['presta'];
    if (isset($config['mode_test']) and $config['mode_test']) {
        $mode .= "_test";
    }
    $config_id = bank_config_id($config);
    $id_transaction = $response['vads_order_id'];
    if (!($row = sql_fetsel("*", "spip_transactions", "id_transaction=" . intval($id_transaction)))) {
        return bank_transaction_invalide($id_transaction, array('mode' => $mode, 'erreur' => "transaction inconnue", 'log' => bank_shell_args($response)));
    }
    $is_sepa = (isset($response['vads_card_brand']) and $response['vads_card_brand'] == "SDD");
    $is_payment = true;
    $is_registering = false;
    $is_subscribing = false;
    // si c'est une souscription ou un register, lever les bons flags
    // si pas de paiement on veut enregistrer les donnees et sortir de la sans generer d'erreur (le paiement arrivera plus tard)
    if ($response['vads_page_action'] and in_array($response['vads_page_action'], array('REGISTER', 'REGISTER_SUBSCRIBE', 'REGISTER_PAY_SUBSCRIBE', 'SUBSCRIBE'))) {
        $is_registering = true;
        if ($response['vads_page_action'] !== 'REGISTER_PAY_SUBSCRIBE') {
            $is_payment = false;
        }
        if ($response['vads_page_action'] !== 'REGISTER') {
            $is_subscribing = true;
        }
    } elseif (in_array($response['vads_url_check_src'], array('BO', 'REC', 'RETRY'))) {
        if (isset($response['vads_identifier']) and $response['vads_identifier']) {
            $is_registering = true;
        }
        if (isset($response['vads_subscription']) and $response['vads_subscription']) {
            $is_subscribing = true;
        } elseif ($is_registering and !isset($response['vads_subscription']) and isset($response['vads_sequence_number']) and $response['vads_sequence_number']) {
            $is_subscribing = true;
            if (!$response['vads_card_number']) {
                $response['vads_card_number'] = 'X_X';
            }
        }
    }
    // si c'est un debit, a-t-on bien l'operation attendue ?
    if ($is_payment and $response['vads_operation_type'] !== "DEBIT" and !in_array($response['vads_trans_status'], array('ABANDONED', 'NOT_CREATED', 'REFUSED'))) {
        // si la transaction est deja reglee, ne pas la modifier, c'est OK
        if ($row['statut'] == 'ok') {
            return array($id_transaction, true);
        }
        return bank_transaction_invalide($id_transaction, array('mode' => $mode, 'erreur' => "vads_operation_type=" . $response['vads_operation_type'] . " non prise en charge", 'log' => bank_shell_args($response), 'sujet' => "Operation invalide", 'update' => true));
    }
    // ok, on traite le reglement
    $date = $response['vads_effective_creation_date'];
    // si c'est un paiement SEPA, on prend la date de presentation du SEPA comme date de paiement
    // (date_paiement dans le futur donc)
    if ($is_sepa) {
        $date = $response['vads_presentation_date'];
    }
    // date paiement et date transaction
    $t = gmmktime(substr($date, 8, 2), substr($date, 10, 2), substr($date, 12, 2), substr($date, 4, 2), substr($date, 6, 2), substr($date, 0, 4));
    $date_paiement = date('Y-m-d H:i:s', $t);
    $date_transaction = $date_paiement;
    if (isset($response['vads_presentation_date'])) {
        $date = $response['vads_trans_date'];
        $t = gmmktime(substr($date, 8, 2), substr($date, 10, 2), substr($date, 12, 2), substr($date, 4, 2), substr($date, 6, 2), substr($date, 0, 4));
        $date_transaction = date('Y-m-d H:i:s', $t);
    }
    $erreur = array(systempay_response_code($response['vads_result']), systempay_auth_response_code($response['vads_auth_result']));
    $erreur = array_filter($erreur);
    $erreur = trim(implode(' ', $erreur));
    $authorisation_id = $response['vads_auth_number'];
    $transaction = $response['vads_payment_certificate'];
    // si c'est un SEPA, on a pas encore la transaction et le numero d'autorisation car il y a un delai avant presentation
    // (paiement dans le futur)
    if ($is_sepa and !$transaction) {
        list($transaction, $authorisation_id) = explode("_", $response['vads_card_number']);
    }
    if ($is_payment and !$erreur and !in_array($response['vads_trans_status'], array('AUTHORISED', 'CAPTURED', 'WAITING_AUTHORISATION'))) {
        $erreur = "vads_trans_status " . $response['vads_trans_status'] . " (!IN AUTHORISED,CAPTURED,WAITING_AUTHORISATION)";
    }
    if (!$erreur and $is_payment and !$transaction) {
        $erreur = "pas de vads_payment_certificate";
    }
    if (!$erreur and !$authorisation_id) {
        $erreur = "pas de vads_auth_number";
    }
    if ($erreur) {
        // regarder si l'annulation n'arrive pas apres un reglement (internaute qui a ouvert 2 fenetres de paiement)
        if ($row['reglee'] == 'oui') {
            return array($id_transaction, true);
        }
        // sinon enregistrer l'absence de paiement et l'erreur
        return bank_transaction_echec($id_transaction, array('mode' => $mode, 'config_id' => $config_id, 'date_paiement' => $date_paiement, 'code_erreur' => $response['vads_result'], 'erreur' => $erreur, 'log' => bank_shell_args($response), 'send_mail' => intval($response['vads_result']) == 2));
    }
    $set = array("autorisation_id" => "{$authorisation_id}/{$transaction}", "mode" => "{$mode}/{$config_id}");
    if ($is_payment) {
        // Ouf, le reglement a ete accepte
        // on verifie que le montant est bon !
        $montant_regle = $response['vads_effective_amount'] / 100;
        if ($montant_regle != $row['montant']) {
            spip_log($t = "call_response : id_transaction {$id_transaction}, montant regle {$montant_regle}!=" . $row['montant'] . ":" . bank_shell_args($response), $mode);
            // on log ca dans un journal dedie
            spip_log($t, $mode . '_reglements_partiels');
        }
        $set['montant_regle'] = $montant_regle;
        $set['date_paiement'] = $date_paiement;
        $set['statut'] = 'ok';
        $set['reglee'] = 'oui';
    } else {
        $set['statut'] = 'attente';
    }
    // si la date de transaction Systempay est anterieure a celle du site - 1h, on la met a jour
    // (cas ou l'on rejoue a posteriori une notification qui n'a pas marche)
    if ($date_transaction < $row['date_transaction'] or $date_paiement < $row['date_transaction']) {
        $set['date_transaction'] = $date_transaction;
    }
    // si on a les infos de validite / card number, on les note ici
    if (isset($response['vads_expiry_year'])) {
        $set['validite'] = $response['vads_expiry_year'] . "-" . $response['vads_expiry_month'];
    }
    if (isset($response['vads_card_brand']) or isset($response['vads_card_number'])) {
        // par defaut on note brand et number dans refcb
        // mais ecrase si le paiement a genere un identifiant de paiement
        // qui peut etre reutilise
        $set['refcb'] = '';
        if (isset($response['vads_card_brand'])) {
            $set['refcb'] = $response['vads_card_brand'];
            if ($set['refcb'] === "SDD") {
                $set['refcb'] = "SEPA";
            }
            // more user friendly
        }
        if (isset($response['vads_card_number'])) {
            $set['refcb'] .= " " . $response['vads_card_number'];
        }
        $set['refcb'] = trim($set['refcb']);
    }
    // si vads_identifier fourni on le note dans refcb : c'est un identifiant de paiement
    if (isset($response['vads_identifier']) and $response['vads_identifier']) {
        $set['pay_id'] = $response['vads_identifier'];
    } elseif ($is_registering) {
        // si pas de paiement, on genere un echec
        if (!$is_payment) {
            return bank_transaction_echec($id_transaction, array('mode' => $mode, 'config_id' => $config_id, 'date_paiement' => $date_paiement, 'erreur' => "Pas de vads_identifier sur operation " . $response['vads_operation_type'], 'log' => bank_shell_args($response)));
        } else {
            // sinon on enregistre l'erreur et on log+mail mais on fini le paiement en OK quand meme
            $set['erreur'] = "Pas de vads_identifier sur operation " . $response['vads_operation_type'];
            bank_transaction_invalide($id_transaction, array('mode' => $mode, 'sujet' => 'Echec REGISTER', 'erreur' => $set['erreur'], 'log' => bank_shell_args($response)));
        }
    }
    // si on a un numero d'abonnement on le note dans abo_uid
    if (isset($response['vads_subscription']) and $response['vads_subscription']) {
        $set['abo_uid'] = $response['vads_subscription'];
    } elseif ($is_subscribing) {
        // si pas de paiement, on genere un echec
        if (!$is_payment) {
            return bank_transaction_echec($id_transaction, array('mode' => $mode, 'config_id' => $config_id, 'date_paiement' => $date_paiement, 'erreur' => "Pas de vads_subscription sur operation " . $response['vads_operation_type'], 'log' => bank_shell_args($response)));
        } else {
            // sinon on enregistre l'erreur et on log+mail mais on fini le paiement en OK quand meme
            $set['erreur'] = "Pas de vads_subscription sur operation " . $response['vads_operation_type'];
            bank_transaction_invalide($id_transaction, array('mode' => $mode, 'sujet' => 'Echec SUBSCRIBE', 'erreur' => $set['erreur'], 'log' => bank_shell_args($response)));
        }
    }
    // OK on met a jour la transaction en base
    sql_updateq("spip_transactions", $set, "id_transaction=" . intval($id_transaction));
    spip_log("call_response : id_transaction {$id_transaction}, reglee", $mode);
    // si on dispose des informations utilisateurs, les utiliser pour peupler la gloable bank_session
    // qui peut etre utilisee pour creer le compte client a la volee
    $var_users = array('vads_cust_email' => 'email', 'vads_cust_name' => 'nom', 'vads_cust_title' => 'civilite');
    foreach ($var_users as $kr => $ks) {
        if (isset($response[$kr]) and $response[$kr]) {
            if (!isset($GLOBALS['bank_session'])) {
                $GLOBALS['bank_session'] = array();
            }
            $GLOBALS['bank_session'][$ks] = $response[$kr];
        }
    }
    // si transaction reglee, on poursuit le processus
    if (isset($set['reglee']) and $set['reglee'] == 'oui') {
        $regler_transaction = charger_fonction('regler_transaction', 'bank');
        $regler_transaction($id_transaction, array('row_prec' => $row));
        $res = true;
    } else {
        $row = sql_fetsel("*", "spip_transactions", "id_transaction=" . intval($id_transaction));
        pipeline('trig_bank_reglement_en_attente', array('args' => array('statut' => 'attente', 'mode' => $row['mode'], 'type' => $row['abo_uid'] ? 'abo' : 'acte', 'id_transaction' => $id_transaction, 'row' => $row), 'data' => ''));
        $res = 'wait';
    }
    // c'est un succes
    return array($id_transaction, $res);
}
Esempio n. 7
0
/**
 * Verifier le statut d'une transaction lors du retour de l'internaute
 *
 * @param array $config
 * @param null|array $response
 * @return array
 */
function presta_stripe_call_response_dist($config, $response = null)
{
    include_spip('inc/bank');
    $mode = $config['presta'];
    if (isset($config['mode_test']) and $config['mode_test']) {
        $mode .= "_test";
    }
    // recuperer la reponse en post et la decoder, en verifiant la signature
    if (!$response) {
        $response = bank_response_simple($mode);
    }
    // Stripe token
    $token = '';
    if (isset($_REQUEST['stripeToken'])) {
        $token = $_REQUEST['stripeToken'];
    }
    if (!$response or !$token and !$response['charge']) {
        spip_log("call_response : token/charge invalide", $mode . _LOG_ERREUR);
        return array(0, false);
    }
    if ($token) {
        $response['token'] = $token;
    }
    if (isset($_REQUEST['stripeTokenType'])) {
        $response['token_type'] = $_REQUEST['stripeTokenType'];
    }
    $recurence = false;
    // c'est une reconduction d'abonnement ?
    if ($response['charge_id'] and $response['abo_uid']) {
        // verifier qu'on a pas deja traite cette recurrence !
        if ($t = sql_fetsel("*", "spip_transactions", "autorisation_id LIKE " . sql_quote("%/" . $response['charge_id']))) {
            $response['id_transaction'] = $t['id_transaction'];
            $response['transaction_hash'] = $t['transaction_hash'];
        } elseif ($preparer_echeance = charger_fonction('preparer_echeance', 'abos', true)) {
            $abo_uid = $response['abo_uid'];
            $id_transaction = $preparer_echeance("uid:" . $abo_uid);
            // on reinjecte le bon id de transaction ici si fourni
            if ($id_transaction) {
                $response['id_transaction'] = $id_transaction;
                $response['transaction_hash'] = sql_getfetsel('transaction_hash', 'spip_transactions', 'id_transaction=' . intval($id_transaction));
            } else {
                return bank_transaction_invalide($response['abo_uid'] . '/' . $response['charge_id'], array('mode' => $mode, 'sujet' => 'Echec creation transaction echeance', 'erreur' => "uid:" . $response['abo_uid'] . ' inconnu de $preparer_echeance', 'log' => bank_shell_args($response), 'update' => false, 'send_mail' => true));
            }
        }
        $recurence = true;
    }
    // depouillement de la transaction
    // stripe_traite_reponse_transaction modifie $response
    list($id_transaction, $success) = stripe_traite_reponse_transaction($config, $response);
    if (($recurence or $response['abo']) and $abo_uid = $response['abo_uid'] and $id_transaction) {
        // c'est un premier paiement d'abonnement, l'activer
        if (!$recurence) {
            if ($success) {
                // date de fin de mois de validite de la carte
                $date_fin = "0000-00-00 00:00:00";
                if (isset($response['validite'])) {
                    list($year, $month) = explode('-', $response['validite']);
                    $date_fin = bank_date_fin_mois($year, $month);
                }
                #spip_log('response:'.var_export($response,true),$mode.'db');
                #spip_log('date_fin:'.$date_fin,$mode.'db');
                if ($activer_abonnement = charger_fonction('activer_abonnement', 'abos', true)) {
                    $activer_abonnement($id_transaction, $abo_uid, $mode, $date_fin);
                }
            }
        } else {
            // reussi, il faut repercuter sur l'abonnement
            if ($success) {
                if ($renouveler_abonnement = charger_fonction('renouveler_abonnement', 'abos', true)) {
                    $renouveler_abonnement($id_transaction, $response['abo'], $mode);
                }
            }
            // echoue, il faut resilier l'abonnement
            if (!$success) {
                if ($resilier = charger_fonction('resilier', 'abos', true)) {
                    $options = array('notify_bank' => false, 'immediat' => true, 'message' => "[bank] Transaction #{$id_transaction} refusee");
                    $resilier("uid:{$abo_uid}", $options);
                }
            }
        }
    }
    return array($id_transaction, $success);
}
Esempio n. 8
0
/**
 * il faut avoir un id_transaction et un transaction_hash coherents
 * pour se premunir d'une tentative d'appel exterieur
 *
 * @param array $config
 * @param null|array $response
 * @return array
 */
function presta_systempay_call_response_dist($config, $response = null)
{
    include_spip('inc/bank');
    $mode = $config['presta'];
    if (!$response) {
        // recuperer la reponse en post et la decoder
        $response = systempay_recupere_reponse($config);
    }
    if (!$response) {
        return array(0, false);
    }
    $recurence = false;
    // c'est une reconduction d'abonnement ?
    if (isset($response['vads_url_check_src']) and in_array($response['vads_url_check_src'], array('REC', 'RETRY')) and isset($response['vads_recurrence_number']) and $response['vads_recurrence_number']) {
        // si la transaction reference n'existe pas ou a deja ete payee c'est bien une recurence
        // sinon c'est le paiement de la premiere transaction
        $trans = sql_fetsel("*", "spip_transactions", "id_transaction=" . intval($response['vads_order_id']));
        // pour $response['vads_recurrence_number']=1 on est pas sur, mais au dela c'est une recurence certaine
        if (!$trans or $trans['statut'] == 'ok' or $response['vads_recurrence_number'] > 1) {
            // verifier qu'on a pas deja traite cette recurrence !
            if ($t2 = sql_fetsel("*", "spip_transactions", "autorisation_id=" . sql_quote($response['vads_order_id'] . "/" . $response['vads_trans_id']))) {
                $response['vads_auth_number'] = $response['vads_order_id'];
                $response['vads_payment_certificate'] = $response['vads_trans_id'];
                $response['vads_order_id'] = $t2['id_transaction'];
            } elseif ($preparer_echeance = charger_fonction('preparer_echeance', 'abos', true)) {
                $id_transaction = 0;
                // si c'est un RETRY qui n'a pas son vads_subscription, on le prend de la transaction si possible
                $abo_uid = $response['vads_subscription'];
                if (!$abo_uid and $trans and $trans['abo_uid']) {
                    $abo_uid = $trans['abo_uid'];
                    $response['vads_subscription'] = $abo_uid;
                }
                if (!$abo_uid or !($id_transaction = $preparer_echeance("uid:" . $abo_uid))) {
                    // si on avait pas le abo_uid dans la transaction initiale, essayer avec id_transaction
                    if ($trans and !$trans['abo_uid']) {
                        // si c'est la 1ere recurence essayer de reparer la transaction initiale
                        if ($response['vads_recurrence_number'] == 1 and $response['vads_subscription']) {
                            sql_updateq("spip_transactions", array('abo_uid' => $response['vads_subscription']), 'id_transaction=' . intval($trans['id_transaction']));
                            $trans['abo_uid'] = $response['vads_subscription'];
                            $id_transaction = $preparer_echeance("uid:" . $abo_uid);
                        }
                        // sinon essayer avec le numero de transaction comme numero d'abonnement
                        if (!$id_transaction) {
                            $id_transaction = $preparer_echeance("uid:" . $trans['id_transaction']);
                            if ($id_transaction) {
                                $response['vads_subscription'] = $trans['id_transaction'];
                            }
                        }
                    }
                }
                // on reinjecte le bon id de transaction ici si fourni
                if ($id_transaction) {
                    $response['vads_auth_number'] = $response['vads_order_id'];
                    $response['vads_payment_certificate'] = $response['vads_trans_id'];
                    $response['vads_order_id'] = $id_transaction;
                } else {
                    return bank_transaction_invalide($response['vads_order_id'] . 'R' . $response['vads_recurrence_number'], array('mode' => $mode, 'sujet' => 'Echec creation transaction echeance', 'erreur' => "uid:" . $response['abo'] . ' inconnu de $preparer_echeance', 'log' => bank_shell_args($response), 'update' => false, 'send_mail' => true));
                }
            }
            $recurence = true;
        }
    }
    // depouillement de la transaction
    list($id_transaction, $success) = systempay_traite_reponse_transaction($config, $response);
    if (($recurence or strpos($response['vads_page_action'], "SUBSCRIBE") !== false or in_array($response['vads_url_check_src'], array('RETRY'))) and isset($response['vads_subscription']) and $abo_uid = $response['vads_subscription'] and $id_transaction) {
        $transaction = sql_fetsel("*", "spip_transactions", "id_transaction=" . intval($id_transaction));
        // c'est le premier paiement de l'abonnement ?
        if (!$recurence and $success) {
            // date de fin de mois de validite de la carte (mais pas pour un SEPA qui se reconduit tout seul)
            $date_fin = "0000-00-00 00:00:00";
            if (isset($response['vads_expiry_year']) and isset($response['vads_expiry_month']) and strncmp($transaction['refcb'], 'SEPA', 4) !== 0) {
                $date_fin = bank_date_fin_mois($response['vads_expiry_year'], $response['vads_expiry_month']);
            }
            if ($activer_abonnement = charger_fonction('activer_abonnement', 'abos', true)) {
                $activer_abonnement($id_transaction, $abo_uid, $mode, $date_fin);
            }
        }
        // c'est un renouvellement reussi, il faut repercuter sur l'abonnement
        if ($recurence and $success) {
            if ($renouveler_abonnement = charger_fonction('renouveler_abonnement', 'abos', true)) {
                $renouveler_abonnement($id_transaction, $abo_uid, $mode);
            }
        }
        // c'est un echec, il faut le resilier, que ce soit la premiere ou la Nieme transaction
        if (!$success) {
            if ($resilier = charger_fonction('resilier', 'abos', true)) {
                $options = array('notify_bank' => false, 'immediat' => true, 'message' => "[bank] Transaction #{$id_transaction} refusee");
                $resilier("uid:" . $abo_uid, $options);
            }
        }
    }
    return array($id_transaction, $success);
}
Esempio n. 9
0
/**
 * Verifier que la notification de paiement vient bien de paypal !
 * @param array $config
 * @param bool $is_ipn
 * @return bool
 */
function paypal_get_response($config, $is_ipn = false)
{
    $mode = $config['presta'];
    if (isset($config['mode_test']) and $config['mode_test']) {
        $mode .= "_test";
    }
    $bank_recuperer_post_https = charger_fonction("bank_recuperer_post_https", "inc");
    // recuperer le POST
    $response = array();
    foreach ($_POST as $key => $value) {
        $response[$key] = $value;
    }
    if (isset($response['tx']) and $response['tx']) {
        $tx = $response['tx'];
    } elseif (isset($response['txn_id']) and $response['txn_id']) {
        $tx = $response['txn_id'];
    } else {
        $tx = _request('tx');
    }
    if (!$tx) {
        bank_transaction_invalide(0, array('mode' => $mode, 'erreur' => "Reponse sans tx ni txn_id", 'log' => bank_shell_args($response)));
        return false;
    }
    // si on a un $tx et un identity token dans la config on l'utilise de preference (PDT)
    if ($tx and isset($config['IDENTITY_TOKEN']) and $config['IDENTITY_TOKEN']) {
        $post_check = array('cmd' => '_notify-synch', 'tx' => $tx, 'at' => $config['IDENTITY_TOKEN']);
        // envoyer la demande de verif en post
        // attention, c'est une demande en ssl, il faut avoir un php qui le supporte
        $url = paypal_url_serveur($config);
        list($resultat, $erreur, $erreur_msg) = $bank_recuperer_post_https($url, $post_check, isset($response['payer_id']) ? $response['payer_id'] : '');
        $resultat = trim($resultat);
        if (strncmp($resultat, "SUCCESS", 7) == 0) {
            $resultat = trim(substr($resultat, 7));
            $resultat = explode("\n", $resultat);
            $resultat = array_map("trim", $resultat);
            $resultat = implode("&", $resultat);
            parse_str($resultat, $response);
            return paypal_charset_reponse($response);
        }
        // donnees invalides
        bank_transaction_invalide(0, array('mode' => $mode, 'erreur' => "Retour PDT :{$resultat}:Erreur {$erreur}:{$erreur_msg}:", 'log' => bank_shell_args($response)));
        return false;
    }
    if (!$response) {
        bank_transaction_invalide(0, array('mode' => $mode, 'sujet' => 'Paypal IDENTITY_TOKEN manquant', 'erreur' => "IDENTITY_TOKEN manquant pour decoder la reponse", 'log' => "tx={$tx}"));
        return false;
    }
    // ce n'est pas l'IPN, on ne sait pas verifier autrement
    // on "fait confiance" a la reponse telle quelle
    if (!$is_ipn) {
        // mais on le log+mail pour information du webmestre
        bank_transaction_invalide(0, array('mode' => $mode, 'sujet' => 'Transaction non securisee', 'erreur' => "IDENTITY_TOKEN non configure, impossible de verifier la reponse de Paypal (possible fraude)", 'log' => bank_shell_args($response)));
        // et on utilise la response
        return paypal_charset_reponse($response);
    }
    // notif de debug pour tests
    /*
    $response = json_decode
        (
            '{
                "residence_country": "US",
                "invoice": "abc1234",
                "address_city": "San Jose",
                "first_name": "John",
                "payer_id": "TESTBUYERID01",
                "shipping": "3.04",
                "mc_fee": "0.44",
                "txn_id": "611422392",
                "receiver_email": "*****@*****.**",
                "quantity": "1",
                "custom": "xyz123",
                "payment_date": "22:29:21 28 Oct 2013 PDT",
                "address_country_code": "US",
                "address_zip": "95131",
                "tax": "2.02",
                "item_name": "something",
                "address_name": "John Smith",
                "last_name": "Smith",
                "receiver_id": "*****@*****.**",
                "item_number": "AK-1234",
                "verify_sign": "AiPC9BjkCyDFQXbSkoZcgqH3hpacAaChsjNZq2jHG82F97aoFSMa6SED",
                "address_country": "United States",
                "payment_status": "Completed",
                "address_status": "confirmed",
                "business": "*****@*****.**",
                "payer_email": "*****@*****.**",
                "notify_version": "2.1",
                "txn_type": "web_accept",
                "test_ipn": "1",
                "payer_status": "verified",
                "mc_currency": "USD",
                "mc_gross": "12.34",
                "address_state": "CA",
                "mc_gross1": "12.34",
                "payment_type": "echeck",
                "address_street": "123, any street"
            }',
            true
        );
    */
    // lire la publication du systeme PayPal et ajouter 'cmd' en tete
    $post_check = array('cmd' => '_notify-validate');
    foreach ($response as $k => $v) {
        $post_check[$k] = $v;
    }
    // envoyer la demande de verif en post
    // attention, c'est une demande en ssl, il faut avoir un php qui le supporte
    $c = $config;
    if (isset($response['test_ipn']) and $response['test_ipn']) {
        $c['mode_test'] = true;
    } else {
        $c['mode_test'] = false;
    }
    $url = paypal_url_serveur($c);
    list($resultat, $erreur, $erreur_msg) = $bank_recuperer_post_https($url, $post_check, isset($post_check['payer_id']) ? $post_check['payer_id'] : '');
    if (strncmp(trim($resultat), 'VERIFIE', 7) == 0) {
        return paypal_charset_reponse($response);
    }
    bank_transaction_invalide(0, array('mode' => $mode, 'erreur' => "Retour IPN :{$resultat}:Erreur {$erreur}:{$erreur_msg}:", 'log' => bank_shell_args($response)));
    return false;
}