Changeset 3431194
- Timestamp:
- 01/02/2026 06:00:34 PM (3 months ago)
- Location:
- camoo-pay-for-ecommerce/trunk
- Files:
-
- 2 added
- 8 edited
-
camoo-pay-for-ecommerce.php (modified) (6 diffs)
-
includes/Gateway.php (modified) (6 diffs)
-
includes/Plugin.php (modified) (16 diffs)
-
includes/admin/PluginAdmin.php (modified) (3 diffs)
-
includes/assets/css/style.css (modified) (1 diff)
-
includes/assets/js (added)
-
includes/assets/js/index.js (added)
-
readme.txt (modified) (2 diffs)
-
vendor/composer/installed.json (modified) (1 diff)
-
vendor/composer/installed.php (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
-
camoo-pay-for-ecommerce/trunk/camoo-pay-for-ecommerce.php
r3420361 r3431194 8 8 * Plugin URI: https://github.com/camoo/camoo-woocommerce-gateway 9 9 * Description: Receive Mobile Money payments on your store using CamooPay for WooCommerce. 10 * Version: 1.0. 710 * Version: 1.0.8 11 11 * Tested up to: 6.9 12 12 * Author: Camoo Sarl … … 28 28 add_action('admin_notices', static function () { 29 29 echo '<div class="notice notice-error"><p>' 30 . esc_html('CamooPay for e-Commerce requires PHP 8.1 or higher.')31 . '</p></div>';30 . esc_html('CamooPay for e-Commerce requires PHP 8.1 or higher.') 31 . '</p></div>'; 32 32 }); 33 33 … … 37 37 require_once __DIR__ . '/includes/Plugin.php'; 38 38 require_once __DIR__ . '/includes/admin/PluginAdmin.php'; 39 40 39 /** 41 40 * Delay plugin boot until plugins_loaded … … 45 44 add_action('admin_notices', static function () { 46 45 echo '<div class="notice notice-error"><p>' 47 . esc_html__('WooCommerce must be active to use CamooPay.', 'camoo-pay-for-ecommerce')48 . '</p></div>';46 . esc_html__('WooCommerce must be active to use CamooPay.', 'camoo-pay-for-ecommerce') 47 . '</p></div>'; 49 48 }); 49 50 50 return; 51 51 } … … 54 54 add_action('init', function () { 55 55 $plugin = new Plugin( 56 __FILE__,57 'WC_CamooPay_Gateway',58 'Gateway',59 'CamooPay for e-commerce payment gateway',60 '1.0.7'56 __FILE__, 57 'WC_CamooPay_Gateway', 58 'Gateway', 59 'CamooPay for e-commerce payment gateway', 60 '1.0.8' 61 61 ); 62 62 … … 64 64 $plugin->onInit(); 65 65 }); 66 } );66 }, 0); -
camoo-pay-for-ecommerce/trunk/includes/Gateway.php
r3244543 r3431194 41 41 $this->id = Plugin::WC_CAMOO_PAY_GATEWAY_ID; 42 42 43 $this->init_form_fields(); 43 44 $this->init_settings(); 44 $this->init_form_fields();45 45 46 46 $this->title = esc_html($this->get_option('title')); … … 278 278 $orderData['shopping_cart_details'] = wp_json_encode($orderData['shopping_cart_details']); 279 279 $payment = $this->placeOrder($orderData); 280 280 281 $this->handleOrderResponse($wcOrder, $payment); 281 282 … … 306 307 307 308 // Return to site 308 $returnUrl = get_permalink(wc_get_page_id('shop')) . '?trx=' . $merchantReferenceId . '&status=' . strtolower($status->value); 309 310 return [ 309 $returnData = [ 311 310 'result' => $payment === null ? 'failure' : 'success', 312 'redirect' => $ returnUrl,311 'redirect' => $this->get_return_url($wcOrder), 313 312 ]; 313 if ($returnData['result'] === 'failure') { 314 $returnData['redirect'] = esc_url_raw( 315 add_query_arg( 316 [ 317 'trx' => $merchantReferenceId, 318 'status' => strtolower($status->value), 319 ], 320 get_permalink(wc_get_page_id('shop')) 321 ) 322 ); 323 } 324 325 return $returnData; 314 326 } catch (Throwable $exception) { 315 327 $this->logger->error(__FILE__, __LINE__, esc_html($exception->getMessage())); … … 388 400 public function get_icon() 389 401 { 390 391 402 $attachment_id = get_option(MediaEnum::CAMOO_PAY_ICON->value); 392 403 if ($attachment_id) { … … 405 416 ); 406 417 418 // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedHooknameFound 407 419 return apply_filters('woocommerce_gateway_icon', $icon_html, $this->id); 420 408 421 } 409 422 … … 421 434 } 422 435 436 public function render_thankyou_notice(int $order_id): void 437 { 438 $order = wc_get_order($order_id); 439 if (!$order) { 440 return; 441 } 442 443 // Show only while waiting for Mobile Money confirmation 444 if (in_array($order->get_status(), ['pending', 'on-hold'], true)) { 445 echo '<p class="woocommerce-info">'; 446 echo esc_html__( 447 'Awaiting CamooPay payment confirmation', 448 'camoo-pay-for-ecommerce' 449 ); 450 echo '</p>'; 451 } 452 } 453 423 454 private function registerHooks(): void 424 455 { 425 456 add_action('woocommerce_update_options_payment_gateways_' . $this->id, [$this, 'process_admin_options']); 457 458 add_action( 459 'woocommerce_thankyou_' . $this->id, 460 [$this, 'render_thankyou_notice'] 461 ); 426 462 427 463 // ADD refund hook -
camoo-pay-for-ecommerce/trunk/includes/Plugin.php
r3420361 r3431194 9 9 namespace Camoo\Pay\WooCommerce; 10 10 11 use Automattic\WooCommerce\StoreApi\Schemas\V1\CheckoutSchema; 11 12 use Automattic\WooCommerce\Utilities\FeaturesUtil; 12 13 use Camoo\Pay\WooCommerce\Admin\Enum\MetaKeysEnum; … … 21 22 use WC_Order_Query; 22 23 use WC_Order_Refund; 24 use WP_REST_Request; 23 25 24 26 defined('ABSPATH') || exit; … … 26 28 class Plugin 27 29 { 28 public const WC_CAMOO_PAY_DB_VERSION = '1.0. 7';30 public const WC_CAMOO_PAY_DB_VERSION = '1.0.8'; 29 31 30 32 public const DEFAULT_TITLE = 'CamooPay'; … … 33 35 34 36 private const DEFAULT_COUNTRY_CODE = '237'; 35 36 private const DOMAIN_TEXT = 'camoo-pay-for-ecommerce';37 37 38 38 protected $id; … … 89 89 require_once __DIR__ . '/Media.php'; 90 90 91 92 91 if (!is_plugin_active('woocommerce/woocommerce.php')) { 93 92 … … 101 100 } 102 101 103 104 102 register_activation_hook($this->pluginPath, [Install::class, 'install']); 105 106 103 107 104 add_filter( 108 105 'plugin_action_links_' . plugin_basename($this->pluginPath), 109 [$this, 'onPluginActionLinks'], 1, 1 106 [$this, 'onPluginActionLinks'], 107 1, 108 1 110 109 ); 111 110 … … 113 112 register_deactivation_hook($this->pluginPath, [$this, 'route_status_plugin_deactivate']); 114 113 add_action('before_woocommerce_init', [__CLASS__, 'camoo_pay_hpos_compatibility']); 114 add_action('woocommerce_blocks_loaded', [$this, 'register_store_api_extensions']); 115 add_action( 116 'woocommerce_store_api_checkout_update_order_from_request', 117 [$this, 'manage_api_order_from_request'], 118 10, 119 2 120 ); 115 121 116 122 if (is_admin()) { 117 123 PluginAdmin::instance()->register(); 118 124 } 125 } 126 127 public function manage_api_order_from_request(WC_Order $order, WP_REST_Request $request): void 128 { 129 $payment_data = $request->get_param('payment_data') ?? []; 130 131 foreach ($payment_data as $item) { 132 if ( 133 isset($item['key'], $item['value']) && 134 $item['key'] === 'camoo_pay_phone_number' 135 ) { 136 $order->update_meta_data( 137 MetaKeysEnum::BUYER_MOBILE_MONEY_NUMBER->value, 138 sanitize_text_field($item['value']) 139 ); 140 } 141 } 142 } 143 144 public function register_store_api_extensions(): void 145 { 146 if (!function_exists('woocommerce_store_api_register_endpoint_data')) { 147 return; 148 } 149 150 woocommerce_store_api_register_endpoint_data( 151 [ 152 'endpoint' => CheckoutSchema::IDENTIFIER, 153 'namespace' => 'camoo_pay', 154 'schema_callback' => static fn (): array => [ 155 'phone_number' => [ 156 'description' => __('Mobile Money phone number', 'camoo-pay-for-ecommerce'), 157 'type' => 'string', 158 'required' => true, 159 ], 160 ], 161 162 ] 163 ); 119 164 } 120 165 … … 144 189 plugins_url('/assets/css/style.css', __FILE__), 145 190 [], 146 Plugin::WC_CAMOO_PAY_DB_VERSION 147 ); 191 self::WC_CAMOO_PAY_DB_VERSION 192 ); 193 194 if ( 195 !function_exists('is_checkout') || 196 !is_checkout() || 197 !function_exists('WC') 198 ) { 199 return; 200 } 201 202 wp_register_script( 203 'camoo-pay-blocks', 204 plugins_url('/assets/js/index.js', __FILE__), 205 ['wc-blocks-registry', 'wp-element', 'wp-i18n'], 206 self::WC_CAMOO_PAY_DB_VERSION, 207 true 208 ); 209 210 wp_enqueue_script('camoo-pay-blocks'); 148 211 } 149 212 … … 169 232 __('Do you like our plugin and can recommend to others.', 'camoo-pay-for-ecommerce') 170 233 ); 234 235 /** 236 * The hook camoo_pay_order_status_changed can be used during order status change. 237 * 238 * Example usage: 239 * 240 * // The action callback function. 241 * Function example_on_change_status_callback( $order, $status) { 242 * // (maybe) do something for the $order and $status info depending on your logic. 243 * } 244 * 245 * add_action('camoo_pay_order_status_changed', 'example_on_change_status_callback', 10, 2 ); 246 * 247 * /* 248 * * Trigger the actions by calling the 'example_on_change_status_callback()' function 249 * * that's hooked onto `camoo_pay_order_status_changed`. 250 * 251 * * @param WC_Order $order The WooCommerce order object. 252 * * @param Status $status The new status of the order. 253 * * @param string|null $merchantReferenceId The merchant reference ID associated with the order (if available). 254 * * @param Payment|null $payment The payment object associated with the order (if available). 255 * 256 * * @return void 257 * 258 * @since 1.0.8 259 */ 260 add_action('camoo_pay_order_status_changed', [$this, 'onCamooPayStatusChanged'], 10, 4); 171 261 172 262 add_action('rest_api_init', [$this, 'notification_route']); … … 314 404 ): void { 315 405 406 $current = $order->get_meta(MetaKeysEnum::PAYMENT_ORDER_STATUS->value); 407 408 if ($current === sanitize_title($status)) { 409 return; 410 } 411 316 412 $enumStatus = Status::from(strtoupper($status)); 317 413 match ($enumStatus) { 318 Status::IN_PROGRESS, Status::CREATED, Status::INITIALISED, Status::PENDING, Status::UNDERINVESTIGATION => self::processWebhookProgress( 414 Status::IN_PROGRESS, Status::CREATED, Status::INITIALISED, Status::PENDING, Status::UNDERINVESTIGATION => do_action( 415 'camoo_pay_order_status_changed', 319 416 $order, 417 $enumStatus, 418 $merchantReferenceId 419 ), 420 Status::CONFIRMED, Status::SUCCESS => do_action( 421 'camoo_pay_order_status_changed', 422 $order, 423 Status::CONFIRMED, 320 424 $merchantReferenceId, 321 $ enumStatus425 $payment 322 426 ), 323 Status::CONFIRMED, Status::SUCCESS => self::processWebhookConfirmed($order, $merchantReferenceId, $payment), 324 Status::CANCELED => self::processWebhookCanceled($order, $merchantReferenceId), 325 Status::FAILED, Status::ERRORED => self::processWebhookFailed($order, $merchantReferenceId), 427 Status::CANCELED => do_action( 428 'camoo_pay_order_status_changed', 429 $order, 430 Status::CANCELED, 431 $merchantReferenceId 432 ), 433 Status::FAILED, Status::ERRORED => do_action( 434 'camoo_pay_order_status_changed', 435 $order, 436 Status::FAILED, 437 $merchantReferenceId 438 ) 326 439 }; 327 440 … … 344 457 345 458 return substr($number, 0, 1) . str_repeat('*', strlen($number) - 3) . substr($number, -2); 459 } 460 461 public function onCamooPayStatusChanged( 462 WC_Order $order, 463 Status $status, 464 ?string $merchantReferenceId = null, 465 ?Payment $payment = null, 466 ): void { 467 if ($order->get_payment_method() !== self::WC_CAMOO_PAY_GATEWAY_ID) { 468 return; 469 } 470 471 self::$logger?->info( 472 __FILE__, 473 __LINE__, 474 sprintf( 475 'CamooPay order %d transitioned to %s', 476 $order->get_id(), 477 $status->value 478 ) 479 ); 480 481 match ($status) { 482 Status::FAILED => self::processWebhookFailed($order, $merchantReferenceId), 483 Status::CONFIRMED => self::processWebhookConfirmed($order, $merchantReferenceId, $payment), 484 Status::CANCELED => self::processWebhookCanceled($order, $merchantReferenceId), 485 default => self::processWebhookProgress($order, $merchantReferenceId, $status), 486 }; 346 487 } 347 488 … … 374 515 $order->add_order_note(__('CamooPay payment completed', 'camoo-pay-for-ecommerce'), true); 375 516 self::applyStatusChange(Status::CONFIRMED, $order, $merchantReferenceId, $fees); 376 do_action('woocommerce_order_edit_status', $order->get_id(), 'completed');377 517 } 378 518 … … 389 529 $order->update_status('pending'); 390 530 self::applyStatusChange($realStatus, $order, $merchantReferenceId); 391 do_action('woocommerce_order_edit_status', $order->get_id(), 'pending');392 531 } 393 532 … … 398 537 $order->add_order_note(__('CamooPay payment cancelled', 'camoo-pay-for-ecommerce'), true); 399 538 self::applyStatusChange(Status::CANCELED, $order, $merchantReferenceId); 400 do_action('woocommerce_order_edit_status', $order->get_id(), 'cancelled');401 539 } 402 540 … … 407 545 $order->add_order_note(__('CamooPay payment failed', 'camoo-pay-for-ecommerce'), true); 408 546 self::applyStatusChange(Status::FAILED, $order, $merchantReferenceId); 409 do_action('woocommerce_order_edit_status', $order->get_id(), 'failed');410 547 } 411 548 … … 447 584 * } 448 585 * 449 * Add_action('camoo_pay_after_status_change', 'example_callback', 10, 2 );586 * add_action('camoo_pay_after_status_change', 'example_callback', 10, 2 ); 450 587 * 451 588 * /* -
camoo-pay-for-ecommerce/trunk/includes/admin/PluginAdmin.php
r3420361 r3431194 185 185 ); 186 186 187 // add the source of the status update 188 $message = sprintf( 189 /* translators: 1: status, 2: transaction id */ 190 __('CamooPay payment status: %1$s (Transaction ID: %2$s) via admin check', 'camoo-pay-for-ecommerce'), 191 esc_html($verify->status), 192 esc_html($ptn) 193 ); 194 195 $order->add_order_note($message); 187 196 Plugin::processWebhookStatus( 188 197 $order, … … 196 205 wp_safe_redirect(self::getRedirectUrl()); 197 206 exit; 198 }199 200 private static function getRedirectUrl(): string201 {202 return wp_get_referer() ?: admin_url('edit.php?post_type=shop_order');203 207 } 204 208 … … 323 327 } 324 328 329 private static function getRedirectUrl(): string 330 { 331 return wp_get_referer() ?: admin_url('edit.php?post_type=shop_order'); 332 } 333 325 334 private static function getLogger(): Logger 326 335 { -
camoo-pay-for-ecommerce/trunk/includes/assets/css/style.css
r3240808 r3431194 31 31 .camoo-pay-mobile-money-phone-number img { 32 32 max-width:80%; 33 height: auto !important; border: 3px solid #50575e; border-radius: 15px; padding:5px; box-shadow: 0 4px 10px rgba(0,0,0,0.1);33 height: auto !important; border: 2px solid #50575e; border-radius: 14px; padding:6px; box-shadow: 0 4px 10px rgba(0,0,0,0.1); 34 34 } 35 35 .camoo-pay-phone-input { 36 36 width: 100%; padding: 10px; 37 37 font-size: 14px; 38 border-radius: 5px;38 border-radius: 6px; 39 39 border: 2px solid #ddd; 40 40 background-color: #f9f9f9; margin-top: 8px; 41 transition: border-color .15s ease, box-shadow .15s ease; 41 42 } 43 44 45 /* =============================== 46 CAMOO PAY – SHARED STYLES 47 Works for Classic + Blocks 48 ================================ */ 49 50 /* Mobile Money image wrapper */ 51 .camoo-pay-mobile-money-phone-number { 52 text-align: center; 53 margin-top: 16px; 54 } 55 56 .camoo-pay-phone-input:focus { 57 outline: none; 58 border-color: #2271b1; 59 box-shadow: 0 0 0 1px rgba(34,113,177,.2); 60 } 61 62 /* =============================== 63 BLOCK CHECKOUT ONLY 64 ================================ */ 65 66 .wc-block-components-payment-method__content .camoo-pay-fields { 67 margin-top: 8px; 68 } 69 70 .wc-block-components-payment-method__content .camoo-pay-fields p { 71 margin-bottom: 10px; 72 font-size: 0.9rem; 73 color: #333; 74 } 75 76 /* Input + icon row */ 77 .camoo-pay-fields .camoo-pay-input-row { 78 display: flex; 79 align-items: center; 80 gap: 10px; 81 } 82 83 /* Icon inside Blocks */ 84 .camoo-pay-fields img { 85 width: 36px; 86 height: 36px; 87 object-fit: contain; 88 } 89 90 .wc-block-components-payment-method-label img[alt="CamooPay"] { 91 max-height: 22px; 92 } -
camoo-pay-for-ecommerce/trunk/readme.txt
r3420361 r3431194 4 4 Requires Plugins: woocommerce 5 5 Tested up to: 6.9 6 Stable tag: 1.0. 76 Stable tag: 1.0.8 7 7 License: GPLv2 or later 8 8 License URI: http://www.gnu.org/licenses/gpl-2.0.html … … 88 88 89 89 == Changelog == 90 = 1.0.8: Jan 02, 2026 = 91 * Tweak - Support for new WooCommerce block checkout improvements 92 * Fixed - Fix thanks page display issue 93 90 94 = 1.0.7: December 15, 2025 = 91 95 * Fixed - Support for new status 'wc-camoo-pending' -
camoo-pay-for-ecommerce/trunk/vendor/composer/installed.json
r3237199 r3431194 221 221 } 222 222 ], 223 "dev": false,223 "dev": true, 224 224 "dev-package-names": [] 225 225 } -
camoo-pay-for-ecommerce/trunk/vendor/composer/installed.php
r3237199 r3431194 8 8 'install_path' => __DIR__ . '/../../', 9 9 'aliases' => array(), 10 'dev' => false,10 'dev' => true, 11 11 ), 12 12 'versions' => array(
Note: See TracChangeset
for help on using the changeset viewer.