Skip to content
Code-Schnipsel Gruppen Projekte
Commit d0e2f2c6 erstellt von Patrick Müller's avatar Patrick Müller
Dateien durchsuchen

feat: handle declined authorizations for subscriptions

Übergeordneter d3a1a177
Keine zugehörigen Branchen gefunden
Keine zugehörigen Tags gefunden
Keine zugehörigen Merge Requests gefunden
......@@ -7,6 +7,8 @@
use QUI\ERP\Payments\Stripe\PaymentMethods\Recurring\Subscriptions;
use Stripe\Subscription as StripeSubscription;
use Stripe\Customer as StripeCustomer;
use Stripe\PaymentMethod as StripePaymentMethod;
use Stripe\Invoice as StripeInvoice;
/**
* Create a Stripe PaymentIntent
......@@ -32,8 +34,27 @@ function ($orderHash, $paymentMethodId, $resetPaymentMethod = null) {
// Create Stripe Subscription (and Plan if necessary)
$subscriptionId = $Payment->createSubscription($Order);
/**
* The process to re-set a payment method (e.g. if the user authentication failed) consists
* of the following steps:
*
* 1. Add newly generated PaymentMethod to the Stripe Customer
* 2. Set the PaymentMethod as the Customer default
* 3. Set the PaymentMethod as the Subscription default
* 4. Try to pay the latest Subscription Invoice -> This can fail initially if the new PaymentMethod requires
* additional authentication.
* 5. Confirm Subscription
*/
if (!empty($resetPaymentMethod)) {
$StripeCustomer = Subscriptions::createStripeCustomerFromQuiqqerUser($paymentMethodId);
$StripeCustomer = Subscriptions::createStripeCustomerFromQuiqqerUser(
$paymentMethodId,
$Order->getCustomer()
);
$StripePaymentMethod = StripePaymentMethod::retrieve($paymentMethodId);
$StripePaymentMethod->attach([
'customer' => $StripeCustomer->id
]);
StripeCustomer::update(
$StripeCustomer->id,
......@@ -50,6 +71,12 @@ function ($orderHash, $paymentMethodId, $resetPaymentMethod = null) {
'default_payment_method' => $paymentMethodId
]
);
try {
StripeInvoice::retrieve(Subscriptions::getLatestSubscriptionInvoiceId($subscriptionId))->pay();
} catch (\Exception $Exception) {
QUI\System\Log::writeDebugException($Exception);
}
}
return Subscriptions::confirmSubscription($subscriptionId);
......
......@@ -48,6 +48,9 @@ define('package/quiqqer/payment-stripe/bin/controls/Recurring/PaymentDisplay', [
this.getAttribute('paymentmethod'),
this.$StripeFormElement
).then(function (result) {
console.log(result);
if (result.error) {
self.$onStripeError(result.error);
return;
......
......@@ -45,8 +45,24 @@ class Subscriptions
*/
public static function createSubscription(AbstractOrder $Order)
{
$SystemUser = QUI::getUsers()->getSystemUser();
if ($Order->getPaymentDataEntry(BasePayment::ATTR_STRIPE_SUBSCRIPTION_ID)) {
return $Order->getPaymentDataEntry(BasePayment::ATTR_STRIPE_SUBSCRIPTION_ID);
$confirmData = self::confirmSubscription($Order->getPaymentDataEntry(BasePayment::ATTR_STRIPE_SUBSCRIPTION_ID));
switch ($confirmData['status']) {
/**
* If the Subscription could not be fully finalized and is expired ->
* delete it from the Order and create a new Subscription.
*/
case StripeSubscription::STATUS_INCOMPLETE_EXPIRED:
$Order->setPaymentData(BasePayment::ATTR_STRIPE_SUBSCRIPTION_ID, false);
$Order->update($SystemUser);
break;
default:
return $Order->getPaymentDataEntry(BasePayment::ATTR_STRIPE_SUBSCRIPTION_ID);
}
}
// Create Stripe billing plan
......@@ -57,7 +73,7 @@ public static function createSubscription(AbstractOrder $Order)
]));
$Order->setPaymentData(BasePayment::ATTR_STRIPE_BILLING_PLAN_ID, $billingPlanId);
$Order->update(QUI::getUsers()->getSystemUser());
$Order->update($SystemUser);
$paymentMethodId = $Order->getPaymentDataEntry(BasePayment::ATTR_STRIPE_PAYMENT_METHOD_ID);
......@@ -155,6 +171,27 @@ public static function confirmSubscription($subscriptionId)
return $data;
}
/**
* Get ID of latest Stripe Invoice of a Stripe Subscription
*
* @param string $subscriptionId
* @return string - Stripe Invoice ID
* @throws ApiErrorException
*/
public static function getLatestSubscriptionInvoiceId($subscriptionId)
{
Provider::setupApi();
$StripeSubscription = StripeSubscription::retrieve([
'id' => $subscriptionId,
'expand' => [
'latest_invoice'
]
]);
return $StripeSubscription->latest_invoice->id;
}
/**
* Bills the balance for an agreement based on an Invoice
*
......@@ -830,6 +867,7 @@ protected static function getSubscriptionData($subscriptionId)
* @param QUI\Users\User $User
* @return StripeCustomer
*
* @throws QUI\Exception
* @throws ApiErrorException
*/
public static function createStripeCustomerFromQuiqqerUser($paymentMethodId, $User = null)
......@@ -838,6 +876,11 @@ public static function createStripeCustomerFromQuiqqerUser($paymentMethodId, $Us
$User = QUI::getUserBySession();
}
// If ERPUser -> get QUIQQER User
if ($User instanceof QUI\ERP\User) {
$User = QUI::getUsers()->get($User->getId());
}
$stripeCustomerId = $User->getAttribute(BasePayment::USER_ATTR_STRIPE_CUSTOMER_ID);
if (!empty($stripeCustomerId)) {
......@@ -845,17 +888,20 @@ public static function createStripeCustomerFromQuiqqerUser($paymentMethodId, $Us
}
$quiqqerCustomerEmail = $User->getAttribute('email');
$userLocaleList = $User->getLocale()->getLocalesByLang($User->getLang());
$Customer = StripeCustomer::create([
'payment_method' => $paymentMethodId,
'invoice_settings' => [
'payment_method' => $paymentMethodId,
'invoice_settings' => [
'default_payment_method' => $paymentMethodId
],
'metadata' => [
'metadata' => [
'quiqqerUserId' => $User->getId()
],
'email' => $quiqqerCustomerEmail ?: '',
'description' => QUI::conf('globals', 'host')
'email' => $quiqqerCustomerEmail ?: '',
'description' => QUI::conf('globals', 'host'),
'preferred_locales' => [str_replace('_', '-', $userLocaleList[0])]
// transform strings like "de_DE" to "de-DE"
]);
try {
......
0% Lade oder .
You are about to add 0 people to the discussion. Proceed with caution.
Bearbeitung dieser Nachricht zuerst beenden!
Bitte registrieren oder zum Kommentieren