Close #11152 by a manual merge to keep only required things

This commit is contained in:
Laurent Destailleur 2019-06-16 17:08:23 +02:00
parent bc8c7e0d4f
commit 48b2cb83af
6 changed files with 205 additions and 37 deletions

View File

@ -148,32 +148,50 @@ class InterfaceStripe
{ {
$namecleaned = $object->name ? $object->name : null; $namecleaned = $object->name ? $object->name : null;
$vatcleaned = $object->tva_intra ? $object->tva_intra : null; $vatcleaned = $object->tva_intra ? $object->tva_intra : null;
$desccleaned = $object->name_alias ? $object->name_alias : null;
$taxinfo = array('type'=>'vat'); $taxexemptcleaned = $object->tva_assuj ? 'none' : 'exempt';
$langcleaned = $object->default_lang ? array(substr($object->default_lang, 0, 2)) : null;
/*$taxinfo = array('type'=>'vat');
if ($vatcleaned) if ($vatcleaned)
{ {
$taxinfo["tax_id"] = $vatcleaned; $taxinfo["tax_id"] = $vatcleaned;
} }
// We force data to "null" if not defined as expected by Stripe // We force data to "null" if not defined as expected by Stripe
if (empty($vatcleaned)) $taxinfo=null; if (empty($vatcleaned)) $taxinfo=null;*/
// Detect if we change a Stripe info (email, description, vat id) // Detect if we change a Stripe info (email, description, vat id)
$changerequested = 0; $changerequested = 0;
if (! empty($object->email) && $object->email != $customer->email) $changerequested++; if (! empty($object->email) && $object->email != $customer->email) $changerequested++;
if ($namecleaned != $customer->description) $changerequested++; /* if ($namecleaned != $customer->description) $changerequested++;
if (! isset($customer->tax_info['tax_id']) && ! is_null($vatcleaned)) $changerequested++; if (! isset($customer->tax_info['tax_id']) && ! is_null($vatcleaned)) $changerequested++;
elseif (isset($customer->tax_info['tax_id']) && is_null($vatcleaned)) $changerequested++; elseif (isset($customer->tax_info['tax_id']) && is_null($vatcleaned)) $changerequested++;
elseif (isset($customer->tax_info['tax_id']) && ! is_null($vatcleaned)) elseif (isset($customer->tax_info['tax_id']) && ! is_null($vatcleaned))
{ {
if ($vatcleaned != $customer->tax_info['tax_id']) $changerequested++; if ($vatcleaned != $customer->tax_info['tax_id']) $changerequested++;
} */
if ($namecleaned != $customer->name) $changerequested++;
if ($desccleaned != $customer->description) $changerequested++;
if (($customer->tax_exempt == 'exempt' && ! $object->tva_assuj) || (! $customer->tax_exempt == 'exempt' && empty($object->tva_assuj))) $changerequested++;
if (! isset($customer->tax_ids['data']) && ! is_null($vatcleaned)) $changerequested++;
elseif (isset($customer->tax_ids['data']) && is_null($vatcleaned)) $changerequested++;
elseif (isset($customer->tax_ids['data']) && ! is_null($vatcleaned))
{
$taxinfo = reset($customer->tax_ids['data']);
if (isset($taxinfo->value) && $vatcleaned != $taxinfo->value) $changerequested++;
} }
if ($changerequested) if ($changerequested)
{ {
if (! empty($object->email)) $customer->email = $object->email; /*if (! empty($object->email)) $customer->email = $object->email;
$customer->description = $namecleaned; $customer->description = $namecleaned;
if (empty($taxinfo)) $customer->tax_info = array('type'=>'vat', 'tax_id'=>null); if (empty($taxinfo)) $customer->tax_info = array('type'=>'vat', 'tax_id'=>null);
else $customer->tax_info = $taxinfo; else $customer->tax_info = $taxinfo; */
$customer->name = $namecleaned;
$customer->description = $desccleaned;
$customer->preferred_locales = $langcleaned;
$customer->tax_exempt = $taxexemptcleaned;
if (! empty($vatcleaned)) $customer->tax_ids = array('object'=>'list', 'data'=>array('value'=>$vatcleaned));
else $customer->tax_ids = null;
$customer->save(); $customer->save();
} }

View File

@ -293,7 +293,6 @@ elseif ($event->type == 'customer.source.delete') {
elseif ($event->type == 'customer.deleted') { elseif ($event->type == 'customer.deleted') {
$db->begin(); $db->begin();
$sql = "DELETE FROM ".MAIN_DB_PREFIX."societe_account WHERE key_account = '".$db->escape($event->data->object->id)."' and site='stripe'"; $sql = "DELETE FROM ".MAIN_DB_PREFIX."societe_account WHERE key_account = '".$db->escape($event->data->object->id)."' and site='stripe'";
dol_syslog(get_class($this) . "::delete sql=" . $sql, LOG_DEBUG);
$db->query($sql); $db->query($sql);
$db->commit(); $db->commit();
} }
@ -309,6 +308,94 @@ elseif ($event->type == 'checkout.session.completed') // Called when making pay
// TODO: create fees // TODO: create fees
// TODO: Redirect to paymentok.php // TODO: Redirect to paymentok.php
} }
elseif ($event->type == 'payment_method.attached') {
require_once DOL_DOCUMENT_ROOT.'/societe/class/companypaymentmode.class.php';
require_once DOL_DOCUMENT_ROOT.'/societe/class/societeaccount.class.php';
$societeaccount = new SocieteAccount($db);
$companypaymentmode = new CompanyPaymentMode($db);
$idthirdparty = $societeaccount->getThirdPartyID($db->escape($event->data->object->customer), 'stripe', $servicestatus);
if ($idthirdparty > 0) // If the payment mode is on an external customer that is known in societeaccount, we can create the payment mode
{
$companypaymentmode->stripe_card_ref = $db->escape($event->data->object->id);
$companypaymentmode->fk_soc = $idthirdparty;
$companypaymentmode->bank = null;
$companypaymentmode->label = null;
$companypaymentmode->number = $db->escape($event->data->object->id);
$companypaymentmode->last_four = $db->escape($event->data->object->card->last4);
$companypaymentmode->card_type = $db->escape($event->data->object->card->branding);
$companypaymentmode->proprio = $db->escape($event->data->object->billing_details->name);
$companypaymentmode->exp_date_month = $db->escape($event->data->object->card->exp_month);
$companypaymentmode->exp_date_year = $db->escape($event->data->object->card->exp_year);
$companypaymentmode->cvn = null;
$companypaymentmode->datec = $db->escape($event->data->object->created);
$companypaymentmode->default_rib = 0;
$companypaymentmode->type = $db->escape($event->data->object->type);
$companypaymentmode->country_code = $db->escape($event->data->object->card->country);
$companypaymentmode->status = $servicestatus;
$db->begin();
if (! $error)
{
$result = $companypaymentmode->create($user);
if ($result < 0)
{
$error++;
}
}
if (! $error)
{
$db->commit();
}
else
{
$db->rollback();
}
}
}
elseif ($event->type == 'payment_method.updated') {
require_once DOL_DOCUMENT_ROOT.'/societe/class/companypaymentmode.class.php';
$companypaymentmode = new CompanyPaymentMode($db);
$companypaymentmode->fetch(0, '', 0, '', " AND stripe_card_ref = '".$db->escape($event->data->object->id)."'");
$companypaymentmode->bank = null;
$companypaymentmode->label = null;
$companypaymentmode->number = $db->escape($event->data->object->id);
$companypaymentmode->last_four = $db->escape($event->data->object->card->last4);
$companypaymentmode->proprio = $db->escape($event->data->object->billing_details->name);
$companypaymentmode->exp_date_month = $db->escape($event->data->object->card->exp_month);
$companypaymentmode->exp_date_year = $db->escape($event->data->object->card->exp_year);
$companypaymentmode->cvn = null;
$companypaymentmode->datec = $db->escape($event->data->object->created);
$companypaymentmode->default_rib = 0;
$companypaymentmode->type = $db->escape($event->data->object->type);
$companypaymentmode->country_code = $db->escape($event->data->object->card->country);
$companypaymentmode->status = $servicestatus;
$db->begin();
if (! $error)
{
$result = $companypaymentmode->update($user);
if ($result < 0)
{
$error++;
}
}
if (! $error)
{
$db->commit();
}
else
{
$db->rollback();
}
}
elseif ($event->type == 'payment_method.detached') {
$db->begin();
$sql = "DELETE FROM ".MAIN_DB_PREFIX."societe_rib WHERE ref = '".$db->escape($event->data->object->id)."' and status = ".$servicestatus;
$db->query($sql);
$db->commit();
}
elseif ($event->type == 'charge.succeeded') { elseif ($event->type == 'charge.succeeded') {
// TODO: create fees // TODO: create fees
// TODO: Redirect to paymentok.php // TODO: Redirect to paymentok.php

View File

@ -301,11 +301,11 @@ class CompanyPaymentMode extends CommonObject
* @param string $ref Ref * @param string $ref Ref
* @param int $socid Id of company to get first default payment mode * @param int $socid Id of company to get first default payment mode
* @param string $type Filter on type ('ban', 'card', ...) * @param string $type Filter on type ('ban', 'card', ...)
* @param string $morewhere More SQL filters (' AND ...')
* @return int <0 if KO, 0 if not found, >0 if OK * @return int <0 if KO, 0 if not found, >0 if OK
*/ */
public function fetch($id, $ref = null, $socid = 0, $type = '') public function fetch($id, $ref = null, $socid = 0, $type = '', $morewhere = '')
{ {
$morewhere = '';
if ($socid) $morewhere.= " AND fk_soc = ".$this->db->escape($socid)." AND default_rib = 1"; if ($socid) $morewhere.= " AND fk_soc = ".$this->db->escape($socid)." AND default_rib = 1";
if ($type) $morewhere.= " AND type = '".$this->db->escape($type)."'"; if ($type) $morewhere.= " AND type = '".$this->db->escape($type)."'";

View File

@ -3,7 +3,6 @@
* Copyright (C) 2014-2016 Juanjo Menent <jmenent@2byte.es> * Copyright (C) 2014-2016 Juanjo Menent <jmenent@2byte.es>
* Copyright (C) 2015 Florian Henry <florian.henry@open-concept.pro> * Copyright (C) 2015 Florian Henry <florian.henry@open-concept.pro>
* Copyright (C) 2015 Raphaël Doursenaud <rdoursenaud@gpcsolutions.fr> * Copyright (C) 2015 Raphaël Doursenaud <rdoursenaud@gpcsolutions.fr>
* Copyright (C) ---Put here your own copyright and developer email---
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
@ -281,12 +280,13 @@ class SocieteAccount extends CommonObject
} }
/** /**
* Try to find the external customer id of a thirdparty for an another site/system. * Try to find the external customer id of a thirdparty for another site/system.
* *
* @param int $id Id of third party * @param int $id Id of third party
* @param string $site Site (example: 'stripe', '...') * @param string $site Site (example: 'stripe', '...')
* @param int $status Status (0=test, 1=live) * @param int $status Status (0=test, 1=live)
* @return string Stripe customer ref 'cu_xxxxxxxxxxxxx' or '' * @return string Stripe customer ref 'cu_xxxxxxxxxxxxx' or ''
* @see getThirdPartyID()
*/ */
public function getCustomerAccount($id, $site, $status = 0) public function getCustomerAccount($id, $site, $status = 0)
{ {
@ -314,6 +314,38 @@ class SocieteAccount extends CommonObject
return $key; return $key;
} }
/**
* Try to find the thirdparty id for an another site/system external id.
*
* @param string $id Id of customer in external system (example: 'cu_xxxxxxxxxxxxx', ...)
* @param string $site Site (example: 'stripe', '...')
* @param int $status Status (0=test, 1=live)
* @return string Id of third party
* @see getCustomerAccount()
*/
public function getThirdPartyID($id, $site, $status = 0)
{
$socid = 0;
$sql = "SELECT sa.fk_soc as fk_soc, sa.key_account, sa.entity";
$sql.= " FROM " . MAIN_DB_PREFIX . "societe_account as sa";
$sql.= " WHERE sa.key_account = '".$this->db->escape($id)."'";
$sql.= " AND sa.entity IN (".getEntity('societe').")";
$sql.= " AND sa.site = '".$this->db->escape($site)."' AND sa.status = ".((int) $status);
$sql.= " AND sa.fk_soc > 0";
dol_syslog(get_class($this) . "::getCustomerAccount Try to find the first thirdparty id for ".$site." for external id=".$id, LOG_DEBUG);
$result = $this->db->query($sql);
if ($result) {
if ($this->db->num_rows($result)) {
$obj = $this->db->fetch_object($result);
$socid = $obj->fk_soc;
}
}
return $socid;
}
/** /**
* Update object into database * Update object into database
* *

View File

@ -1123,7 +1123,8 @@ if ($socid && $action != 'edit' && $action != 'create' && $action != 'editcard'
print '</td>'; print '</td>';
// Default // Default
print '<td class="center" width="50">'; print '<td class="center" width="50">';
if (($customerstripe->default_source != $src->id)) 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">'; print '<a href="' . DOL_URL_ROOT.'/societe/paymentmodes.php?socid='.$object->id.'&source='.$src->id.'&action=setassourcedefault">';
print img_picto($langs->trans("Default"), 'off'); print img_picto($langs->trans("Default"), 'off');

View File

@ -237,6 +237,33 @@ class Stripe extends CommonObject
return $customer; return $customer;
} }
/**
* Get the Stripe payment method Object from its ID
*
* @param string $paymentmethod Payment Method ID
* @param string $key ''=Use common API. If not '', it is the Stripe connect account 'acc_....' to use Stripe connect
* @param int $status Status (0=test, 1=live)
* @return \Stripe\PaymentMethod|null Stripe PaymentMethod or null if not found
*/
public function getPaymentMethodStripe($paymentmethod, $key = '', $status = 0)
{
try {
// Force to use the correct API key
global $stripearrayofkeysbyenv;
\Stripe\Stripe::setApiKey($stripearrayofkeysbyenv[$status]['secret_key']);
if (empty($key)) { // If the Stripe connect account not set, we use common API usage
$stripepaymentmethod = \Stripe\PaymentMethod::retrieve(''.$paymentmethod->id.'');
} else {
$stripepaymentmethod = \Stripe\PaymentMethod::retrieve(''.$paymentmethod->id.'', array("stripe_account" => $key));
}
}
catch(Exception $e)
{
$this->error = $e->getMessage();
}
return $stripepaymentmethod;
}
/** /**
* Get the Stripe payment intent. Create it with confirm=false * Get the Stripe payment intent. Create it with confirm=false
* Warning. If a payment was tried and failed, a payment intent was created. * Warning. If a payment was tried and failed, a payment intent was created.
@ -259,7 +286,7 @@ class Stripe extends CommonObject
*/ */
public function getPaymentIntent($amount, $currency_code, $tag, $description = '', $object = null, $customer = null, $key = null, $status = 0, $usethirdpartyemailforreceiptemail = 0, $mode = 'automatic', $confirmnow = false) public function getPaymentIntent($amount, $currency_code, $tag, $description = '', $object = null, $customer = null, $key = null, $status = 0, $usethirdpartyemailforreceiptemail = 0, $mode = 'automatic', $confirmnow = false)
{ {
global $conf, $user, $mysoc; global $conf;
dol_syslog("getPaymentIntent"); dol_syslog("getPaymentIntent");
@ -272,12 +299,14 @@ class Stripe extends CommonObject
if (! in_array($currency_code, $arrayzerounitcurrency)) $stripeamount = $amount * 100; if (! in_array($currency_code, $arrayzerounitcurrency)) $stripeamount = $amount * 100;
else $stripeamount = $amount; else $stripeamount = $amount;
$fee = round(($$stripeamount * ($conf->global->STRIPE_APPLICATION_FEE_PERCENT / 100) + $conf->global->STRIPE_APPLICATION_FEE) * 100); $fee = round($amount * ($conf->global->STRIPE_APPLICATION_FEE_PERCENT / 100) + $conf->global->STRIPE_APPLICATION_FEE);
if ($fee >= ($conf->global->STRIPE_APPLICATION_FEE_MAXIMAL * 100) && $conf->global->STRIPE_APPLICATION_FEE_MAXIMAL>$conf->global->STRIPE_APPLICATION_FEE_MINIMAL) { if ($fee >= $conf->global->STRIPE_APPLICATION_FEE_MAXIMAL && $conf->global->STRIPE_APPLICATION_FEE_MAXIMAL > $conf->global->STRIPE_APPLICATION_FEE_MINIMAL) {
$fee = round($conf->global->STRIPE_APPLICATION_FEE_MAXIMAL * 100); $fee = round($conf->global->STRIPE_APPLICATION_FEE_MAXIMAL);
} elseif ($fee < ($conf->global->STRIPE_APPLICATION_FEE_MINIMAL * 100)) { } elseif ($fee < $conf->global->STRIPE_APPLICATION_FEE_MINIMAL) {
$fee = round($conf->global->STRIPE_APPLICATION_FEE_MINIMAL * 100); $fee = round($conf->global->STRIPE_APPLICATION_FEE_MINIMAL);
} }
if (! in_array($currency_code, $arrayzerounitcurrency)) $stripefee = $fee * 100;
else $stripefee = $fee;
$paymentintent = null; $paymentintent = null;
@ -352,9 +381,9 @@ class Stripe extends CommonObject
// payment_method_types = array('card') // payment_method_types = array('card')
//var_dump($dataforintent); //var_dump($dataforintent);
if ($conf->entity!=$conf->global->STRIPECONNECT_PRINCIPAL && $fee>0) if ($conf->entity!=$conf->global->STRIPECONNECT_PRINCIPAL && $stripefee > 0)
{ {
$dataforintent["application_fee"] = $fee; $dataforintent["application_fee"] = $stripefee;
} }
if ($usethirdpartyemailforreceiptemail && is_object($object) && $object->thirdparty->email) if ($usethirdpartyemailforreceiptemail && is_object($object) && $object->thirdparty->email)
{ {
@ -461,8 +490,7 @@ class Stripe extends CommonObject
$sql = "SELECT sa.stripe_card_ref, sa.proprio, sa.exp_date_month, sa.exp_date_year, sa.number, sa.cvn"; // stripe_card_ref is card_.... $sql = "SELECT sa.stripe_card_ref, sa.proprio, sa.exp_date_month, sa.exp_date_year, sa.number, sa.cvn"; // stripe_card_ref is card_....
$sql.= " FROM " . MAIN_DB_PREFIX . "societe_rib as sa"; $sql.= " FROM " . MAIN_DB_PREFIX . "societe_rib as sa";
$sql.= " WHERE sa.rowid = " . $object->id; $sql.= " WHERE sa.rowid = " . $object->id; // We get record from ID, no need for filter on entity
//$sql.= " AND sa.entity IN (".getEntity('societe').")";
$sql.= " AND sa.type = 'card'"; $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) . "::fetch search stripe card id for paymentmode id=".$object->id.", stripeacc=".$stripeacc.", status=".$status.", createifnotlinkedtostripe=".$createifnotlinkedtostripe, LOG_DEBUG);
@ -660,13 +688,15 @@ class Stripe extends CommonObject
$charge = \Stripe\Charge::create($paymentarray, array("idempotency_key" => "$description")); $charge = \Stripe\Charge::create($paymentarray, array("idempotency_key" => "$description"));
} }
} else { } else {
$fee = round(($object->total_ttc * ($conf->global->STRIPE_APPLICATION_FEE_PERCENT / 100) + $conf->global->STRIPE_APPLICATION_FEE) * 100); $fee = round($amount * ($conf->global->STRIPE_APPLICATION_FEE_PERCENT / 100) + $conf->global->STRIPE_APPLICATION_FEE);
if ($fee >= ($conf->global->STRIPE_APPLICATION_FEE_MAXIMAL * 100) && $conf->global->STRIPE_APPLICATION_FEE_MAXIMAL>$conf->global->STRIPE_APPLICATION_FEE_MINIMAL) { if ($fee >= $conf->global->STRIPE_APPLICATION_FEE_MAXIMAL && $conf->global->STRIPE_APPLICATION_FEE_MAXIMAL > $conf->global->STRIPE_APPLICATION_FEE_MINIMAL) {
$fee = round($conf->global->STRIPE_APPLICATION_FEE_MAXIMAL * 100); $fee = round($conf->global->STRIPE_APPLICATION_FEE_MAXIMAL);
} }
elseif ($fee < ($conf->global->STRIPE_APPLICATION_FEE_MINIMAL * 100)) { elseif ($fee < $conf->global->STRIPE_APPLICATION_FEE_MINIMAL) {
$fee = round($conf->global->STRIPE_APPLICATION_FEE_MINIMAL * 100); $fee = round($conf->global->STRIPE_APPLICATION_FEE_MINIMAL);
} }
if (! in_array($currency, $arrayzerounitcurrency)) $stripefee = $fee * 100;
else $stripefee = $fee;
$paymentarray = array( $paymentarray = array(
"amount" => "$stripeamount", "amount" => "$stripeamount",
@ -678,9 +708,9 @@ class Stripe extends CommonObject
"source" => "$source", "source" => "$source",
"customer" => "$customer" "customer" => "$customer"
); );
if ($conf->entity!=$conf->global->STRIPECONNECT_PRINCIPAL && $fee>0) if ($conf->entity!=$conf->global->STRIPECONNECT_PRINCIPAL && $stripefee > 0)
{ {
$paymentarray["application_fee"] = $fee; $paymentarray["application_fee"] = $stripefee;
} }
if ($societe->email && $usethirdpartyemailforreceiptemail) if ($societe->email && $usethirdpartyemailforreceiptemail)
{ {