印尼本地第三方支付Veritrans的ecshop插件

做一個印尼的ecshop二次開發,需要開發一個印尼本地的第三方支付的插件。印尼本地最大的線上支付是日本公司開發的Veritrans,Veritrans網址爲:https://www.veritrans.co.id

以下是ecshop的完整代碼:

第一步:在includes/modules/payment下,新建一個veritrans.php

<?php
/**
 * veritrans 支付插件
 * @author yuanjiang 04.29.2015
 * @932625974#qq.com
*/

if (!defined('IN_ECS'))
{
    die('Hacking attempt');
}

$payment_lang = ROOT_PATH . 'languages/' .$GLOBALS['_CFG']['lang']. '/payment/veritrans.php';

if (file_exists($payment_lang))
{
    global $_LANG;

    include_once($payment_lang);
}

/* 模塊的基本信息 */
if (isset($set_modules) && $set_modules == TRUE)
{
    $i = isset($modules) ? count($modules) : 0;

    /* 代碼 */
    $modules[$i]['code']    = basename(__FILE__, '.php');

    /* 描述對應的語言項 */
    $modules[$i]['desc']    = 'veritrans_desc';

    /* 是否支持貨到付款 */
    $modules[$i]['is_cod']  = '0';

    /* 是否支持在線支付 */
    $modules[$i]['is_online']  = '1';

    /* 作者 */
    $modules[$i]['author']  = 'Yuan Jiang';

    /* 網址 */
    $modules[$i]['website'] = 'http://www.veritrans.co.id';

    /* 版本號 */
    $modules[$i]['version'] = '1.0.0';

    /* 配置信息 */
    $modules[$i]['config']  = array(
        array('name' => 'veritrans_client_key',     'type' => 'text',   'value' => ''),
        array('name' => 'veritrans_server_key',     'type' => 'text',   'value' => ''),
    );

    return;
}

/* config */
class Veritrans_Config {

  public static $serverKey = 'your serverKey';
  public static $clientKey;
  public static $apiVersion = 2;
  public static $isProduction = false;
  public static $is3ds = false;
  public static $isSanitized = false;

  const SANDBOX_BASE_URL = 'https://api.sandbox.veritrans.co.id/v2';
  const PRODUCTION_BASE_URL = 'https://api.veritrans.co.id/v2';

  public static function getBaseUrl() 
  {
    return Veritrans_Config::$isProduction ?
        Veritrans_Config::PRODUCTION_BASE_URL : Veritrans_Config::SANDBOX_BASE_URL;
  }
}

/* verify */
class Veritrans_Sanitizer {

  public static function jsonRequest(&$json)
  {
    $keys = array('item_details', 'customer_details');
    foreach ($keys as $key) {
      if (!array_key_exists($key, $json)) continue;

      $camel = self::upperCamelize($key);
      $function = "field$camel";
      self::$function($json[$key]);
    }
  }

  private static function upperCamelize($string)
  {
    return str_replace(' ', '',
        ucwords(str_replace('_', ' ', $string)));
  }
}

/* tool */
class Veritrans_ApiRequestor {

  public static function get($url, $server_key, $data_hash)
  {
    return self::remoteCall($url, $server_key, $data_hash, false);
  }

  public static function post($url, $server_key, $data_hash)
  {
    return self::remoteCall($url, $server_key, $data_hash, true);
  }
  
  public static function remoteCall($url, $server_key, $data_hash, $post = true)
  {
    $ch = curl_init();

    curl_setopt($ch, CURLOPT_URL, $url);
    curl_setopt($ch, CURLOPT_HTTPHEADER, array(
        'Content-Type: application/json',
        'Accept: application/json',
        'Authorization: Basic ' . base64_encode($server_key . ':')
      ));

    if ($post) {
      curl_setopt($ch, CURLOPT_POST, 1);

      if ($data_hash) {
        $body = json_encode($data_hash);
        curl_setopt($ch, CURLOPT_POSTFIELDS, $body);
      }
      else {
        curl_setopt($ch, CURLOPT_POSTFIELDS, '');
      }
    }

    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
    curl_setopt ($ch, CURLOPT_CAINFO, dirname(__FILE__) . "/../../../cert/veritrans.pem");

    $result = curl_exec($ch);
    // curl_close($ch);

    if ($result === FALSE) { 
      throw new Exception('CURL Error: ' . curl_error($ch), curl_errno($ch));
    }
    else { 
      $result_array = json_decode($result);
      if (!in_array($result_array->status_code, array(200, 201, 202, 407))) {
        $message = 'Veritrans Error (' . $result_array->status_code . '): '
            . $result_array->status_message;
        throw new Exception($message, $result_array->status_code);
      }
      else {
        return $result_array;
      }
    }
  }
}  

class Veritrans_Notification {

  private $response;

  public function __construct($input_source = "php://input")
  {
    $this->response = json_decode(file_get_contents($input_source), true);
  }

  public function __get($name)
  {
    if (array_key_exists($name, $this->response)) {
      return $this->response[$name];
    }
  }
}

/* transaction: confirm the status, approve or cancel the payment */
class Veritrans_Transaction {

  public static function status($id)
  {
    return Veritrans_ApiRequestor::get(
        Veritrans_Config::getBaseUrl() . '/' . $id . '/status',
        Veritrans_Config::$serverKey,
        false);
  }

  public static function approve($id)
  {
    return Veritrans_ApiRequestor::post(
        Veritrans_Config::getBaseUrl() . '/' . $id . '/approve',
        Veritrans_Config::$serverKey,
        false)->status_code;
  }

  public static function cancel($id)
  {
    return Veritrans_ApiRequestor::post(
        Veritrans_Config::getBaseUrl() . '/' . $id . '/cancel',
        Veritrans_Config::$serverKey,
        false)->status_code;
  }
}

/* main */
class veritrans {
  
  /* pay code */
  public function get_code($order, $payment)
  { 
    $params = array(
      'transaction_details' => array('order_id' => $order['order_sn'], 'gross_amount' => $order['order_amount']),
	  'custom_field1' => $order['log_id'],   //支付記錄id,支付完成後Veritrans返回此參數,用於更新
    );
    $payloads = array(
        'payment_type' => 'vtweb',
        'vtweb' => array(
          // 'enabled_payments' => array('credit_card'),
          'credit_card_3d_secure' => Veritrans_Config::$is3ds
        )
      );

    if (array_key_exists('item_details', $params)) {
      $gross_amount = 0;
      foreach ($params['item_details'] as $item) {
        $gross_amount += $item['quantity'] * $item['price'];
      }
      $payloads['transaction_details']['gross_amount'] = $gross_amount;
    }

    $payloads = array_replace_recursive($payloads, $params);

    if (Veritrans_Config::$isSanitized) {
      Veritrans_Sanitizer::jsonRequest($payloads);
    }

    $result = Veritrans_ApiRequestor::post(
        Veritrans_Config::getBaseUrl() . '/charge',
        $payment['veritrans_server_key'],
        $payloads);
    if($result){
	    $button = '<div class="tc"><input type="button" οnclick="window.open(\''.$result->redirect_url.'\')" value="' .$GLOBALS['_LANG']['pay_button']. '" /></div>';
    }
	else{
	    $button = '<div class="tc"><input type="button" οnclick="window.location.reload();" value="' .$GLOBALS['_LANG']['pay_button']. '" /></div>';
	}
	return $button;
	
  }
  
  /* respond */
  public function respond(){
	 $action = $_REQUEST['action'];
	 //notification
	 if($action=='notification'){
	    $notif = new Veritrans_Notification();
		$order_id = $notif->order_id;
	 }
	 //finish
	 else{
	    $order_id = $_REQUEST['order_id'];
	 }
	 $status = Veritrans_Transaction::status($order_id);
	 $transaction = $status->transaction_status;
     $fraud = $status->fraud_status;
	 if ($transaction == 'capture') {
	    if ($fraud == 'challenge') {
	       // TODO Set payment status in merchant's database to 'challenge'
	    }
	    else if ($fraud == 'accept') {
	       // TODO Set payment status in merchant's database to 'success'
		   /* 檢查支付的金額是否相符 */
           if (!check_money($status->custom_field1, $status->gross_amount)){
               return false;
           }
		   else{
		       /* 改變訂單狀態 */
               order_paid($status->custom_field1, PS_PAYED, $action_note = 'paid by veritrans at '.$status->transaction_time);
               return true;
		   }
	    }
     }
     else if ($transaction == 'cancel') {
	    if ($fraud == 'challenge') {
	       // TODO Set payment status in merchant's database to 'failure'
	    }
	    else if ($fraud == 'accept') {
	       // TODO Set payment status in merchant's database to 'failure'
	    }
     }
     else if ($transaction == 'deny') {
        // TODO Set payment status in merchant's database to 'failure'
     }
	 return false;
  }
}
?>

第二步:爲veritrans.php新建語言文件,在languages/en_us/payment下,新建veritrans.php

<?php

/**
 * ECSHOP Veritrans language file
 * ============================================================================
 * All right reserved (C) 2005-2011 Beijing Yi Shang Interactive Technology
 * Development Ltd.
 * Web site: http://www.ecshop.com
 * ----------------------------------------------------------------------------
 * This is a free/open source software;it means that you can modify, use and
 * republish the program code, on the premise of that your behavior is not for
 * commercial purposes.
 * ============================================================================
 * $Author: yuanjiang $
 * $Id: veritrans.php 17217 2011-01-19 06:29:08Z yuanjiang $
 */

global $_LANG;

$_LANG['veritrans']            = 'Veritrans';
$_LANG['veritrans_desc']       = 'veritrans is the online payment for Indonesia eCommerce';
$_LANG['veritrans_client_key']    = 'client key';
$_LANG['veritrans_server_key']    = 'server key';
$_LANG['pay_button']        = 'Pay in Veritrans immediately';
?>

第三步:將veritrans的demo中的證書cacert.pem上傳到ecshop的cert下,並改名爲veritrans.pem

以上三步就完成了veritrans支付的全過程。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章