PluginProbe
FluentCart A New Era of eCommerce – Faster, Lighter, and Simpler / 1.6.6
FluentCart A New Era of eCommerce – Faster, Lighter, and Simpler v1.6.6
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/Modules/PaymentMethods/AirwallexGateway/Airwallex.php +21 -1 1.3.21 → 1.6.6 View file →
@@ -27,8 +27,9 @@
27 27 'title' => __('Airwallex', 'fluent-cart'),
28 28 'route' => 'airwallex',
29 29 'description' => __('Pay securely with Airwallex - Global payment processing', 'fluent-cart'),
30 30 'logo' => Vite::getAssetUrl("images/payment-methods/airwallex-logo.svg"),
31 + 'logo_light' => Vite::getAssetUrl("images/payment-methods/airwallex-logo-light.svg"),
31 32 'icon' => Vite::getAssetUrl("images/payment-methods/airwallex-logo.svg"),
32 33 'brand_color' => '#6c5ce7',
33 34 'status' => $this->settings->get('is_active') === 'yes',
34 35 'upcoming' => true,
@@ -54,8 +55,27 @@
54 55 }
55 56
56 57 public function handleIPN(): void
57 58 {
59 + // Airwallex is not released yet (meta 'upcoming' => true). The event
60 + // handlers below are unfinished scaffolding that write order state
61 + // directly, outside the transaction/event pipeline every live gateway
62 + // uses, and without the cross-checks a real listener needs. Refuse to
63 + // process any event while the gateway is upcoming so no forged or
64 + // replayed payload can reach them.
65 + //
66 + // Before removing this guard at GA, the handlers MUST:
67 + // - resolve the order by the intent id we stamped at intent creation,
68 + // never by attacker-supplied metadata.order_id;
69 + // - verify amount, currency and payment mode against the stored order;
70 + // - reject stale callbacks (timestamp-age window + per-event dedup) and
71 + // guard terminal states (do not flip a paid order to failed);
72 + // - route through the shared PaymentHelper/transaction machinery.
73 + if ($this->isUpcoming()) {
74 + http_response_code(404);
75 + exit();
76 + }
77 +
58 78 $payload = json_decode(file_get_contents('php://input'), true); // will get from request after verification
59 79 // Verify webhook signature
60 80 if (!$this->verifyWebhookSignature($payload)) {
61 81 http_response_code(401);
@@ -103,9 +123,9 @@
103 123 }
104 124
105 125 public function fields()
106 126 {
107 - $webhook_url = site_url() . '?fct_payment_listener=1&method=airwallex';
127 + $webhook_url = Arr::get($this->getListenerUrl(), 'listener_url');
108 128 $webhook_instructions = sprintf(
109 129 '<div>
110 130 <p><b>%1$s</b><code class="copyable-content">%2$s</code></p>
111 131 <p>%3$s</p>