Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Permettre de s'abonner plus d'une heure, un jour ou un mois avec Stri… #126

Open
wants to merge 5 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 18 additions & 0 deletions bank_fonctions.php
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,24 @@ function balise_PAYER_ABONNEMENT_dist($p){
return $p;
}

/**
* #CHANGER_MOYEN_PAIEMENT{#ID_ABONNEMENT,#ID_TRANSACTION}
* @param $p
* @return mixed
*/
function balise_CHANGER_MOYEN_PAIEMENT_dist($p){

$_idabo = interprete_argument_balise(1, $p);
$_idtrans = interprete_argument_balise(2, $p);
$p->code = "";

if ($_idabo AND $_idtrans) {
$p->code = "bank_changer_paiement($_idabo,$_idtrans)";
}

$p->interdire_scripts = false;
return $p;
}

/**
* #GERER_ABONNEMENT{#MODE_PAIEMENT,#ABO_UID}
Expand Down
20 changes: 20 additions & 0 deletions bank_options.php
Original file line number Diff line number Diff line change
Expand Up @@ -183,3 +183,23 @@ function bank_affiche_gerer_abonnement($config, $abo_uid){

return "";
}

/**
* Afficher le bouton pour changer de moyen de paiement d'un abonnement
* @param array|string $config
* @param string $abo_uid
* @return array|string
*/
function bank_changer_paiement($id_abo, $id_trans){
// $config de type string ?
include_spip('inc/bank');

if ($trans = sql_fetsel("*", "spip_transactions", $w = "id_transaction=" . sql_quote($id_trans))){
$config = bank_config($trans['mode']);
if ($configurer = charger_fonction('configurer', 'presta/'.$config['presta'] . '/payer', true)){
return $configurer($id_trans, $trans['transaction_hash']);
}
}

return "";
}
130 changes: 130 additions & 0 deletions presta/stripe/call/modifier_paiement.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
<?php
/*
* Paiement Bancaire
* module de paiement bancaire multi prestataires
* stockage des transactions
*
* Auteurs :
* Laurent Lefebvre largement inspiré du code de Cedric Morin / Nursit.com
* (c) 2012-2024 - Distribue sous licence GNU/GPL
*
*/

use Stripe\Exception\ApiErrorException;

if (!defined('_ECRIRE_INC_VERSION')){
return;
}

include_spip('presta/stripe/inc/stripe');

/**
* Preparation de modification de cartes
* il faut avoir un id_transaction et un transaction_hash coherents
* pour se premunir d'une tentative d'appel exterieur
*
* @param int $id_transaction
* @param string $transaction_hash
* @param $config
* configuration du module
* @param string $type
* type de paiement : acte ou abo
* @return array
*/
function presta_stripe_call_modifier_paiement_dist($id_transaction, $transaction_hash){

include_spip('inc/bank');
$mode = 'stripe';
$config = bank_config('stripe','setup');
if (isset($config['mode_test']) AND $config['mode_test']){
$mode .= "_test";
}

// Coté Spip : Recherche de transaction
if (!$row = sql_fetsel("*", "spip_transactions", "id_transaction=" . intval($id_transaction) . " AND transaction_hash=" . sql_quote($transaction_hash))){
spip_log("call_modifier_paiement : transaction $id_transaction / $transaction_hash introuvable",$mode._LOG_ERREUR);
return false;
}
// Coté Spip : Recherche d'auteur
if ($auteur = sql_fetsel("*","spip_auteurs","id_auteur=".intval($row['id_auteur']))){
// spip_log("call_modifier_paiement : auteur ". $auteur['id_auteur'],$mode._LOG_DEBUG);
if( !isset($GLOBALS['visiteur_session']['id_auteur'])
OR $GLOBALS['visiteur_session']['id_auteur']!=$auteur['id_auteur']) {
spip_log("call_modifier_paiement : Seul l'auteur spécifié peut modifier son moyen de paiement ",$mode._LOG_ERREUR);
return "";
}
} else {
spip_log("call_modifier_paiement : auteur introuvable ",$mode._LOG_ERREUR);
return "";
}

$billing = bank_porteur_infos_facturation($auteur);
$email = $billing['email'];
// Variables qui vont être récupérés en POST
$contexte = array(
'id_transaction' => $id_transaction,
'transaction_hash' => $transaction_hash,
);
$contexte['sign'] = bank_sign_response_simple($mode, $contexte);
$url_success = bank_url_api_retour($config,"response");
$url_cancel = bank_url_api_retour($config,"cancel");
foreach($contexte as $k=>$v){
$url_success = parametre_url($url_success, $k, $v, '&');
$url_cancel = parametre_url($url_cancel, $k, $v, '&');
}

$contexte['action'] = str_replace('&', '&amp;', $url_success);
$contexte['email'] = $email;
$contexte['key'] = ($config['mode_test'] ? $config['PUBLISHABLE_KEY_test'] : $config['PUBLISHABLE_KEY']);
$contexte['name'] = bank_nom_site();
$contexte['description'] = _T('bank:titre_transaction') . '#' . $id_transaction;
$contexte['image'] = find_in_path('img/logo-paiement-stripe.png');

stripe_init_api($config);
stripe_set_webhook($config);

// ================== CUSTOMER ===================

// Coté Stripe : on vérifie que le customer existe
if ($row['id_auteur']) {
$config_id = bank_config_id($config);
$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
and $customer = stripe_customer($mode, ['id' => $customer_id])
and $customer->email === $contexte['email']
){
spip_log("call_modifier_paiement : Customer retrouvé :". $id_customer,$mode._LOG_DEBUG);
$checkout_customer_id = $customer_id;
} else {
spip_log("call_modifier_paiement : ce Customer n'existe pas chez Stripe". $id_customer,$mode._LOG_ERREUR);
return false;
}
if (!$checkout_customer_id
and $customer = stripe_customer($mode, ['email' => $contexte['email'], 'nom' => trim($billing['prenom'] . ' ' . $billing['nom'])])){
$checkout_customer_id = $customer->id;
}
}

// On prépare la sessions avec les données génériques
$session_desc = [
'payment_method_types' => ['card'],
'success_url' => $url_success . '&session_id={CHECKOUT_SESSION_ID}',
'cancel_url' => $url_success, // on revient sur success aussi car response gerera l'echec du fait de l'absence de session_id
'locale' => stripe_locale($GLOBALS['spip_lang']),
'customer_email' => $email,
];

// Et on déclare les paramètres particuliers du mode "setup" de la session checkout.
$session_desc['mode'] = 'setup';
$session_desc[ 'setup_intent_data']['description'] = 'Enregistrement de nouveau moyen de paiement';
$session_desc[ 'setup_intent_data']['metadata']['customer_id'] = $id_customer;
$session_desc[ 'setup_intent_data']['metadata']['subscription_id'] = str_replace('/','',$row['abo_uid']);

$session = \Stripe\Checkout\Session::create($session_desc);
$contexte['checkout_session_id'] = $session->id;

return $contexte;

}
4 changes: 3 additions & 1 deletion presta/stripe/call/request.php
Original file line number Diff line number Diff line change
Expand Up @@ -291,6 +291,8 @@ function presta_stripe_call_request_dist($id_transaction, $transaction_hash, $co
}
}

$interval_count = 1;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

mais du coup là tu l'initialises à 1 mais tu ne l'utilises jamais ensuite non ? ça devrait être le fallback de si c'est pas fourni dans le tableau

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ce sont les plugins qui font l'interface entre les commandes et les abonnements qui sont censés les manipuler, non ?


$session_desc = [
'payment_method_types' => $payment_types,
'mode' => 'subscription',
Expand Down Expand Up @@ -321,7 +323,7 @@ function presta_stripe_call_request_dist($id_transaction, $transaction_hash, $co
'unit_amount' => $montant_echeance,
'recurring' => [
'interval' => $interval,
'interval_count' => 1,
'interval_count' => $echeance['interval_count'],
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

quelque chose comme $echeance['interval_count'] ?? $interval_count ?

autre question : est-ce que dans le tableau qui est générique et qui vient de "decrire_echeance", on doit attendre une clé qui s'appelle "interval_count" et qui est propre à stripe, ou bien on peut trouver un nom qui est plus générique et qui sémantiquement pourrait s'appliquer à tout ?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Alors, tu peux soulever le chantier de la cohérence des noms des variables pour "decrire_echeance", parce qu'entre les variables en français ("montant", "montant_init"), les variables en anglais ("count",, "count_init","date_start"), et les variables dans les 2 langues abregées, ("frequ", "nb"), j'en n'ai pas vraiment trouvé, perso, de cohérence. J'ai l'impression qu'elles ont été ajoutées en fonction de ce qu'amenaient les API de paiement. Alors j'ai fait pareil avec Stripe.

Ils font comment les autres prestataires pour proposer des abonnements trimestriels par exemple ?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

quelque chose comme $echeance['interval_count'] ?? $interval_count ?

En fait, tu as raison. Je corrige ça...

//'trial_period_days' => 0, // default
],
//'billing_scheme' => 'per_unit', // implicite, non modifiable via price_data
Expand Down
28 changes: 28 additions & 0 deletions presta/stripe/payer/configurer.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
[(#REM)
/*
* Paiement Bancaire
* module de paiement bancaire multi prestataires
* stockage des transactions
*
* Auteurs :
* Laurent Lefebvre largement inspiré du code de Cedric Morin / Nursit.com
* (c) 2012-2024 - Distribue sous licence GNU/GPL
*
*/
]#CACHE{0}
<BOUCLE_trans(TRANSACTIONS){id_transaction}{transaction_hash}>
<div class='boutons[ (#ENV{autosubmit}|?{loading})]'>
[(#SET{id,[setup(#ID_TRANSACTION)]})]
[(#BOUTON_ACTION{
Modifier le moyen de paiement pour cet abonnement,
#ENV*{action},
[stripe_button_(#GET{id}) btn btn-defaut btn-petit btn-fleche],
'',
'',
[stripe_button_(#GET{id})_callback\(\)]
})]
[<script src="https://js.stripe.com/v3/"></script>
<script type="text/javascript">(#INCLURE{fond=presta/stripe/payer/inc-checkout-js,env,id=#GET{id}}|compacte{js})</script>]
<style type="text/css">.payer_stripe .loading .bouton_action_post{position: relative} .payer_stripe .loading .bouton_action_post::after{content:'';display: block;position: absolute;left:0;right: 0;top:0;bottom: 0;background: rgba(255,255,255,0.5) url([(#CHEMIN{images/loader.svg})]) no-repeat center;background-size: contain;}</style>
</div>
</BOUCLE_trans>
35 changes: 35 additions & 0 deletions presta/stripe/payer/configurer.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
<?php
/*
* Paiement Bancaire
* module de paiement bancaire multi prestataires
* stockage des transactions
*
* Auteurs :
* Laurent Lefebvre largement inspiré du code de Cedric Morin / Nursit.com
* (c) 2012-2024 - Distribue sous licence GNU/GPL
*
*/
if (!defined('_ECRIRE_INC_VERSION')) return;


/**
* @param array $config
* @param int $id_transaction
* @param string $transaction_hash
* @param array $options
* @return array|string
*/
function presta_stripe_payer_configurer_dist($id_transaction,$th){
$call = charger_fonction('modifier_paiement','presta/stripe/call');
$contexte = $call($id_transaction, $th);
// si moyen de paiement pas applicable
if (!$contexte) {
return '';
}

$contexte['id_transaction'] = $id_transaction;
$contexte['transaction_hash'] = $th;

return recuperer_fond('presta/stripe/payer/configurer', $contexte);
}