← 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> |