momo payment

https://gist.github.com/webantam43/6d4ef3e1055b65082a3e7971943817ac

<?php
/*
Plugin Name: momo payment
Plugin URI: https://webantam.com
Description: Thanh toán bằng ví momo
Version: 1.0.
Author: Web An Tâm.
Author URI: https://webantam.com
License: GPLv2 or later
License URI: http://www.gnu.org/licenses/gpl-2.0.html
*/

//bắt đầu cho các đoạn code này ở bên dưới

class Momo_Payment_Gateway extends WC_Payment_Gateway {

	public function __construct() {
  
	  $this->id = 'momo_payment_gateway';
	  $this->method_title = 'MoMo Payment Gateway';
	  $this->method_description = 'Pay via MoMo Wallet';
	  $this->has_fields = false;
	  $this->supports = array(
		'products',
		'subscriptions',
		'subscription_cancellation',
		'subscription_suspension',
		'subscription_reactivation',
		'subscription_amount_changes',
		'subscription_date_changes',
		'multiple_subscriptions'
	  );
  
	  $this->init_form_fields();
	  $this->init_settings();
  
	  add_action('woocommerce_update_options_payment_gateways_' . $this->id, array($this, 'process_admin_options'));
	}
  
	public function init_form_fields() {
	  $this->form_fields = array(
		'enabled' => array(
		  'title' => __('Enable/Disable', 'woocommerce'),
		  'type' => 'checkbox',
		  'label' => __('Enable MoMo Payment Gateway', 'woocommerce'),
		  'default' => 'no'
		),
		'momo_merchant_code' => array(
		  'title' => __('MoMo Merchant Code', 'woocommerce'),
		  'type' => 'text',
		  'description' => __('Enter your MoMo Merchant Code.', 'woocommerce'),
		  'default' => ''
		),
		'momo_access_key' => array(
		  'title' => __('MoMo Access Key', 'woocommerce'),
		  'type' => 'text',
		  'description' => __('Enter your MoMo Access Key.', 'woocommerce'),
		  'default' => ''
		),
		'momo_secret_key' => array(
		  'title' => __('MoMo Secret Key', 'woocommerce'),
		  'type' => 'text',
		  'description' => __('Enter your MoMo Secret Key.', 'woocommerce'),
		  'default' => ''
		),
		'momo_description' => array(
		  'title' => __('Description', 'woocommerce'),
		  'type' => 'textarea',
		  'description' => __('Enter a short description of the payment method.', 'woocommerce'),
		  'default' => 'Pay via MoMo Wallet'
		),
	  );
	}
  
	public function process_payment($order_id) {
	  global $woocommerce;
	  $order = new WC_Order($order_id);
  
	  $momo_merchant_code =
	  $this->get_option('momo_merchant_code');
	  $momo_access_key = $this->get_option('momo_access_key');
	  $momo_secret_key = $this->get_option('momo_secret_key');
	  
	  // Set up the parameters for the MoMo API request
	  $params = array(
		'partnerCode' => $momo_merchant_code,
		'accessKey' => $momo_access_key,
		'requestId' => uniqid(),
		'amount' => $order->get_total(),
		'orderId' => $order_id,
		'orderInfo' => 'Order #' . $order_id,
		'returnUrl' => $this->get_return_url($order),
		'notifyUrl' => WC()->api_request_url('Momo_Payment_Gateway'),
		'requestType' => 'captureMoMoWallet'
	  );
	  
	  // Generate the signature for the MoMo API request
	  ksort($params);
	  $signature = hash_hmac('sha256', implode('', $params), $momo_secret_key);
	  
	  // Add the signature to the MoMo API request parameters
	  $params['signature'] = $signature;
	  
	  // Send the MoMo API request
	  $result = wp_remote_post('https://test-payment.momo.vn/gw_payment/transactionProcessor', array(
		'body' => json_encode($params),
		'headers' => array('Content-Type' => "application/json"),
		'timeout' => 30,
	  ));
	  
	  if (is_wp_error($result)) {
		$error_message = $result->get_error_message();
		throw new Exception('There was a problem communicating with MoMo: ' . $error_message);
	  }
	  
	  // Parse the MoMo API response
$response = json_decode(wp_remote_retrieve_body($result), true);

	  
	  if ($response['errorCode'] == 0) {
		// Redirect the customer to the MoMo payment page
		return array(
		  'result' => 'success',
		  'redirect' => $response['payUrl']
		);
	  } else {
		throw new Exception('There was a problem creating the MoMo payment request: ' . $response['message']);
	  }
	}

	public function check_momo_response() {
	global $woocommerce;
	if (!empty($_REQUEST['transaction_id'])) {
		$order_id = $_REQUEST['order_id'];
		$order = new WC_Order($order_id);
		$transaction_id = $_REQUEST['transaction_id'];
	  
		$momo_merchant_code = $this->get_option('momo_merchant_code');
		$momo_access_key = $this->get_option('momo_access_key');
		$momo_secret_key = $this->get_option('momo_secret_key');
	  
		// Set up the parameters for the MoMo API request
		$params = array(
		  'partnerCode' => $momo_merchant_code,
		  'accessKey' => $momo_access_key,
		  'requestId' => uniqid(),
		  'orderId' => $order_id,
		  'requestType' => 'querytransaction'
		);
	  
		// Generate the signature for the MoMo API request
		ksort($params);
		$signature = hash_hmac('sha256', implode('', $params), $momo_secret_key);
	  
		// Add the signature to the MoMo API request parameters
		$params['signature'] = $signature;
	  
		// Send the MoMo API request
		$result = wp_remote_post('https://test-payment.momo.vn/gw_payment/transactionProcessor', array(
		  'body' => json_encode($params),
		  'headers' => array('Content-Type'=>"application/json"),
		  'timeout' => 30,
		));
		  if (is_wp_error($result)) {
			$error_message = $result->get_error_message();
			throw new Exception('There was a problem communicating with MoMo: ' . $error_message);
		  }
		
		  // Parse the MoMo API response
		  $response = json_decode(wp_remote_retrieve_body($result), true);
		
		  if ($response['errorCode'] == 0 && $response['orderInfo'] == 'Order #' . $order_id) {
			// Mark the order as complete
			$order->payment_complete($transaction_id);
			$woocommerce->cart->empty_cart();
		
			// Redirect the customer to the thank you page
			wp_redirect($this->get_return_url($order));
			exit;
		  } else {
			// Redirect the customer to the checkout page with an error message
			$error_message = $response['message'] ?? 'There was a problem processing your payment. Please try again later.';
			wc_add_notice($error_message, 'error');
			wp_redirect(wc_get_checkout_url());
			exit;
		  }
		}
	}
}

// Register the MoMo payment gateway with WooCommerce
function add_momo_payment_gateway($methods) {
$methods[] = 'Momo_Payment_Gateway';
return $methods;
}
add_filter('woocommerce_payment_gateways', 'add_momo_payment_gateway');

// Handle MoMo API requests
function handle_momo_api_request() {
$gateway = new Momo_Payment_Gateway();
$gateway->check_momo_response();
}
add_action('woocommerce_api_momo_payment_gateway', 'handle_momo_api_request');
// Add MoMo payment method to WooCommerce checkout page
function add_momo_payment_method($methods) {
	$methods[] = 'Momo_Payment_Gateway';
	return $methods;
	}
	add_filter('woocommerce_payment_methods', 'add_momo_payment_method');
	
	// Add MoMo payment method to WooCommerce emails
	function add_momo_payment_method_to_emails($available_gateways) {
	if (isset($available_gateways['momo_payment_gateway'])) {
	$gateway = $available_gateways['momo_payment_gateway'];
	$available_gateways['momo_payment_gateway'] = $gateway->title;
	}
	return $available_gateways;
	}
	add_filter('woocommerce_available_payment_gateways', 'add_momo_payment_method_to_emails');
	
	// Add custom order status for MoMo payments
	function register_momo_order_status() {
	register_post_status('wc-momo-paid', array(
	'label' => 'MoMo Paid',
	'public' => true,
	'exclude_from_search' => false,
	'show_in_admin_all_list' => true,
	'show_in_admin_status_list' => true,
	'label_count' => _n_noop('MoMo Paid <span class="count">(%s)</span>', 'MoMo Paid <span class="count">(%s)</span>')
	));
	}
	add_action('init', 'register_momo_order_status');
	
	// Add MoMo payment status to order page
	function add_momo_payment_status_to_order_page($order_statuses) {
	$new_order_statuses = array();
	foreach ($order_statuses as $key => $status) {
	$new_order_statuses[$key] = $status;
	if ($key == 'wc-processing') {
	$new_order_statuses['wc-momo-paid'] = 'MoMo Paid';
	}
	}
	return $new_order_statuses;
	}
	add_filter('wc_order_statuses', 'add_momo_payment_status_to_order_page');
	
	// Add MoMo payment status to order emails
	function add_momo_payment_status_to_emails($statuses) {
	$statuses['wc-momo-paid'] = 'MoMo Paid';
	return $statuses;
	}
	add_filter('woocommerce_email_order_statuses', 'add_momo_payment_status_to_emails');
	// MoMo payment gateway class
class Momo_Payment_Gateway extends WC_Payment_Gateway {

	public function __construct() {
	$this->id = 'momo_payment_gateway';
	$this->icon = '';
	$this->method_title = __('MoMo Payment Gateway', 'woocommerce');
	$this->method_description = __('Pay via MoMo Payment Gateway', 'woocommerce');
	$this->has_fields = true;
	$this->supports = array(
	'products',
	'refunds'
	);
	$this->init_form_fields();
$this->init_settings();

// Define user set variables
$this->title = $this->get_option('title');
$this->description = $this->get_option('description');
$this->merchant_id = $this->get_option('merchant_id');
$this->access_key = $this->get_option('access_key');
$this->secret_key = $this->get_option('secret_key');
$this->webhook_url = $this->get_option('webhook_url');

// Hooks
add_action('woocommerce_update_options_payment_gateways_' . $this->id, array($this, 'process_admin_options'));
add_action('woocommerce_receipt_' . $this->id, array($this, 'receipt_page'));
add_action('woocommerce_api_momo_payment_gateway', array($this, 'webhook_listener'));
}

public function init_form_fields() {
$this->form_fields = array(
'enabled' => array(
'title' => __('Enable/Disable', 'woocommerce'),
'type' => 'checkbox',
'label' => __('Enable MoMo Payment Gateway', 'woocommerce'),
'default' => 'no'
),
'title' => array(
'title' => __('Title', 'woocommerce'),
'type' => 'text',
'description' => __('This controls the title which the user sees during checkout.', 'woocommerce'),
'default' => __('MoMo Payment Gateway', 'woocommerce'),
'desc_tip' => true
),
'description' => array(
'title' => __('Description', 'woocommerce'),
'type' => 'textarea',
'description' => __('This controls the description which the user sees during checkout.', 'woocommerce'),
'default' => __('Pay via MoMo Payment Gateway', 'woocommerce'),
'desc_tip' => true
),
'merchant_id' => array(
'title' => __('Merchant ID', 'woocommerce'),
'type' => 'text',
'description' => __('Your MoMo merchant ID.', 'woocommerce'),
'default' => '',
'desc_tip' => true
),
'access_key' => array(
'title' => __('Access Key', 'woocommerce'),
'type' => 'text',
'description' => __('Your MoMo access key.', 'woocommerce'),
'default' => '',
'desc_tip' => true
),
'secret_key' => array(
'title' => __('Secret Key', 'woocommerce'),
'type' => 'password',
'description' => __('Your MoMo secret key.', 'woocommerce'),
'default' => '',
'desc_tip' => true
),

'webhook_url' => array(
    'title' => __('Webhook URL', 'woocommerce'),
    'type' => 'url',
    'description' => __('The URL that MoMo will send payment status updates to.', 'woocommerce'),
    'default' => WC()->api_request_url('momo_payment_gateway'),
    'desc_tip' => true,
),
'transaction_type' => array(
    'title' => __('Transaction Type', 'woocommerce'),
    'type' => 'select',
    'description' => __('The type of transaction to create on the MoMo gateway.', 'woocommerce'),
    'default' => 'pay',
    'desc_tip' => true,
    'options' => array(
        'pay' => __('Pay', 'woocommerce'),
        'transfer' => __('Transfer', 'woocommerce')
    ),
)
}
public function process_payment($order_id) {
$order = wc_get_order($order_id);
$momo_args = array(
	'accessKey' => $this->access_key,
	'partnerCode' => $this->merchant_id,
	'requestId' => $order->get_order_number(),
	'amount' => intval($order->get_total()),
	'orderId' => $order->get_order_number(),
	'orderInfo' => 'Order #' . $order->get_order_number(),
	'returnUrl' => $this->get_return_url($order),
	'notifyUrl' => $this->webhook_url,
	'requestType' => $this->get_option('transaction_type'),
	'extraData' => ''
  );
  
  $momo_args['signature'] = hash_hmac('sha256', implode('', $momo_args), $this->secret_key);
  
  $momo_args = apply_filters('woocommerce_momo_args', $momo_args);
  
  return array(
	'result' => 'success',
	'redirect' => 'https://test-payment.momo.vn/gw_payment/transactionProcessor'
		. '?accessKey=' . $momo_args['accessKey']
		. '&partnerCode=' . $momo_args['partnerCode']
		. '&requestId=' . $momo_args['requestId']
		. '&amount=' . $momo_args['amount']
		. '&orderId=' . $momo_args['orderId']
		. '&orderInfo=' . urlencode($momo_args['orderInfo'])
		. '&returnUrl=' . urlencode($momo_args['returnUrl'])
		. '&notifyUrl=' . urlencode($momo_args['notifyUrl'])
		. '&requestType=' . $momo_args['requestType']
		. '&signature=' . $momo_args['signature']
		. '&extraData=' . urlencode($momo_args['extraData'])
  );
}

public function receipt_page($order_id) {
echo '<p>' . __('Thank you for your order, please click the button below to pay with MoMo.', 'woocommerce') . '</p>';
echo $this->generate_momo_form($order_id);
}

public function generate_momo_form($order_id) {
$order = wc_get_order($order_id);
$momo_args = array(
	'accessKey' => $this->access_key,
	'partnerCode' => $this->merchant_id,
	'requestId' => $order->get_order_number(),
	'amount' => intval($order->get_total()),
	'orderId' => $order->get_order_number(),
	'orderInfo' => 'Order #' . $order->get_order_number(),
	'returnUrl' => $this->get_return_url($order),
	'notifyUrl' => $this->webhook_url,
	'requestType' => $this->get_option('transaction_type'),
	'extraData' => ''
  );
  
  $momo_args['signature'] = hash_hmac('sha256', implode('', $momo_args), $this->secret_key);
  
  $momo_args = apply_filters('woocommerce_momo_args', $momo_args);
  
  $momo
  ob_start();
  ?>
  <form id="momo_payment_form" action="<?php echo $this->gateway_url; ?>" method="post">
	<?php foreach ($momo_args as $key => $value) : ?>
	  <input type="hidden" name="<?php echo esc_attr($key); ?>" value="<?php echo esc_attr($value); ?>" />
	<?php endforeach; ?>
	<input type="submit" class="button alt" id="submit_momo_payment_form" value="<?php echo __('Pay with MoMo', 'woocommerce'); ?>" />
	<a class="button cancel" href="<?php echo esc_url($order->get_cancel_order_url()); ?>"><?php echo __('Cancel order &amp; restore cart', 'woocommerce'); ?></a>
  </form>
  <?php
  return ob_get_clean();
}

public function check_momo_response() {
@ob_clean();
$data = $_GET;

if (!empty($data['errorCode'])) {
  $error_message = __('An error occurred while processing your payment. Please try again later.', 'woocommerce');
  wc_add_notice($error_message, 'error');
  wp_redirect(wc_get_checkout_url());
  exit;
}

$signature = hash_hmac('sha256', implode('', $data), $this->secret_key);

if ($signature !== $data['signature']) {
  $error_message = __('An error occurred while processing your payment. Please try again later.', 'woocommerce');
  wc_add_notice($error_message, 'error');
  wp_redirect(wc_get_checkout_url());
  exit;
}

$order = wc_get_order($data['orderId']);

if (!$order) {
  $error_message = __('An error occurred while processing your payment. Please try again later.', 'woocommerce');
  wc_add_notice($error_message, 'error');
  wp_redirect(wc_get_checkout_url());
  exit;
}

if (intval($order->get_total()) !== intval($data['amount'])) {
  $error_message = __('An error occurred while processing your payment. Please try again later.', 'woocommerce');
  wc_add_notice($error_message, 'error');
  wp_redirect(wc_get_checkout_url());
  exit;
}

$order->payment_complete();
$order->reduce_order_stock();

WC()->cart->empty_cart();

wp_redirect($this->get_return_url($order));
exit;
}
}

function add_momo_gateway_class($methods) {
$methods[] = 'WC_Momo_Gateway';
return $methods;
}

add_filter('woocommerce_payment_gateways', 'add_momo_gateway_class');

function init_momo_webhook() {
if (isset($_GET['momo_payment_response'])) {
$momo_gateway = new WC_Momo_Gateway();
$momo_gateway->check_momo_response();
}
}

add_action('init', 'init_momo_webhook');

?>

Last updated