public function init_form_fields() { $this->form_fields = array( 'enabled' => array( 'title' => __('Enable/Disable', 'woocommerce'), 'type' => 'checkbox', 'label' => __('Enable Selcom Payments', 'woocommerce'), 'default' => 'yes' ), 'title' => array( 'title' => __('Title', 'woocommerce'), 'type' => 'text', 'description' => __('This controls the title which the user sees during checkout.', 'woocommerce'), 'default' => __('Pay via mobile phone or card', 'woocommerce'), 'desc_tip' => true, ), 'description' => array( 'title' => __('Customer Message', 'woocommerce'), 'type' => 'textarea', 'default' => 'Pay directly from your mobile phone or card', 'description' => 'This controls the description which the user sees during checkout.', ), 'merchant_id' => array( 'title' => __('Vendor/Merchant ID', 'woocommerce'), 'type' => 'text', 'description' => __('Your merchant id received from Selcom.', $this->id), 'default' => '', 'desc_tip' => true, ), 'api_key' => array( 'title' => __('API Key', 'woocommerce'), 'type' => 'text', 'description' => __('Your API Key received from Selcom.', $this->id), 'default' => '', 'desc_tip' => true, ), 'secret_key' => array( 'title' => __('Secret Key', 'woocommerce'), 'type' => 'text', 'description' => __('Your Secret Key received from Selcom.', $this->id), 'default' => '', 'desc_tip' => true, ), 'api_url' => array( 'title' => __('API URL', 'woocommerce'), 'type' => 'text', 'description' => __('Base URL for Selcom API (e.g., https://apigw.selcommobile.com). Contact Selcom support to confirm.', $this->id), 'default' => 'https://apigw.selcommobile.com', 'desc_tip' => true, ), 'prefix' => array( 'title' => __('Unique Vendor Prefix', 'woocommerce'), 'type' => 'text', 'description' => __('Vendor prefix for auto-generated transaction IDs.', $this->id), 'default' => 'YAT', 'desc_tip' => true, ) ); } public function process_payment($order_id) { global $woocommerce; // Get an instance of the WC_Order object $order = new WC_Order($order_id); // Selcom API prerequisites $apiKey = $this->api_key; $apiSecret = $this->api_secret; $baseUrl = rtrim($this->api_url, '/'); // Ensure no trailing slash $vendorPrefix = $this->prefix; date_default_timezone_set('Africa/Dar_es_Salaam'); // Validate required fields if (empty($apiKey) || empty($apiSecret) || empty($this->vendor) || empty($baseUrl)) { wc_add_notice(__('Error: Selcom API credentials are not configured correctly.', 'woocommerce'), 'error'); return array('result' => 'failure'); } // Test API URL reachability with endpoint $testUrl = $baseUrl . '/checkout/create-order'; error_log('Selcom: Testing API URL: ' . $testUrl); $headers = array( 'Authorization' => 'SELCOM ' . base64_encode($apiKey), 'Accept' => 'application/json', ); $testResponse = wp_remote_get($testUrl, array( 'timeout' => 5, 'headers' => $headers, )); if (is_wp_error($testResponse)) { $error_message = $testResponse->get_error_message(); error_log('Selcom: API URL test failed: ' . $error_message); wc_add_notice(__('Error: Cannot connect to Selcom API (' . $error_message . '). Please verify the API URL or contact Selcom support at support@selcom.net.', 'woocommerce'), 'error'); return array('result' => 'failure'); } $httpCode = wp_remote_retrieve_response_code($testResponse); if ($httpCode >= 400) { $response_body = wp_remote_retrieve_body($testResponse); error_log('Selcom: API URL test failed: HTTP ' . $httpCode . ' | Response: ' . $response_body); wc_add_notice(__('Error: Selcom API returned an error (HTTP ' . $httpCode . '). Please verify the API URL or contact Selcom support at support@selcom.net.', 'woocommerce'), 'error'); return array('result' => 'failure'); } // Log raw phone number error_log('Selcom: Raw billing phone from order: ' . $order->get_billing_phone()); // Order array $minOrder = array( "vendor" => $this->vendor, "order_id" => $order->get_id(), "buyer_email" => $order->get_billing_email() ?: 'no-email@selcom.com', // Fallback for guest checkout "buyer_name" => trim($order->get_billing_first_name() . " " . $order->get_billing_last_name()), "buyer_phone" => '', // Will be set after normalization "amount" => (float) $order->get_total(), "webhook" => base64_encode(get_site_url() . '/wp-json/selcom-push/v2/selcomstat'), "currency" => "TZS", "no_of_items" => (int) $woocommerce->cart->cart_contents_count, "cancel_url" => base64_encode(get_site_url() . '/checkout'), "redirect_url" => base64_encode($this->get_return_url($order)), "payment_methods" => "ALL", "billing.firstname" => $order->get_billing_first_name() ?: 'Guest', "billing.lastname" => $order->get_billing_last_name() ?: 'User', "billing.address_1" => $order->get_billing_address_1() ?: 'Unknown', "billing.city" => $order->get_billing_city() ?: 'Dar es Salaam', "billing.state_or_region" => $order->get_billing_state() ?: 'Dar es Salaam', "billing.postcode_or_pobox" => $order->get_billing_postcode() ?: '94103', "billing.country" => $order->get_billing_country() ?: 'TZ', "billing.phone" => $order->get_billing_phone(), ); // Normalize phone number $raw_phone = $order->get_billing_phone(); $normalized_phone = preg_replace('/[^0-9]/', '', $raw_phone); // Remove non-digits if (substr($normalized_phone, 0, 1) === '0') { $normalized_phone = '255' . substr($normalized_phone, 1); // Convert 07xx to 2557xx } elseif (substr($normalized_phone, 0, 3) === '+255') { $normalized_phone = substr($normalized_phone, 1); // Convert +255 to 255 } $minOrder['buyer_phone'] = $normalized_phone; // Log webhook URL error_log('Selcom: Webhook URL: ' . base64_decode($minOrder['webhook'])); // Validate order data if (empty($minOrder['buyer_phone']) || !preg_match('/^255[0-9]{9}$/', $minOrder['buyer_phone'])) { error_log('Selcom: Invalid phone number provided: ' . $raw_phone); wc_add_notice(__('Error: Invalid or missing billing phone number. Please enter a valid Tanzanian phone number (e.g., 255123456789).', 'woocommerce'), 'error'); return array('result' => 'failure'); } // Send Order Request error_log('Selcom: Sending order request to: ' . $testUrl); $orderResponse = sendOrder($minOrder, $apiKey, $apiSecret, $baseUrl); // Log the full API response for debugging error_log('Selcom API Response: ' . print_r($orderResponse, true)); // Based on the order response, continue implementing USSD Push if (!isset($orderResponse->result)) { $order->update_status('failed', __('Order failed: Invalid API response.', 'woocommerce')); wc_add_notice(__('Error: Selcom API returned an invalid response.', 'woocommerce'), 'error'); return array('result' => 'failure'); } if ($orderResponse->result == 'FAIL') { $order->update_status('failed', __('Order not created: ' . ($orderResponse->message ?? 'Unknown error'), 'woocommerce')); wc_add_notice(__('Error: ', 'woocommerce') . ($orderResponse->message ?? 'Order could not be created. Please try again or contact support.'), 'error'); return array('result' => 'failure'); } elseif ($orderResponse->result == 'SUCCESS') { $data1 = (array) $orderResponse->data; $data1 = (object) $data1[0]; $payment_gateway_url = base64_decode($data1->payment_gateway_url); $order->update_status('pending', __('Order has been received, waiting for payment.', 'woocommerce')); wc_add_notice(__('Update: ', 'woocommerce') . 'Order has been created, waiting for payment completion.', 'success'); return array( 'result' => 'success', 'redirect' => $payment_gateway_url ); } elseif ($orderResponse->result == 'INPROGRESS' || $orderResponse->result == 'AMBIGOUS') { // Handle INPROGRESS or AMBIGOUS by scheduling a status check $order->update_status('pending', __('Order in progress, awaiting confirmation.', 'woocommerce')); wc_add_notice(__('Update: ', 'woocommerce') . 'Order is being processed, please wait.', 'success'); // Schedule a status check (requires WP-Cron) wp_schedule_single_event(time() + 180, 'selcom_check_order_status', array($order->get_id(), $baseUrl, $apiKey, $apiSecret)); return array( 'result' => 'success', 'redirect' => $this->get_return_url($order) ); } else { $order->update_status('failed', __('Order failed: ' . ($orderResponse->message ?? 'Unknown error'), 'woocommerce')); wc_add_notice(__('Error: ', 'woocommerce') . ($orderResponse->message ?? 'Something went wrong with the order. Please try again.'), 'error'); return array('result' => 'failure'); } } Health Outreach Tanzania Jobs & Career Vacancies - Mabumbe.TZ
Health Outreach Tanzania

Health Outreach Tanzania

Follow

Health Outreach Tanzania has posted 1 job

0 Review

Rate This Company ( No reviews yet )

Work/Life Balance
Comp & Benefits
Senior Management
Culture & Value

Health Outreach Tanzania

Health Outreach Tanzania

(0)

About Us

Health Outreach Tanzania (HoTA) is non-Governmental organization which registered in 14th July 2022 with registration number 00NGO/R/3541 with vision ‘’A community to live better healthier life’’.

Our main Objectives are:

Go to our Homepage To Get Relevant Information.

  1. Provide health education and promote awareness to the community on the outbreak diseases local and global.
  2. Engage and empower individuals and communities to choose healthy behaviors, and make changes that reduce the risk of developing chronic diseases and other morbidities
  • To create supportive environments for health, strengthen community action for health, develop personal skills and reorient health services
  1. Improved access to health and wellbeing of women, youth and children

Contact Us