mardi 26 janvier 2016

How to make a Custom Payment Gateway Plugin in Wordpress?

I am trying to make a Custom Gateway Plugin for my Merchant Account in wordpress based on this API Doc but I got stuck and I don't know how to continue. This plugin using CURL for POST Method to Gateway Server

Now, here is what I done so far:

index.php

<?php
/**
 * Plugin Name: Custom WooCommerce Addon
 */

include 'lib.php';
if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly
function merchantone_init()
{

    function add_merchantone_gateway_class( $methods ) 
    {
        $methods[] = 'WC_MerchantOne_Gateway'; 
        return $methods;
    }
    add_filter( 'woocommerce_payment_gateways', 'add_merchantone_gateway_class' );

    if(class_exists('WC_Payment_Gateway'))
    {
        class WC_MerchantOne_Gateway extends WC_Payment_Gateway 
        {
        public function __construct()
        {

        $this->id               = 'merchantonegateway';
        $this->icon             = plugins_url( 'images/merchantone.png' , __FILE__ )  ;
        $this->has_fields       = true;
        $this->method_title     = 'BCA Sakuku Settings';        
        $this->init_form_fields();
        $this->init_settings();

        $this->title                      = $this->get_option( 'merchantone_title' );
        $this->description                = $this->get_option( 'merchantone_description' );
        $this->merchant_id                = $this->get_option( 'merchant_id' );
        $this->client_id                  = $this->get_option( 'client_id' ); 
        $this->secret_key                  = $this->get_option( 'secret_key' ); 
        $this->redirect_url                = site_url('/thank-you');


        $this->merchantone_liveurl         = 'http://ift.tt/1PzjUhK';


         if (is_admin()) 
         {
            add_action( 'woocommerce_update_options_payment_gateways_' . $this->id, array( $this, 'process_admin_options' ) );       }

        }



        public function admin_options()
        {
        ?>
        <h3><?php _e( 'Merchant One addon for WooCommerce', 'woocommerce' ); ?></h3>
        <p><?php  _e( 'Merchant One is a payment gateway service provider allowing merchants to accept credit card.', 'woocommerce' ); ?></p>
        <table class="form-table">
          <?php $this->generate_settings_html(); ?>
        </table>
        <?php
        }



        public function init_form_fields()
        {
        $this->form_fields = array
        (
            'enabled' => array(
              'title' => __( 'Enable/Disable', 'woocommerce' ),
              'type' => 'checkbox',
              'label' => __( 'Enable Merchant One', 'woocommerce' ),
              'default' => 'yes'
              ),
            'merchantone_title' => array(
              'title' => __( 'Title', 'woocommerce' ),
              'type' => 'text',
              'description' => __( 'This controls the title which the buyer sees during checkout.', 'woocommerce' ),
              'default' => __( 'BCA Sakuku', 'woocommerce' ),
              'desc_tip'      => true,
              ),
            'merchantone_description' => array(
              'title' => __( 'Description', 'woocommerce' ),
              'type' => 'text',
              'description' => __( 'Description for BCA Sakuku.', 'woocommerce' ),
              'default' => '',
              'desc_tip'      => true,
              'placeholder' => 'description'
              ),
            'merchant_id' => array(
              'title' => __( 'Merchant ID', 'woocommerce' ),
              'type' => 'text',
              'description' => __( 'This is Merchant ID.', 'woocommerce' ),
              'default' => '',
              'desc_tip'      => true,
              'placeholder' => 'Merchant ID'
              ),
            'client_id' => array(
              'title' => __( 'Client ID', 'woocommerce' ),
              'type' => 'text',
              'description' => __( 'This is Client ID.', 'woocommerce' ),
              'default' => '',
              'desc_tip'      => true,
              'placeholder' => 'Client ID'
              ),
            'secret_key' => array(
              'title' => __( 'Secret Key', 'woocommerce' ),
              'type' => 'text',
              'description' => __( 'This is Secret Key.', 'woocommerce' ),
              'default' => '',
              'desc_tip'      => true,
              'placeholder' => 'Secret Key'
              ),
        );
        }


        public function get_icon() {
        $icon = '';
        if(is_array($this->merchantone_cardtypes ))
        {
        foreach ($this->merchantone_cardtypes as $card_type ) {

            if ( $url = $this->get_payment_method_image_url( $card_type ) ) {

                $icon .= '<img src="' . esc_url( $url ) . '" alt="' . esc_attr( strtolower( $card_type ) ) . '" />';
            }
          }
        }
        else
        {
            $icon .= '<img src="' . esc_url( plugins_url( 'images/merchantone.png' , __FILE__ ) ).'" alt="Mercant One Gateway" />';   
        }

         return apply_filters( 'woocommerce_merchantone_icon', $icon, $this->id );
        }

        public function get_payment_method_image_url( $type ) {

        $image_type = strtolower( $type );

            return  WC_HTTPS::force_https_url( plugins_url( 'images/' . $image_type . '.png' , __FILE__ ) ); 
        }



        /*Get Card Types*/
        function get_card_type($number)
        {
            $number=preg_replace('/[^\d]/','',$number);
            if (preg_match('/^3[47][0-9]{13}$/',$number))
            {
                return 'amex';
            }
            elseif (preg_match('/^3(?:0[0-5]|[68][0-9])[0-9]{11}$/',$number))
            {
                return 'dinersclub';
            }
            elseif (preg_match('/^6(?:011|5[0-9][0-9])[0-9]{12}$/',$number))
            {
                return 'discover';
            }
            elseif (preg_match('/^(?:2131|1800|35\d{3})\d{11}$/',$number))
            {
                return 'jcb';
            }
            elseif (preg_match('/^5[1-5][0-9]{14}$/',$number))
            {
                return 'mastercard';
            }
            elseif (preg_match('/^4[0-9]{12}(?:[0-9]{3})?$/',$number))
            {
                return 'visa';
            }
            else
            {
                return 'Invalid Card No';
            }
        }// End of getcard type function


    //Pre-Authentication using Request Format: JSON and Request Method: Host-to-host HTTP Post

        public function merchantone_params($wc_order) {

            $RequestDate      = date("d/m/Y h:m:s");  
            $data = $this->client_id; 
            $secret = $this->secret_key;
            $currency='IDR';
            $signature = encrypt($data, $secret);
            $merchantone_args = array(
            'MerchantID' => $this->merchant_id,     
            'TransactionID' => $wc_order->get_order_number(),   
            'RequestDate' =>  $RequestDate, 
            'Amount' =>number_format($wc_order->order_total,2,".",""),    
            'CurrencyCode' => $currency,   
            'Tax' => '',    
            'Signature' => $signature,   
            'Description' => get_bloginfo('blogname').' Order #'.$wc_order->get_order_number(),       
            'CallbackURL' => $this->redirect_url, 
            'UserSession'  => '',   
            'TransactionNote' => '',  

            );
            return $merchantone_args ; 
        }





        /*Payment Processing Fields*/
        public function process_payment($order_id)
        {

            global $woocommerce;
                $wc_order = new WC_Order($order_id);




            $gatewayurl = $this->merchantone_liveurl;


            $params = $this->merchantone_params($wc_order);


            $post_string = '';
            foreach( $params as $key => $value )
            { 
              $post_string .= urlencode( $key )."=".urlencode($value )."&"; 
            }
            $post_string = rtrim($post_string,"&");

            $curl_header = array('Accept: application/json', 'Content-Type: application/json');
$trans = array('MerchantID', 'TransactionID' , 'RequestDate', 'Amount','CurrencyCode','Tax','Signature', 'Description','CallbackURL','UserSession','TransactionNote');

$ch = curl_init($gatewayurl);    
curl_setopt($ch, CURLOPT_HTTPHEADER, $curl_header);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
    curl_setopt($ch, CURLOPT_POST, TRUE);
    curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($trans));
    curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
    curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);



            if (!($data2 = curl_exec($ch))) {
                throw new Exception( __( 'Empty Merchant One Gateway response.','woocommerce') );;
            }
            curl_close($ch);
            unset($ch);

            $data2 = explode("&",$data2);

            for($i=0;$i<count($data2);$i++) 
            {
                $rsponsedata = explode("=",$data2[$i]);
                $response_array[$rsponsedata[0]] = $rsponsedata[1];

            }


        if ( count($response_array) > 1 )
        {
             if( 100 == $response_array['response_code'] )
            {
            $wc_order->add_order_note( __( $response_array['responsetext']. 'on '.date("d-m-Y h:i:s e").' with Transaction ID = '.$response_array['transactionid'].' using '.$response_array['type'].', Authorization Code ='.$response_array['authcode'].',Response Code ='.$response_array['response_code'].', Response ='.$response_array['response'],  'woocommerce' ) );

            $wc_order->payment_complete($response_array['transactionid']);
            WC()->cart->empty_cart();
            return array (
                        'result'   => 'success',
                        'redirect' => $this->get_return_url( $wc_order ),
                       );
            }
            else 
            {
                $wc_order->add_order_note( __( 'Merchant One payment failed.'.$response_array['responsetext'].', Response Code'.$response_array['response_code'].', Response ='.$response_array['response'],  'woocommerce' ) );
                wc_add_notice('Error Processing Merchant One Payments', $notice_type = 'error' );
            }
        }
        else 
        {
            $wc_order->add_order_note( __( 'Merchant One payment failed.'.$response_array['responsetext'].', Response Code'.$response_array['response_code'].', Response ='.$response_array['response'], 'woocommerce' ) );
            wc_add_notice('Error Processing Merchant One Payments', $notice_type = 'error' );
        }

        }// End of process_payment


        }// End of class WC_Authorizenet_merchantone_Gateway
    } // End if WC_Payment_Gateway
}// End of function authorizenet_merchantone_init

add_action( 'plugins_loaded', 'merchantone_init' );

function merchantone_addon_activate() {

    if(!function_exists('curl_exec'))
    {
         wp_die( '<pre>This plugin requires PHP CURL library installled in order to be activated </pre>' );
    }
}
register_activation_hook( __FILE__, 'merchantone_addon_activate' );

/*Plugin Settings Link*/
function merchantone_settings_link( $links ) {
    $settings_link = '<a href="admin.php?page=wc-settings&tab=checkout&section=wc_merchantone_gateway">' . __( 'Settings' ) . '</a>';
    array_push( $links, $settings_link );
    return $links;
}
$plugin = plugin_basename( __FILE__ );
add_filter( "plugin_action_links_$plugin", 'merchantone_settings_link' );

lib.php

<?php

/*
 * Requirement php library: mcrypt
 * - http://ift.tt/15lxKeT
*/

function encrypt($data, $secret) {
    //Generate a key from a hash
    $key = $secret;

    $key .= substr($key, 0, 8);
    $blockSize = mcrypt_get_block_size(MCRYPT_3DES, MCRYPT_MODE_ECB);
    $len = strlen($data);
    $pad = $blockSize - ($len % $blockSize);
    $data .= str_repeat(chr($pad), $pad);

    $encData = mcrypt_encrypt(MCRYPT_3DES, $key, $data, MCRYPT_MODE_ECB);

    return base64_encode($encData);
}

?>

I already tested on my development url and always got error message such as "internal server error" when checkout using "BCA Sakuku" payment option like screenshot below: bca sakuku payment option

I will make new administrator account in wordpress if anyone interested.



via Chebli Mohamed

Aucun commentaire:

Enregistrer un commentaire