PluginProbe
FluentCart A New Era of eCommerce – Faster, Lighter, and Simpler / 1.6.5
FluentCart A New Era of eCommerce – Faster, Lighter, and Simpler v1.6.5
1.6.5 1.6.4 1.6.3 1.6.2 1.6.1 1.6.0 1.5.4 1.5.5 1.5.3 1.5.2 1.5.1 1.5.0 1.4.2 1.4.1 1.4.0 1.3.28 1.3.27 1.3.26 1.3.25 1.3.23 1.3.22 1.3.21 1.3.20 1.3.19 trunk All 48 releases
← All changes | app/Helpers/CheckoutProcessor.php +15 -10 1.6.4 → 1.6.5 View file →
@@ -486,19 +486,25 @@
486 486 ->where('order_id', $this->orderModel->id)
487 487 ->first();
488 488
489 489 if ($existingTransaction) {
490 + $meta = $existingTransaction->meta ?: [];
491 +
490 492 // Retry vs duplicate for gateway idempotency (PaymentInstance::getIdempotencySeed):
491 493 // re-submitting a pending transaction is a duplicate (keep attempt -> gateway
492 494 // dedupes); re-submitting a FAILED one is a retry (bump attempt -> fresh seed,
493 495 // never answered with the failed attempt's cached gateway response).
494 - $attempt = (int) Arr::get($existingTransaction->meta ?: [], 'payment_attempt', 0);
496 + $attempt = (int) Arr::get($meta, 'payment_attempt', 0);
495 497 if ($existingTransaction->status === Status::PAYMENT_FAILED) {
496 498 $attempt++;
497 499 }
500 +
501 + // The gateway object prepared last time (a Paddle transaction, a PayPal
502 + // order) is kept so the gateway can reuse it instead of creating another.
498 503 if ($attempt) {
499 - $transactionData['meta'] = ['payment_attempt' => $attempt];
504 + $meta['payment_attempt'] = $attempt;
500 505 }
506 + $transactionData['meta'] = $meta;
501 507
502 508 $existingTransaction->fill($transactionData);
503 509 $existingTransaction->save();
504 510 $this->transactionModel = $existingTransaction;
@@ -925,9 +931,9 @@
925 931 'line_meta' => Arr::get($item, 'line_meta', []),
926 932 'signup_fee' => $signupFee,
927 933 'signup_fee_tax' => $signupFeeTax,
928 934 'first_iteration_tax' => $firstIterationTax,
929 - 'is_recurring_coupon' => Arr::get($item, 'is_recurring_coupon', 'no'),
935 + 'recurring_discount' => $recurringDiscountAmount,
930 936 'total_discount' => $discountTotal
931 937 ]);
932 938
933 939 // removable upon discussion
@@ -951,13 +957,8 @@
951 957 'variation_type' => Arr::get($item, 'other_info.variation_type', '')
952 958 ]
953 959 ];
954 960
955 - // if recurring coupon is applied, we need to subtract the total discount from the recurring total
956 - if (Arr::get($item, 'is_recurring_coupon', 'no') === 'yes') {
957 - $subscriptionItem['recurring_total'] -= $discountTotal;
958 - }
959 -
960 961 $subscriptionData = wp_parse_args($subscriptionPricing, $subscriptionItem);
961 962 $paymentMethod = Arr::get($this->orderData, 'payment_method', '');
962 963
963 964 $collectionMethod = apply_filters('fluent_cart/subscription_collection_method_' . $paymentMethod, $this->determineCollectionMethod());
@@ -1251,8 +1252,9 @@
1251 1252 $signupFee = (int)($inputData['signup_fee'] ?? 0);
1252 1253 $signupFeeTax = (int)($inputData['signup_fee_tax'] ?? 0);
1253 1254 $firstIterationTax = (int)($inputData['first_iteration_tax'] ?? 0);
1254 1255 $totalDiscount = (int)($inputData['total_discount'] ?? 0);
1256 + $recurringDiscount = (int)($inputData['recurring_discount'] ?? 0);
1255 1257
1256 1258 // Determine if THIS subscription item is tax-inclusive (for behavior=3 mixed carts)
1257 1259 $taxBehavior = (int) Arr::get($inputData, 'tax_behavior', 0);
1258 1260 $itemInclusive = (bool) Arr::get($inputData, 'line_meta.tax_config.inclusive', false);
@@ -1292,10 +1294,13 @@
1292 1294 }
1293 1295 } else {
1294 1296 $firstCycleCost = $recurringAmount + $signupFee - $totalDiscount;
1295 1297
1296 - if (Arr::get($inputData, 'is_recurring_coupon', 'no') === 'yes') {
1297 - $recurringAmount -= $totalDiscount; // as now discount applied on recurring amount
1298 + // A recurring coupon discounts every cycle, so the per-cycle price itself
1299 + // is lower — the first cycle is not cheaper than the ones after it and
1300 + // must not be expressed as a trial.
1301 + if ($recurringDiscount > 0) {
1302 + $recurringAmount -= $recurringDiscount;
1298 1303 }
1299 1304
1300 1305 if ($firstCycleCost < $recurringAmount) {
1301 1306 $adjustedTrialDays = Helper::calculateAdjustedTrialDaysForInterval($trialDays, $repeatInterval);