Showing all 8 resultsSorted by latest
/** * Process Payment * * @param int $order_id * @return array */ public function process_payment($order_id) { $order = wc_get_order($order_id); $phone = $this->get_option('phone'); $type = $this->get_option('idtype'); if (empty($phone)) { wc_add_notice(__('Please enter the phone number you wish to use for payment.', 'woocommerce'), 'error'); return; } $phone = "254" . substr(preg_replace('/\D/', '', $phone), -9); $amount = $order->get_total(); $account = $order->get_billing_account_number() ?: $order->get_id(); try { $response = $this->submit_stk_request($phone, $amount, $order_id, $account); // Debug logging $this->log("STK Push Response: " . print_r($response, true)); // Check if STK push was successfully initiated if (isset($response['ResponseCode']) && $response['ResponseCode'] == '0') { // Check for MerchantRequestID in different possible locations $merchant_request_id = isset($response['MerchantRequestID']) ? $response['MerchantRequestID'] : (isset($response['merchantRequestID']) ? $response['merchantRequestID'] : (isset($response['requestId']) ? $response['requestId'] : '')); $checkout_request_id = isset($response['CheckoutRequestID']) ? $response['CheckoutRequestID'] : (isset($response['checkoutRequestID']) ? $response['checkoutRequestID'] : (isset($response['checkoutRequestId']) ? $response['checkoutRequestId'] : '')); // Store the IDs in order meta for later verification if (!empty($merchant_request_id)) { update_post_meta($order_id, '_merchant_request_id', $merchant_request_id); } if (!empty($checkout_request_id)) { update_post_meta($order_id, '_checkout_request_id', $checkout_request_id); } // Store the payment initiation time update_post_meta($order_id, '_mpesa_payment_initiated', time()); // Mark as on-hold (we're awaiting the payment) $order->update_status('on-hold', __('Awaiting MPesa payment confirmation. Please complete the payment on your phone.', 'woocommerce')); // Reduce stock levels wc_reduce_stock_levels($order_id); // Remove cart WC()->cart->empty_cart(); // Return thank you page redirect return array( 'result' => 'success', 'redirect' => $this->get_return_url($order) ); } else { // STK push failed $error_message = isset($response['ResponseDescription']) ? $response['ResponseDescription'] : (isset($response['errorMessage']) ? $response['errorMessage'] : __('STK push initiation failed. Please try again.', 'woocommerce')); $this->log("STK Push Failed: " . $error_message); wc_add_notice(__('Payment initiation failed: ', 'woocommerce') . $error_message, 'error'); return; } } catch (Exception $e) { $this->log("Exception in process_payment: " . $e->getMessage()); wc_add_notice(__('Payment error: ', 'woocommerce') . $e->getMessage(), 'error'); return; } } /** * Submit STK Push Request */ private function submit_stk_request($phone, $amount, $order_id, $account) { $token = $this->generate_token(); if (is_wp_error($token)) { throw new Exception($token->get_error_message()); } $env = $this->get_option('env', 'sandbox'); $shortcode = $this->get_option('shortcode'); $passkey = $this->get_option('passkey'); $timestamp = date('YmdHis'); $password = base64_encode($shortcode . $passkey . $timestamp); $endpoint = ($env == 'live') ? 'https://api.safaricom.co.ke/mpesa/stkpush/v1/processrequest' : 'https://sandbox.safaricom.co.ke/mpesa/stkpush/v1/processrequest'; $callback_url = $this->get_option('callback_url', home_url('/wc-api/lipwa')); $payload = array( 'BusinessShortCode' => $shortcode, 'Password' => $password, 'Timestamp' => $timestamp, 'TransactionType' => 'CustomerPayBillOnline', 'Amount' => round($amount), 'PartyA' => $phone, 'PartyB' => $shortcode, 'PhoneNumber' => $phone, 'CallBackURL' => $callback_url, 'AccountReference' => $account, 'TransactionDesc' => 'Payment for Order ' . $order_id ); $this->log("STK Push Payload: " . print_r($payload, true)); $response = wp_remote_post($endpoint, array( 'headers' => array( 'Authorization' => 'Bearer ' . $token, 'Content-Type' => 'application/json' ), 'body' => json_encode($payload), 'timeout' => 45 )); if (is_wp_error($response)) { throw new Exception($response->get_error_message()); } $body = wp_remote_retrieve_body($response); $data = json_decode($body, true); if (json_last_error() !== JSON_ERROR_NONE) { throw new Exception('Invalid JSON response from MPesa API'); } return $data; } /** * Generate Access Token */ private function generate_token() { $env = $this->get_option('env', 'sandbox'); $key = $this->get_option('key'); $secret = $this->get_option('secret'); $endpoint = ($env == 'live') ? 'https://api.safaricom.co.ke/oauth/v1/generate?grant_type=client_credentials' : 'https://sandbox.safaricom.co.ke/oauth/v1/generate?grant_type=client_credentials'; $response = wp_remote_get($endpoint, array( 'headers' => array( 'Authorization' => 'Basic ' . base64_encode($key . ':' . $secret) ), 'timeout' => 30 )); if (is_wp_error($response)) { return $response; } $body = wp_remote_retrieve_body($response); $data = json_decode($body, true); if (isset($data['access_token'])) { return $data['access_token']; } else { return new WP_Error('token_error', isset($data['errorMessage']) ? $data['errorMessage'] : 'Failed to generate access token'); } } /** * Remove the problematic hook that references non-existent method */ public function __construct() { parent::__construct(); // Remove any problematic hooks during construction remove_filter('woocommerce_payment_complete_order_status', array($this, 'change_payment_complete_order_status'), 10); } /** * Add proper logging method if it doesn't exist */ private function log($message) { if (function_exists('wc_get_logger')) { $logger = wc_get_logger(); $logger->info($message, array('source' => 'wc-mpesa')); } }
Call us now : +254 7165 46107 or Email: info@purpleapple.biz
By continuing, you accept the Website Regulations , Regulations for the sale of alcoholic beverages and the
You dont have an account yet? Register Now