Example #1
1
/**
 * Gerer la reponse du POST JS sur paiement/abonnement
 * @param array $config
 * @param array $response
 * @return array
 */
function stripe_traite_reponse_transaction($config, &$response)
{
    $mode = $config['presta'];
    if (isset($config['mode_test']) and $config['mode_test']) {
        $mode .= "_test";
    }
    $config_id = bank_config_id($config);
    $is_abo = (isset($response['abo']) and $response['abo']);
    if (!isset($response['id_transaction']) or !isset($response['transaction_hash'])) {
        return bank_transaction_invalide(0, array('mode' => $mode, 'erreur' => "transaction inconnue", 'log' => var_export($response, true)));
    }
    if ((!isset($response['charge_id']) or !$response['charge_id']) and (!isset($response['token']) or !$response['token'])) {
        return bank_transaction_invalide(0, array('mode' => $mode, 'erreur' => "token/charge_id absent dans la reponse", 'log' => var_export($response, true)));
    }
    $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 non trouvee", 'log' => var_export($response, true)));
    }
    if ($transaction_hash != $row['transaction_hash']) {
        return bank_transaction_invalide($id_transaction, array('mode' => $mode, 'erreur' => "hash {$transaction_hash} non conforme", 'log' => var_export($response, true)));
    }
    $montant = intval(round(100 * $row['montant'], 0));
    if (strlen($montant) < 3) {
        $montant = str_pad($montant, 3, '0', STR_PAD_LEFT);
    }
    $email = bank_porteur_email($row);
    // ok, on traite le reglement
    $date = $_SERVER['REQUEST_TIME'];
    $date_paiement = date('Y-m-d H:i:s', $date);
    $erreur = "";
    $erreur_code = 0;
    // charger l'API Stripe avec la cle
    stripe_init_api($config);
    // preparer le paiement
    $nom_site = textebrut($GLOBALS['meta']['nom_site']);
    $desc_charge = array('amount' => $montant, "currency" => "eur", "source" => $response['token'], "description" => "Transaction #" . $id_transaction . " [{$nom_site}]", "receipt_email" => $email, "metadata" => array('id_transaction' => $id_transaction, 'id_auteur' => $row['id_auteur'], 'nom_site' => $nom_site, 'url_site' => $GLOBALS['meta']['adresse_site']));
    // la charge existe deja (autoresponse webhook sur abonnement)
    if (isset($response['charge_id']) and $response['charge_id']) {
        try {
            $charge = \Stripe\Charge::retrieve($response['charge_id']);
            $charge->description = $desc_charge['description'];
            $charge->metadata = $desc_charge['metadata'];
            $charge->save();
            if (!$charge->paid) {
                $erreur_code = 'unpaid';
                $erreur = 'payment failed';
            }
        } 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';
            }
        }
    } else {
        // est-ce un abonnement ?
        if ($is_abo) {
            // on decrit l'echeance
            if ($decrire_echeance = charger_fonction("decrire_echeance", "abos", true) and $echeance = $decrire_echeance($id_transaction)) {
                if ($echeance['montant'] > 0) {
                    $montant_echeance = intval(round(100 * $echeance['montant'], 0));
                    if (strlen($montant_echeance) < 3) {
                        $montant_echeance = str_pad($montant_echeance, 3, '0', STR_PAD_LEFT);
                    }
                    $interval = 'month';
                    if (isset($echeance['freq']) and $echeance['freq'] == 'yearly') {
                        $interval = 'year';
                    }
                    $desc_plan = array('amount' => $montant_echeance, 'interval' => $interval, 'name' => "#{$id_transaction} [{$nom_site}]", 'currency' => $desc_charge['currency'], 'metadata' => $desc_charge['metadata']);
                    // dans tous les cas on fait preleve la premiere echeance en paiement unique
                    // et en faisant démarrer l'abonnement par "1 periode" en essai sans paiement
                    // ca permet de gerer le cas paiement initial different, et de recuperer les infos de CB dans tous les cas
                    $time_start = strtotime($date_paiement);
                    $time_paiement_1_interval = strtotime("+1 {$interval}", $time_start);
                    $nb_days = intval(round(($time_paiement_1_interval - $time_start) / 86400));
                    $desc_plan['trial_period_days'] = $nb_days;
                    // un id unique (sauf si on rejoue le meme paiement)
                    $desc_plan['id'] = md5(json_encode($desc_plan) . "-{$transaction_hash}");
                    try {
                        $plan = \Stripe\Plan::retrieve($desc_plan['id']);
                    } catch (Exception $e) {
                        // erreur si on ne retrouve pas le plan, on ignore
                        $plan = false;
                    }
                    try {
                        if (!$plan) {
                            $plan = \Stripe\Plan::create($desc_plan);
                        }
                        if (!$plan) {
                            $erreur = "Erreur creation plan d'abonnement";
                            $erreur_code = "plan_failed";
                        }
                    } 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) {
                        // 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' => $erreur_code, 'erreur' => $erreur, 'log' => var_export($response, true)));
                    }
                }
            }
        }
        // essayer de retrouver ou creer un customer pour l'id_auteur
        $customer = null;
        try {
            if ($row['id_auteur']) {
                $customer_id = sql_getfetsel('pay_id', 'spip_transactions', 'pay_id!=' . sql_quote('') . ' AND id_auteur=' . intval($row['id_auteur']) . ' AND statut=' . sql_quote('ok') . ' AND mode=' . sql_quote("{$mode}/{$config_id}"), '', 'date_paiement DESC', '0,1');
                if ($customer_id) {
                    $customer = \Stripe\Customer::retrieve($customer_id);
                }
            }
            // si customer retrouve, on ajoute la source et la transaction
            if ($customer and $customer->email === $email) {
                $customer->source = $desc_charge['source'];
                $metadata = $customer->metadata;
                if (!$metadata) {
                    $metadata = array();
                }
                if (isset($metadata['id_transaction'])) {
                    $metadata['id_transaction'] .= ',' . $id_transaction;
                } else {
                    $metadata['id_transaction'] = $id_transaction;
                }
                $metadata['id_auteur'] = $row['id_auteur'];
                $customer->metadata = $metadata;
                $customer->description = sql_getfetsel('nom', 'spip_auteurs', 'id_auteur=' . intval($row['id_auteur']));
                $customer->save();
            } else {
                $d = array('email' => $email, 'source' => $desc_charge['source'], 'metadata' => $desc_charge['metadata']);
                if ($row['id_auteur']) {
                    $d['description'] = sql_getfetsel('nom', 'spip_auteurs', 'id_auteur=' . intval($row['id_auteur']));
                }
                $customer = \Stripe\Customer::create($d);
            }
            if ($is_abo and !$customer) {
                $erreur = "Erreur creation customer";
                $erreur_code = "cust_failed";
            }
        } 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';
            }
            spip_log("Echec creation/recherche customer transaction #{$id_transaction} {$erreur}", $mode . _LOG_ERREUR);
        }
        if ($is_abo and ($erreur or $erreur_code)) {
            // 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' => $erreur_code, 'erreur' => $erreur, 'log' => var_export($response, true)));
        }
        // Create a charge if needed: this will charge the user's card
        try {
            // If we have a Customer
            if ($customer and $customer->id) {
                $desc_charge['customer'] = $customer->id;
                $response['pay_id'] = $customer->id;
                // permet de faire de nouveau paiement sans saisie CB
                unset($desc_charge['source']);
            }
            if ($desc_charge['amount']) {
                $charge = \Stripe\Charge::create($desc_charge);
                // pour les logs en cas d'echec
                $r = $charge->getLastResponse()->json;
                $response = array_merge($response, $r);
                if (!$charge) {
                    $erreur = "Erreur creation charge";
                    $erreur_code = "charge_failed";
                } elseif (!$charge['paid']) {
                    $erreur_code = 'not_paid';
                    $erreur = 'echec paiement stripe';
                    if ($charge['failure_code'] or $charge['failure_message']) {
                        $erreur_code = $charge['failure_code'];
                        $erreur = $charge['failure_message'];
                    }
                }
            }
        } catch (\Stripe\Error\Card $e) {
            // Since it's a decline, \Stripe\Error\Card will be caught
            $body = $e->getJsonBody();
            $err = $body['error'];
            list($erreur_code, $erreur) = stripe_error_code($err);
        } 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';
            }
        }
        // si abonnement : on a un customer et un plan, creer la subscription
        if ($is_abo) {
            if ($plan and $customer) {
                $desc_sub = array('customer' => $customer->id, 'plan' => $plan->id, 'metadata' => array('id_transaction' => $id_transaction));
                try {
                    $sub = \Stripe\Subscription::create($desc_sub);
                    if (!$sub) {
                        $erreur = "Erreur creation subscription";
                        $erreur_code = "sub_failed";
                    } else {
                        $response['abo_uid'] = $sub->id;
                    }
                } 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';
                    }
                }
            } else {
                $erreur = "Erreur creation subscription (plan or customer missing)";
                $erreur_code = "sub_failed";
            }
        }
    }
    if ($erreur or $erreur_code) {
        // 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' => $erreur_code, 'erreur' => $erreur, 'log' => var_export($response, true)));
    }
    // Ouf, le reglement a ete accepte
    // on verifie que le montant est bon !
    $montant_regle = 0;
    if ($charge) {
        $montant_regle = $charge['amount'] / 100;
    } elseif ($sub) {
        $montant_regle = $sub->plan->amount;
    }
    if ($montant_regle != $row['montant']) {
        spip_log($t = "call_response : id_transaction {$id_transaction}, montant regle {$montant_regle}!=" . $row['montant'] . ":" . var_export($charge, true), $mode);
        // on log ca dans un journal dedie
        spip_log($t, $mode . '_reglements_partiels');
    }
    if ($charge) {
        $transaction = $charge['balance_transaction'];
        $authorisation_id = $charge['id'];
    } elseif ($sub) {
        $transaction = $sub->id;
        $authorisation_id = $plan->id;
    }
    $set = array("autorisation_id" => "{$transaction}/{$authorisation_id}", "mode" => "{$mode}/{$config_id}", "montant_regle" => $montant_regle, "date_paiement" => $date_paiement, "statut" => 'ok', "reglee" => 'oui');
    if (isset($response['pay_id'])) {
        $set['pay_id'] = $response['pay_id'];
    }
    if (isset($response['abo_uid'])) {
        $set['abo_uid'] = $response['abo_uid'];
    }
    // type et numero de carte ?
    if ($charge) {
        if (isset($charge['source']) and $charge['source']['object'] == 'card') {
            // par defaut on note carte et BIN6 dans refcb
            $set['refcb'] = '';
            if (isset($charge['source']['brand'])) {
                $set['refcb'] .= $charge['source']['brand'];
            }
            if (isset($charge['source']['last4']) and $charge['source']['last4']) {
                $set['refcb'] .= ' ****' . $charge['source']['last4'];
            }
            $set['refcb'] = trim($set['refcb']);
            // validite de carte ?
            if (isset($charge['source']['exp_month']) and $charge['source']['exp_year']) {
                $set['validite'] = $charge['source']['exp_year'] . "-" . str_pad($charge['source']['exp_month'], 2, '0', STR_PAD_LEFT);
            }
        }
    }
    $response = array_merge($response, $set);
    // il faudrait stocker le $charge aussi pour d'eventuels retour ?
    sql_updateq("spip_transactions", $set, "id_transaction=" . intval($id_transaction));
    spip_log("call_response : 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);
}
Example #2
0
/**
 * @param array $config
 * @return array
 */
function presta_internetplus_inc_traiter_reponse_dist($config)
{
    $mode = 'wha';
    // historique...
    if ($config['type'] == 'abo') {
        $mode = 'wha_abo';
    }
    $config_id = bank_config_id($config);
    $id_transaction = 0;
    if (!($m = _request('m'))) {
        return array($id_transaction, false, false);
    }
    $m = urldecode($m);
    $mp = false;
    if (!($decode = wha_unsign($m))) {
        include_spip('inc/bank');
        bank_transaction_invalide($id_transaction, array('mode' => $mode, 'erreur' => "signature invalide", 'log' => $m));
        return array($id_transaction, false, false);
    }
    list($unsign, $partnerId, $keyId) = $decode;
    #var_dump($unsign);
    $args = wha_extract_args($unsign);
    $mp = $args['v']['mp'];
    #var_dump($args);
    // recuperer le code de resultat
    $c = isset($args['c']) ? $args['c'] : "";
    // annulation de l'internaute
    if (preg_match(",^(OfferAuthorization|Authorize)Cancel\$,i", $c)) {
        spip_log($t = "wha_traiter_reponse : annulation de la transaction : {$m}", $mode);
        if (isset($args['v']) and is_array($mp = $v = $args['v']) and $id_transaction = intval($v['id_transaction'])) {
            $row = sql_fetsel("*", "spip_transactions", "id_transaction=" . intval($id_transaction));
            if ($row['reglee'] == 'oui') {
                return array($id_transaction, true, $mp);
            }
            // sinon enregistrer echec transaction
            $date_paiement = date('Y-m-d H:i:s');
            include_spip('inc/bank');
            bank_transaction_echec($id_transaction, array('mode' => $mode, 'config_id' => $config_id, 'date_paiement' => $date_paiement, 'code_erreur' => "", 'erreur' => "Annulation", 'log' => var_export($args, true)));
        } else {
            include_spip('inc/bank');
            bank_transaction_invalide($id_transaction, array('mode' => $mode, 'erreur' => "id_transaction inconnu dans args[v] lors de l'annulation, traitement impossible", 'log' => $m));
        }
        return array($id_transaction, false, $mp);
    }
    // Code inconnu : on ne fait rien ?
    if (!preg_match(",^(OfferAuthorization|Authorize)Success\$,i", $c)) {
        include_spip('inc/bank');
        bank_transaction_invalide($id_transaction, array('mode' => $mode, 'erreur' => "code reponse c inconnu, traitement impossible", 'log' => $m));
        return array($id_transaction, false, $mp);
    }
    // Verifier le numero de transaction, dans mp
    if (!isset($args['v']) or !is_array($v = $args['v']) or !isset($v['mp']) or !is_array($mp = $v['mp'])) {
        include_spip('inc/bank');
        bank_transaction_invalide($id_transaction, array('mode' => $mode, 'erreur' => "mp inconnu, traitement impossible", 'log' => $m));
        return array($id_transaction, false, $mp);
    }
    // OK
    $traiter_reponse = charger_fonction("traiter_reponse_{$mode}", 'presta/internetplus/inc');
    return $traiter_reponse($config, $m, $args, $partnerId, $keyId);
}
Example #3
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);
}
Example #4
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);
}
Example #5
0
/**
 * Retour de la demande de paiement chez PaypalExpress
 *
 * @param array $config
 * @param null|array $response
 * @return array
 */
function presta_paypalexpress_call_response($config, $response = null)
{
    include_spip('inc/bank');
    $mode = $config['presta'];
    $ack = false;
    include_spip('presta/paypalexpress/inc/paypalexpress');
    /* At this point, the buyer has completed in authorizing payment
    	at PayPal.  The script will now call PayPal with the details
    	of the authorization, incuding any shipping information of the
    	buyer.  Remember, the authorization is not a completed transaction
    	at this state - the buyer still needs an additional step to finalize
    	the transaction
    	*/
    $token = urlencode(_request('token'));
    $id_transaction = intval($_SESSION['id_transaction']);
    if (!($row = sql_fetsel("*", "spip_transactions", "id_transaction=" . intval($id_transaction)))) {
        return bank_transaction_invalide($id_transaction, array('mode' => $mode, 'log' => var_export($_REQUEST, true) . var_export($_SESSION, true), 'erreur' => 'donnees Paypal non conformes'));
    }
    /* Build a second API request to PayPal, using the token as the
    	ID to get the details on the payment authorization
    	*/
    $nvpstr = "&TOKEN=" . $token;
    #var_dump($nvpstr);
    // pas la peine de faire un call Paypal si Cancel
    if ($token and _request('action') !== 'bank_cancel' and !defined('_BANK_CANCEL_TRANSACTION')) {
        /* Make the API call and store the results in an array.  If the
        		call was a success, show the authorization details, and provide
        		an action to complete the payment.  If failed, show the error
        		*/
        $resArray = bank_paypalexpress_hash_call($config, "GetExpressCheckoutDetails", $nvpstr);
        #var_dump($resArray);
        $_SESSION['reshash'] = $resArray;
        $ack = strtoupper($resArray["ACK"]);
    }
    if ($ack == "SUCCESS" and isset($resArray["PAYERID"]) and isset($resArray["EMAIL"]) and $resArray["PAYERID"] == _request('PayerID')) {
        $url = $_SESSION['paypalexpress_url_confirm'];
        $url_checkout = generer_action_auteur('paypalexpress_checkoutpayment', $resArray["PAYERID"] . "-" . $mode . "-" . bank_config_id($config));
        $url = parametre_url($url, 'checkout', $url_checkout, '&');
        $resume = "Paiement par compte Paypal : <br/>" . $resArray['FIRSTNAME'] . ' ' . $resArray['LASTNAME'] . "," . $resArray['EMAIL'];
        $_SESSION['order_resume'] = $resume;
        $_SESSION['token'] = $token;
        $_SESSION['payer_id'] = $resArray["PAYERID"];
        // on redirige (un peu sauvagement) sur l'URL de confirmation
        // qui est l'url d'origine du paiement avec un &confirm=oui
        // et va rafficher la commande avec un bouton de validation de paiement
        include_spip("inc/headers");
        redirige_par_entete($url);
    } else {
        // 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);
        }
        return bank_transaction_echec($id_transaction, array('mode' => $mode, 'config_id' => bank_config_id($config), 'log' => var_export($_REQUEST, true) . var_export($_SESSION['reshash'], true), 'erreur' => $ack, 'where' => 'GetExpressCheckoutDetails'));
    }
}
Example #6
0
function presta_internetplus_inc_traiter_reponse_wha_dist($config, $m, $args, $partnerId, $keyId)
{
    $mode = 'wha';
    // historique...
    $config_id = bank_config_id($config);
    $v = $args['v'];
    $mp = $v['mp'];
    if (!isset($mp['id_transaction']) or !($id_transaction = $mp['id_transaction'])) {
        bank_transaction_invalide(0, array('where' => 'wha_traiter_reponse', 'mode' => $mode, 'erreur' => "pas de id_transaction en retour", 'log' => $m));
        return array(0, false, $mp);
    }
    // verifier que la transaction est connue
    $res = sql_select("*", "spip_transactions", "id_transaction=" . intval($id_transaction));
    if (!($row = sql_fetch($res))) {
        bank_transaction_invalide($id_transaction, array('where' => 'wha_traiter_reponse', 'mode' => $mode, 'erreur' => "transaction inconnue", 'log' => $m));
        return array($id_transaction, false, $mp);
    }
    if (!$row['id_auteur']) {
        if (!isset($GLOBALS['visiteur_session']['id_auteur']) or !$GLOBALS['visiteur_session']['id_auteur']) {
            $_SESSION['wha_traiter_reponse_wha'] = array('m' => $m, 'args' => $args, 'partnerId' => $partnerId, 'keyId' => $keyId);
            return array($id_transaction, 'delayed', $mp);
        } else {
            sql_updateq("spip_transactions", array("id_auteur" => $row['id_auteur'] = $GLOBALS['visiteur_session']['id_auteur']), "id_transaction=" . intval($id_transaction));
        }
    }
    if ($row['statut'] !== 'ok') {
        // ok, on traite le reglement
        $montant_regle = $row['montant'];
        // on verifie que le montant est bon !
        /*$montant_regle = isset($v['amt'])?$v['amt']:0;
        		if ($montant_regle!=$row['montant']){
        			spip_log($t = "wha_traiter_reponse : id_transaction $id_transaction, montant regle $montant_regle!=".$row['montant'].":".$m,'internetplus'._LOG_ERREUR);
        			// on log ca dans un journal dedie
        			spip_log($t,'internetplus_partiels'._LOG_ERREUR);
        			// on est sympa avec le client, dans le doute on livre le produit
        		}*/
        $authorisation_id = $v['tId'];
        // declencher l'url de confirmation de reglement
        $node_response = $v['rt'];
        $config = array('MERCHANT_ID' => $partnerId, 'KEY_ID' => $keyId, 'node' => $node_response);
        $url = wha_url_confirm($authorisation_id, $row['montant'], $config);
        include_spip('inc/distant');
        $ack = @recuperer_page($url);
        if (!$ack or !($unsign = wha_unsign($ack)) or !($args = wha_extract_args(reset($unsign))) or !isset($args['c']) or !$args['c'] == 'ack') {
            bank_transaction_invalide($id_transaction, array('where' => 'wha_traiter_reponse', 'mode' => $mode, 'erreur' => "pas de confirmation de debit / {$url} : {$ack}", 'update' => true, 'log' => $m));
            return array($id_transaction, false, $mp);
        }
        sql_updateq("spip_transactions", array("autorisation_id" => $authorisation_id, "mode" => "wha/{$config_id}", "montant_regle" => $montant_regle, "date_paiement" => date('Y-m-d H:i:s'), "statut" => 'ok', "reglee" => 'oui'), "id_transaction=" . intval($id_transaction));
        spip_log("wha_traiter_reponse : id_transaction {$id_transaction}, reglee", $mode . _LOG_INFO_IMPORTANTE);
        spip_log("{$m}", $mode . '_autorisations' . _LOG_INFO_IMPORTANTE);
    }
    $regler_transaction = charger_fonction('regler_transaction', 'bank');
    $regler_transaction($id_transaction, array('row_prec' => $row));
    return array($id_transaction, true, $mp);
}
Example #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_sips_call_response_dist($config, $response = null)
{
    include_spip('inc/bank');
    $mode = $config['presta'];
    include_spip('inc/config');
    $merchant_id = $config['merchant_id'];
    $service = $config['service'];
    $certif = $config['certificat'];
    // recuperer la reponse en post et la decoder
    if (is_null($response)) {
        $response = sips_response($service, $merchant_id, $certif);
    }
    if ($response['merchant_id'] !== $merchant_id) {
        return bank_transaction_invalide(0, array('mode' => $mode, 'erreur' => "merchant_id invalide", 'log' => sips_shell_args($response)));
    }
    return sips_traite_reponse_transaction($config, $response);
}
Example #8
0
function presta_internetplus_inc_traiter_reponse_wha_abo_dist($config, $m, $args, $partnerId, $keyId)
{
    $mode = 'wha_abo';
    // historique...
    $config_id = bank_config_id($config);
    $v = $args['v'];
    $mp = $v['mp'];
    if (!isset($mp['id_transaction']) or !($id_transaction = $mp['id_transaction'])) {
        bank_transaction_invalide(0, array('where' => 'wha_traiter_reponse_abo', 'mode' => $mode, 'erreur' => "pas de id_transaction en retour", 'log' => $m));
        return array(0, false, $mp);
    }
    // verifier que la transaction est connue
    $res = sql_select("*", "spip_transactions", "id_transaction=" . intval($id_transaction));
    if (!($row = sql_fetch($res))) {
        bank_transaction_invalide($id_transaction, array('where' => 'wha_traiter_reponse_abo', 'mode' => $mode, 'erreur' => "transaction inconnue", 'log' => $m));
        return array($id_transaction, false, $mp);
    }
    if ($row['statut'] !== 'ok') {
        // id abonne
        $uoid = $v['uoid'];
        // de quoi generer la confirmation async si auteur pas connu
        $confirm = array('node' => $v['ru'], 'partner' => $partnerId, 'key' => $keyId);
        $confirm_offer = charger_fonction("confirm_offer", "presta/internetplus/inc");
        if (!$confirm_offer($id_transaction, $uoid, $confirm)) {
            bank_transaction_invalide($id_transaction, array('where' => 'wha_traiter_reponse_abo', 'mode' => $mode, 'erreur' => "pas de confirmation du debit par Internet+", 'update' => true, 'log' => $m));
            // invalider abo ?
            return array($id_transaction, false, $mp);
        }
        // OK ici la transaction est bien reglee
        $authorisation_id = $uoid;
        // url de confirmation
        sql_updateq("spip_transactions", array("autorisation_id" => $authorisation_id, "mode" => "{$mode}/{$config_id}", "date_paiement" => date('Y-m-d H:i:s'), "statut" => 'ok', "reglee" => 'oui', 'abo_uid' => $uoid), "id_transaction=" . intval($id_transaction));
        // activer l'abonnement
        if ($activer_abonnement = charger_fonction('activer_abonnement', 'abos', true)) {
            $activer_abonnement($id_transaction, $uoid, "wha/{$partnerId}");
        }
    }
    return array($id_transaction, true, $mp);
}
Example #9
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);
}
Example #10
0
File: sips.php Project: nursit/bank
/**
 * Traiter la reponse apres son decodage
 *
 * @param array $config
 * @param array $response
 * @return array
 */
function sips_traite_reponse_transaction($config, $response)
{
    $mode = $config['presta'];
    $config_id = bank_config_id($config);
    $id_transaction = $response['order_id'];
    $transaction_id = $response['transaction_id'];
    $row = sql_fetsel("*", "spip_transactions", "id_transaction=" . intval($id_transaction));
    if (!$row) {
        return bank_transaction_invalide($id_transaction, array('mode' => $mode, 'erreur' => "transaction inconnue", 'log' => sips_shell_args($response)));
    }
    /*
    include_spip('inc/filtres');
    if ($transaction_hash!=modulo($row['transaction_hash'],999999)){
    	return bank_transaction_invalide($id_transaction,
    		array(
    			'mode'=>$mode,
    			'erreur' => "hash $transaction_hash invalide",
    			'log' => sips_shell_args($response)
    		)
    	);
    }
    */
    // ok, on traite le reglement
    $date = 'payment';
    if ($mode == 'sipsabo') {
        $date = 'sub';
    }
    //"Y-m-d H:i:s"
    $date_paiement = substr($response[$date . '_date'], 0, 4) . "-" . substr($response[$date . '_date'], 4, 2) . "-" . substr($response[$date . '_date'], 6, 2) . " " . substr($response[$date . '_time'], 0, 2) . ":" . substr($response[$date . '_time'], 2, 2) . ":" . substr($response[$date . '_time'], 4, 2);
    $response_code = sips_response_code($response['response_code']);
    $bank_response_code = sips_bank_response_code($response['bank_response_code']);
    if ($response_code !== true or $bank_response_code !== true) {
        // 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['response_code'] . (strlen($response['bank_response_code']) ? ":" . $response['bank_response_code'] : ''), 'erreur' => trim($response_code . " " . $bank_response_code), 'log' => sips_shell_args($response), 'send_mail' => $response['response_code'] == '03'));
    }
    // Ouf, le reglement a ete accepte
    // on verifie que le montant est bon !
    $montant_regle = $response[($mode == 'sipsabo' ? 'sub_' : '') . 'amount'] / 100;
    if ($montant_regle != $row['montant']) {
        spip_log($t = "call_response : id_transaction {$id_transaction}, montant regle {$montant_regle}!=" . $row['montant'] . ":" . sips_shell_args($response), $mode);
        // on log ca dans un journal dedie
        spip_log($t, $mode . '_reglements_partiels');
    }
    // mais sinon on note regle quand meme,
    // pour ne pas creer des problemes hasardeux
    // (il y a des fois une erreur d'un centime)
    $authorisation_id = $response['authorisation_id'];
    $set = array("autorisation_id" => $authorisation_id, "mode" => "{$mode}/{$config_id}", "montant_regle" => $montant_regle, "date_paiement" => $date_paiement, "statut" => 'ok', "reglee" => 'oui');
    sql_updateq("spip_transactions", $set, "id_transaction=" . intval($id_transaction));
    spip_log("call_response : 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);
}
Example #11
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);
}
Example #12
0
File: bank.php Project: nursit/bank
/**
 * Call response simple (cheque, virement, simu)
 * 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 bank_simple_call_response($config, $response = null)
{
    $mode = $config['presta'];
    $config_id = bank_config_id($config);
    // 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' => "transaction inconnue", 'log' => var_export($response, true)));
    }
    $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 non trouvee", 'log' => var_export($response, true)));
    }
    if ($transaction_hash != $row['transaction_hash']) {
        return bank_transaction_invalide($id_transaction, array('mode' => $mode, 'erreur' => "hash {$transaction_hash} non conforme", 'log' => var_export($response, true)));
    }
    $autorisation = isset($response['autorisation_id']) ? $response['autorisation_id'] : '';
    if ($autorisation === "wait") {
        // c'est un reglement en attente, on le note
        $set = array("mode" => "{$mode}/{$config_id}", 'autorisation_id' => date('d/m/Y-H:i:s') . "/" . $GLOBALS['ip'], "date_paiement" => date('Y-m-d H:i:s'), "statut" => 'attente');
    } else {
        // si rien fourni l'autorisation refere l'id_auteur et le nom de celui qui accepte le cheque|virement
        if (!$autorisation) {
            $autorisation = $GLOBALS['visiteur_session']['id_auteur'] . "/" . $GLOBALS['visiteur_session']['nom'];
        }
        include_spip("inc/autoriser");
        if (!autoriser('utilisermodepaiement', $mode)) {
            return bank_transaction_invalide($id_transaction, array('mode' => $mode, 'erreur' => "{$mode} pas autorisee"));
        }
        if (!autoriser('encaisser' . $mode, 'transaction', $id_transaction)) {
            return bank_transaction_invalide($id_transaction, array('mode' => $mode, 'erreur' => "tentative d'encaisser un {$mode} par auteur #{$autorisation} pas autorise"));
        }
        // est-ce une demande d'echec ? (cas de la simulation)
        if (isset($response['fail']) and $response['fail']) {
            // sinon enregistrer l'absence de paiement et l'erreur
            include_spip('inc/bank');
            return bank_transaction_echec($id_transaction, array('mode' => $mode, 'config_id' => $config_id, 'code_erreur' => 'fail', 'erreur' => $response['fail']));
        }
        // OK, on peut accepter le reglement
        $set = array("mode" => "{$mode}/{$config_id}", "autorisation_id" => $autorisation, "montant_regle" => $row['montant'], "date_paiement" => date('Y-m-d H:i:s'), "statut" => 'ok', "reglee" => 'oui');
    }
    // est-ce un abonnement ?
    if (isset($response['abo_uid']) and $response['abo_uid']) {
        $set['abo_uid'] = $response['abo_uid'];
    }
    sql_updateq("spip_transactions", $set, "id_transaction=" . intval($id_transaction));
    // si ok on regle
    if ($set['statut'] === 'ok') {
        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));
        $res = true;
    } else {
        // cela permet de factoriser le code
        $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';
    }
    // Si c'est un abonnnement, activer ou resilier
    if ($id_transaction and $row = sql_fetsel("*", "spip_transactions", "id_transaction=" . intval($id_transaction)) and $abo_uid = $row['abo_uid']) {
        // c'est un paiement reussi ou en 'wait'
        if ($res) {
            // date de fin de mois de validite de la carte
            $date_fin = "0000-00-00 00:00:00";
            if ($row['validite']) {
                list($year, $month) = explode('-', $row['validite']);
                $date_fin = bank_date_fin_mois($year, $month);
            }
            if ($activer_abonnement = charger_fonction('activer_abonnement', 'abos', true)) {
                $activer_abonnement($id_transaction, $abo_uid, $mode, $date_fin);
            }
        }
        // c'est un echec, il faut le resilier, que ce soit la premiere ou la Nieme transaction
        if (!$res) {
            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, $res);
}
Example #13
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;
}
Example #14
0
/**
 * Decoder la reponse renvoyee par Ogone
 *
 * @param array $config
 * @param array $response
 * @return array
 */
function ogone_traite_reponse_transaction($config, $response)
{
    $mode = $config['presta'];
    if (isset($config['mode_test']) and $config['mode_test']) {
        $mode .= "_test";
    }
    $config_id = bank_config_id($config);
    /*
    	'orderID' => string '15' (length=2)
     'currency' => string 'EUR' (length=3)
     'amount' => string '7' (length=1)
     'PM' => string 'CreditCard' (length=10)
     'ACCEPTANCE' => string 'test123' (length=7)
     'STATUS' => string '9' (length=1)
     'CARDNO' => string 'XXXXXXXXXXXX1111' (length=16)
     'ED' => string '1110' (length=4)
     'CN' => string 'John Doe' (length=12)
     'TRXDATE' => string '06/28/10' (length=8)
     'PAYID' => string '7599709' (length=7)
     'NCERROR' => string '0' (length=1)
     'BRAND' => string 'VISA' (length=4)
     'ECI' => string '7' (length=1)
     'IP' => string '88.173.4.97' (length=11)
     'SHASIGN' => string '6AC414390B39177A3EA9B70CE2D91BC03DED35F4' (length=40)
    */
    $id_transaction = intval($response['orderID']);
    if (!($row = sql_fetsel("*", "spip_transactions", "id_transaction=" . intval($id_transaction)))) {
        return bank_transaction_invalide($id_transaction, array('mode' => $mode, 'erreur' => "transaction inconnue", 'log' => var_export($response, true)));
    }
    // ok, on traite le reglement
    $date = time();
    $date_paiement = date("Y-m-d H:i:s", $date);
    $erreur = ogone_response_code($response['STATUS'], $response['NCERROR']);
    $authorisation_id = $response['ACCEPTANCE'];
    $transaction = $response['PAYID'];
    if (!$transaction or !$authorisation_id or $erreur !== true) {
        // 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);
        }
        return bank_transaction_echec($id_transaction, array('mode' => $mode, 'config_id' => $config_id, 'date_paiement' => $date_paiement, 'code_erreur' => $response['STATUS'] . ':' . $response['NCERROR'], 'erreur' => $erreur, 'log' => var_export($response, true)));
    }
    // Ouf, le reglement a ete accepte
    // on verifie que le montant est bon !
    $montant_regle = floatval($response['amount']);
    if ($montant_regle != $row['montant']) {
        spip_log($t = "call_response : id_transaction {$id_transaction}, montant regle {$montant_regle}!=" . $row['montant'] . ":" . var_export($response, true), $mode);
        // on log ca dans un journal dedie
        spip_log($t, $mode . '_reglements_partiels');
        // mais on continue en acceptant quand meme le paiement
        // car l'erreur est en general dans le traitement
    }
    sql_updateq("spip_transactions", array("autorisation_id" => "{$transaction}/{$authorisation_id}", "mode" => "{$mode}/{$config_id}", "montant_regle" => $montant_regle, "date_paiement" => $date_paiement, "statut" => 'ok', "reglee" => 'oui'), "id_transaction=" . intval($id_transaction));
    spip_log("call_response : 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);
}
Example #15
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);
}
Example #16
0
/**
 * Traite la réponse de la banque
 *
 * @param array $config
 *     configuration du module
 * @param array $response
 *     Données envoyées par la banque
 * @return array(int $id_transaction, bool $paiement_ok)
**/
function cmcic_traite_reponse_transaction($config, $response)
{
    $mode = $config['presta'];
    if (isset($config['mode_test']) and $config['mode_test']) {
        $mode .= "_test";
    }
    $config_id = bank_config_id($config);
    #spip_log("call_response : traitement d'une réponse de la banque $mode !", $mode);
    // on verifie que notre transaction existe bien
    $contenu = $response['texte-libre'];
    $contenu = urldecode($contenu);
    $contenu = @unserialize($contenu);
    if ($contenu === false) {
        $res = bank_transaction_invalide(0, array('mode' => $mode, 'erreur' => "contenu non deserialisable", 'log' => var_export($response, true)));
        cmcic_notifier_banque_erreur();
        return $res;
    }
    // id & hash
    $id_transaction = $contenu['id'];
    $transaction_hash = $contenu['hash'];
    $lang = $contenu['lang'];
    // remettre la langue de l'utilisateur qui a demandé la transaction
    // puisque ici c'est le serveur cmcic qui fait le hit
    include_spip('inc/lang');
    changer_langue($lang);
    // cette ligne id/hash doit exister !
    if (!($row = sql_fetsel("*", "spip_transactions", array("id_transaction=" . intval($id_transaction), 'transaction_hash=' . sql_quote($contenu['hash']))))) {
        $res = bank_transaction_invalide($id_transaction, array('mode' => $mode, 'erreur' => "{$id_transaction} / {$transaction_hash} inconnu", 'log' => var_export($response, true)));
        cmcic_notifier_banque_erreur();
        return $res;
    }
    // ici on a tout bon !
    #spip_log("call_response : données de la banque correctes. On les traite.", $mode);
    switch ($response['code-retour']) {
        case "Annulation":
            // Payment has been refused
            // put your code here (email sending / Database update)
            // Attention : an autorization may still be delivered for this payment
            $retour = cmcic_gerer_transaction_annulee($config, $id_transaction, $response, $row);
            break;
        case "payetest":
            // Payment has been accepeted on the test server
            // put your code here (email sending / Database update)
            $retour = cmcic_gerer_transaction_payee($config, $id_transaction, $response, $row, true);
            break;
        case "paiement":
            // Payment has been accepted on the productive server
            // put your code here (email sending / Database update)
            $retour = cmcic_gerer_transaction_payee($config, $id_transaction, $response, $row);
            break;
            /*** ONLY FOR MULTIPART PAYMENT ***/
        /*** ONLY FOR MULTIPART PAYMENT ***/
        case "paiement_pf2":
        case "paiement_pf3":
        case "paiement_pf4":
            // Payment has been accepted on the productive server for the part #N
            // return code is like paiement_pf[#N]
            // put your code here (email sending / Database update)
            // You have the amount of the payment part in $CMCIC_bruteVars['montantech']
            break;
        case "Annulation_pf2":
        case "Annulation_pf3":
        case "Annulation_pf4":
            // Payment has been refused on the productive server for the part #N
            // return code is like Annulation_pf[#N]
            // put your code here (email sending / Database update)
            // You have the amount of the payment part in $CMCIC_bruteVars['montantech']
            break;
    }
    cmcic_notifier_banque_ok();
    return $retour;
}
Example #17
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);
}
Example #18
0
/**
 * @param array $config
 * @param array $response
 * @return array
 */
function paybox_traite_reponse_transaction($config, $response)
{
    $mode = $config['presta'];
    if (isset($config['mode_test']) and $config['mode_test']) {
        $mode .= "_test";
    }
    $config_id = bank_config_id($config);
    // $response['id_transaction'] Peut contenir /email ou IBSxx... en cas d'abo
    $id_transaction = intval($response['id_transaction']);
    if (!($row = sql_fetsel("*", "spip_transactions", "id_transaction=" . intval($id_transaction)))) {
        return bank_transaction_invalide($id_transaction, array('mode' => $mode, 'erreur' => "transaction inconnue", 'log' => paybox_shell_args($response)));
    }
    // ok, on traite le reglement
    $date = $_SERVER['REQUEST_TIME'];
    $date_paiement = sql_format_date(date('Y', $date), date('m', $date), date('d', $date), date('H', $date), date('i', $date), date('s', $date));
    $erreur = paybox_response_code($response['erreur']);
    $authorisation_id = $response['auth'];
    $transaction = $response['trans'];
    if (!$transaction or !$authorisation_id or $erreur !== true) {
        // 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['erreur'], 'erreur' => $erreur, 'log' => paybox_shell_args($response), 'send_mail' => in_array($response['erreur'], array(3, 6)) ? true : false));
    }
    // Ouf, le reglement a ete accepte
    // on verifie que le montant est bon !
    $montant_regle = $response['montant'] / 100;
    if ($montant_regle != $row['montant']) {
        spip_log($t = "call_response : id_transaction {$id_transaction}, montant regle {$montant_regle}!=" . $row['montant'] . ":" . paybox_shell_args($response), $mode);
        // on log ca dans un journal dedie
        spip_log($t, $mode . '_reglements_partiels');
    }
    $set = array("autorisation_id" => "{$transaction}/{$authorisation_id}", "mode" => "{$mode}/{$config_id}", "montant_regle" => $montant_regle, "date_paiement" => $date_paiement, "statut" => 'ok', "reglee" => 'oui');
    // type et numero de carte ?
    if (isset($response['carte']) or isset($response['BIN6'])) {
        // par defaut on note carte et BIN6 dans refcb
        $set['refcb'] = '';
        if (isset($response['carte'])) {
            $set['refcb'] .= $response['carte'];
        }
        if (isset($response['BIN6'])) {
            $set['refcb'] .= " " . $response['BIN6'];
        }
        $set['refcb'] = trim($set['refcb']);
    }
    // validite de carte ?
    if (isset($response['valid']) and $response['valid']) {
        $set['validite'] = "20" . substr($response['valid'], 0, 2) . "-" . substr($response['valid'], 2, 2);
    }
    // si on a envoye un U il faut recuperer les donnees CB et les stocker sur le compte client
    if (isset($response['ppps']) and $response['ppps']) {
        $set['pay_id'] = $response['ppps'];
    }
    // si abonnement, stocker les 2 infos importantes : uid et validite
    if (isset($response['abo']) and $response['abo']) {
        $set['abo_uid'] = $response['abo'];
    }
    // il faudrait stocker le $transaction aussi pour d'eventuels retour vers paybox ?
    sql_updateq("spip_transactions", $set, "id_transaction=" . intval($id_transaction));
    spip_log("call_response : 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);
}
Example #19
0
function bank_paypalexpress_checkoutpayment($payerid, $config)
{
    $mode = $config['presta'];
    if (isset($config['mode_test']) and $config['mode_test']) {
        $mode .= "_test";
    }
    $config_id = bank_config_id($config);
    include_spip('inc/date');
    if (!($id_transaction = $_SESSION['id_transaction'])) {
        return bank_transaction_invalide(0, array('mode' => $mode, 'erreur' => "id_transaction absent de la session", 'log' => var_export($_SESSION, true)));
    }
    if (!($row = sql_fetsel("*", "spip_transactions", "id_transaction=" . intval($id_transaction)))) {
        return bank_transaction_invalide($id_transaction, array('mode' => $mode, 'erreur' => "transaction inconnue", 'log' => var_export($_SESSION, true)));
    }
    // hmm bizare, double hit ? On fait comme si c'etait OK
    if ($row['reglee'] == 'oui') {
        spip_log("Erreur transaction {$id_transaction} deja reglee", $mode . _LOG_INFO_IMPORTANTE);
        return array($id_transaction, true);
    }
    // verifier que le payerid est conforme
    if ($payerid !== $_SESSION['payer_id']) {
        $trace = "Payerid:{$payerid}\n" . var_export($_SESSION, true);
        // sinon enregistrer l'absence de paiement et l'erreur
        return bank_transaction_echec($id_transaction, array('mode' => $mode, 'config_id' => $config_id, 'code_erreur' => '', 'erreur' => "Annulation", 'log' => $trace));
    }
    /* Gather the information to make the final call to
    	finalize the PayPal payment.  The variable nvpstr
    	holds the name value pairs
    	*/
    $token = urlencode($_SESSION['token']);
    $paymentAmount = $row['montant'];
    $currencyCodeType = "EUR";
    $paymentType = "Sale";
    $payerID = urlencode($_SESSION['payer_id']);
    $serverName = urlencode($_SERVER['SERVER_NAME']);
    $nvpstr = '&TOKEN=' . $token . '&PAYERID=' . $payerID . '&PAYMENTACTION=' . $paymentType . '&AMT=' . $paymentAmount . '&ORDERTOTAL=' . $paymentAmount . '&CURRENCYCODE=' . $currencyCodeType . '&IPADDRESS=' . $serverName;
    /* Make the call to PayPal to finalize payment
    	If an error occured, show the resulting errors
    	*/
    $resArray = bank_paypalexpress_hash_call($config, "DoExpressCheckoutPayment", $nvpstr);
    $date_paiement = date('Y-m-d H:i:s');
    /* Display the API response back to the browser.
    	If the response from PayPal was a success, display the response parameters'
    	If the response was an error, display the errors received using APIError.php.
    	*/
    $ack = strtoupper($resArray["ACK"]);
    if ($ack != "SUCCESS") {
        $_SESSION['reshash'] = $resArray;
        return bank_transaction_echec($id_transaction, array('mode' => $mode, 'config_id' => $config_id, "date_paiement" => $date_paiement, 'code_erreur' => '', 'erreur' => "Erreur lors de la transaction avec Paypal", 'log' => var_export($resArray, true), 'where' => 'DoExpressCheckoutPayment'));
    }
    $authorisation_id = $resArray['TRANSACTIONID'];
    $montant_regle = $resArray['AMT'];
    $set = array("autorisation_id" => $authorisation_id, "mode" => "{$mode}/{$config_id}", "montant_regle" => $montant_regle, "date_paiement" => $date_paiement, "statut" => 'ok', "reglee" => 'oui');
    sql_updateq("spip_transactions", $set, "id_transaction=" . intval($id_transaction));
    spip_log("DoExpressCheckoutPayment : id_transaction {$id_transaction}, reglee", $mode . _LOG_INFO_IMPORTANTE);
    if (isset($_SESSION['reshash']) and $response = $_SESSION['reshash']) {
        // 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('EMAIL' => 'email', 'LASTNAME' => 'nom', 'FIRSTNAME' => 'prenom', 'SHIPTONAME' => 'nom', 'SHIPTOSTREET' => 'adresse', 'SHIPTOCITY' => 'ville', 'SHIPTOZIP' => 'code_postal', 'SHIPTOCOUNTRYCODE' => 'pays');
        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];
            }
        }
    }
    // a faire avant le reglement qui va poser d'autres variables de session
    session_unset();
    $regler_transaction = charger_fonction('regler_transaction', 'bank');
    $regler_transaction($id_transaction, array('row_prec' => $row));
    return array($id_transaction, true);
}