Clean code to manage SEPA payment using external service
This commit is contained in:
parent
9a09e0f304
commit
584f9e6a73
@ -823,6 +823,815 @@ abstract class CommonInvoice extends CommonObject
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
|
||||
/**
|
||||
* Create a withdrawal request for a direct debit order or a credit transfer order.
|
||||
* Use the remain to pay excluding all existing open direct debit requests.
|
||||
*
|
||||
* @param User $fuser User asking the direct debit transfer
|
||||
* @param float $amount Amount we request direct debit for
|
||||
* @param string $type 'direct-debit' or 'bank-transfer'
|
||||
* @param string $sourcetype Source ('facture' or 'supplier_invoice')
|
||||
* @return int <0 if KO, >0 if OK
|
||||
*/
|
||||
public function demande_prelevement_stripe($fuser, $amount = 0, $type = 'direct-debit', $sourcetype = 'facture')
|
||||
{
|
||||
// phpcs:enable
|
||||
global $conf, $mysoc, $user, $langs;
|
||||
|
||||
if (empty($conf->global->STRIPE_SEPA_DIRECT_DEBIT)) {
|
||||
//exit
|
||||
return 0;
|
||||
}
|
||||
|
||||
$error = 0;
|
||||
|
||||
dol_syslog(get_class($this)."::demande_prelevement_stripe 0", LOG_DEBUG);
|
||||
|
||||
if ($this->statut > self::STATUS_DRAFT && $this->paye == 0) {
|
||||
require_once DOL_DOCUMENT_ROOT.'/societe/class/companybankaccount.class.php';
|
||||
$bac = new CompanyBankAccount($this->db);
|
||||
$bac->fetch(0, $this->socid);
|
||||
|
||||
$sql = 'SELECT count(*)';
|
||||
$sql .= ' FROM '.MAIN_DB_PREFIX.'prelevement_facture_demande';
|
||||
$sql .= ' WHERE fk_facture = '.$this->id;
|
||||
$sql .= ' AND ext_payment_id IS NULL'; // To exclude record done for some online payments
|
||||
$sql .= ' AND traite = 0';
|
||||
|
||||
dol_syslog(get_class($this)."::demande_prelevement_stripe 1", LOG_DEBUG);
|
||||
$resql = $this->db->query($sql);
|
||||
if ($resql) {
|
||||
$row = $this->db->fetch_row($resql);
|
||||
|
||||
if ($row[0] == 0) {
|
||||
$now = dol_now();
|
||||
|
||||
$totalpaye = $this->getSommePaiement();
|
||||
$totalcreditnotes = $this->getSumCreditNotesUsed();
|
||||
$totaldeposits = $this->getSumDepositsUsed();
|
||||
//print "totalpaye=".$totalpaye." totalcreditnotes=".$totalcreditnotes." totaldeposts=".$totaldeposits;
|
||||
|
||||
// We can also use bcadd to avoid pb with floating points
|
||||
// For example print 239.2 - 229.3 - 9.9; does not return 0.
|
||||
//$resteapayer=bcadd($this->total_ttc,$totalpaye,$conf->global->MAIN_MAX_DECIMALS_TOT);
|
||||
//$resteapayer=bcadd($resteapayer,$totalavoir,$conf->global->MAIN_MAX_DECIMALS_TOT);
|
||||
if (empty($amount)) {
|
||||
$amount = price2num($this->total_ttc - $totalpaye - $totalcreditnotes - $totaldeposits, 'MT');
|
||||
}
|
||||
|
||||
if (is_numeric($amount) && $amount != 0) {
|
||||
require_once DOL_DOCUMENT_ROOT.'/societe/class/companypaymentmode.class.php';
|
||||
$companypaymentmode = new CompanyPaymentMode($this->db);
|
||||
$companypaymentmode->fetch($bac->id);
|
||||
|
||||
dol_syslog(get_class($this)."::demande_prelevement_stripe amount=$amount, companypaymentmode = " . $companypaymentmode->id, LOG_DEBUG);
|
||||
|
||||
//Start code from sellyoursaas
|
||||
$service = 'StripeTest';
|
||||
$servicestatus = 0;
|
||||
if (!empty($conf->global->STRIPE_LIVE) && !GETPOST('forcesandbox', 'alpha')) {
|
||||
$service = 'StripeLive';
|
||||
$servicestatus = 1;
|
||||
}
|
||||
|
||||
$langs->load("agenda");
|
||||
dol_syslog("doTakePaymentStripeForThirdparty service=" . $service . " servicestatus=" . $servicestatus . " thirdparty_id=" . $this->socid . " companypaymentmode=" . $companypaymentmode->id . " noemailtocustomeriferror=" . $noemailtocustomeriferror . " nocancelifpaymenterror=" . $nocancelifpaymenterror . " calledinmyaccountcontext=" . $calledinmyaccountcontext);
|
||||
|
||||
$this->stripechargedone = 0;
|
||||
$this->stripechargeerror = 0;
|
||||
$now = dol_now();
|
||||
|
||||
$currency = $conf->currency;
|
||||
|
||||
global $stripearrayofkeysbyenv;
|
||||
global $savstripearrayofkeysbyenv;
|
||||
|
||||
$errorforinvoice = 0; // We reset the $errorforinvoice at each invoice loop
|
||||
|
||||
$this->fetch_thirdparty();
|
||||
|
||||
dol_syslog("--- Process invoice thirdparty_id=" . $this->id . ", thirdparty_name=" . $this->thirdparty->name . " id=" . $this->id . ", ref=" . $this->ref . ", datef=" . dol_print_date($this->date, 'dayhourlog'), LOG_DEBUG);
|
||||
|
||||
$alreadypayed = $this->getSommePaiement();
|
||||
$amount_credit_notes_included = $this->getSumCreditNotesUsed();
|
||||
$amounttopay = $this->total_ttc - $alreadypayed - $amount_credit_notes_included;
|
||||
|
||||
// Correct the amount according to unit of currency
|
||||
// See https://support.stripe.com/questions/which-zero-decimal-currencies-does-stripe-support
|
||||
$arrayzerounitcurrency = ['BIF', 'CLP', 'DJF', 'GNF', 'JPY', 'KMF', 'KRW', 'MGA', 'PYG', 'RWF', 'VND', 'VUV', 'XAF', 'XOF', 'XPF'];
|
||||
$amountstripe = $amounttopay;
|
||||
if (!in_array($currency, $arrayzerounitcurrency)) {
|
||||
$amountstripe = $amountstripe * 100;
|
||||
}
|
||||
|
||||
if ($amountstripe > 0) {
|
||||
try {
|
||||
//var_dump($companypaymentmode);
|
||||
dol_syslog("We will try to pay with companypaymentmodeid=" . $companypaymentmode->id . " stripe_card_ref=" . $companypaymentmode->stripe_card_ref . " mode=" . $companypaymentmode->status, LOG_DEBUG);
|
||||
|
||||
$thirdparty = new Societe($this->db);
|
||||
$resultthirdparty = $thirdparty->fetch($this->socid);
|
||||
|
||||
include_once DOL_DOCUMENT_ROOT . '/stripe/class/stripe.class.php'; // This include the include of htdocs/stripe/config.php
|
||||
// So it inits or erases the $stripearrayofkeysbyenv
|
||||
$stripe = new Stripe($this->db);
|
||||
|
||||
if (empty($savstripearrayofkeysbyenv)) {
|
||||
$savstripearrayofkeysbyenv = $stripearrayofkeysbyenv;
|
||||
}
|
||||
dol_syslog("Current Stripe environment is " . $stripearrayofkeysbyenv[$servicestatus]['publishable_key']);
|
||||
dol_syslog("Current Saved Stripe environment is " . $savstripearrayofkeysbyenv[$servicestatus]['publishable_key']);
|
||||
|
||||
$foundalternativestripeaccount = '';
|
||||
|
||||
// Force stripe to another value (by default this value is empty)
|
||||
if (!empty($thirdparty->array_options['options_stripeaccount'])) {
|
||||
dol_syslog("The thirdparty id=" . $thirdparty->id . " has a dedicated Stripe Account, so we switch to it.");
|
||||
|
||||
$tmparray = explode('@', $thirdparty->array_options['options_stripeaccount']);
|
||||
if (!empty($tmparray[1])) {
|
||||
$tmparray2 = explode(':', $tmparray[1]);
|
||||
if (!empty($tmparray2[3])) {
|
||||
$stripearrayofkeysbyenv = [
|
||||
0 => [
|
||||
"publishable_key" => $tmparray2[0],
|
||||
"secret_key" => $tmparray2[1]
|
||||
],
|
||||
1 => [
|
||||
"publishable_key" => $tmparray2[2],
|
||||
"secret_key" => $tmparray2[3]
|
||||
]
|
||||
];
|
||||
|
||||
$stripearrayofkeys = $stripearrayofkeysbyenv[$servicestatus];
|
||||
\Stripe\Stripe::setApiKey($stripearrayofkeys['secret_key']);
|
||||
|
||||
$foundalternativestripeaccount = $tmparray[0]; // Store the customer id
|
||||
|
||||
dol_syslog("We use now customer=" . $foundalternativestripeaccount . " publishable_key=" . $stripearrayofkeys['publishable_key'], LOG_DEBUG);
|
||||
}
|
||||
}
|
||||
|
||||
if (!$foundalternativestripeaccount) {
|
||||
$stripearrayofkeysbyenv = $savstripearrayofkeysbyenv;
|
||||
|
||||
$stripearrayofkeys = $savstripearrayofkeysbyenv[$servicestatus];
|
||||
\Stripe\Stripe::setApiKey($stripearrayofkeys['secret_key']);
|
||||
dol_syslog("We found a bad value for Stripe Account for thirdparty id=" . $thirdparty->id . ", so we ignore it and keep using the global one, so " . $stripearrayofkeys['publishable_key'], LOG_WARNING);
|
||||
}
|
||||
} else {
|
||||
$stripearrayofkeysbyenv = $savstripearrayofkeysbyenv;
|
||||
|
||||
$stripearrayofkeys = $savstripearrayofkeysbyenv[$servicestatus];
|
||||
\Stripe\Stripe::setApiKey($stripearrayofkeys['secret_key']);
|
||||
dol_syslog("The thirdparty id=" . $thirdparty->id . " has no dedicated Stripe Account, so we use global one, so " . json_encode($stripearrayofkeys), LOG_DEBUG);
|
||||
}
|
||||
|
||||
|
||||
dol_syslog("get stripe account", LOG_DEBUG);
|
||||
$stripeacc = $stripe->getStripeAccount($service, $this->socid); // Get Stripe OAuth connect account if it exists (no network access here)
|
||||
dol_syslog("get stripe account return " . json_encode($stripeacc), LOG_DEBUG);
|
||||
|
||||
if ($foundalternativestripeaccount) {
|
||||
if (empty($stripeacc)) { // If the Stripe connect account not set, we use common API usage
|
||||
$customer = \Stripe\Customer::retrieve(['id' => "$foundalternativestripeaccount", 'expand[]' => 'sources']);
|
||||
} else {
|
||||
$customer = \Stripe\Customer::retrieve(['id' => "$foundalternativestripeaccount", 'expand[]' => 'sources'], ["stripe_account" => $stripeacc]);
|
||||
}
|
||||
} else {
|
||||
$customer = $stripe->customerStripe($thirdparty, $stripeacc, $servicestatus, 0);
|
||||
if (empty($customer) && !empty($stripe->error)) {
|
||||
$this->errors[] = $stripe->error;
|
||||
}
|
||||
/*if (!empty($customer) && empty($customer->sources)) {
|
||||
$customer = null;
|
||||
$this->errors[] = '\Stripe\Customer::retrieve did not returned the sources';
|
||||
}*/
|
||||
}
|
||||
|
||||
// $nbhoursbetweentries = (empty($conf->global->SELLYOURSAAS_NBHOURSBETWEENTRIES) ? 49 : $conf->global->SELLYOURSAAS_NBHOURSBETWEENTRIES); // Must have more that 48 hours + 1 between each try (so 1 try every 3 daily batch)
|
||||
// $nbdaysbeforeendoftries = (empty($conf->global->SELLYOURSAAS_NBDAYSBEFOREENDOFTRIES) ? 35 : $conf->global->SELLYOURSAAS_NBDAYSBEFOREENDOFTRIES);
|
||||
$labeltouse = '';
|
||||
$postactionmessages = [];
|
||||
|
||||
if ($resultthirdparty > 0 && !empty($customer)) {
|
||||
if (!$error && !empty($this->array_options['options_delayautopayment']) && $this->array_options['options_delayautopayment'] > $now && empty($calledinmyaccountcontext)) {
|
||||
$errmsg = 'Payment try was canceled (invoice qualified by the automatic payment was delayed after the ' . dol_print_date($this->array_options['options_delayautopayment'], 'day') . ')';
|
||||
dol_syslog($errmsg, LOG_DEBUG);
|
||||
|
||||
$error++;
|
||||
$errorforinvoice++;
|
||||
$this->errors[] = $errmsg;
|
||||
}
|
||||
// if (!$error && ($this->date < ($now - ($nbdaysbeforeendoftries * 24 * 3600))) // We try until we reach $nbdaysbeforeendoftries
|
||||
// && ($this->date < ($now - (62 * 24 * 3600)) || $this->date > ($now - (60 * 24 * 3600))) // or when we have 60 days
|
||||
// && ($this->date < ($now - (92 * 24 * 3600)) || $this->date > ($now - (90 * 24 * 3600))) // or when we have 90 days
|
||||
// && empty($nocancelifpaymenterror)) {
|
||||
// $errmsg = 'Payment try was canceled (invoice date is older than ' . $nbdaysbeforeendoftries . ' days and not 60 days old and not 90 days old) - You can still take payment from backoffice.';
|
||||
// dol_syslog($errmsg, LOG_DEBUG);
|
||||
|
||||
// $error++;
|
||||
// $errorforinvoice++;
|
||||
// $this->errors[] = $errmsg;
|
||||
// }
|
||||
// if (!$error && empty($nocancelifpaymenterror)) { // If we are not in a mode that ask to avoid cancelation, we cancel payment.
|
||||
// // Test if last AC_PAYMENT_STRIPE_KO event is an old error lower than $nbhoursbetweentries hours.
|
||||
// $recentfailedpayment = false;
|
||||
// $sqlonevents = 'SELECT COUNT(*) as nb FROM ' . MAIN_DB_PREFIX . 'actioncomm WHERE fk_soc = ' . $thirdparty->id . " AND code ='AC_PAYMENT_STRIPE_KO' AND datep > '" . $this->db->idate($now - ($nbhoursbetweentries * 3600)) . "'";
|
||||
// $resqlonevents = $this->db->query($sqlonevents);
|
||||
// if ($resqlonevents) {
|
||||
// $obj = $this->db->fetch_object($resqlonevents);
|
||||
// if ($obj && $obj->nb > 0) {
|
||||
// $recentfailedpayment = true;
|
||||
// }
|
||||
// }
|
||||
|
||||
// if ($recentfailedpayment) {
|
||||
// $errmsg = 'Payment try was canceled (recent payment, in last ' . $nbhoursbetweentries . ' hours, with error AC_PAYMENT_STRIPE_KO for this customer)';
|
||||
// dol_syslog($errmsg, LOG_DEBUG);
|
||||
|
||||
// $error++;
|
||||
// $errorforinvoice++;
|
||||
// $this->errors[] = $errmsg;
|
||||
// }
|
||||
// }
|
||||
|
||||
if (!$error) { // Payment was not canceled
|
||||
//erics card or sepa ?
|
||||
$sepaMode = false;
|
||||
if ($companypaymentmode->type == 'ban') {
|
||||
$sepaMode = true;
|
||||
$stripecard = $stripe->sepaStripe($customer, $companypaymentmode, $stripeacc, $servicestatus, 0);
|
||||
} else {
|
||||
$stripecard = $stripe->cardStripe($customer, $companypaymentmode, $stripeacc, $servicestatus, 0);
|
||||
}
|
||||
|
||||
if ($stripecard) { // Can be card_... (old mode) or pm_... (new mode)
|
||||
$FULLTAG = 'INV=' . $this->id . '-CUS=' . $thirdparty->id;
|
||||
$description = 'Stripe payment from doTakePaymentStripeForThirdparty: ' . $FULLTAG . ' ref=' . $this->ref;
|
||||
|
||||
$stripefailurecode = '';
|
||||
$stripefailuremessage = '';
|
||||
$stripefailuredeclinecode = '';
|
||||
|
||||
if (preg_match('/^card_/', $stripecard->id)) { // Using old method
|
||||
dol_syslog("* Create charge on card " . $stripecard->id . ", amountstripe=" . $amountstripe . ", FULLTAG=" . $FULLTAG, LOG_DEBUG);
|
||||
|
||||
$ipaddress = getUserRemoteIP();
|
||||
|
||||
$charge = null; // Force reset of $charge, so, if already set from a previous fetch, it will be empty even if there is an exception at next step
|
||||
try {
|
||||
$charge = \Stripe\Charge::create([
|
||||
'amount' => price2num($amountstripe, 'MU'),
|
||||
'currency' => $currency,
|
||||
'capture' => true, // Charge immediatly
|
||||
'description' => $description,
|
||||
'metadata' => ["FULLTAG" => $FULLTAG, 'Recipient' => $mysoc->name, 'dol_version' => DOL_VERSION, 'dol_entity' => $conf->entity, 'ipaddress' => $ipaddress],
|
||||
'customer' => $customer->id,
|
||||
//'customer' => 'bidon_to_force_error', // To use to force a stripe error
|
||||
'source' => $stripecard,
|
||||
'statement_descriptor' => dol_trunc('INV=' . $this->id, 10, 'right', 'UTF-8', 1), // 22 chars that appears on bank receipt (company + description)
|
||||
]);
|
||||
} catch (\Stripe\Error\Card $e) {
|
||||
// Since it's a decline, Stripe_CardError will be caught
|
||||
$body = $e->getJsonBody();
|
||||
$err = $body['error'];
|
||||
|
||||
$stripefailurecode = $err['code'];
|
||||
$stripefailuremessage = $err['message'];
|
||||
$stripefailuredeclinecode = $err['decline_code'];
|
||||
} catch (Exception $e) {
|
||||
$stripefailurecode = 'UnknownChargeError';
|
||||
$stripefailuremessage = $e->getMessage();
|
||||
}
|
||||
} else { // Using new SCA method
|
||||
if ($sepaMode)
|
||||
dol_syslog("* Create payment on SEPA " . $stripecard->id . ", amounttopay=" . $amounttopay . ", amountstripe=" . $amountstripe . ", FULLTAG=" . $FULLTAG, LOG_DEBUG);
|
||||
else dol_syslog("* Create payment on card " . $stripecard->id . ", amounttopay=" . $amounttopay . ", amountstripe=" . $amountstripe . ", FULLTAG=" . $FULLTAG, LOG_DEBUG);
|
||||
|
||||
// Create payment intent and charge payment (confirmnow = true)
|
||||
$paymentintent = $stripe->getPaymentIntent($amounttopay, $currency, $FULLTAG, $description, $invoice, $customer->id, $stripeacc, $servicestatus, 0, 'automatic', true, $stripecard->id, 1);
|
||||
|
||||
$charge = new stdClass();
|
||||
//erics add processing sepa is like success ?
|
||||
if ($paymentintent->status === 'succeeded' || $paymentintent->status === 'processing') {
|
||||
$charge->status = 'ok';
|
||||
$charge->id = $paymentintent->id;
|
||||
$charge->customer = $customer->id;
|
||||
} elseif ($paymentintent->status === 'requires_action') {
|
||||
//paymentintent->status may be => 'requires_action' (no error in such a case)
|
||||
dol_syslog(var_export($paymentintent, true), LOG_DEBUG);
|
||||
|
||||
$charge->status = 'failed';
|
||||
$charge->customer = $customer->id;
|
||||
$charge->failure_code = $stripe->code;
|
||||
$charge->failure_message = $stripe->error;
|
||||
$charge->failure_declinecode = $stripe->declinecode;
|
||||
$stripefailurecode = $stripe->code;
|
||||
$stripefailuremessage = 'Action required. Contact the support at ';// . $conf->global->SELLYOURSAAS_MAIN_EMAIL;
|
||||
$stripefailuredeclinecode = $stripe->declinecode;
|
||||
} else {
|
||||
dol_syslog(var_export($paymentintent, true), LOG_DEBUG);
|
||||
|
||||
$charge->status = 'failed';
|
||||
$charge->customer = $customer->id;
|
||||
$charge->failure_code = $stripe->code;
|
||||
$charge->failure_message = $stripe->error;
|
||||
$charge->failure_declinecode = $stripe->declinecode;
|
||||
$stripefailurecode = $stripe->code;
|
||||
$stripefailuremessage = $stripe->error;
|
||||
$stripefailuredeclinecode = $stripe->declinecode;
|
||||
}
|
||||
|
||||
//var_dump("stripefailurecode=".$stripefailurecode." stripefailuremessage=".$stripefailuremessage." stripefailuredeclinecode=".$stripefailuredeclinecode);
|
||||
//exit;
|
||||
}
|
||||
|
||||
// Return $charge = array('id'=>'ch_XXXX', 'status'=>'succeeded|pending|failed', 'failure_code'=>, 'failure_message'=>...)
|
||||
if (empty($charge) || $charge->status == 'failed') {
|
||||
dol_syslog('Failed to charge card or payment mode ' . $stripecard->id . ' stripefailurecode=' . $stripefailurecode . ' stripefailuremessage=' . $stripefailuremessage . ' stripefailuredeclinecode=' . $stripefailuredeclinecode, LOG_WARNING);
|
||||
|
||||
// Save a stripe payment was in error
|
||||
$this->stripechargeerror++;
|
||||
|
||||
$error++;
|
||||
$errorforinvoice++;
|
||||
$errmsg = $langs->trans("FailedToChargeCard");
|
||||
if (!empty($charge)) {
|
||||
if ($stripefailuredeclinecode == 'authentication_required') {
|
||||
$errauthenticationmessage = $langs->trans("ErrSCAAuthentication");
|
||||
$errmsg = $errauthenticationmessage;
|
||||
} elseif (in_array($stripefailuredeclinecode, ['insufficient_funds', 'generic_decline'])) {
|
||||
$errmsg .= ': ' . $charge->failure_code;
|
||||
$errmsg .= ($charge->failure_message ? ' - ' : '') . ' ' . $charge->failure_message;
|
||||
if (empty($stripefailurecode)) {
|
||||
$stripefailurecode = $charge->failure_code;
|
||||
}
|
||||
if (empty($stripefailuremessage)) {
|
||||
$stripefailuremessage = $charge->failure_message;
|
||||
}
|
||||
} else {
|
||||
$errmsg .= ': failure_code=' . $charge->failure_code;
|
||||
$errmsg .= ($charge->failure_message ? ' - ' : '') . ' failure_message=' . $charge->failure_message;
|
||||
if (empty($stripefailurecode)) {
|
||||
$stripefailurecode = $charge->failure_code;
|
||||
}
|
||||
if (empty($stripefailuremessage)) {
|
||||
$stripefailuremessage = $charge->failure_message;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
$errmsg .= ': ' . $stripefailurecode . ' - ' . $stripefailuremessage;
|
||||
$errmsg .= ($stripefailuredeclinecode ? ' - ' . $stripefailuredeclinecode : '');
|
||||
}
|
||||
|
||||
$description = 'Stripe payment ERROR from doTakePaymentStripeForThirdparty: ' . $FULLTAG;
|
||||
$postactionmessages[] = $errmsg . ' (' . $stripearrayofkeys['publishable_key'] . ')';
|
||||
$this->errors[] = $errmsg;
|
||||
} else {
|
||||
dol_syslog('Successfuly charge card ' . $stripecard->id);
|
||||
|
||||
$postactionmessages[] = 'Success to charge card (' . $charge->id . ' with ' . $stripearrayofkeys['publishable_key'] . ')';
|
||||
|
||||
// Save a stripe payment was done in realy life so later we will be able to force a commit on recorded payments
|
||||
// even if in batch mode (method doTakePaymentStripe), we will always make all action in one transaction with a forced commit.
|
||||
$this->stripechargedone++;
|
||||
|
||||
// Default description used for label of event. Will be overwrite by another value later.
|
||||
$description = 'Stripe payment OK (' . $charge->id . ') from doTakePaymentStripeForThirdparty: ' . $FULLTAG;
|
||||
|
||||
$db = $this->db;
|
||||
|
||||
$ipaddress = getUserRemoteIP();
|
||||
|
||||
$TRANSACTIONID = $charge->id;
|
||||
$currency = $conf->currency;
|
||||
$paymentmethod = 'stripe';
|
||||
$emetteur_name = $charge->customer;
|
||||
|
||||
// Same code than into paymentok.php...
|
||||
|
||||
$paymentTypeId = 0;
|
||||
if ($paymentmethod == 'paybox') {
|
||||
$paymentTypeId = $conf->global->PAYBOX_PAYMENT_MODE_FOR_PAYMENTS;
|
||||
}
|
||||
if ($paymentmethod == 'paypal') {
|
||||
$paymentTypeId = $conf->global->PAYPAL_PAYMENT_MODE_FOR_PAYMENTS;
|
||||
}
|
||||
if ($paymentmethod == 'stripe') {
|
||||
$paymentTypeId = $conf->global->STRIPE_PAYMENT_MODE_FOR_PAYMENTS;
|
||||
}
|
||||
if (empty($paymentTypeId)) {
|
||||
//erics
|
||||
if ($sepaMode) {
|
||||
$paymentType = 'PRE';
|
||||
} else {
|
||||
$paymentType = $_SESSION["paymentType"];
|
||||
if (empty($paymentType)) {
|
||||
$paymentType = 'CB';
|
||||
}
|
||||
}
|
||||
$paymentTypeId = dol_getIdFromCode($this->db, $paymentType, 'c_paiement', 'code', 'id', 1);
|
||||
}
|
||||
|
||||
$currencyCodeType = $currency;
|
||||
|
||||
$ispostactionok = 1;
|
||||
|
||||
// Creation of payment line
|
||||
include_once DOL_DOCUMENT_ROOT . '/compta/paiement/class/paiement.class.php';
|
||||
$paiement = new Paiement($this->db);
|
||||
$paiement->datepaye = $now;
|
||||
$paiement->date = $now;
|
||||
if ($currencyCodeType == $conf->currency) {
|
||||
$paiement->amounts = [$this->id => $amounttopay]; // Array with all payments dispatching with invoice id
|
||||
} else {
|
||||
$paiement->multicurrency_amounts = [$this->id => $amounttopay]; // Array with all payments dispatching
|
||||
|
||||
$postactionmessages[] = 'Payment was done in a different currency than currency expected of company';
|
||||
$ispostactionok = -1;
|
||||
// Not yet supported, so error
|
||||
$error++;
|
||||
$errorforinvoice++;
|
||||
}
|
||||
$paiement->paiementid = $paymentTypeId;
|
||||
$paiement->num_paiement = '';
|
||||
$paiement->num_payment = '';
|
||||
// Add a comment with keyword 'SellYourSaas' in text. Used by trigger.
|
||||
$paiement->note_public = 'StripeSepa payment ' . dol_print_date($now, 'standard') . ' using ' . $paymentmethod . ($ipaddress ? ' from ip ' . $ipaddress : '') . ' - Transaction ID = ' . $TRANSACTIONID;
|
||||
$paiement->note_private = 'StripeSepa payment ' . dol_print_date($now, 'standard') . ' using ' . $paymentmethod . ($ipaddress ? ' from ip ' . $ipaddress : '') . ' - Transaction ID = ' . $TRANSACTIONID;
|
||||
$paiement->ext_payment_id = $charge->id . ':' . $customer->id . '@' . $stripearrayofkeys['publishable_key'];
|
||||
$paiement->ext_payment_site = 'stripe';
|
||||
|
||||
if (!$errorforinvoice) {
|
||||
dol_syslog('* Record payment for invoice id ' . $this->id . '. It includes closing of invoice and regenerating document');
|
||||
|
||||
// This include closing invoices to 'paid' (and trigger including unsuspending) and regenerating document
|
||||
$paiement_id = $paiement->create($user, 1);
|
||||
if ($paiement_id < 0) {
|
||||
$postactionmessages[] = $paiement->error . ($paiement->error ? ' ' : '') . join("<br>\n", $paiement->errors);
|
||||
$ispostactionok = -1;
|
||||
$error++;
|
||||
$errorforinvoice++;
|
||||
} else {
|
||||
$postactionmessages[] = 'Payment created';
|
||||
}
|
||||
|
||||
dol_syslog("The payment has been created for invoice id " . $this->id);
|
||||
}
|
||||
|
||||
if (!$errorforinvoice && !empty($conf->banque->enabled)) {
|
||||
dol_syslog('* Add payment to bank');
|
||||
|
||||
$bankaccountid = 0;
|
||||
if ($paymentmethod == 'paybox') {
|
||||
$bankaccountid = $conf->global->PAYBOX_BANK_ACCOUNT_FOR_PAYMENTS;
|
||||
}
|
||||
if ($paymentmethod == 'paypal') {
|
||||
$bankaccountid = $conf->global->PAYPAL_BANK_ACCOUNT_FOR_PAYMENTS;
|
||||
}
|
||||
if ($paymentmethod == 'stripe') {
|
||||
$bankaccountid = $conf->global->STRIPE_BANK_ACCOUNT_FOR_PAYMENTS;
|
||||
}
|
||||
|
||||
if ($bankaccountid > 0) {
|
||||
$label = '(CustomerInvoicePayment)';
|
||||
if ($this->type == Facture::TYPE_CREDIT_NOTE) {
|
||||
$label = '(CustomerInvoicePaymentBack)';
|
||||
} // Refund of a credit note
|
||||
$result = $paiement->addPaymentToBank($user, 'payment', $label, $bankaccountid, $emetteur_name, '');
|
||||
if ($result < 0) {
|
||||
$postactionmessages[] = $paiement->error . ($paiement->error ? ' ' : '') . join("<br>\n", $paiement->errors);
|
||||
$ispostactionok = -1;
|
||||
$error++;
|
||||
$errorforinvoice++;
|
||||
} else {
|
||||
$postactionmessages[] = 'Bank transaction of payment created (by doTakePaymentStripeForThirdparty)';
|
||||
}
|
||||
} else {
|
||||
$postactionmessages[] = 'Setup of bank account to use in module ' . $paymentmethod . ' was not set. No way to record the payment.';
|
||||
$ispostactionok = -1;
|
||||
$error++;
|
||||
$errorforinvoice++;
|
||||
}
|
||||
}
|
||||
|
||||
if ($ispostactionok < 1) {
|
||||
$description = 'Stripe payment OK (' . $charge->id . ' - ' . $amounttopay . ' ' . $conf->currency . ') but post action KO from doTakePaymentStripeForThirdparty: ' . $FULLTAG;
|
||||
} else {
|
||||
$description = 'Stripe payment+post action OK (' . $charge->id . ' - ' . $amounttopay . ' ' . $conf->currency . ') from doTakePaymentStripeForThirdparty: ' . $FULLTAG;
|
||||
}
|
||||
}
|
||||
|
||||
$object = $invoice;
|
||||
|
||||
// Send emails
|
||||
$labeltouse = 'InvoicePaymentSuccess';
|
||||
$sendemailtocustomer = 1;
|
||||
|
||||
if (empty($charge) || $charge->status == 'failed') {
|
||||
$labeltouse = 'InvoicePaymentFailure';
|
||||
if ($noemailtocustomeriferror) {
|
||||
$sendemailtocustomer = 0;
|
||||
} // $noemailtocustomeriferror is set when error already reported on myaccount screen
|
||||
}
|
||||
|
||||
// Track an event
|
||||
if (empty($charge) || $charge->status == 'failed') {
|
||||
$actioncode = 'PAYMENT_STRIPE_KO';
|
||||
$extraparams = $stripefailurecode;
|
||||
$extraparams .= (($extraparams && $stripefailuremessage) ? ' - ' : '') . $stripefailuremessage;
|
||||
$extraparams .= (($extraparams && $stripefailuredeclinecode) ? ' - ' : '') . $stripefailuredeclinecode;
|
||||
} else {
|
||||
$actioncode = 'PAYMENT_STRIPE_OK';
|
||||
$extraparams = '';
|
||||
}
|
||||
} else {
|
||||
$error++;
|
||||
$errorforinvoice++;
|
||||
dol_syslog("No card or payment method found for this stripe customer " . $customer->id, LOG_WARNING);
|
||||
$this->errors[] = 'Failed to get card | payment method for stripe customer = ' . $customer->id;
|
||||
|
||||
$labeltouse = 'InvoicePaymentFailure';
|
||||
$sendemailtocustomer = 1;
|
||||
if ($noemailtocustomeriferror) {
|
||||
$sendemailtocustomer = 0;
|
||||
} // $noemailtocustomeriferror is set when error already reported on myaccount screen
|
||||
|
||||
$description = 'Failed to find or use the payment mode - no credit card defined for the customer account';
|
||||
$stripefailurecode = 'BADPAYMENTMODE';
|
||||
$stripefailuremessage = 'Failed to find or use the payment mode - no credit card defined for the customer account';
|
||||
$postactionmessages[] = $description . ' (' . $stripearrayofkeys['publishable_key'] . ')';
|
||||
|
||||
$object = $invoice;
|
||||
|
||||
$actioncode = 'PAYMENT_STRIPE_KO';
|
||||
$extraparams = '';
|
||||
}
|
||||
} else {
|
||||
// If error because payment was canceled for a logical reason, we do nothing (no email and no event added)
|
||||
$labeltouse = '';
|
||||
$sendemailtocustomer = 0;
|
||||
|
||||
$description = '';
|
||||
$stripefailurecode = '';
|
||||
$stripefailuremessage = '';
|
||||
|
||||
$object = $invoice;
|
||||
|
||||
$actioncode = '';
|
||||
$extraparams = '';
|
||||
}
|
||||
} else { // Else of the if ($resultthirdparty > 0 && ! empty($customer)) {
|
||||
if ($resultthirdparty <= 0) {
|
||||
dol_syslog('SellYourSaasUtils Failed to load customer for thirdparty_id = ' . $thirdparty->id, LOG_WARNING);
|
||||
$this->errors[] = 'Failed to load customer for thirdparty_id = ' . $thirdparty->id;
|
||||
} else { // $customer stripe not found
|
||||
dol_syslog('SellYourSaasUtils Failed to get Stripe customer id for thirdparty_id = ' . $thirdparty->id . " in mode " . $servicestatus . " in Stripe env " . $stripearrayofkeysbyenv[$servicestatus]['publishable_key'], LOG_WARNING);
|
||||
$this->errors[] = 'Failed to get Stripe customer id for thirdparty_id = ' . $thirdparty->id . " in mode " . $servicestatus . " in Stripe env " . $stripearrayofkeysbyenv[$servicestatus]['publishable_key'];
|
||||
}
|
||||
$error++;
|
||||
$errorforinvoice++;
|
||||
|
||||
$labeltouse = 'InvoicePaymentFailure';
|
||||
$sendemailtocustomer = 1;
|
||||
if ($noemailtocustomeriferror) {
|
||||
$sendemailtocustomer = 0;
|
||||
} // $noemailtocustomeriferror is set when error already reported on myaccount screen
|
||||
|
||||
$description = 'Failed to find or use your payment mode (no payment mode for this customer id)';
|
||||
$stripefailurecode = 'BADPAYMENTMODE';
|
||||
$stripefailuremessage = 'Failed to find or use your payment mode (no payment mode for this customer id)';
|
||||
$postactionmessages = [];
|
||||
|
||||
$object = $invoice;
|
||||
|
||||
$actioncode = 'PAYMENT_STRIPE_KO';
|
||||
$extraparams = '';
|
||||
}
|
||||
|
||||
// Send email + create action after
|
||||
if ($sendemailtocustomer && $labeltouse) {
|
||||
dol_syslog("* Send email with result of payment - " . $labeltouse);
|
||||
|
||||
// Set output language
|
||||
$outputlangs = new Translate('', $conf);
|
||||
$outputlangs->setDefaultLang(empty($object->thirdparty->default_lang) ? $mysoc->default_lang : $object->thirdparty->default_lang);
|
||||
$outputlangs->loadLangs(["main", "members", "bills"]);
|
||||
|
||||
// Get email content from templae
|
||||
$arraydefaultmessage = null;
|
||||
|
||||
include_once DOL_DOCUMENT_ROOT . '/core/class/html.formmail.class.php';
|
||||
$formmail = new FormMail($this->db);
|
||||
|
||||
if (!empty($labeltouse)) {
|
||||
$arraydefaultmessage = $formmail->getEMailTemplate($this->db, 'facture_send', $user, $outputlangs, 0, 1, $labeltouse);
|
||||
}
|
||||
|
||||
if (!empty($labeltouse) && is_object($arraydefaultmessage) && $arraydefaultmessage->id > 0) {
|
||||
$subject = $arraydefaultmessage->topic;
|
||||
$msg = $arraydefaultmessage->content;
|
||||
}
|
||||
|
||||
$substitutionarray = getCommonSubstitutionArray($outputlangs, 0, null, $object);
|
||||
|
||||
//$substitutionarray['__SELLYOURSAAS_PAYMENT_ERROR_DESC__'] = $stripefailurecode . ' ' . $stripefailuremessage;
|
||||
|
||||
complete_substitutions_array($substitutionarray, $outputlangs, $object);
|
||||
|
||||
// Set the property ->ref_customer with ref_customer of contract so __REF_CLIENT__ will be replaced in email content
|
||||
// Search contract linked to invoice
|
||||
$foundcontract = null;
|
||||
$this->fetchObjectLinked();
|
||||
if (is_array($this->linkedObjects['contrat']) && count($this->linkedObjects['contrat']) > 0) {
|
||||
//dol_sort_array($object->linkedObjects['facture'], 'date');
|
||||
foreach ($this->linkedObjects['contrat'] as $idcontract => $contract) {
|
||||
$substitutionarray['__CONTRACT_REF__'] = $contract->ref_customer;
|
||||
$substitutionarray['__REFCLIENT__'] = $contract->ref_customer; // For backward compatibility
|
||||
$substitutionarray['__REF_CLIENT__'] = $contract->ref_customer;
|
||||
$foundcontract = $contract;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
dol_syslog('__DIRECTDOWNLOAD_URL_INVOICE__=' . $substitutionarray['__DIRECTDOWNLOAD_URL_INVOICE__']);
|
||||
|
||||
//erics - erreur de réécriture de l'url de téléchargement direct de la facture ... le lien de base est le bon
|
||||
//on cherche donc d'ou vien le pb ...
|
||||
//$urlforsellyoursaasaccount = getRootUrlForAccount($foundcontract);
|
||||
// if ($urlforsellyoursaasaccount) {
|
||||
// $tmpforurl = preg_replace('/.*document.php/', '', $substitutionarray['__DIRECTDOWNLOAD_URL_INVOICE__']);
|
||||
// if ($tmpforurl) {
|
||||
// dol_syslog('__DIRECTDOWNLOAD_URL_INVOICE__ cas 1, urlforsellyoursaasaccount=' . $urlforsellyoursaasaccount);
|
||||
// // $substitutionarray['__DIRECTDOWNLOAD_URL_INVOICE__'] = $urlforsellyoursaasaccount . '/source/document.php' . $tmpforurl;
|
||||
// } else {
|
||||
// dol_syslog('__DIRECTDOWNLOAD_URL_INVOICE__ cas 2, urlforsellyoursaasaccount=' . $urlforsellyoursaasaccount);
|
||||
// // $substitutionarray['__DIRECTDOWNLOAD_URL_INVOICE__'] = $urlforsellyoursaasaccount;
|
||||
// }
|
||||
// }
|
||||
|
||||
$subjecttosend = make_substitutions($subject, $substitutionarray, $outputlangs);
|
||||
$texttosend = make_substitutions($msg, $substitutionarray, $outputlangs);
|
||||
|
||||
// Attach a file ?
|
||||
$file = '';
|
||||
$listofpaths = [];
|
||||
$listofnames = [];
|
||||
$listofmimes = [];
|
||||
if (is_object($invoice)) {
|
||||
$invoicediroutput = $conf->facture->dir_output;
|
||||
//erics - choix du PDF a joindre aux mails
|
||||
$fileparams = dol_most_recent_file($invoicediroutput . '/' . $this->ref, preg_quote($this->ref, '/') . '[^\-]+*.pdf');
|
||||
$file = $fileparams['fullname'];
|
||||
//$file = $invoicediroutput . '/' . $this->ref . '/' . $this->ref . '.pdf';
|
||||
// $file = ''; // Disable attachment of invoice in emails
|
||||
|
||||
if ($file) {
|
||||
$listofpaths = [$file];
|
||||
$listofnames = [basename($file)];
|
||||
$listofmimes = [dol_mimetype($file)];
|
||||
}
|
||||
}
|
||||
$from = "";//$conf->global->SELLYOURSAAS_NOREPLY_EMAIL;
|
||||
|
||||
$trackid = 'inv' . $this->id;
|
||||
$moreinheader = 'X-Dolibarr-Info: doTakeStripePaymentForThirdParty' . "\r\n";
|
||||
|
||||
// Send email (substitutionarray must be done just before this)
|
||||
include_once DOL_DOCUMENT_ROOT . '/core/class/CMailFile.class.php';
|
||||
$mailfile = new CMailFile($subjecttosend, $this->thirdparty->email, $from, $texttosend, $listofpaths, $listofmimes, $listofnames, '', '', 0, -1, '', '', $trackid, $moreinheader);
|
||||
if ($mailfile->sendfile()) {
|
||||
$result = 1;
|
||||
} else {
|
||||
$this->error = $langs->trans("ErrorFailedToSendMail", $from, $this->thirdparty->email) . '. ' . $mailfile->error;
|
||||
$result = -1;
|
||||
}
|
||||
|
||||
if ($result < 0) {
|
||||
$errmsg = $this->error;
|
||||
$postactionmessages[] = $errmsg;
|
||||
$ispostactionok = -1;
|
||||
} else {
|
||||
if ($file) {
|
||||
$postactionmessages[] = 'Email sent to thirdparty (to ' . $this->thirdparty->email . ' with invoice document attached: ' . $file . ', language = ' . $outputlangs->defaultlang . ')';
|
||||
} else {
|
||||
$postactionmessages[] = 'Email sent to thirdparty (to ' . $this->thirdparty->email . ' without any attached document, language = ' . $outputlangs->defaultlang . ')';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ($description) {
|
||||
dol_syslog("* Record event for payment result - " . $description);
|
||||
require_once DOL_DOCUMENT_ROOT.'/comm/action/class/actioncomm.class.php';
|
||||
|
||||
// Insert record of payment (success or error)
|
||||
$actioncomm = new ActionComm($this->db);
|
||||
|
||||
$actioncomm->type_code = 'AC_OTH_AUTO'; // Type of event ('AC_OTH', 'AC_OTH_AUTO', 'AC_XXX'...)
|
||||
$actioncomm->code = 'AC_' . $actioncode;
|
||||
$actioncomm->label = $description;
|
||||
$actioncomm->note_private = join(",\n", $postactionmessages);
|
||||
$actioncomm->fk_project = $this->fk_project;
|
||||
$actioncomm->datep = $now;
|
||||
$actioncomm->datef = $now;
|
||||
$actioncomm->percentage = -1; // Not applicable
|
||||
$actioncomm->socid = $thirdparty->id;
|
||||
$actioncomm->contactid = 0;
|
||||
$actioncomm->authorid = $user->id; // User saving action
|
||||
$actioncomm->userownerid = $user->id; // Owner of action
|
||||
// Fields when action is a real email (content is already into note)
|
||||
/*$actioncomm->email_msgid = $object->email_msgid;
|
||||
$actioncomm->email_from = $object->email_from;
|
||||
$actioncomm->email_sender= $object->email_sender;
|
||||
$actioncomm->email_to = $object->email_to;
|
||||
$actioncomm->email_tocc = $object->email_tocc;
|
||||
$actioncomm->email_tobcc = $object->email_tobcc;
|
||||
$actioncomm->email_subject = $object->email_subject;
|
||||
$actioncomm->errors_to = $object->errors_to;*/
|
||||
$actioncomm->fk_element = $this->id;
|
||||
$actioncomm->elementtype = $this->element;
|
||||
$actioncomm->extraparams = dol_trunc($extraparams, 250);
|
||||
|
||||
$actioncomm->create($user);
|
||||
}
|
||||
|
||||
$this->description = $description;
|
||||
$this->postactionmessages = $postactionmessages;
|
||||
} catch (Exception $e) {
|
||||
$error++;
|
||||
$errorforinvoice++;
|
||||
dol_syslog('Error ' . $e->getMessage(), LOG_ERR);
|
||||
$this->errors[] = 'Error ' . $e->getMessage();
|
||||
}
|
||||
} else { // If remain to pay is null
|
||||
$error++;
|
||||
$errorforinvoice++;
|
||||
dol_syslog("Remain to pay is null for the invoice " . $this->id . " " . $this->ref . ". Why is the invoice not classified 'Paid' ?", LOG_WARNING);
|
||||
$this->errors[] = "Remain to pay is null for the invoice " . $this->id . " " . $this->ref . ". Why is the invoice not classified 'Paid' ?";
|
||||
}
|
||||
|
||||
//end copy
|
||||
// print json_encode($stripecard);
|
||||
// exit;
|
||||
|
||||
$sql = 'INSERT INTO '.MAIN_DB_PREFIX.'prelevement_facture_demande(';
|
||||
$sql .= 'fk_facture, ';
|
||||
$sql .= ' amount, date_demande, fk_user_demande, ext_payment_id, ext_payment_site, sourcetype, entity)';
|
||||
$sql .= ' VALUES ('.$this->id;
|
||||
$sql .= ",'".price2num($amount)."'";
|
||||
$sql .= ",'".$this->db->idate($now)."'";
|
||||
$sql .= ",".$fuser->id;
|
||||
$sql .= ",'".$this->db->escape($stripe_id)."'";
|
||||
$sql .= ",'".$this->db->escape($stripe_uri)."'";
|
||||
$sql .= ",'".$this->db->escape($sourcetype)."'";
|
||||
$sql .= ",".$conf->entity;
|
||||
$sql .= ")";
|
||||
|
||||
dol_syslog(get_class($this)."::demande_prelevement_stripe", LOG_DEBUG);
|
||||
$resql = $this->db->query($sql);
|
||||
if (!$resql) {
|
||||
$this->error = $this->db->lasterror();
|
||||
dol_syslog(get_class($this).'::demande_prelevement_stripe Erreur');
|
||||
$error++;
|
||||
}
|
||||
} else {
|
||||
$this->error = 'WithdrawRequestErrorNilAmount';
|
||||
dol_syslog(get_class($this).'::demande_prelevement_stripe WithdrawRequestErrorNilAmount');
|
||||
$error++;
|
||||
}
|
||||
|
||||
if (!$error) {
|
||||
// Force payment mode of invoice to withdraw
|
||||
$payment_mode_id = dol_getIdFromCode($this->db, ($type == 'bank-transfer' ? 'VIR' : 'PRE'), 'c_paiement', 'code', 'id', 1);
|
||||
if ($payment_mode_id > 0) {
|
||||
$result = $this->setPaymentMethods($payment_mode_id);
|
||||
}
|
||||
}
|
||||
|
||||
if ($error) {
|
||||
return -1;
|
||||
}
|
||||
return 1;
|
||||
} else {
|
||||
$this->error = "A request already exists";
|
||||
dol_syslog(get_class($this).'::demande_prelevement_stripe Impossible de creer une demande, demande deja en cours');
|
||||
return 0;
|
||||
}
|
||||
} else {
|
||||
$this->error = $this->db->error();
|
||||
dol_syslog(get_class($this).'::demande_prelevement_stripe Erreur -2');
|
||||
return -2;
|
||||
}
|
||||
} else {
|
||||
$this->error = "Status of invoice does not allow this";
|
||||
dol_syslog(get_class($this)."::demande_prelevement_stripe ".$this->error." $this->statut, $this->paye, $this->mode_reglement_id");
|
||||
return -3;
|
||||
}
|
||||
}
|
||||
|
||||
// phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
|
||||
/**
|
||||
* Remove a direct debit request or a credit transfer request
|
||||
|
||||
@ -292,7 +292,8 @@ ErrorThirpdartyOrMemberidIsMandatory=Third party or Member of partnership is man
|
||||
ErrorFailedToWriteInTempDirectory=Failed to write in temp directory
|
||||
ErrorQuantityIsLimitedTo=Quantity is limited to %s
|
||||
ErrorFailedToLoadThirdParty=Failed to find/load thirdparty from id=%s, email=%s, name=%s
|
||||
|
||||
ErrorThisPaymentModeIsNotSepa=This payment mode is not a bank account
|
||||
|
||||
# Warnings
|
||||
WarningParamUploadMaxFileSizeHigherThanPostMaxSize=Your PHP parameter upload_max_filesize (%s) is higher than PHP parameter post_max_size (%s). This is not a consistent setup.
|
||||
WarningPasswordSetWithNoAccount=A password was set for this member. However, no user account was created. So this password is stored but can't be used to login to Dolibarr. It may be used by an external module/interface but if you don't need to define any login nor password for a member, you can disable option "Manage a login for each member" from Member module setup. If you need to manage a login but don't need any password, you can keep this field empty to avoid this warning. Note: Email can also be used as a login if the member is linked to a user.
|
||||
|
||||
@ -47,6 +47,9 @@ class CompanyBankAccount extends Account
|
||||
public $rum;
|
||||
public $date_rum;
|
||||
|
||||
public $stripe_card_ref; // ID of BAN into an external payment system
|
||||
public $stripe_account; // Account of the external payment system
|
||||
|
||||
/**
|
||||
* Date creation record (datec)
|
||||
*
|
||||
@ -187,6 +190,8 @@ class CompanyBankAccount extends Account
|
||||
} else {
|
||||
$sql .= ",label = NULL";
|
||||
}
|
||||
$sql .= ",stripe_card_ref = '".$this->db->escape($this->stripe_card_ref)."'";
|
||||
$sql .= ",stripe_account = '".$this->db->escape($this->stripe_account)."'";
|
||||
$sql .= " WHERE rowid = ".((int) $this->id);
|
||||
|
||||
$result = $this->db->query($sql);
|
||||
@ -232,7 +237,8 @@ class CompanyBankAccount extends Account
|
||||
}
|
||||
|
||||
$sql = "SELECT rowid, type, fk_soc, bank, number, code_banque, code_guichet, cle_rib, bic, iban_prefix as iban, domiciliation, proprio,";
|
||||
$sql .= " owner_address, default_rib, label, datec, tms as datem, rum, frstrecur, date_rum";
|
||||
$sql .= " owner_address, default_rib, label, datec, tms as datem, rum, frstrecur, date_rum,";
|
||||
$sql .= " stripe_card_ref, stripe_account";
|
||||
$sql .= " FROM ".MAIN_DB_PREFIX."societe_rib";
|
||||
if ($id) {
|
||||
$sql .= " WHERE rowid = ".((int) $id);
|
||||
@ -274,6 +280,8 @@ class CompanyBankAccount extends Account
|
||||
$this->rum = $obj->rum;
|
||||
$this->frstrecur = $obj->frstrecur;
|
||||
$this->date_rum = $this->db->jdate($obj->date_rum);
|
||||
$this->stripe_card_ref = $obj->stripe_card_ref;
|
||||
$this->stripe_account = $obj->stripe_account;
|
||||
}
|
||||
$this->db->free($resql);
|
||||
|
||||
|
||||
@ -175,6 +175,12 @@ if (empty($reshook)) {
|
||||
$companybankaccount->rum = $prelevement->buildRumNumber($object->code_client, $companybankaccount->datec, $companybankaccount->id);
|
||||
}
|
||||
|
||||
if (GETPOST('stripe_card_ref', 'alpha') && GETPOST('stripe_card_ref', 'alpha') != $companypaymentmode->stripe_card_ref) {
|
||||
// If we set a stripe value that is different than previous one, we also set the stripe account
|
||||
$companypaymentmode->stripe_account = $stripecu.'@'.$site_account;
|
||||
}
|
||||
$companybankaccount->stripe_card_ref = GETPOST('stripe_card_ref', 'alpha');
|
||||
|
||||
$result = $companybankaccount->update($user);
|
||||
if (!$result) {
|
||||
setEventMessages($companybankaccount->error, $companybankaccount->errors, 'errors');
|
||||
@ -416,6 +422,7 @@ if (empty($reshook)) {
|
||||
if ($action == 'confirm_deletecard' && GETPOST('confirm', 'alpha') == 'yes') {
|
||||
$companypaymentmode = new CompanyPaymentMode($db);
|
||||
if ($companypaymentmode->fetch($ribid ? $ribid : $id)) {
|
||||
// TODO This is currently done at bottom of page instead of asking confirm
|
||||
/*if ($companypaymentmode->stripe_card_ref && preg_match('/pm_/', $companypaymentmode->stripe_card_ref))
|
||||
{
|
||||
$payment_method = \Stripe\PaymentMethod::retrieve($companypaymentmode->stripe_card_ref);
|
||||
@ -440,6 +447,16 @@ if (empty($reshook)) {
|
||||
if ($action == 'confirm_delete' && GETPOST('confirm', 'alpha') == 'yes') {
|
||||
$companybankaccount = new CompanyBankAccount($db);
|
||||
if ($companybankaccount->fetch($ribid ? $ribid : $id)) {
|
||||
// TODO This is currently done at bottom of page instead of asking confirm
|
||||
/*if ($companypaymentmode->stripe_card_ref && preg_match('/pm_/', $companypaymentmode->stripe_card_ref))
|
||||
{
|
||||
$payment_method = \Stripe\PaymentMethod::retrieve($companypaymentmode->stripe_card_ref);
|
||||
if ($payment_method)
|
||||
{
|
||||
$payment_method->detach();
|
||||
}
|
||||
}*/
|
||||
|
||||
$result = $companybankaccount->delete($user);
|
||||
if ($result > 0) {
|
||||
$url = $_SERVER['PHP_SELF']."?socid=".$object->id;
|
||||
@ -505,7 +522,7 @@ if (empty($reshook)) {
|
||||
}
|
||||
|
||||
if (!$error) {
|
||||
// Creation of Stripe card + update of societe_account
|
||||
// Creation of Stripe card + update of llx_societe_rib
|
||||
// Note that with the new Stripe API, option to create a card is no more available, instead an error message will be returned to
|
||||
// ask to create the crdit card from Stripe backoffice.
|
||||
$card = $stripe->cardStripe($cu, $companypaymentmode, $stripeacc, $servicestatus, 1);
|
||||
@ -517,18 +534,13 @@ if (empty($reshook)) {
|
||||
}
|
||||
}
|
||||
if ($action == 'syncsepatostripe') {
|
||||
$companybankaccount->fetch(GETPOST('bankid', 'int'));
|
||||
// print "stripe account = " . json_encode($stripe->getStripeAccount($service));
|
||||
// print json_encode($companybankaccount);
|
||||
// print "fetch id = " . json_encode($socid);
|
||||
|
||||
$companypaymentmode = new CompanyPaymentMode($db);
|
||||
$companypaymentmode->fetch(null, null, $socid);
|
||||
// print json_encode($companypaymentmode);
|
||||
$companypaymentmode = new CompanyPaymentMode($db); // Get record in llx_societe_rib
|
||||
$companypaymentmode->fetch($id);
|
||||
|
||||
if ($companypaymentmode->type != 'ban') {
|
||||
$error++;
|
||||
setEventMessages('ThisPaymentModeIsNotSepa', null, 'errors');
|
||||
$langs->load("errors");
|
||||
setEventMessages('ThisPaymentModeIsNotABan', null, 'errors');
|
||||
} else {
|
||||
// Get the Stripe customer
|
||||
$cu = $stripe->customerStripe($object, $stripeacc, $servicestatus);
|
||||
@ -539,13 +551,13 @@ if (empty($reshook)) {
|
||||
}
|
||||
|
||||
if (!$error) {
|
||||
// Creation of Stripe SEPA + update of societe_account
|
||||
// Creation of Stripe SEPA + update of llx_societe_rib
|
||||
$card = $stripe->sepaStripe($cu, $companypaymentmode, $stripeacc, $servicestatus, 1);
|
||||
if (!$card) {
|
||||
$error++;
|
||||
setEventMessages($stripe->error, $stripe->errors, 'errors');
|
||||
} else {
|
||||
setEventMessages("", array("SEPA on Stripe", "SEPA IBAN is now linked to the Stripe customer account !"));
|
||||
setEventMessages("", array("Bank Account on Stripe", "BAN is now linked to the Stripe customer account !"));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -711,6 +723,37 @@ if (empty($reshook)) {
|
||||
$error++;
|
||||
setEventMessages($e->getMessage(), null, 'errors');
|
||||
}
|
||||
} elseif ($action == 'delete' && $source) {
|
||||
try {
|
||||
if (preg_match('/pm_/', $source)) {
|
||||
$payment_method = \Stripe\PaymentMethod::retrieve($source, array("stripe_account" => $stripeacc));
|
||||
if ($payment_method) {
|
||||
$payment_method->detach();
|
||||
}
|
||||
} else {
|
||||
$cu = $stripe->customerStripe($object, $stripeacc, $servicestatus);
|
||||
$card = $cu->sources->retrieve("$source");
|
||||
if ($card) {
|
||||
// $card->detach(); Does not work with card_, only with src_
|
||||
if (method_exists($card, 'detach')) {
|
||||
$card->detach();
|
||||
$sql = "UPDATE ".MAIN_DB_PREFIX."societe_rib as sr ";
|
||||
$sql .= " SET stripe_card_ref = null";
|
||||
$sql .= " WHERE sr.stripe_card_ref = '".$db->escape($source)."'";
|
||||
$resql = $db->query($sql);
|
||||
} else {
|
||||
$card->delete();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$url = DOL_URL_ROOT.'/societe/paymentmodes.php?socid='.$object->id;
|
||||
header('Location: '.$url);
|
||||
exit;
|
||||
} catch (Exception $e) {
|
||||
$error++;
|
||||
setEventMessages($e->getMessage(), null, 'errors');
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -938,70 +981,75 @@ if ($socid && $action != 'edit' && $action != 'create' && $action != 'editcard'
|
||||
|
||||
print '<br>';
|
||||
|
||||
// List of Stripe payment modes
|
||||
if (!(empty($conf->stripe->enabled)) && $object->client) {
|
||||
$showcardpaymentmode = 0;
|
||||
if (isModEnabled('stripe')) {
|
||||
$showcardpaymentmode++;
|
||||
}
|
||||
|
||||
// Get list of remote payment modes
|
||||
$listofsources = array();
|
||||
|
||||
if (is_object($stripe)) {
|
||||
try {
|
||||
$customerstripe = $stripe->customerStripe($object, $stripeacc, $servicestatus);
|
||||
if (!empty($customerstripe->id)) {
|
||||
// When using the Charge API architecture
|
||||
if (empty($conf->global->STRIPE_USE_INTENT_WITH_AUTOMATIC_CONFIRMATION)) {
|
||||
$listofsources = $customerstripe->sources->data;
|
||||
} else {
|
||||
$service = 'StripeTest';
|
||||
$servicestatus = 0;
|
||||
if (!empty($conf->global->STRIPE_LIVE) && !GETPOST('forcesandbox', 'alpha')) {
|
||||
$service = 'StripeLive';
|
||||
$servicestatus = 1;
|
||||
}
|
||||
|
||||
// Force to use the correct API key
|
||||
global $stripearrayofkeysbyenv;
|
||||
\Stripe\Stripe::setApiKey($stripearrayofkeysbyenv[$servicestatus]['secret_key']);
|
||||
|
||||
try {
|
||||
if (empty($stripeacc)) { // If the Stripe connect account not set, we use common API usage
|
||||
$paymentmethodobjsA = \Stripe\PaymentMethod::all(array("customer" => $customerstripe->id, "type" => "card"));
|
||||
$paymentmethodobjsB = \Stripe\PaymentMethod::all(array("customer" => $customerstripe->id, "type" => "sepa_debit"));
|
||||
} else {
|
||||
$paymentmethodobjsA = \Stripe\PaymentMethod::all(array("customer" => $customerstripe->id, "type" => "card"), array("stripe_account" => $stripeacc));
|
||||
$paymentmethodobjsB = \Stripe\PaymentMethod::all(array("customer" => $customerstripe->id, "type" => "sepa_debit"), array("stripe_account" => $stripeacc));
|
||||
}
|
||||
|
||||
if ($paymentmethodobjsA->data != null && $paymentmethodobjsB->data != null) {
|
||||
$listofsources = array_merge((array) $paymentmethodobjsA->data, (array) $paymentmethodobjsB->data);
|
||||
} elseif ($paymentmethodobjsB->data != null) {
|
||||
$listofsources = $paymentmethodobjsB->data;
|
||||
} else {
|
||||
$listofsources = $paymentmethodobjsA->data;
|
||||
}
|
||||
} catch (Exception $e) {
|
||||
$error++;
|
||||
setEventMessages($e->getMessage(), null, 'errors');
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (Exception $e) {
|
||||
dol_syslog("Error when searching/loading Stripe customer for thirdparty id =".$object->id);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// List of Card payment modes
|
||||
if ($showcardpaymentmode && $object->client) {
|
||||
$morehtmlright = '';
|
||||
if (!empty($conf->global->STRIPE_ALLOW_LOCAL_CARD)) {
|
||||
$morehtmlright .= dolGetButtonTitle($langs->trans('Add'), '', 'fa fa-plus-circle', $_SERVER["PHP_SELF"].'?socid='.$object->id.'&action=createcard');
|
||||
}
|
||||
print load_fiche_titre($langs->trans('StripePaymentModes').($stripeacc ? ' (Stripe connection with StripeConnect account '.$stripeacc.')' : ' (Stripe connection with keys from Stripe module setup)'), $morehtmlright, 'stripe-s');
|
||||
print load_fiche_titre($langs->trans('CreditCard').($stripeacc ? ' (Stripe connection with StripeConnect account '.$stripeacc.')' : ' (Stripe connection with keys from Stripe module setup)'), $morehtmlright, 'fa-credit-card');
|
||||
|
||||
$listofsources = array();
|
||||
if (is_object($stripe)) {
|
||||
try {
|
||||
$customerstripe = $stripe->customerStripe($object, $stripeacc, $servicestatus);
|
||||
if (!empty($customerstripe->id)) {
|
||||
// When using the Charge API architecture
|
||||
if (empty($conf->global->STRIPE_USE_INTENT_WITH_AUTOMATIC_CONFIRMATION)) {
|
||||
$listofsources = $customerstripe->sources->data;
|
||||
} else {
|
||||
$service = 'StripeTest';
|
||||
$servicestatus = 0;
|
||||
if (!empty($conf->global->STRIPE_LIVE) && !GETPOST('forcesandbox', 'alpha')) {
|
||||
$service = 'StripeLive';
|
||||
$servicestatus = 1;
|
||||
}
|
||||
|
||||
// Force to use the correct API key
|
||||
global $stripearrayofkeysbyenv;
|
||||
\Stripe\Stripe::setApiKey($stripearrayofkeysbyenv[$servicestatus]['secret_key']);
|
||||
|
||||
try {
|
||||
if (empty($stripeacc)) { // If the Stripe connect account not set, we use common API usage
|
||||
$paymentmethodobjsA = \Stripe\PaymentMethod::all(array("customer" => $customerstripe->id, "type" => "card"));
|
||||
$paymentmethodobjsB = \Stripe\PaymentMethod::all(array("customer" => $customerstripe->id, "type" => "sepa_debit"));
|
||||
} else {
|
||||
$paymentmethodobjsA = \Stripe\PaymentMethod::all(array("customer" => $customerstripe->id, "type" => "card"), array("stripe_account" => $stripeacc));
|
||||
$paymentmethodobjsB = \Stripe\PaymentMethod::all(array("customer" => $customerstripe->id, "type" => "sepa_debit"), array("stripe_account" => $stripeacc));
|
||||
}
|
||||
|
||||
if ($paymentmethodobjsA->data != null && $paymentmethodobjsB->data != null) {
|
||||
$listofsources = array_merge((array) $paymentmethodobjsA->data, (array) $paymentmethodobjsB->data);
|
||||
} elseif ($paymentmethodobjsB->data != null) {
|
||||
$listofsources = $paymentmethodobjsB->data;
|
||||
} else {
|
||||
$listofsources = $paymentmethodobjsA->data;
|
||||
}
|
||||
} catch (Exception $e) {
|
||||
$error++;
|
||||
setEventMessages($e->getMessage(), null, 'errors');
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (Exception $e) {
|
||||
dol_syslog("Error when searching/loading Stripe customer for thirdparty id =".$object->id);
|
||||
}
|
||||
}
|
||||
|
||||
print '<!-- List of stripe payments -->'."\n";
|
||||
print '<!-- List of card payments -->'."\n";
|
||||
print '<div class="div-table-responsive-no-min">'; // You can use div-table-responsive-no-min if you dont need reserved height for your table
|
||||
print '<table class="liste centpercent">'."\n";
|
||||
print '<tr class="liste_titre">';
|
||||
if (!empty($conf->global->STRIPE_ALLOW_LOCAL_CARD)) {
|
||||
print '<td>'.$langs->trans('LocalID').'</td>';
|
||||
}
|
||||
print '<td>'.$langs->trans('Label').'</td>';
|
||||
print '<td>'.$langs->trans('StripeID').'</td>';
|
||||
print '<td>'.$langs->trans('StripeID').'</td>'; // external system ID
|
||||
print '<td>'.$langs->trans('Type').'</td>';
|
||||
print '<td>'.$langs->trans('Informations').'</td>';
|
||||
print '<td></td>';
|
||||
@ -1018,7 +1066,7 @@ if ($socid && $action != 'edit' && $action != 'create' && $action != 'editcard'
|
||||
|
||||
$nbremote = 0;
|
||||
$nblocal = 0;
|
||||
$arrayofstripecard = array();
|
||||
$arrayofremotecard = array();
|
||||
|
||||
// Show local sources
|
||||
if (!empty($conf->global->STRIPE_ALLOW_LOCAL_CARD)) {
|
||||
@ -1042,18 +1090,16 @@ if ($socid && $action != 'edit' && $action != 'create' && $action != 'editcard'
|
||||
if ($obj) {
|
||||
$companypaymentmodetemp->fetch($obj->rowid);
|
||||
|
||||
$arrayofstripecard[$companypaymentmodetemp->stripe_card_ref] = $companypaymentmodetemp->stripe_card_ref;
|
||||
$arrayofremotecard[$companypaymentmodetemp->stripe_card_ref] = $companypaymentmodetemp->stripe_card_ref;
|
||||
|
||||
print '<tr class="oddeven">';
|
||||
print '<td>';
|
||||
print $companypaymentmodetemp->id;
|
||||
print '</td>';
|
||||
print '<tr class="oddeven" data-rowid="'.((int) $companypaymentmodetemp->id).'">';
|
||||
// Label
|
||||
print '<td class="tdoverflowmax150" title="'.dol_escape_htmltag($companypaymentmodetemp->label).'">';
|
||||
print dol_escape_htmltag($companypaymentmodetemp->label);
|
||||
print '</td>';
|
||||
print '<td>';
|
||||
print $companypaymentmodetemp->stripe_card_ref;
|
||||
if ($companypaymentmodetemp->stripe_card_ref) {
|
||||
// External card ID
|
||||
print '<td class="tdoverflowmax150">';
|
||||
if (!empty($companypaymentmodetemp->stripe_card_ref)) {
|
||||
$connect = '';
|
||||
if (!empty($stripeacc)) {
|
||||
$connect = $stripeacc.'/';
|
||||
@ -1062,12 +1108,15 @@ if ($socid && $action != 'edit' && $action != 'create' && $action != 'editcard'
|
||||
if ($servicestatus) {
|
||||
$url = 'https://dashboard.stripe.com/'.$connect.'search?query='.$companypaymentmodetemp->stripe_card_ref;
|
||||
}
|
||||
print ' <a href="'.$url.'" target="_stripe">'.img_picto($langs->trans('ShowInStripe').' - Customer and Publishable key = '.$companypaymentmodetemp->stripe_account, 'globe').'</a>';
|
||||
print '<a href="'.$url.'" target="_stripe">'.img_picto($langs->trans('ShowInStripe').' - Customer and Publishable key = '.$companypaymentmodetemp->stripe_account, 'globe').'</a> ';
|
||||
}
|
||||
print $companypaymentmodetemp->stripe_card_ref;
|
||||
print '</td>';
|
||||
// Type
|
||||
print '<td>';
|
||||
print img_credit_card($companypaymentmodetemp->type);
|
||||
print '</td>';
|
||||
// Information (Owner, ...)
|
||||
print '<td>';
|
||||
if ($companypaymentmodetemp->proprio) {
|
||||
print '<span class="opacitymedium">'.$companypaymentmodetemp->proprio.'</span><br>';
|
||||
@ -1121,7 +1170,6 @@ if ($socid && $action != 'edit' && $action != 'create' && $action != 'editcard'
|
||||
print '<a class="editfielda marginleftonly marginrightonly" href="'.DOL_URL_ROOT.'/societe/paymentmodes.php?socid='.$object->id.'&id='.$companypaymentmodetemp->id.'&action=editcard&token='.newToken().'">';
|
||||
print img_picto($langs->trans("Modify"), 'edit');
|
||||
print '</a>';
|
||||
print ' ';
|
||||
print '<a class="marginleftonly marginrightonly" href="'.DOL_URL_ROOT.'/societe/paymentmodes.php?socid='.$object->id.'&id='.$companypaymentmodetemp->id.'&action=deletecard&token='.newToken().'">'; // source='.$companypaymentmodetemp->stripe_card_ref.'&
|
||||
print img_picto($langs->trans("Delete"), 'delete');
|
||||
print '</a>';
|
||||
@ -1140,24 +1188,31 @@ if ($socid && $action != 'edit' && $action != 'create' && $action != 'editcard'
|
||||
// Show remote sources (not already shown as local source)
|
||||
if (is_array($listofsources) && count($listofsources)) {
|
||||
foreach ($listofsources as $src) {
|
||||
if (!empty($arrayofstripecard[$src->id])) {
|
||||
if (!empty($arrayofremotecard[$src->id])) {
|
||||
continue; // Already in previous list
|
||||
}
|
||||
|
||||
$nbremote++;
|
||||
|
||||
print '<tr class="oddeven">';
|
||||
// Local ID
|
||||
if (!empty($conf->global->STRIPE_ALLOW_LOCAL_CARD)) {
|
||||
print '<td>';
|
||||
print '</td>';
|
||||
$imgline = '';
|
||||
if ($src->object == 'card') {
|
||||
$imgline = img_credit_card($src->brand);
|
||||
} elseif ($src->object == 'source' && $src->type == 'card') {
|
||||
$imgline = img_credit_card($src->card->brand);
|
||||
} elseif ($src->object == 'payment_method' && $src->type == 'card') {
|
||||
$imgline = img_credit_card($src->card->brand);
|
||||
} elseif ($src->object == 'source' && $src->type == 'sepa_debit') {
|
||||
continue;
|
||||
} elseif ($src->object == 'payment_method' && $src->type == 'sepa_debit') {
|
||||
continue;
|
||||
}
|
||||
|
||||
print '<tr class="oddeven">';
|
||||
print '<td>';
|
||||
print '</td>';
|
||||
// Src ID
|
||||
print '<td>';
|
||||
print '<td class="tdoverflowmax150">';
|
||||
$connect = '';
|
||||
print $src->id;
|
||||
if (!empty($stripeacc)) {
|
||||
$connect = $stripeacc.'/';
|
||||
}
|
||||
@ -1167,21 +1222,12 @@ if ($socid && $action != 'edit' && $action != 'create' && $action != 'editcard'
|
||||
//$url='https://dashboard.stripe.com/'.$connect.'sources/'.$src->id;
|
||||
$url = 'https://dashboard.stripe.com/'.$connect.'search?query='.$src->id;
|
||||
}
|
||||
print " <a href='".$url."' target='_stripe'>".img_picto($langs->trans('ShowInStripe'), 'globe')."</a>";
|
||||
print "<a href='".$url."' target='_stripe'>".img_picto($langs->trans('ShowInStripe'), 'globe')."</a> ";
|
||||
print $src->id;
|
||||
print '</td>';
|
||||
// Img of credit card
|
||||
// Img
|
||||
print '<td>';
|
||||
if ($src->object == 'card') {
|
||||
print img_credit_card($src->brand);
|
||||
} elseif ($src->object == 'source' && $src->type == 'card') {
|
||||
print img_credit_card($src->card->brand);
|
||||
} elseif ($src->object == 'source' && $src->type == 'sepa_debit') {
|
||||
print '<span class="fa fa-university fa-2x fa-fw"></span>';
|
||||
} elseif ($src->object == 'payment_method' && $src->type == 'card') {
|
||||
print img_credit_card($src->card->brand);
|
||||
} elseif ($src->object == 'payment_method' && $src->type == 'sepa_debit') {
|
||||
print '<span class="fa fa-university fa-2x fa-fw"></span>';
|
||||
}
|
||||
print $imgline;
|
||||
print'</td>';
|
||||
// Information
|
||||
print '<td valign="middle">';
|
||||
@ -1256,18 +1302,20 @@ if ($socid && $action != 'edit' && $action != 'create' && $action != 'editcard'
|
||||
print $langs->trans("Remote");
|
||||
//if ($src->cvc_check == 'fail') print ' - CVC check fail';
|
||||
print '</td>';
|
||||
|
||||
print '<td>';
|
||||
//var_dump($src);
|
||||
print '';
|
||||
print '</td>';
|
||||
|
||||
// Fields from hook
|
||||
$parameters = array('arrayfields'=>array(), 'stripesource'=>$src, 'linetype'=>'stripecardremoteonly');
|
||||
$reshook = $hookmanager->executeHooks('printFieldListValue', $parameters, $object); // Note that $action and $object may have been modified by hook
|
||||
print $hookmanager->resPrint;
|
||||
|
||||
// Action column
|
||||
print '<td class="right nowraponall">';
|
||||
if ($permissiontoaddupdatepaymentinformation) {
|
||||
print '<a href="'.DOL_URL_ROOT.'/societe/paymentmodes.php?socid='.$object->id.'&source='.$src->id.'&action=deletecard&token='.newToken().'">';
|
||||
print '<a class="marginleftonly marginrightonly" href="'.DOL_URL_ROOT.'/societe/paymentmodes.php?socid='.$object->id.'&source='.$src->id.'&action=deletecard&token='.newToken().'">';
|
||||
print img_picto($langs->trans("Delete"), 'delete');
|
||||
print '</a>';
|
||||
}
|
||||
@ -1286,7 +1334,7 @@ if ($socid && $action != 'edit' && $action != 'create' && $action != 'editcard'
|
||||
print '<br>';
|
||||
}
|
||||
|
||||
// List of Stripe payment modes
|
||||
// List of Stripe connect accounts
|
||||
if (!empty($conf->stripe->enabled) && !empty($conf->stripeconnect->enabled) && !empty($stripesupplieracc)) {
|
||||
print load_fiche_titre($langs->trans('StripeBalance').($stripesupplieracc ? ' (Stripe connection with StripeConnect account '.$stripesupplieracc.')' : ' (Stripe connection with keys from Stripe module setup)'), $morehtmlright, 'stripe-s');
|
||||
$balance = \Stripe\Balance::retrieve(array("stripe_account" => $stripesupplieracc));
|
||||
@ -1337,16 +1385,20 @@ if ($socid && $action != 'edit' && $action != 'create' && $action != 'editcard'
|
||||
$morehtmlright = dolGetButtonTitle($langs->trans('Add'), '', 'fa fa-plus-circle', $_SERVER["PHP_SELF"] . '?socid=' . $object->id . '&action=create');
|
||||
}
|
||||
|
||||
|
||||
print load_fiche_titre($langs->trans("BankAccounts"), $morehtmlright, 'bank');
|
||||
|
||||
$nblocal = 0; $nbremote = 0;
|
||||
$arrayofremoteban = array();
|
||||
|
||||
$rib_list = $object->get_all_rib();
|
||||
|
||||
if (is_array($rib_list)) {
|
||||
print '<div class="div-table-responsive-no-min">'; // You can use div-table-responsive-no-min if you don't need reserved height for your table
|
||||
print '<table class="liste centpercent">';
|
||||
|
||||
print '<tr class="liste_titre">';
|
||||
print_liste_field_titre("LabelRIB");
|
||||
print_liste_field_titre("Label");
|
||||
print_liste_field_titre("StripeID"); // external system ID
|
||||
print_liste_field_titre("Bank");
|
||||
print_liste_field_titre("RIB");
|
||||
print_liste_field_titre("IBAN");
|
||||
@ -1356,17 +1408,43 @@ if ($socid && $action != 'edit' && $action != 'create' && $action != 'editcard'
|
||||
print_liste_field_titre("DateRUM");
|
||||
print_liste_field_titre("WithdrawMode");
|
||||
}
|
||||
print_liste_field_titre("DefaultRIB", '', '', '', '', '', '', '', 'center ');
|
||||
print_liste_field_titre("Default", '', '', '', '', '', '', '', 'center ');
|
||||
print_liste_field_titre('', '', '', '', '', '', '', '', 'center ');
|
||||
// Fields from hook
|
||||
$parameters = array('arrayfields'=>array(), 'linetype'=>'stripebantitle');
|
||||
$reshook = $hookmanager->executeHooks('printFieldListValue', $parameters, $object); // Note that $action and $object may have been modified by hook
|
||||
print $hookmanager->resPrint;
|
||||
print_liste_field_titre('', $_SERVER["PHP_SELF"], "", '', '', '', '', '', 'maxwidthsearch ');
|
||||
print "</tr>\n";
|
||||
|
||||
// List of local BAN
|
||||
foreach ($rib_list as $rib) {
|
||||
$arrayofremoteban[$rib->stripe_card_ref] = $rib->stripe_card_ref;
|
||||
|
||||
$nblocal++;
|
||||
|
||||
print '<tr class="oddeven">';
|
||||
// Label
|
||||
print '<td>'.$rib->label.'</td>';
|
||||
print '<td>'.dol_escape_htmltag($rib->label).'</td>';
|
||||
// Stripe ID
|
||||
print '<td class="tdoverflowmax150">';
|
||||
if ($rib->stripe_card_ref) {
|
||||
$connect = '';
|
||||
if (!empty($stripeacc)) {
|
||||
$connect = $stripeacc.'/';
|
||||
}
|
||||
//$url='https://dashboard.stripe.com/'.$connect.'test/sources/'.$src->id;
|
||||
$url = 'https://dashboard.stripe.com/'.$connect.'test/search?query='.$rib->stripe_card_ref;
|
||||
if ($servicestatus) {
|
||||
//$url='https://dashboard.stripe.com/'.$connect.'sources/'.$src->id;
|
||||
$url = 'https://dashboard.stripe.com/'.$connect.'search?query='.$rib->stripe_card_ref;
|
||||
}
|
||||
print "<a href='".$url."' target='_stripe'>".img_picto($langs->trans('ShowInStripe'), 'globe')."</a> ";
|
||||
}
|
||||
print $rib->stripe_card_ref;
|
||||
print '</td>';
|
||||
// Bank name
|
||||
print '<td>'.$rib->bank.'</td>';
|
||||
print '<td class="tdoverflowmax100" title="'.dol_escape_htmltag($rib->bank).'">'.dol_escape_htmltag($rib->bank).'</td>';
|
||||
// Account number
|
||||
print '<td>';
|
||||
$string = '';
|
||||
@ -1398,7 +1476,7 @@ if ($socid && $action != 'edit' && $action != 'create' && $action != 'editcard'
|
||||
print $string;
|
||||
print '</td>';
|
||||
// IBAN
|
||||
print '<td>'.$rib->iban;
|
||||
print '<td class="tdoverflowmax100" title="'.dol_escape_htmltag($rib->iban).'">'.dol_escape_htmltag($rib->iban);
|
||||
if (!empty($rib->iban)) {
|
||||
if (!checkIbanForAccount($rib)) {
|
||||
print ' '.img_picto($langs->trans("IbanNotValid"), 'warning');
|
||||
@ -1417,7 +1495,7 @@ if ($socid && $action != 'edit' && $action != 'create' && $action != 'editcard'
|
||||
if (!empty($conf->prelevement->enabled)) {
|
||||
// RUM
|
||||
//print '<td>'.$prelevement->buildRumNumber($object->code_client, $rib->datec, $rib->id).'</td>';
|
||||
print '<td>'.$rib->rum.'</td>';
|
||||
print '<td class="tdoverflowmax100" title="'.dol_escape_htmltag($rib->rum).'">'.dol_escape_htmltag($rib->rum).'</td>';
|
||||
|
||||
print '<td>'.dol_print_date($rib->date_rum, 'day').'</td>';
|
||||
|
||||
@ -1500,12 +1578,19 @@ if ($socid && $action != 'edit' && $action != 'create' && $action != 'editcard'
|
||||
print $out;
|
||||
print '</td>';
|
||||
|
||||
// Fields from hook
|
||||
$parameters = array('arrayfields'=>array(), 'stripe_card_ref'=>$rib->stripe_card_ref, 'stripe_account'=>$rib->stripe_account, 'linetype'=>'stripeban');
|
||||
$reshook = $hookmanager->executeHooks('printFieldListValue', $parameters, $object); // Note that $action and $object may have been modified by hook
|
||||
print $hookmanager->resPrint;
|
||||
|
||||
// Edit/Delete
|
||||
print '<td class="right nowraponall">';
|
||||
if ($permissiontoaddupdatepaymentinformation) {
|
||||
print '<a class="editfielda marginrightonly marginleftonly" href="'.$_SERVER["PHP_SELF"].'?socid='.$object->id.'&id='.$rib->id.'&action=syncsepatostripe">';
|
||||
print img_picto($langs->trans("CreateBAN"), 'stripe');
|
||||
print '</a>';
|
||||
if (empty($rib->stripe_card_ref)) {
|
||||
print '<a class="editfielda marginrightonly marginleftonly" href="'.$_SERVER["PHP_SELF"].'?socid='.$object->id.'&id='.$rib->id.'&action=syncsepatostripe">';
|
||||
print img_picto($langs->trans("CreateBAN"), 'stripe');
|
||||
print '</a>';
|
||||
}
|
||||
|
||||
print '<a class="editfielda" href="'.$_SERVER["PHP_SELF"].'?socid='.$object->id.'&id='.$rib->id.'&action=edit">';
|
||||
print img_picto($langs->trans("Modify"), 'edit');
|
||||
@ -1520,10 +1605,114 @@ if ($socid && $action != 'edit' && $action != 'create' && $action != 'editcard'
|
||||
print '</tr>';
|
||||
}
|
||||
|
||||
if (count($rib_list) == 0) {
|
||||
$colspan = 9;
|
||||
|
||||
// List of remote BAN (if not already added as local)
|
||||
foreach ($listofsources as $src) {
|
||||
if (!empty($arrayofremoteban[$src->id])) {
|
||||
continue; // Already in previous list
|
||||
}
|
||||
|
||||
$nbremote++;
|
||||
|
||||
$imgline = '';
|
||||
if ($src->object == 'source' && $src->type == 'sepa_debit') {
|
||||
$imgline = '<span class="fa fa-university fa-2x fa-fw"></span>';
|
||||
} elseif ($src->object == 'payment_method' && $src->type == 'sepa_debit') {
|
||||
$imgline = '<span class="fa fa-university fa-2x fa-fw"></span>';
|
||||
} else {
|
||||
continue;
|
||||
}
|
||||
|
||||
print '<tr class="oddeven">';
|
||||
print '<td>';
|
||||
print '</td>';
|
||||
// Src ID
|
||||
print '<td class="tdoverflowmax150">';
|
||||
$connect = '';
|
||||
if (!empty($stripeacc)) {
|
||||
$connect = $stripeacc.'/';
|
||||
}
|
||||
//$url='https://dashboard.stripe.com/'.$connect.'test/sources/'.$src->id;
|
||||
$url = 'https://dashboard.stripe.com/'.$connect.'test/search?query='.$src->id;
|
||||
if ($servicestatus) {
|
||||
//$url='https://dashboard.stripe.com/'.$connect.'sources/'.$src->id;
|
||||
$url = 'https://dashboard.stripe.com/'.$connect.'search?query='.$src->id;
|
||||
}
|
||||
print "<a href='".$url."' target='_stripe'>".img_picto($langs->trans('ShowInStripe'), 'globe')."</a> ";
|
||||
print $src->id;
|
||||
print '</td>';
|
||||
// Bank
|
||||
print '<td>';
|
||||
print'</td>';
|
||||
// Account number
|
||||
print '<td valign="middle">';
|
||||
print '</td>';
|
||||
// IBAN
|
||||
print '<td valign="middle">';
|
||||
//var_dump($src);
|
||||
print '</td>';
|
||||
// BIC
|
||||
print '<td valign="middle">';
|
||||
//var_dump($src);
|
||||
print '</td>';
|
||||
|
||||
if (!empty($conf->prelevement->enabled)) {
|
||||
$colspan += 2;
|
||||
// RUM
|
||||
print '<td valign="middle">';
|
||||
//var_dump($src);
|
||||
print '</td>';
|
||||
// Date
|
||||
print '<td valign="middle">';
|
||||
//var_dump($src);
|
||||
print '</td>';
|
||||
// Mode mandate
|
||||
print '<td valign="middle">';
|
||||
//var_dump($src);
|
||||
print '</td>';
|
||||
}
|
||||
|
||||
// Default
|
||||
print '<td class="center" width="50">';
|
||||
if ((empty($customerstripe->invoice_settings) && $customerstripe->default_source != $src->id) ||
|
||||
(!empty($customerstripe->invoice_settings) && $customerstripe->invoice_settings->default_payment_method != $src->id)) {
|
||||
print '<a href="'.DOL_URL_ROOT.'/societe/paymentmodes.php?socid='.$object->id.'&source='.$src->id.'&action=setassourcedefault&token='.newToken().'">';
|
||||
print img_picto($langs->trans("Default"), 'off');
|
||||
print '</a>';
|
||||
} else {
|
||||
print img_picto($langs->trans("Default"), 'on');
|
||||
}
|
||||
print '</td>';
|
||||
/*
|
||||
print '<td>';
|
||||
print $langs->trans("Remote");
|
||||
//if ($src->cvc_check == 'fail') print ' - CVC check fail';
|
||||
print '</td>';
|
||||
*/
|
||||
|
||||
print '<td>';
|
||||
print '</td>';
|
||||
|
||||
// Fields from hook
|
||||
$parameters = array('arrayfields'=>array(), 'stripe_card_ref'=>$rib->stripe_card_ref, 'stripe_account'=>$rib->stripe_account, 'linetype'=>'stripebanremoteonly');
|
||||
$reshook = $hookmanager->executeHooks('printFieldListValue', $parameters, $object); // Note that $action and $object may have been modified by hook
|
||||
print $hookmanager->resPrint;
|
||||
|
||||
// Action column
|
||||
print '<td class="right nowraponall">';
|
||||
if ($permissiontoaddupdatepaymentinformation) {
|
||||
print '<a class="marginleftonly marginrightonly" href="'.DOL_URL_ROOT.'/societe/paymentmodes.php?socid='.$object->id.'&source='.$src->id.'&action=delete&token='.newToken().'">';
|
||||
print img_picto($langs->trans("Delete"), 'delete');
|
||||
print '</a>';
|
||||
}
|
||||
print '</td>';
|
||||
|
||||
print '</tr>';
|
||||
}
|
||||
|
||||
if ($nbremote == 0 && $nblocal == 0) {
|
||||
$colspan = 10;
|
||||
if (!empty($conf->prelevement->enabled)) {
|
||||
$colspan += 3;
|
||||
}
|
||||
print '<tr><td colspan="'.$colspan.'"><span class="opacitymedium">'.$langs->trans("NoBANRecord").'</span></td></tr>';
|
||||
}
|
||||
@ -1603,10 +1792,12 @@ if ($socid && $action == 'edit' && $permissiontoaddupdatepaymentinformation) {
|
||||
|
||||
print '<div class="underbanner clearboth"></div>';
|
||||
|
||||
print '<br>';
|
||||
|
||||
print '<div class="div-table-responsive-no-min">';
|
||||
print '<table class="border centpercent">';
|
||||
|
||||
print '<tr><td class="titlefield fieldrequired">'.$langs->trans("LabelRIB").'</td>';
|
||||
print '<tr><td class="titlefield fieldrequired">'.$langs->trans("Label").'</td>';
|
||||
print '<td><input class="minwidth300" type="text" name="label" value="'.$companybankaccount->label.'"></td></tr>';
|
||||
|
||||
print '<tr><td class="fieldrequired">'.$langs->trans("BankName").'</td>';
|
||||
@ -1702,6 +1893,9 @@ if ($socid && $action == 'edit' && $permissiontoaddupdatepaymentinformation) {
|
||||
print $form->selectarray("frstrecur", $tblArraychoice, dol_escape_htmltag(GETPOST('frstrecur', 'alpha') ?GETPOST('frstrecur', 'alpha') : $companybankaccount->frstrecur), 0);
|
||||
print '</td></tr>';
|
||||
|
||||
print '<tr><td>'.$langs->trans("StripeID")." ('src_....')</td>";
|
||||
print '<td><input class="minwidth300" type="text" name="stripe_card_ref" value="'.$companypaymentmode->stripe_card_ref.'"></td></tr>';
|
||||
|
||||
print '</table>';
|
||||
print '</div>';
|
||||
}
|
||||
@ -1720,9 +1914,12 @@ if ($socid && $action == 'editcard' && $permissiontoaddupdatepaymentinformation)
|
||||
|
||||
dol_banner_tab($object, 'socid', $linkback, ($user->socid ? 0 : 1), 'rowid', 'nom');
|
||||
|
||||
print '<div class="fichecenter">';
|
||||
print '<div class="nofichecenter">';
|
||||
|
||||
print '<div class="underbanner clearboth"></div>';
|
||||
|
||||
print '<br>';
|
||||
|
||||
print '<table class="border centpercent">';
|
||||
|
||||
print '<tr><td class="titlefieldcreate fieldrequired">'.$langs->trans("Label").'</td>';
|
||||
@ -1766,9 +1963,12 @@ if ($socid && $action == 'create' && $permissiontoaddupdatepaymentinformation) {
|
||||
print '<div class="nofichecenter">';
|
||||
|
||||
print '<div class="underbanner clearboth"></div>';
|
||||
|
||||
print '<br>';
|
||||
|
||||
print '<table class="border centpercent">';
|
||||
|
||||
print '<tr><td class="titlefieldcreate fieldrequired">'.$langs->trans("LabelRIB").'</td>';
|
||||
print '<tr><td class="titlefieldcreate fieldrequired">'.$langs->trans("Label").'</td>';
|
||||
print '<td><input class="minwidth200" type="text" id="label" name="label" value="'.(GETPOSTISSET('label') ? GETPOST('label') : $object->name).'"></td></tr>';
|
||||
|
||||
print '<tr><td class="fieldrequired">'.$langs->trans("Bank").'</td>';
|
||||
@ -1858,6 +2058,9 @@ if ($socid && $action == 'create' && $permissiontoaddupdatepaymentinformation) {
|
||||
print $form->selectarray("frstrecur", $tblArraychoice, (GETPOSTISSET('frstrecur') ? GETPOST('frstrecur') : 'FRST'), 0);
|
||||
print '</td></tr>';
|
||||
|
||||
print '<tr><td>'.$langs->trans("StripeID")." ('src_....')</td>";
|
||||
print '<td><input class="minwidth300" type="text" name="stripe_card_ref" value="'.GETPOST('stripe_card_ref', 'alpha').'"></td></tr>';
|
||||
|
||||
print '</table>';
|
||||
}
|
||||
|
||||
@ -1881,6 +2084,9 @@ if ($socid && $action == 'createcard' && $permissiontoaddupdatepaymentinformatio
|
||||
print '<div class="nofichecenter">';
|
||||
|
||||
print '<div class="underbanner clearboth"></div>';
|
||||
|
||||
print '<br>';
|
||||
|
||||
print '<table class="border centpercent">';
|
||||
|
||||
print '<tr><td class="titlefieldcreate fieldrequired">'.$langs->trans("Label").'</td>';
|
||||
|
||||
@ -774,7 +774,7 @@ class Stripe extends CommonObject
|
||||
$sql .= " WHERE sa.rowid = ".((int) $object->id); // We get record from ID, no need for filter on entity
|
||||
$sql .= " AND sa.type = 'card'";
|
||||
|
||||
dol_syslog(get_class($this)."::fetch search stripe card id for paymentmode id=".$object->id.", stripeacc=".$stripeacc.", status=".$status.", createifnotlinkedtostripe=".$createifnotlinkedtostripe, LOG_DEBUG);
|
||||
dol_syslog(get_class($this)."::cardStripe search stripe card id for paymentmode id=".$object->id.", stripeacc=".$stripeacc.", status=".$status.", createifnotlinkedtostripe=".$createifnotlinkedtostripe, LOG_DEBUG);
|
||||
$resql = $this->db->query($sql);
|
||||
if ($resql) {
|
||||
$num = $this->db->num_rows($resql);
|
||||
@ -914,14 +914,14 @@ class Stripe extends CommonObject
|
||||
$soc = new Societe($this->db);
|
||||
$soc->fetch($object->fk_soc);
|
||||
|
||||
dol_syslog(get_class($this)."::fetch search stripe sepa(card) id for paymentmode id=".$object->id.", stripeacc=".$stripeacc.", status=".$status.", createifnotlinkedtostripe=".$createifnotlinkedtostripe, LOG_DEBUG);
|
||||
dol_syslog(get_class($this)."::sepaStripe search stripe ban id for paymentmode id=".$object->id.", stripeacc=".$stripeacc.", status=".$status.", createifnotlinkedtostripe=".$createifnotlinkedtostripe, LOG_DEBUG);
|
||||
$resql = $this->db->query($sql);
|
||||
if ($resql) {
|
||||
$num = $this->db->num_rows($resql);
|
||||
if ($num) {
|
||||
$obj = $this->db->fetch_object($resql);
|
||||
$cardref = $obj->stripe_card_ref;
|
||||
dol_syslog(get_class($this)."::cardStripe cardref=".$cardref);
|
||||
dol_syslog(get_class($this)."::sepaStripe cardref=".$cardref);
|
||||
if ($cardref) {
|
||||
try {
|
||||
if (empty($stripeacc)) { // If the Stripe connect account not set, we use common API usage
|
||||
@ -990,7 +990,7 @@ class Stripe extends CommonObject
|
||||
$sql = "UPDATE ".MAIN_DB_PREFIX."societe_rib";
|
||||
$sql .= " SET stripe_card_ref = '".$this->db->escape($sepa->id)."', card_type = 'sepa_debit',";
|
||||
$sql .= " stripe_account= '" . $this->db->escape($cu->id . "@" . $stripeacc) . "'";
|
||||
$sql .= " WHERE rowid = '".$this->db->escape($object->id)."'";
|
||||
$sql .= " WHERE rowid = ".((int) $object->id);
|
||||
$sql .= " AND type = 'ban'";
|
||||
$resql = $this->db->query($sql);
|
||||
if (!$resql) {
|
||||
|
||||
Loading…
Reference in New Issue
Block a user