Debug payment SEPA from backoffice with Stripe
This commit is contained in:
parent
330f2307bd
commit
a384bdecdc
@ -807,13 +807,13 @@ if ($object->id > 0) {
|
||||
print '<td class="center">'.$langs->trans("User").'</td>';
|
||||
print '<td class="center">'.$langs->trans("Amount").'</td>';
|
||||
print '<td class="center">'.$langs->trans("DateProcess").'</td>';
|
||||
print '<td> </td>';
|
||||
if ($type == 'bank-transfer') {
|
||||
print '<td class="center">'.$langs->trans("BankTransferReceipt").'</td>';
|
||||
} else {
|
||||
print '<td class="center">'.$langs->trans("WithdrawalReceipt").'</td>';
|
||||
}
|
||||
print '<td> </td>';
|
||||
print '<td> </td>';
|
||||
print '</tr>';
|
||||
|
||||
$sql = "SELECT pfd.rowid, pfd.traite, pfd.date_demande as date_demande,";
|
||||
@ -864,9 +864,10 @@ if ($object->id > 0) {
|
||||
// Amount
|
||||
print '<td class="center"><span class="amount">'.price($obj->amount).'</span></td>';
|
||||
|
||||
// Ref of SEPA request
|
||||
// Date process
|
||||
print '<td class="center"><span class="opacitymedium">'.$langs->trans("OrderWaiting").'</span></td>';
|
||||
|
||||
// Link to make payment now
|
||||
print '<td>';
|
||||
if (!empty($conf->global->STRIPE_SEPA_DIRECT_DEBIT)) {
|
||||
$langs->load("stripe");
|
||||
@ -874,8 +875,10 @@ if ($object->id > 0) {
|
||||
}
|
||||
print '</td>';
|
||||
|
||||
//
|
||||
print '<td align="center">-</td>';
|
||||
|
||||
// Actions
|
||||
print '<td class="right">';
|
||||
print '<a href="'.$_SERVER['PHP_SELF'].'?id='.$object->id.'&action=delete&token='.newToken().'&did='.$obj->rowid.'&type='.$type.'">';
|
||||
print img_delete();
|
||||
@ -929,14 +932,21 @@ if ($object->id > 0) {
|
||||
|
||||
print '<tr class="oddeven">';
|
||||
|
||||
// Date
|
||||
print '<td class="left">'.dol_print_date($db->jdate($obj->date_demande), 'day')."</td>\n";
|
||||
|
||||
// User
|
||||
print '<td align="center">';
|
||||
print $tmpuser->getNomUrl(1, '', 0, 0, 0, 0, 'login');
|
||||
print '</td>';
|
||||
|
||||
// Amount
|
||||
print '<td class="center">'.price($obj->amount).'</td>';
|
||||
|
||||
// Date process
|
||||
print '<td class="center">'.dol_print_date($db->jdate($obj->date_traite), 'day')."</td>\n";
|
||||
|
||||
// Link to payment request done
|
||||
print '<td class="center">';
|
||||
if ($obj->fk_prelevement_bons > 0) {
|
||||
$withdrawreceipt = new BonPrelevement($db);
|
||||
@ -946,10 +956,10 @@ if ($object->id > 0) {
|
||||
}
|
||||
print "</td>\n";
|
||||
|
||||
//
|
||||
print '<td> </td>';
|
||||
|
||||
print '<td class="center">'.dol_print_date($db->jdate($obj->date_traite), 'day')."</td>\n";
|
||||
|
||||
// Actions
|
||||
print '<td> </td>';
|
||||
|
||||
print "</tr>\n";
|
||||
|
||||
@ -865,7 +865,7 @@ abstract class CommonInvoice extends CommonObject
|
||||
|
||||
|
||||
/**
|
||||
* Create a withdrawal request for a direct debit order or a credit transfer order.
|
||||
* Create a withdrawal request at Stripe 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
|
||||
@ -900,6 +900,7 @@ abstract class CommonInvoice extends CommonObject
|
||||
|
||||
$sql = "SELECT rowid, date_demande, amount, fk_facture, fk_facture_fourn";
|
||||
$sql .= " FROM ".$this->db->prefix()."prelevement_demande";
|
||||
$sql .= " AND fk_facture = ".((int) $this->fk_facture); // Add a protection to not pay another invoice than current one
|
||||
$sql .= " WHERE rowid = ".((int) $did);
|
||||
|
||||
dol_syslog(get_class($this)."::makeStripeSepaRequest 1", LOG_DEBUG);
|
||||
@ -1035,9 +1036,9 @@ abstract class CommonInvoice extends CommonObject
|
||||
}
|
||||
|
||||
|
||||
dol_syslog("makeStripeSepaRequest get stripe account", LOG_DEBUG);
|
||||
dol_syslog("makeStripeSepaRequest get stripe connet account", LOG_DEBUG);
|
||||
$stripeacc = $stripe->getStripeAccount($service, $this->socid); // Get Stripe OAuth connect account if it exists (no network access here)
|
||||
dol_syslog("makeStripeSepaRequest get stripe account return " . json_encode($stripeacc), LOG_DEBUG);
|
||||
dol_syslog("makeStripeSepaRequest get stripe connect account return " . json_encode($stripeacc), LOG_DEBUG);
|
||||
|
||||
if ($foundalternativestripeaccount) {
|
||||
if (empty($stripeacc)) { // If the Stripe connect account not set, we use common API usage
|
||||
@ -1072,101 +1073,64 @@ abstract class CommonInvoice extends CommonObject
|
||||
}
|
||||
|
||||
if (!$error) { // Payment was not canceled
|
||||
//erics card or sepa ?
|
||||
$sepaMode = false;
|
||||
$stripecard = null;
|
||||
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)
|
||||
if ($stripecard) { // Can be src_... (for sepa) - Other card_... (old mode) or pm_... (new mode) should not happen here.
|
||||
$FULLTAG = 'INV=' . $this->id . '-CUS=' . $thirdparty->id;
|
||||
$description = 'Stripe payment from doTakePaymentStripeForThirdparty: ' . $FULLTAG . ' ref=' . $this->ref;
|
||||
$description = 'Stripe payment from makeStripeSepaRequest: ' . $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);
|
||||
// Using new SCA method
|
||||
dol_syslog("* Create payment on SEPA " . $stripecard->id . ", amounttopay=" . $amounttopay . ", amountstripe=" . $amountstripe . ", FULLTAG=" . $FULLTAG, LOG_DEBUG);
|
||||
|
||||
$ipaddress = getUserRemoteIP();
|
||||
// Create payment intent and charge payment (confirmnow = true)
|
||||
$paymentintent = $stripe->getPaymentIntent($amounttopay, $currency, $FULLTAG, $description, $this, $customer->id, $stripeacc, $servicestatus, 0, 'automatic', true, $stripecard->id, 1);
|
||||
|
||||
$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'];
|
||||
$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);
|
||||
|
||||
$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);
|
||||
}
|
||||
$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);
|
||||
|
||||
// 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;
|
||||
$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);
|
||||
dol_syslog('Failed to charge payment mode ' . $stripecard->id . ' stripefailurecode=' . $stripefailurecode . ' stripefailuremessage=' . $stripefailuremessage . ' stripefailuredeclinecode=' . $stripefailuredeclinecode, LOG_WARNING);
|
||||
|
||||
// Save a stripe payment was in error
|
||||
$this->stripechargeerror++;
|
||||
@ -1202,20 +1166,20 @@ abstract class CommonInvoice extends CommonObject
|
||||
$errmsg .= ($stripefailuredeclinecode ? ' - ' . $stripefailuredeclinecode : '');
|
||||
}
|
||||
|
||||
$description = 'Stripe payment ERROR from doTakePaymentStripeForThirdparty: ' . $FULLTAG;
|
||||
$description = 'Stripe payment ERROR from makeStripeSepaRequest: ' . $FULLTAG;
|
||||
$postactionmessages[] = $errmsg . ' (' . $stripearrayofkeys['publishable_key'] . ')';
|
||||
$this->errors[] = $errmsg;
|
||||
} else {
|
||||
dol_syslog('Successfuly charge card ' . $stripecard->id);
|
||||
dol_syslog('Successfuly charge direct debit ' . $stripecard->id);
|
||||
|
||||
$postactionmessages[] = 'Success to charge card (' . $charge->id . ' with ' . $stripearrayofkeys['publishable_key'] . ')';
|
||||
$postactionmessages[] = 'Success to charge direct debit (' . $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;
|
||||
$description = 'Stripe payment OK (' . $charge->id . ') from makeStripeSepaRequest: ' . $FULLTAG;
|
||||
|
||||
$db = $this->db;
|
||||
|
||||
@ -1300,13 +1264,8 @@ abstract class CommonInvoice extends CommonObject
|
||||
if (!$errorforinvoice && isModEnabled('banque')) {
|
||||
dol_syslog('* Add payment to bank');
|
||||
|
||||
// The bank used is the one defined into Stripe setup
|
||||
$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;
|
||||
}
|
||||
@ -1323,7 +1282,7 @@ abstract class CommonInvoice extends CommonObject
|
||||
$error++;
|
||||
$errorforinvoice++;
|
||||
} else {
|
||||
$postactionmessages[] = 'Bank transaction of payment created (by doTakePaymentStripeForThirdparty)';
|
||||
$postactionmessages[] = 'Bank transaction of payment created (by makeStripeSepaRequest)';
|
||||
}
|
||||
} else {
|
||||
$postactionmessages[] = 'Setup of bank account to use in module ' . $paymentmethod . ' was not set. No way to record the payment.';
|
||||
@ -1334,55 +1293,24 @@ abstract class CommonInvoice extends CommonObject
|
||||
}
|
||||
|
||||
if ($ispostactionok < 1) {
|
||||
$description = 'Stripe payment OK (' . $charge->id . ' - ' . $amounttopay . ' ' . $conf->currency . ') but post action KO from doTakePaymentStripeForThirdparty: ' . $FULLTAG;
|
||||
$description = 'Stripe payment OK (' . $charge->id . ' - ' . $amounttopay . ' ' . $conf->currency . ') but post action KO from makeStripeSepaRequest: ' . $FULLTAG;
|
||||
} else {
|
||||
$description = 'Stripe payment+post action OK (' . $charge->id . ' - ' . $amounttopay . ' ' . $conf->currency . ') from doTakePaymentStripeForThirdparty: ' . $FULLTAG;
|
||||
$description = 'Stripe payment+post action OK (' . $charge->id . ' - ' . $amounttopay . ' ' . $conf->currency . ') from makeStripeSepaRequest: ' . $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 = '';
|
||||
}
|
||||
$actioncode = '';
|
||||
$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'] . ')';
|
||||
|
||||
dol_syslog("No direct debit payment method found for this stripe customer " . $customer->id, LOG_WARNING);
|
||||
$this->errors[] = 'Failed to get direct debit payment method for stripe customer = ' . $customer->id;
|
||||
$object = $invoice;
|
||||
|
||||
$actioncode = 'PAYMENT_STRIPE_KO';
|
||||
$actioncode = '';
|
||||
$extraparams = '';
|
||||
}
|
||||
} else {
|
||||
@ -1427,6 +1355,7 @@ abstract class CommonInvoice extends CommonObject
|
||||
$extraparams = '';
|
||||
}
|
||||
|
||||
/*
|
||||
// Send email + create action after
|
||||
if ($sendemailtocustomer && $labeltouse) {
|
||||
dol_syslog("* Send email with result of payment - " . $labeltouse);
|
||||
@ -1537,6 +1466,7 @@ abstract class CommonInvoice extends CommonObject
|
||||
}
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
if ($description) {
|
||||
dol_syslog("* Record event for payment result - " . $description);
|
||||
@ -1588,18 +1518,12 @@ abstract class CommonInvoice extends CommonObject
|
||||
$this->errors[] = "Remain to pay is null for the invoice " . $this->id . " " . $this->ref . ". Why is the invoice not classified 'Paid' ?";
|
||||
}
|
||||
|
||||
$sql = "INSERT INTO ".MAIN_DB_PREFIX."prelevement_demande(";
|
||||
$sql .= "fk_facture, ";
|
||||
$sql .= " amount, date_demande, fk_user_demande, ext_payment_id, ext_payment_site, sourcetype, entity)";
|
||||
$sql .= " VALUES (".$this->id;
|
||||
$sql .= ",".((float) price2num($amount));
|
||||
$sql .= ",'".$this->db->idate($now)."'";
|
||||
$sql .= ",".((int) $fuser->id);
|
||||
$sql .= ",'".$this->db->escape($stripe_id)."'";
|
||||
$sql .= ",'".$this->db->escape($stripe_uri)."'";
|
||||
$sql .= ",'".$this->db->escape($sourcetype)."'";
|
||||
$sql .= ",".$conf->entity;
|
||||
$sql .= ")";
|
||||
// TODO Create a prelevement_bon ?
|
||||
// For the moment no
|
||||
|
||||
// We must update the direct debit payment request as "done"
|
||||
$sql = "UPDATE".MAIN_DB_PREFIX."prelevement_demande SET traite = 1, date_traite = '".$this->db->idate(dol_now())."'";
|
||||
$sql .= "WHERE rowid = ".((int) $did);
|
||||
|
||||
dol_syslog(get_class($this)."::makeStripeSepaRequest", LOG_DEBUG);
|
||||
$resql = $this->db->query($sql);
|
||||
|
||||
Loading…
Reference in New Issue
Block a user