Merge pull request #21227 from ptibogxiv/patch-454

NEW support of Stripe Terminal with Takepos
This commit is contained in:
Laurent Destailleur 2022-07-10 19:34:39 +02:00 committed by GitHub
commit a7515cb620
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 489 additions and 6 deletions

View File

@ -2,7 +2,7 @@
/* Copyright (C) 2017 Alexandre Spangaro <aspangaro@open-dsi.fr>
* Copyright (C) 2017 Olivier Geffroy <jeff@jeffinfo.com>
* Copyright (C) 2017 Saasprov <saasprov@gmail.com>
* Copyright (C) 2018-2021 Thibault FOUCART <support@ptibogxiv.net>
* Copyright (C) 2018-2022 Thibault FOUCART <support@ptibogxiv.net>
* Copyright (C) 2018 Frédéric France <frederic.france@netlogic.fr>
*
* This program is free software; you can redistribute it and/or modify
@ -104,6 +104,12 @@ if ($action == 'setvalue' && $user->admin) {
if (!$result > 0) {
$error++;
}
if (GETPOSTISSET('STRIPE_LOCATION')) {
$result = dolibarr_set_const($db, "STRIPE_LOCATION", GETPOST('STRIPE_LOCATION', 'alpha'), 'chaine', 0, '', $conf->entity);
if (!$result > 0) {
$error++;
}
}
$result = dolibarr_set_const($db, "ONLINE_PAYMENT_CSS_URL", GETPOST('ONLINE_PAYMENT_CSS_URL', 'alpha'), 'chaine', 0, '', $conf->entity);
if (!$result > 0) {
$error++;
@ -364,6 +370,56 @@ if (getDolGlobalInt('MAIN_FEATURES_LEVEL') >= 2) { // What is this for ?
print '</td></tr>';
}
// Card Present for Stripe Terminal
if ($conf->global->MAIN_FEATURES_LEVEL >= 2) { // TODO Not used by current code
print '<tr class="oddeven"><td>';
print $langs->trans("STRIPE_CARD_PRESENT").'</td><td>';
if ($conf->use_javascript_ajax) {
print ajax_constantonoff('STRIPE_CARD_PRESENT');
} else {
$arrval = array('0' => $langs->trans("No"), '1' => $langs->trans("Yes"));
print $form->selectarray("STRIPE_CARD_PRESENT", $arrval, $conf->global->STRIPE_CARD_PRESENT);
}
print '</td></tr>';
}
// Locations for Stripe Terminal
if ($conf->global->MAIN_FEATURES_LEVEL >= 2) { // TODO Not used by current code
print '<tr class="oddeven"><td>';
print $langs->trans("STRIPE_LOCATION").'</td><td>';
$service = 'StripeTest';
$servicestatus = 0;
if (!empty($conf->global->STRIPE_LIVE) && !GETPOST('forcesandbox', 'alpha')) {
$service = 'StripeLive';
$servicestatus = 1;
}
global $stripearrayofkeysbyenv;
$site_account = $stripearrayofkeysbyenv[$servicestatus]['secret_key'];
\Stripe\Stripe::setApiKey($site_account);
if (!empty($conf->stripe->enabled) && (empty($conf->global->STRIPE_LIVE) || GETPOST('forcesandbox', 'alpha'))) {
$service = 'StripeTest';
$servicestatus = '0';
dol_htmloutput_mesg($langs->trans('YouAreCurrentlyInSandboxMode', 'Stripe'), '', 'warning');
} else {
$service = 'StripeLive';
$servicestatus = '1';
}
$stripe = new Stripe($db);
$stripeacc = $stripe->getStripeAccount($service);
if ($stripeacc) {
$locations = \Stripe\Terminal\Location::all('', array("stripe_account" => $stripeacc));
} else {
$locations = \Stripe\Terminal\Location::all();
}
$location = array();
$location[""] = $langs->trans("EmptyLocation");
foreach ($locations as $locations) {
$location[$locations->id] = $locations->display_name;
}
print $form->selectarray("STRIPE_LOCATION", $location, $conf->global->STRIPE_LOCATION);
print '</td></tr>';
}
// Activate Payment Request API
if ($conf->global->MAIN_FEATURES_LEVEL >= 2) { // TODO Not used by current code
print '<tr class="oddeven"><td>';

124
htdocs/stripe/ajax/ajax.php Normal file
View File

@ -0,0 +1,124 @@
<?php
/* Copyright (C) 2021 Thibault FOUCART <support@ptibogxiv.net>
*
* 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
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
/**
* \file htdocs/stripe/ajax/ajax.php
* \brief Ajax action for Stipe ie: Terminal
*/
if (!defined('NOCSRFCHECK')) {
define('NOCSRFCHECK', '1');
}
if (!defined('NOTOKENRENEWAL')) {
define('NOTOKENRENEWAL', '1');
}
if (!defined('NOREQUIREMENU')) {
define('NOREQUIREMENU', '1');
}
if (!defined('NOREQUIREHTML')) {
define('NOREQUIREHTML', '1');
}
if (!defined('NOREQUIREAJAX')) {
define('NOREQUIREAJAX', '1');
}
if (!defined('NOBROWSERNOTIF')) {
define('NOBROWSERNOTIF', '1');
}
require '../../main.inc.php'; // Load $user and permissions
require_once DOL_DOCUMENT_ROOT.'/includes/stripe/stripe-php/init.php';
require_once DOL_DOCUMENT_ROOT.'/stripe/class/stripe.class.php';
require_once DOL_DOCUMENT_ROOT.'/compta/facture/class/facture.class.php';
$action = GETPOST('action', 'aZ09');
$location = GETPOST('location', 'alphanohtml');
$stripeacc = GETPOST('stripeacc', 'alphanohtml');
$servicestatus = GETPOST('servicestatus', 'int');
$amount = GETPOST('amount', 'int');
if (empty($user->rights->takepos->run)) {
accessforbidden();
}
/*
* View
*/
if ($action == 'getConnexionToken') {
try {
// Be sure to authenticate the endpoint for creating connection tokens.
// Force to use the correct API key
global $stripearrayofkeysbyenv;
\Stripe\Stripe::setApiKey($stripearrayofkeysbyenv[$servicestatus]['secret_key']);
// The ConnectionToken's secret lets you connect to any Stripe Terminal reader
// and take payments with your Stripe account.
$array = array();
if (isset($location) && !empty($location)) $array['location'] = $location;
if (empty($stripeacc)) { // If the Stripe connect account not set, we use common API usage
$connectionToken = \Stripe\Terminal\ConnectionToken::create($array);
} else {
$connectionToken = \Stripe\Terminal\ConnectionToken::create($array, array("stripe_account" => $stripeacc));
}
echo json_encode(array('secret' => $connectionToken->secret));
} catch (Error $e) {
http_response_code(500);
echo json_encode(['error' => $e->getMessage()]);
}
} elseif ($action == 'createPaymentIntent') {
try {
$json_str = file_get_contents('php://input');
$json_obj = json_decode($json_str);
// For Terminal payments, the 'payment_method_types' parameter must include
// 'card_present' and the 'capture_method' must be set to 'manual'
$object = new Facture($db);
$object->fetch($json_obj->invoiceid);
$object->fetch_thirdparty();
$fulltag='INV='.$object->id.'.CUS='.$object->thirdparty->id;
$tag=null;
$fulltag=dol_string_unaccent($fulltag);
$stripe = new Stripe($db);
$customer = $stripe->customerStripe($object->thirdparty, $stripeacc, $servicestatus, 1);
$intent = $stripe->getPaymentIntent($json_obj->amount, $object->multicurrency_code, null, 'Stripe payment: '.$fulltag.(is_object($object)?' ref='.$object->ref:''), $object, $customer, $stripeacc, $servicestatus, 1, 'terminal', false, null, 0, 1);
echo json_encode(array('client_secret' => $intent->client_secret));
} catch (Error $e) {
http_response_code(500);
echo json_encode(['error' => $e->getMessage()]);
}
} elseif ($action == 'capturePaymentIntent') {
try {
// retrieve JSON from POST body
$json_str = file_get_contents('php://input');
$json_obj = json_decode($json_str);
if (empty($stripeacc)) { // If the Stripe connect account not set, we use common API usage
$intent = \Stripe\PaymentIntent::retrieve($json_obj->id);
} else {
$intent = \Stripe\PaymentIntent::retrieve($json_obj->id, array("stripe_account" => $stripeacc));
}
$intent = $intent->capture();
echo json_encode($intent);
} catch (Error $e) {
http_response_code(500);
echo json_encode(['error' => $e->getMessage()]);
}
}

View File

@ -290,6 +290,34 @@ class Stripe extends CommonObject
return $stripepaymentmethod;
}
/**
* Get the Stripe reader Object from its ID
*
* @param string $reader Reader 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\Terminal\Reader|null Stripe Reader or null if not found
*/
public function getSelectedReader($reader, $key = '', $status = 0)
{
$selectedreader = null;
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
$selectedreader = \Stripe\Terminal\Reader::retrieve(''.$reader.'');
} else {
$stripepaymentmethod = \Stripe\Terminal\Reader::retrieve(''.$reader.'', array("stripe_account" => $key));
}
} catch (Exception $e) {
$this->error = $e->getMessage();
}
return $selectedreader;
}
/**
* Get the Stripe payment intent. Create it with confirmnow=false
* Warning. If a payment was tried and failed, a payment intent was created.
@ -350,7 +378,7 @@ class Stripe extends CommonObject
$paymentintent = null;
if (is_object($object) && !empty($conf->global->STRIPE_REUSE_EXISTING_INTENT_IF_FOUND)) {
if (is_object($object) && !empty($conf->global->STRIPE_REUSE_EXISTING_INTENT_IF_FOUND) && empty($conf->global->STRIPE_CARD_PRESENT)) {
// Warning. If a payment was tried and failed, a payment intent was created.
// But if we change something on object to pay (amount or other that does not change the idempotency key), reusing same payment intent is not allowed by Stripe.
// Recommended solution is to recreate a new payment intent each time we need one (old one will be automatically closed by Stripe after a delay), Stripe will
@ -424,6 +452,9 @@ class Stripe extends CommonObject
if (!empty($conf->global->STRIPE_SOFORT)) {
$paymentmethodtypes[] = "sofort";
}
if (!empty($conf->global->STRIPE_CARD_PRESENT) && $mode == 'terminal') {
$paymentmethodtypes = array("card_present");
}
$dataforintent = array(
"confirm" => $confirmnow, // Do not confirm immediatly during creation of intent
@ -456,6 +487,11 @@ class Stripe extends CommonObject
if (!empty($conf->global->STRIPE_KLARNA)) {
unset($dataforintent['setup_future_usage']);
}
if (!empty($conf->global->STRIPE_CARD_PRESENT) && $mode == 'terminal') {
unset($dataforintent['setup_future_usage']);
$dataforintent["capture_method"] = "manual";
$dataforintent["confirmation_method"] = "manual";
}
if (!is_null($payment_method)) {
$dataforintent["payment_method"] = $payment_method;
$description .= ' - '.$payment_method;
@ -607,6 +643,9 @@ class Stripe extends CommonObject
if (!empty($conf->global->STRIPE_BANCONTACT)) {
$paymentmethodtypes[] = "bancontact";
}
if (!empty($conf->global->STRIPE_KLARNA)) {
$paymentmethodtypes[] = "klarna";
}
if (!empty($conf->global->STRIPE_IDEAL)) {
$paymentmethodtypes[] = "ideal";
}

View File

@ -1,6 +1,7 @@
<?php
/* Copyright (C) 2008-2011 Laurent Destailleur <eldy@users.sourceforge.net>
* Copyright (C) 2011-2017 Juanjo Menent <jmenent@2byte.es>
* Copyright (C) 2021 Thibault FOUCART <support@ptibogxiv.net>
*
* 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
@ -28,6 +29,7 @@ require_once DOL_DOCUMENT_ROOT.'/product/class/html.formproduct.class.php';
require_once DOL_DOCUMENT_ROOT.'/core/lib/pdf.lib.php';
require_once DOL_DOCUMENT_ROOT.'/categories/class/categorie.class.php';
require_once DOL_DOCUMENT_ROOT."/core/lib/takepos.lib.php";
require_once DOL_DOCUMENT_ROOT.'/stripe/class/stripe.class.php';
$terminal = GETPOST('terminal', 'int');
// If socid provided by ajax company selector
@ -73,6 +75,9 @@ if (GETPOST('action', 'alpha') == 'set') {
$res = dolibarr_set_const($db, "CASHDESK_ID_BANKACCOUNT_CASH".$terminaltouse, (GETPOST('CASHDESK_ID_BANKACCOUNT_CASH'.$terminaltouse, 'alpha') > 0 ? GETPOST('CASHDESK_ID_BANKACCOUNT_CASH'.$terminaltouse, 'alpha') : ''), 'chaine', 0, '', $conf->entity);
$res = dolibarr_set_const($db, "CASHDESK_ID_BANKACCOUNT_CHEQUE".$terminaltouse, (GETPOST('CASHDESK_ID_BANKACCOUNT_CHEQUE'.$terminaltouse, 'alpha') > 0 ? GETPOST('CASHDESK_ID_BANKACCOUNT_CHEQUE'.$terminaltouse, 'alpha') : ''), 'chaine', 0, '', $conf->entity);
$res = dolibarr_set_const($db, "CASHDESK_ID_BANKACCOUNT_CB".$terminaltouse, (GETPOST('CASHDESK_ID_BANKACCOUNT_CB'.$terminaltouse, 'alpha') > 0 ? GETPOST('CASHDESK_ID_BANKACCOUNT_CB'.$terminaltouse, 'alpha') : ''), 'chaine', 0, '', $conf->entity);
if (!empty($conf->stripe->enabled) && !empty($conf->global->STRIPE_CARD_PRESENT)) {
$res = dolibarr_set_const($db, "CASHDESK_ID_BANKACCOUNT_STRIPETERMINAL".$terminaltouse, GETPOST('CASHDESK_ID_BANKACCOUNT_STRIPETERMINAL'.$terminaltouse, 'alpha'), 'chaine', 0, '', $conf->entity);
}
if (!empty($conf->global->TAKEPOS_ENABLE_SUMUP)) {
$res = dolibarr_set_const($db, "CASHDESK_ID_BANKACCOUNT_SUMUP".$terminaltouse, (GETPOST('CASHDESK_ID_BANKACCOUNT_SUMUP'.$terminaltouse, 'alpha') > 0 ? GETPOST('CASHDESK_ID_BANKACCOUNT_SUMUP'.$terminaltouse, 'alpha') : ''), 'chaine', 0, '', $conf->entity);
}
@ -174,6 +179,44 @@ if (!empty($conf->banque->enabled)) {
$atleastonefound++;
}
print '</td></tr>';
if (!empty($conf->stripe->enabled) && !empty($conf->global->STRIPE_CARD_PRESENT)) {
print '<tr class="oddeven"><td>'.$langs->trans("CashDeskBankAccountForStripeTerminal").'</td>'; // Force Stripe Terminal
print '<td>';
$service = 'StripeTest';
$servicestatus = 0;
if (!empty($conf->global->STRIPE_LIVE) && !GETPOST('forcesandbox', 'alpha')) {
$service = 'StripeLive';
$servicestatus = 1;
}
global $stripearrayofkeysbyenv;
$site_account = $stripearrayofkeysbyenv[$servicestatus]['secret_key'];
\Stripe\Stripe::setApiKey($site_account);
if (!empty($conf->stripe->enabled) && (empty($conf->global->STRIPE_LIVE) || GETPOST('forcesandbox', 'alpha'))) {
$service = 'StripeTest';
$servicestatus = '0';
dol_htmloutput_mesg($langs->trans('YouAreCurrentlyInSandboxMode', 'Stripe'), '', 'warning');
} else {
$service = 'StripeLive';
$servicestatus = '1';
}
$stripe = new Stripe($db);
$stripeacc = $stripe->getStripeAccount($service);
if ($stripeacc) {
$readers = \Stripe\Terminal\Reader::all('', array("location" => $conf->global->STRIPE_LOCATION, "stripe_account" => $stripeacc));
} else {
$readers = \Stripe\Terminal\Reader::all('', array("location" => $conf->global->STRIPE_LOCATION));
}
$reader = array();
$reader[""] = $langs->trans("NoReader");
foreach ($readers as $readers) {
$reader[$reader->id] = $readers->label.' ('.$readers->status.')';
}
print $form->selectarray('CASHDESK_ID_BANKACCOUNT_STRIPETERMINAL'.$terminaltouse, $reader, $conf->global->{'CASHDESK_ID_BANKACCOUNT_STRIPETERMINAL'.$terminaltouse});
print '</td></tr>';
}
if ($conf->global->TAKEPOS_ENABLE_SUMUP) {
print '<tr class="oddeven"><td>'.$langs->trans("CashDeskBankAccountForSumup").'</td>';
print '<td>';

View File

@ -1,5 +1,6 @@
<?php
/* Copyright (C) 2018 Andreu Bisquerra <jove@bisquerra.com>
* Copyright (C) 2021 Thibault FOUCART <support@ptibogxiv.net>
*
* 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
@ -40,6 +41,7 @@ if (!defined('NOREQUIREHTML')) {
require '../main.inc.php'; // Load $user and permissions
require_once DOL_DOCUMENT_ROOT.'/compta/facture/class/facture.class.php';
require_once DOL_DOCUMENT_ROOT.'/stripe/class/stripe.class.php';
$langs->loadLangs(array("main", "bills", "cashdesk", "banks"));
@ -51,11 +53,60 @@ if (empty($user->rights->takepos->run)) {
accessforbidden();
}
if (!empty($conf->stripe->enabled)) {
$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;
$site_account = $stripearrayofkeysbyenv[$servicestatus]['publishable_key'];
$stripe = new Stripe($db);
$stripeacc = $stripe->getStripeAccount($service); // Get Stripe OAuth connect account (no remote access to Stripe here)
$stripecu = $stripe->getStripeCustomerAccount($object->id, $servicestatus, $site_account); // Get remote Stripe customer 'cus_...' (no remote access to Stripe here)
$keyforstripeterminalbank = "CASHDESK_ID_BANKACCOUNT_STRIPETERMINAL".$_SESSION["takeposterminal"];
?>
<script src="https://js.stripe.com/terminal/v1/"></script>
<script>
var terminal = StripeTerminal.create({
onFetchConnectionToken: fetchConnectionToken,
onUnexpectedReaderDisconnect: unexpectedDisconnect,
});
function unexpectedDisconnect() {
// In this function, your app should notify the user that the reader disconnected.
// You can also include a way to attempt to reconnect to a reader.
console.log("Disconnected from reader")
}
function fetchConnectionToken() {
<?php
$urlconnexiontoken = DOL_URL_ROOT.'/stripe/ajax/ajax.php?action=getConnexionToken&servicestatus='.$servicestatus;
if (!empty($conf->global->STRIPE_LOCATION)) $urlconnexiontoken .= '&location='.$conf->global->STRIPE_LOCATION;
if (!empty($stripeacc)) $urlconnexiontoken .= '&stripeacc='.$stripeacc;
?>
// Do not cache or hardcode the ConnectionToken. The SDK manages the ConnectionToken's lifecycle.
return fetch('<?php echo $urlconnexiontoken; ?>', { method: "POST" })
.then(function(response) {
return response.json();
})
.then(function(data) {
return data.secret;
});
}
</script>
<?php }
/*
* View
*/
if (!empty($conf->stripe->enabled) && isset($keyforstripeterminalbank) && (empty($conf->global->STRIPE_LIVE) || GETPOST('forcesandbox', 'alpha'))) {
dol_htmloutput_mesg($langs->trans('YouAreCurrentlyInSandboxMode', 'Stripe'), '', 'warning', 1);
}
$invoice = new Facture($db);
if ($invoiceid > 0) {
$invoice->fetch($invoiceid);
@ -73,6 +124,57 @@ if ($invoiceid > 0) {
}
}
?>
<script>
<?php
if ($invoice->type != $invoice::TYPE_CREDIT_NOTE) {
if (empty($conf->global->$keyforstripeterminalbank)) { ?>
const config = {simulated: <?php if (empty($servicestatus) && !empty($conf->global->STRIPE_TERMINAL_SIMULATED)) { ?> true <?php } else { ?> false <?php } ?>
<?php if (!empty($conf->global->STRIPE_LOCATION)) { ?>, location: '<?php echo $conf->global->STRIPE_LOCATION; ?>'<?php } ?>}
terminal.discoverReaders(config).then(function(discoverResult) {
if (discoverResult.error) {
console.log('Failed to discover: ', discoverResult.error);
} else if (discoverResult.discoveredReaders.length === 0) {
console.log('No available readers.');
} else {
// You should show the list of discoveredReaders to the
// cashier here and let them select which to connect to (see below).
selectedReader = discoverResult.discoveredReaders[0];
//console.log('terminal.discoverReaders', selectedReader); // only active for development
terminal.connectReader(selectedReader).then(function(connectResult) {
if (connectResult.error) {
document.getElementById("card-present-alert").innerHTML = '<div class="error">'+connectResult.error.message+'</div>';
console.log('Failed to connect: ', connectResult.error);
} else {
document.getElementById("card-present-alert").innerHTML = '';
console.log('Connected to reader: ', connectResult.reader.label);
if (document.getElementById("StripeTerminal")) {
document.getElementById("StripeTerminal").innerHTML = '<button type="button" class="calcbutton2" onclick="ValidateStripeTerminal();"><span class="fa fa-2x fa-credit-card iconwithlabel"></span><br>'+connectResult.reader.label+'</button>';
}
}
});
}
});
<?php } else { ?>
terminal.connectReader(<?php echo json_encode($stripe->getSelectedReader($conf->global->$keyforstripeterminalbank, $stripeacc, $servicestatus)); ?>).then(function(connectResult) {
if (connectResult.error) {
document.getElementById("card-present-alert").innerHTML = '<div class="error clearboth">'+connectResult.error.message+'</div>';
console.log('Failed to connect: ', connectResult.error);
} else {
document.getElementById("card-present-alert").innerHTML = '';
console.log('Connected to reader: ', connectResult.reader.label);
if (document.getElementById("StripeTerminal")) {
document.getElementById("StripeTerminal").innerHTML = '<button type="button" class="calcbutton2" onclick="ValidateStripeTerminal();"><span class="fa fa-2x fa-credit-card iconwithlabel"></span><br>'+connectResult.reader.label+'</button>';
}
}
});
<?php } } ?>
</script>
<?php
$arrayofcss = array('/takepos/css/pos.css.php');
$arrayofjs = array();
@ -223,6 +325,112 @@ if ($conf->global->TAKEPOS_NUMPAD == 0) {
});
}
function fetchPaymentIntentClientSecret(amount, invoiceid) {
const bodyContent = JSON.stringify({ amount : amount, invoiceid : invoiceid });
<?php
$urlpaymentintent = DOL_URL_ROOT.'/stripe/ajax/ajax.php?action=createPaymentIntent&servicestatus='.$servicestatus;
if (!empty($stripeacc)) $urlpaymentintent .= '&stripeacc='.$stripeacc;
?>
return fetch('<?php echo $urlpaymentintent; ?>', {
method: "POST",
headers: {
'Content-Type': 'application/json'
},
body: bodyContent
})
.then(function(response) {
return response.json();
})
.then(function(data) {
return data.client_secret;
});
}
function capturePaymentIntent(paymentIntentId) {
const bodyContent = JSON.stringify({"id": paymentIntentId})
<?php
$urlpaymentintent = DOL_URL_ROOT.'/stripe/ajax/ajax.php?action=capturePaymentIntent&servicestatus='.$servicestatus;
if (!empty($stripeacc)) $urlpaymentintent .= '&stripeacc='.$stripeacc;
?>
return fetch('<?php echo $urlpaymentintent; ?>', {
method: "POST",
headers: {
'Content-Type': 'application/json'
},
body: bodyContent
})
.then(function(response) {
return response.json();
})
.then(function(data) {
return data.client_secret;
});
}
function ValidateStripeTerminal() {
console.log("Launch ValidateStripeTerminal");
var invoiceid = <?php echo($invoiceid > 0 ? $invoiceid : 0); ?>;
var accountid = $("#selectaccountid").val();
var amountpayed = $("#change1").val();
var excess = $("#change2").val();
if (amountpayed > <?php echo $invoice->getRemainToPay(); ?>) {
amountpayed = <?php echo $invoice->getRemainToPay(); ?>;
}
if (amountpayed == 0) {
amountpayed = <?php echo $invoice->getRemainToPay(); ?>;
}
console.log("Pay with terminal ", amountpayed);
fetchPaymentIntentClientSecret(amountpayed, invoiceid).then(function(client_secret) {
<?php if (empty($servicestatus) && !empty($conf->global->STRIPE_TERMINAL_SIMULATED)) { ?>
terminal.setSimulatorConfiguration({testCardNumber: '<?php echo $conf->global->STRIPE_TERMINAL_SIMULATED; ?>'});
<?php } ?>
document.getElementById("card-present-alert").innerHTML = '<div class="warning clearboth"><?php echo $langs->trans('PaymentSendToStripeTerminal'); ?></div>';
terminal.collectPaymentMethod(client_secret).then(function(result) {
if (result.error) {
// Placeholder for handling result.error
document.getElementById("card-present-alert").innerHTML = '<div class="error clearboth">'+result.error.message+'</div>';
} else {
document.getElementById("card-present-alert").innerHTML = '<div class="warning clearboth"><?php echo $langs->trans('PaymentBeingProcessed'); ?></div>';
console.log('terminal.collectPaymentMethod', result.paymentIntent);
terminal.processPayment(result.paymentIntent).then(function(result) {
if (result.error) {
document.getElementById("card-present-alert").innerHTML = '<div class="error clearboth">'+result.error.message+'</div>';
console.log(result.error)
} else if (result.paymentIntent) {
paymentIntentId = result.paymentIntent.id;
console.log('terminal.processPayment', result.paymentIntent);
capturePaymentIntent(paymentIntentId).then(function(client_secret) {
if (result.error) {
// Placeholder for handling result.error
document.getElementById("card-present-alert").innerHTML = '<div class="error clearboth">'+result.error.message+'</div>';
console.log("error when capturing paymentIntent", result.error);
} else {
document.getElementById("card-present-alert").innerHTML = '<div class="warning clearboth"><?php echo $langs->trans('PaymentValidated'); ?></div>';
console.log("Capture paymentIntent successfull "+paymentIntentId);
parent.$("#poslines").load("invoice.php?place=<?php echo $place; ?>&action=valid&pay=CB&amount="+amountpayed+"&excess="+excess+"&invoiceid="+invoiceid+"&accountid="+accountid, function() {
if (amountpayed > <?php echo $remaintopay; ?> || amountpayed == <?php echo $remaintopay; ?> || amountpayed==0 ) {
console.log("Close popup");
parent.$.colorbox.close();
}
else {
console.log("Amount is not comple, so we do NOT close popup and reload it.");
location.reload();
}
});
}
});
}
});
}
});
});
}
function ValidateSumup() {
console.log("Launch ValidateSumup");
<?php $_SESSION['SMP_CURRENT_PAYMENT'] = "NEW" ?>
@ -271,7 +479,7 @@ if (!empty($conf->global->TAKEPOS_CUSTOMER_DISPLAY)) {
?>
</script>
<div style="position:relative; padding-top: 20px; left:5%; height:150px; width:90%;">
<div style="position:relative; padding-top: 20px; left:5%; height:140px; width:90%;">
<div class="paymentbordline paymentbordlinetotal center">
<span class="takepospay colorwhite"><?php echo $langs->trans('TotalTTC'); ?>: <span id="totaldisplay" class="colorwhite"><?php echo price($invoice->total_ttc, 1, '', 1, -1, -1, $invoice->multicurrency_code); ?></span></span>
</div>
@ -299,7 +507,6 @@ if (!empty($conf->global->TAKEPOS_CUSTOMER_DISPLAY)) {
}
?>
</div>
<div style="position:absolute; left:5%; height:52%; width:90%;">
<?php
$action_buttons = array(
@ -317,7 +524,11 @@ $action_buttons = array(
),
);
$numpad = $conf->global->TAKEPOS_NUMPAD;
if (!empty($conf->stripe->enabled) && isset($keyforstripeterminalbank) && !empty($conf->global->STRIPE_CARD_PRESENT)) {
print '<span id="card-present-alert">';
dol_htmloutput_mesg($langs->trans('ConnectingToStripeTerminal', 'Stripe'), '', 'warning', 1);
print '</span>';
}
print '<button type="button" class="calcbutton" onclick="addreceived('.($numpad == 0 ? '7' : '10').');">'.($numpad == 0 ? '7' : '10').'</button>';
print '<button type="button" class="calcbutton" onclick="addreceived('.($numpad == 0 ? '8' : '20').');">'.($numpad == 0 ? '8' : '20').'</button>';
print '<button type="button" class="calcbutton" onclick="addreceived('.($numpad == 0 ? '9' : '50').');">'.($numpad == 0 ? '9' : '50').'</button>';
@ -424,8 +635,18 @@ while ($i < count($arrayOfValidPaymentModes)) {
$i = $i + 1;
}
$keyforsumupbank = "CASHDESK_ID_BANKACCOUNT_SUMUP".$_SESSION["takeposterminal"];
if (!empty($conf->stripe->enabled) && isset($keyforstripeterminalbank) && !empty($conf->global->STRIPE_CARD_PRESENT)) {
$keyforstripeterminalbank = "CASHDESK_ID_BANKACCOUNT_STRIPETERMINAL".$_SESSION["takeposterminal"];
print '<span id="StripeTerminal"></span>';
if (!empty($conf->global->$keyforstripeterminalbank)) {
} else {
$langs->loadLangs(array("errors", "admin"));
//print '<button type="button" class="calcbutton2 disabled" title="'.$langs->trans("SetupNotComplete").'">TerminalOff</button>';
}
}
if ($conf->global->TAKEPOS_ENABLE_SUMUP) {
$keyforsumupbank = "CASHDESK_ID_BANKACCOUNT_SUMUP".$_SESSION["takeposterminal"];
if (!empty($conf->global->$keyforsumupbank)) {
print '<button type="button" class="calcbutton2" onclick="ValidateSumup();">Sumup</button>';
} else {