/**
* 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'));
}
}
Godox AD400Pro Witstro All-In-One Outdoor Flash - Purple Apple Store
Call us now : +254 7165 46107 or Email: info@purpleapple.biz
Godox AD400Pro Witstro All-In-One Outdoor Flash
KSh 64,499.00
In Stock
Delivered today (order Mon-Fri before 12:00, delivery between 17:00 and 22:00)Including shipping costs, sent by Purple Apple StorePick up at a Purple Apple Store collection point is possible Day and night customer service
Description
Features
Photography outdoor and indoor lighting
Built-in 2.4 ghz wireless x system
Compatible with most ttl systems
400ws, 1/256 to 1/1 power output
lithium-ion battery powered
up to 390 full-power flashes
flash duration: 1/240 to 1/12,820 sec
1/8000 sec high-speed sync
0.01-0.9 sec recycling time
30w led modeling lamp, 4800k, tlci: 93
stable color temperature mode
Available CBD,Nairobi,Kenya
we guarantee that the pictures are show as the item itself.
All the products are 100% new items with professional checking
Reviews
There are no reviews yet.