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.6 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 All 49 releases
← All changes | app/Models/OrderTransaction.php +60 -2 1.5.5 → 1.6.5 View file →
@@ -3,10 +3,13 @@
3 3 namespace FluentCart\App\Models;
4 4
5 5 use FluentCart\Api\StoreSettings;
6 6 use FluentCart\App\Helpers\Status;
7 +use FluentCart\App\Services\DateTime\DateTime;
7 8 use FluentCart\App\Models\Concerns\CanSearch;
9 +use FluentCart\App\Modules\PaymentMethods\Core\AbstractPaymentGateway;
8 10 use FluentCart\App\Modules\PaymentMethods\Core\GatewayManager;
11 +use FluentCart\App\Services\Payments\PaymentHelper;
9 12 use FluentCart\Framework\Database\Orm\Relations\HasOne;
10 13 use FluentCart\Framework\Support\Arr;
11 14
12 15 /**
@@ -102,8 +105,23 @@
102 105 if (empty($model->uuid)) {
103 106 $model->uuid = md5(time() . wp_generate_uuid4());
104 107 }
105 108 });
109 +
110 + // created_at is the checkout time, which can be weeks before the money
111 + // moves (payment links, delayed webhooks) — the settlement moment is
112 + // only observable at this transition, so record it here. Gateways that
113 + // know the exact remote charge time set meta.settled_at themselves;
114 + // this fallback never overwrites it.
115 + static::saving(function ($model) {
116 + if ($model->status === Status::TRANSACTION_SUCCEEDED && $model->isDirty('status')) {
117 + $meta = $model->meta;
118 + if (empty($meta['settled_at'])) {
119 + $meta['settled_at'] = DateTime::gmtNow()->format('Y-m-d H:i:s');
120 + $model->meta = $meta;
121 + }
122 + }
123 + });
106 124 }
107 125
108 126 public function getUrlAttribute($value)
109 127 {
@@ -179,9 +197,16 @@
179 197
180 198 return $this->payment_method;
181 199 }
182 200
183 - public function getReceiptPageUrl($filtered = false)
201 + /**
202 + * $filtered defaults to true because every caller redirects the customer and
203 + * therefore wants the filter. It defaulted to false, so a caller that omitted
204 + * the argument silently got an unfilterable URL — which is how the Stripe
205 + * confirmation redirect lost its filter in a refactor. The parameter is kept
206 + * so an explicit `false` can still ask for the raw URL.
207 + */
208 + public function getReceiptPageUrl($filtered = true)
184 209 {
185 210 $url = add_query_arg([
186 211 'trx_hash' => $this->uuid
187 212 ], (new StoreSettings())->getReceiptPage());
@@ -190,13 +215,46 @@
190 215 $context = [
191 216 'transaction' => $this,
192 217 'order' => $this->order,
193 218 ];
194 - $url = apply_filters_deprecated('fluentcart/transaction/receipt_page_url', [$url, $context], '1.3.16', 'fluent_cart/transaction/receipt_page_url', 'Use fluent_cart/transaction/receipt_page_url instead of fluentcart/transaction/receipt_page_url. It will be removed in v1.4.3.');
195 219 $url = apply_filters('fluent_cart/transaction/receipt_page_url', $url, $context);
196 220 }
197 221
198 222 return $url;
223 + }
224 +
225 + /**
226 + * Canonical post-payment redirect URL for this transaction.
227 + * Always fires the fluent_cart/payment/success_url filter.
228 + *
229 + * @param array $args Extra query args merged into the URL
230 + * @return string
231 + */
232 + public function getSuccessUrl($args = [])
233 + {
234 + return (new PaymentHelper((string)$this->payment_method))->successUrl($this, $args);
235 + }
236 +
237 + public function syncPendingTransaction()
238 + {
239 + if ($this->transaction_type !== Status::TRANSACTION_TYPE_CHARGE) {
240 + return new \WP_Error('invalid_transaction_type', __('Only charge transactions can be synced from the payment gateway.', 'fluent-cart'));
241 + }
242 +
243 + if ($this->status !== Status::TRANSACTION_PENDING) {
244 + return new \WP_Error('invalid_transaction_status', __('Only pending transactions can be synced from the payment gateway.', 'fluent-cart'));
245 + }
246 +
247 + if (!$this->vendor_charge_id) {
248 + return new \WP_Error('missing_vendor_charge_id', __('This transaction has no gateway charge ID to sync against.', 'fluent-cart'));
249 + }
250 +
251 + $gateway = GatewayManager::getInstance($this->payment_method);
252 + if ($gateway instanceof AbstractPaymentGateway) {
253 + return $gateway->syncRemoteTransaction($this);
254 + }
255 +
256 + return new \WP_Error('invalid_payment_method', __('This payment method does not support remote transaction sync', 'fluent-cart'));
199 257 }
200 258
201 259 public function acceptDispute($args = [])
202 260 {